diff --git a/.deepsource.toml b/.deepsource.toml index 2dfb9d157..cc615ff47 100644 --- a/.deepsource.toml +++ b/.deepsource.toml @@ -2,11 +2,10 @@ version = 1 [[analyzers]] name = "javascript" -enabled = true [analyzers.meta] plugins = ["react"] + environment = ["nodejs"] [[transformers]] name = "prettier" -enabled = true \ No newline at end of file diff --git a/.env b/.env index 494d26fc3..ea6e0a209 100644 --- a/.env +++ b/.env @@ -1,7 +1,8 @@ -VITE_DUMMYGRAM_APIKEY =AIzaSyAldAwalnW6viLMQR-djtoUudQNWTZREOc -VITE_DUMMYGRAM_AUTHDOMAIN =dummy-gram.firebaseapp.com -VITE_DUMMYGRAM_PROJECTID = dummy-gram -VITE_DUMMYGRAM_STORAGEBUCKET = dummy-gram.appspot.com -VITE_DUMMYGRAM_MESSAGINGSENDERID =329994030699 -VITE_DUMMYGRAM_APPID = 1:329994030699:web:4d6e02e440b5def1066b2e -VITE_DUMMYGRAM_MEASUREMENTID = G-E5KS3423ZK +VITE_DUMMYGRAM_APIKEY = AIzaSyCngWCAMuh-3lOk_unlhOes9otDo2Go_kw +VITE_DUMMYGRAM_AUTHDOMAIN = dummy-graham.firebaseapp.com +VITE_DUMMYGRAM_PROJECTID = dummy-graham +VITE_DUMMYGRAM_STORAGEBUCKET = dummy-graham.appspot.com +VITE_DUMMYGRAM_MESSAGINGSENDERID = 1039947824283 +VITE_DUMMYGRAM_APPID = 1:1039947824283:web:b8658e4fdf5b6f90959a3e +VITE_DUMMYGRAM_MEASUREMENTID = G-56JCX3KWGS +VITE_DUMMYGRAM_DBURL = https://dummy-graham-default-rtdb.asia-southeast1.firebasedatabase.app diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index 024526579..1f4f8b2ea 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -14,7 +14,7 @@ body: id: reproduction attributes: label: Steps to reproduce - description: Steps to reproduce the bug that you found ! + description: Steps to reproduce the bug that you found! validations: required: true @@ -49,3 +49,21 @@ body: description: Is there anything else we should know about this bug? validations: required: false + + - type: checkboxes + id: terms + attributes: + label: "Record" + options: + - label: I agree to follow this project's Code of Conduct + required: true + - label: I have checked the existing issues + - label: I am a participant of a program + - label: I want to work on this issue + - type: textarea + id: optionalinfo + attributes: + label: Optional information + description: Which program you`re participating from? + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/docs.yml b/.github/ISSUE_TEMPLATE/docs.yml index e79b6e2e7..aa4b8266d 100644 --- a/.github/ISSUE_TEMPLATE/docs.yml +++ b/.github/ISSUE_TEMPLATE/docs.yml @@ -24,3 +24,13 @@ body: description: Is there anything else we should know about this issue? validations: required: false + - type: checkboxes + id: terms + attributes: + label: "Record" + options: + - label: I agree to follow this project's Code of Conduct + required: true + - label: I have checked the existing issues + - label: I'm a GSSoC'23 contributor + - label: I want to work on this issue diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 139c28e60..ed22b058d 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -24,3 +24,13 @@ body: description: Is there anything else we should know about this idea? validations: required: false + - type: checkboxes + id: terms + attributes: + label: "Record" + options: + - label: I agree to follow this project's Code of Conduct + required: true + - label: I have checked the existing issues + - label: I'm a GSSoC'23 contributor + - label: I want to work on this issue diff --git a/.github/ISSUE_TEMPLATE/other.yml b/.github/ISSUE_TEMPLATE/other.yml index e14996c3d..40a9beeba 100644 --- a/.github/ISSUE_TEMPLATE/other.yml +++ b/.github/ISSUE_TEMPLATE/other.yml @@ -20,3 +20,13 @@ body: description: Is there anything else we should know about this issue? validations: required: false + - type: checkboxes + id: terms + attributes: + label: "Record" + options: + - label: I agree to follow this project's Code of Conduct + required: true + - label: I have checked the existing issues + - label: I'm a GSSoC'23 contributor + - label: I want to work on this issue diff --git a/.github/ISSUE_TEMPLATE/styles.yml b/.github/ISSUE_TEMPLATE/styles.yml new file mode 100644 index 000000000..7f6fd26ac --- /dev/null +++ b/.github/ISSUE_TEMPLATE/styles.yml @@ -0,0 +1,39 @@ +name: Style Changing Request +description: Suggest a style design +title: '[style]: ' +labels: ['enhancement'] + +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this template! + - type: textarea + id: style-idea + attributes: + label: What's the style idea? + placeholder: Add descriptions + value: 'We need to improve...' + validations: + required: true + - type: textarea + id: screenshots + attributes: + label: Add screenshots + description: Add screenshots to demonstrate the idea + placeholder: Add screenshots + value: 'Add screenshots here' + - type: checkboxes + id: terms + attributes: + label: Code of Conduct + description: By submitting this issue, you agree to follow our Code of Conduct + options: + - label: I agree to follow this project's Code of Conduct + required: true + - label: I have read the [Contributing Guidelines](https://github.com/narayan954/dummygram/blob/master/CONTRIBUTING.md) + required: true + - label: I agree to follow this project's [Code of Conduct](https://github.com/narayan954/dummygram/blob/master/CODE_OF_CONDUCT.md) + required: true + - label: I'm a GSSoC'23 contributor + - label: I want to work on this issue diff --git a/.github/workflows/assigner.yml b/.github/workflows/assigner.yml new file mode 100644 index 000000000..dd623f641 --- /dev/null +++ b/.github/workflows/assigner.yml @@ -0,0 +1,44 @@ +# name: Assigner + +# on: +# issue_comment: +# types: [created] + +# jobs: +# slash_assign: +# # If the acton was triggered by a new comment that starts with `/assign` +# # or a on a schedule +# if: > +# (github.event_name == 'issue_comment' && startsWith(github.event.comment.body, '/assign')) || github.event_name == 'workflow_dispatch' +# runs-on: ubuntu-latest +# steps: +# - name: Assign the user or unassign stale assignments +# uses: JasonEtco/slash-assign-action@v0.0.3 +# with: +# assigned_label: Assigned +# days_until_warning: 3 +# days_until_unassign: 4 +# stale_assignment_label: Stale +# assigned_comment: "This issue [has been assigned]({{ comment.html_url }}) to {{ comment.user.login }}!\nIt will become unassigned if it is not closed within {{ totalDays }} days. A maintainer can also add the **{{ inputs.pin_label }}** label to prevent it from being unassigned." +# fail_comment: "This issue is already assigned to a contributor." + +# - name: Message failure +# if: ${{ failure() }} +# uses: actions/github-script@v4 +# with: +# script: | +# github.issues.createComment({ +# issue_number: context.issue.number, +# owner: context.repo.owner, +# repo: context.repo.repo, +# body: 'The issue is already assigned!\nPlease find/create a new issue to contribute to.\nYou can safely disregard the failed workflow notification for this issue. ❌', +# }); +# - name: Checkout code +# uses: actions/checkout@main +# - name: Run Action +# uses: Suvraneel/Issue_Watcher@main +# with: +# token: "${{ secrets.GITHUB_TOKEN }}" +# author: "${{github.actor}}" +# repo: narayan954/dummygram #Change the Repo name +# maxIssue: 1 diff --git a/.github/workflows/close_old_issues.yaml b/.github/workflows/close_old_issues.yaml new file mode 100644 index 000000000..61d211ead --- /dev/null +++ b/.github/workflows/close_old_issues.yaml @@ -0,0 +1,34 @@ +# name: Close Old Issues +# on: +# schedule: +# - cron: "0 0 * * *" + +# jobs: +# close-issues: +# runs-on: ubuntu-latest + +# steps: +# - name: Checkout Repository +# uses: actions/checkout@v3 + +# - name: Close Old Issues +# run: | +# open_issues=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ +# "https://api.github.com/repos/${{ github.repository }}/issues?state=open" \ +# | jq -r '.[] | .number') + +# for issue in $open_issues; do +# # Get the last updated timestamp of the issue +# last_updated=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ +# "https://api.github.com/repos/${{ github.repository }}/issues/$issue" \ +# | jq -r '.updated_at') + +# days_since_update=$(( ( $(date +%s) - $(date -d "$last_updated" +%s) ) / 86400 )) + +# if [ $days_since_update -gt 7 ]; then # Modify the condition to check if days_since_update is greater than 7 +# curl -s -X PATCH -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ +# -H "Accept: application/vnd.github.v3+json" \ +# -d '{"state":"closed"}' \ +# "https://api.github.com/repos/${{ github.repository }}/issues/$issue" +# fi +# done diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 000000000..3ed2906da --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,77 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ "master" ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ "master" ] + schedule: + - cron: '43 3 * * 6' + +jobs: + analyze: + name: Analyze + runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} + timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }} + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'javascript' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby', 'swift' ] + # Use only 'java' to analyze code written in Java, Kotlin or both + # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both + # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + + + # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + + # If the Autobuild fails above, remove it and uncomment the following three lines. + # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. + + # - run: | + # echo "Run, Build Application using script" + # ./location_of_script_within_repo/buildscript.sh + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{matrix.language}}" diff --git a/.github/workflows/greetings.yml b/.github/workflows/greetings.yml index a1a352e6f..34bf39f78 100644 --- a/.github/workflows/greetings.yml +++ b/.github/workflows/greetings.yml @@ -1,17 +1,34 @@ name: Greetings -on: [pull_request_target, issues] +on: + fork: + push: + branches: [main] + issues: + types: [opened] + pull_request_target: + types: [opened] jobs: greeting: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - uses: actions/first-interaction@v1 + continue-on-error: true + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + issue-message: "Hi there ${{ github.actor }}!, welcome to Dummygram :)" + pr-message: "Hi there ${{ github.actor }}!, congratulations on your first pull request :)" + + welcome: runs-on: ubuntu-latest - permissions: - issues: write - pull-requests: write steps: - - uses: actions/first-interaction@v1 - continue-on-error: true - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - issue-message: "Hi there, Thanks a lot for raising the issue, we'll look into it asap. Also please mention if you wish to work on the issue as well so you could be assigned" - pr-message: "Hi there, Thanks a lot for your first pull request, we'll be reviewing it asap :)" + - uses: actions/checkout@v3 + - uses: EddieHubCommunity/gh-action-community/src/welcome@main + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + issue-message: "Hello ${{ github.actor }}! \n Thank you for raising this issue! 😊 Your contribution is valuable to us! 😊 \n\nPlease make sure to follow our [Contributing Guidelines. 💪🏻](https://github.com/narayan954/dummygram/blob/master/CONTRIBUTING.md) \n\nOur reviewers shall carefully assess the issue and reach out to you soon! 😇 \n We appreciate your patience! " + pr-message: "Thank you ${{ github.actor }}! for creating this pull request and contributing to Dummygram! 💗\n\n The maintainers will review this Pull Request and provide feedback as soon as possible! 😇\nWe appreciate your patience and contribution, Keep up the great work! 😀" diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml new file mode 100644 index 000000000..b8374ebfc --- /dev/null +++ b/.github/workflows/linting.yml @@ -0,0 +1,21 @@ +# name: Linting + +# on: [push, pull_request] + +# jobs: + +# Linting: + +# runs-on: ubuntu-latest + +# steps: + +# - name: Checkout +# uses: actions/checkout@v3 +# with: +# ref: ${{ github.head_ref }} + +# - name: Lint code with prettier +# uses: creyD/prettier_action@v4.3 +# with: +# prettier_options: --write **/*.{js,md} diff --git a/.gitignore b/.gitignore index 32d5008b3..ceb20f25b 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,8 @@ dist-ssr *.njsproj *.sln *.sw? +*.lock +vite.config.js.* # testing /coverage @@ -45,3 +47,4 @@ yarn-debug.log* yarn-error.log* pnpm-debug.log* lerna-debug.log* +.env diff --git a/.husky/commit-msg b/.husky/commit-msg new file mode 100755 index 000000000..b56767669 --- /dev/null +++ b/.husky/commit-msg @@ -0,0 +1,4 @@ +#!/usr/bin/env sh +. "$(dirname -- "$0")/_/husky.sh" + +npx --no -- commitlint --edit "$1" diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 000000000..de8114db4 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,5 @@ +{ + "useTabs": false, + "tabWidth": 2, + "trailingComma": "all" +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f3b835f7e..45d6ee0c2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -60,7 +60,7 @@ Open Source projects always have something to workon and improves with each new You have forked the project you want to contribute to your github account. To get this project on your development machine we use clone command of git. -`$ git clone https://github.com//.git` +`$ git clone https://github.com//.git` Now you have the project on your local machine. ### ADD A REMOTE (UPSTREAM) TO ORIGINAL PROJECT REPOSITORY @@ -95,6 +95,57 @@ This will create a new branch out of master branch. Now start working on the pro The first command adds all the files or you can add specific files by removing -a and adding the file names. The second command gives a message to your changes so you can know in future what changes this commit makes. If you are solving an issue on original repository, you should add the issue number like #35 to your commit message. This will show the reference to commits in the issue. +### Commit Message Guidelines using Commitlint + +We follow a standardized commit message format using Commitlint to ensure consistency and clarity in our commit history. Each commit message should adhere to the following guidelines: + +1. **Type**: The commit type must be one of the following: + + - `feat`: A new feature or enhancement. + - `fix`: A bug fix. + - `docs`: Documentation changes. + - `style`: Code style changes (e.g., formatting, semicolons). + - `refactor`: Code refactorings with no feature changes or bug fixes. + - `test`: Adding or improving tests. + - `chore`: General maintenance tasks, build changes, etc. + +2. **Scope** (Optional): The scope provides context for the commit, indicating the specific part of the project being affected. Use a short description in lowercase (e.g., `auth`, `navbar`, `README`). + +3. **Description**: A brief and meaningful description of the changes made. Start with a capital letter and use the imperative mood (e.g., "Add new feature" instead of "Added new feature"). + +4. **Issue reference** (Optional): Include the issue number associated with the commit (e.g., `#123`). + +### Examples: + +#### Valid Commit Messages: + +- `feat: Add user authentication feature` +- `fix(auth): Resolve login page redirect issue` +- `docs: Update installation instructions` +- `style: Format code according to project guidelines` +- `refactor(navbar): Improve responsiveness` +- `test: Add unit tests for API endpoints` +- `chore: Update dependencies to latest versions` +- `fix: Handle edge case in data processing (#456)` + +#### Invalid Commit Messages: + +- `Added new stuff` +- `Fixed a bug` +- `Updated code` +- `auth feature update` +- `chore: fixed some stuff` + +### Commit Example with Commitlint: + +```bash +git commit -m "feat(auth): Implement user signup process (#789)" +``` + +Remember to run `commitlint` before pushing your changes to ensure your commit messages meet the guidelines. + +By following these guidelines, we can maintain a clean commit history that is easy to understand and helps us effectively track changes. If you have any questions or need further assistance, feel free to ask! Happy contributing! + ### REBASE YOUR FEATURE BRANCH WITH UPSTREAM- It can happen that your feature takes time to complete and other contributors are constantly pushing code. After completing the feature your feature branch should be rebase on latest changes to upstream master branch. diff --git a/FlowOfControl.md b/FlowOfControl.md index a3bbb696e..88917bd38 100644 --- a/FlowOfControl.md +++ b/FlowOfControl.md @@ -2,7 +2,7 @@ ## Opening Screen - +opening screen You can SIGNIN or SIGNUP here and also view posts posted on dummygram.
@@ -10,21 +10,21 @@ You can SIGNIN or SIGNUP here and also view posts posted on dummygram. ## SIGNUP Dialog - +signup dialog

## SIGNIN Dialog - +signin dialog

## HOME Page - +home page Now, you can create new post, like and comment on previous posts.
@@ -32,21 +32,21 @@ Now, you can create new post, like and comment on previous posts. ## New Post dialog - +new post dialog

## New Post Preview dialog - +new post preview dialog

## Post-posting - +post posting "Post was uploaded successfully!" will appear at right top. You can view your post now. @@ -55,7 +55,7 @@ You can view your post now. ## Adding Reactions in Comments - +Adding Reactions in Comments You can add reaction in comments by clicking on emoji tab.
@@ -63,7 +63,7 @@ You can add reaction in comments by clicking on emoji tab. ## Comment Dialog - +comment dialog You can view all comments on post on this dialog.
@@ -71,7 +71,7 @@ You can view all comments on post on this dialog. ## Theme Switching - +theme switching You can switch between Light mode and Dark mode using bottom-right button.
@@ -79,6 +79,6 @@ You can switch between Light mode and Dark mode using bottom-right button. ## LOGOUT - +logout You can logout using top-right "LOGOUT" button on nav bar. "Logged out Successfully!" will appear at right top. diff --git a/README-HINDI.md b/README-HINDI.md deleted file mode 100644 index d37ba583f..000000000 --- a/README-HINDI.md +++ /dev/null @@ -1,215 +0,0 @@ -
- -Dummygram - -[लाइव देखें!](https://dummy-gram.web.app/) - -### _इंस्टाग्राम_, डमीफाइड - -![Issues](https://img.shields.io/github/issues/narayan954/dummygram?color=brightgreen) -![Pull requests](https://img.shields.io/github/issues-pr/narayan954/dummygram) -![Forks](https://img.shields.io/github/forks/narayan954/dummygram) -![Stars](https://img.shields.io/github/stars/narayan954/dummygram) -![Licence](https://img.shields.io/github/license/narayan954/dummygram?color=orange) - ---- - -
- -# डमीग्राम क्या है? - -## दृष्टि - -जब आप ReactJs सीखते हैं तो कुछ परियोजनाओं पर काम करना स्पष्ट प्रतीत होता है और उन परियोजनाओं के लिए आप अपनी रुचि के अनुसार कुछ चुनना चाहते हैं। ReactJs जारी करने वाली कंपनी द्वारा विकसित ऐप के क्लोन के बारे में क्या ख्याल है? हां, आपको यह बात समझ में आ रही होगी, यह एप्लिकेशन मूल रूप से मूल इंस्टाग्राम का एक क्लोन है और इंस्टाग्राम जैसी सुविधाओं को जोड़ता है या वास्तव में ऐसी विशेषताएं जो इंस्टाग्राम में नहीं जोड़ी जा सकती थीं। तो आप किस बात की प्रतीक्षा कर रहे हैं? योगदान करने और सीखने के लिए इस अवसर का उपयोग करें। :smiley: - -## स्थिति - -डमीग्राम सितंबर 2022 से विकास में है और शुरुआत से ही गिटहब का हिस्सा है। हमारी वर्तमान प्राथमिकताएं और हम जिस पर काम कर रहे हैं, वह एक तरह से स्पष्ट है, लेकिन फिर भी हम इसे एक अनूठा रूप देना चाहते हैं और इसे सुविधाओं से भरपूर बनाना चाहते हैं।:sparkles: - -# प्रलेखन - -- विषयसूची - - - [कोडबेस](#कोडबेस) - - - [प्रौद्योगिकियों](#प्रौद्योगिकियों) - - [फ़ोल्डर संरचना](#फ़ोल्डर-संरचना) - - - [प्रोजेक्ट सेटअप](#प्रोजेक्ट-सेटअप) - - - [पहली बार सेटअप](#पहली-बार-सेटअप) - - [स्थापना](#स्थापना) - - [ऐप को स्थानीय रूप से चलाना](#ऐप-को-स्थानीय-रूप-से-चलाना) - - - [ओपन सोर्स के साथ शुरुआत कैसे करें](#ओपन-सोर्स-के-साथ-शुरुआत-कैसे-करें) - - [डमीग्राम का उपयोग कैसे करें](#डमीग्राम-का-उपयोग-कैसे-करें) - - [योगदान](#योगदान) - - [नियम](#नियम) - - [ओपन सोर्स प्रोग्राम](#ओपन-सोर्स-प्रोग्राम) - - [लाइसेंस](#लाइसेंस) - -## कोडबेस - -### प्रौद्योगिकियों - -जमीनी नियमों से हटकर, आइए इस मोनो रेपो की मोटे वास्तुकला के बारे में बात करते हैं: - -**फ्रंटेंड जावास्क्रिप्ट**: हम अपने फ्रंटएंड ऐप्स को सशक्त बनाने के लिए रिएक्ट का उपयोग करते हैं। इस कोडबेस में आपके द्वारा स्पर्श किए जाने वाले लगभग सभी कोड जावास्क्रिप्ट होंगे। -JS - -यहां हमारे द्वारा उपयोग की जाने वाली सभी बड़ी तकनीकों की सूची दी गई है: - -- **रिएक्ट**: फ्रंटएंड रिएक्ट ऐप REACT - -- **फायरबेस**: डेटा संग्रहण और प्रमाणीकरण FIREBASE - -### फ़ोल्डर संरचना - -```sh - -dummygram/ - -├── public # सार्वजनिक फ़ाइलें दृश्यपटल पर उपयोग की जाती हैं - -├── src # प्रतिक्रिया में दृश्यपटल कोड - -``` - -## प्रोजेक्ट सेटअप - -### पहली बार सेटअप - -डमीग्राम को स्थानीय रूप से चलाने का पहला चरण रिपॉजिटरी को क्लोन करके कोड डाउनलोड करना है: - -```sh - -git clone git@github.com:narayan954/dummygram.git - -``` - -यदि आपको `ssh` का उपयोग करके `Permission denied` त्रुटि मिलती है तो यहां [यहां](https://help.github.com/articles/error-permission-denied-publickey/) देखें - -या `https` लिंक का फ़ॉलबैक के रूप में उपयोग करें। - -```sh - -git clone https://github.com/narayan954/dummygram.git - -``` - -### स्थापना - -डमीग्राम में एक ही स्थापना चरण है: - -- **निर्भरताओं को स्थापित करें**: - -```sh - -npm install - -``` - -आपने अब सब कुछ इंस्टॉल करना समाप्त कर लिया है! चलो शुरू करो :100: - -Ps: यदि आपको निर्भरताएँ स्थापित करने में त्रुटि हो रही है, तो npm install के साथ --force कमांड आज़माएँ। उदाहरण के लिए - -```sh - -npm install --force - -``` - -अब आप ऐप को स्थानीय रूप से चलाने और अपने स्थानीय उदाहरण में साइन इन करने के लिए तैयार हैं! - -### ऐप को स्थानीय रूप से चलाना - -#### सर्वर शुरू करें - -डेवलपमेंट सर्वर शुरू करने के लिए रन करें - -```sh -npm start -``` - -
- -## ओपन सोर्स के साथ शुरुआत कैसे करें - -यहां ओपन सोर्स के साथ आरंभ करने के तरीके के बारे में एक त्वरित जानकारी दी गई है, सबसे पहले आइए कुछ बुनियादी शब्दावली जानते हैं: - -- गिट: एक वर्जनिंग सिस्टम है जो आपको अपने स्थानीय कंप्यूटर पर अपना कोड और कोड इतिहास स्टोर करने देता है और उस कोड को साझा करने की अनुमति देता है -- गिटहब: एक सर्वर है जो आपको इतिहास को एक डेटाबेस में संग्रहीत करने देता है -- खुला स्रोत: यदि आप GitHub पर कोड देख सकते हैं तो एक परियोजना को खुला स्रोत कहा जाता है -- फोर्क: यह एक कॉपी है जिसे आप GitHub पर एक प्रोजेक्ट बनाते हैं, यह आपके रिपॉजिटरी में जुड़ जाता है -- रिपॉजिटरी: GitHub पर एक प्रोजेक्ट को रिपॉजिटरी कहा जाता है -- पुल अनुरोध: यह एक परियोजना में किए जाने वाले प्रस्तावित मुद्दे के लिए एक समाधान है, इसमें आपको परियोजना में एक फ़ाइल का संपादन करना शामिल है। -- मुद्दा: एक समस्या एक परिवर्तन है जो एक परियोजना में किया जाना चाहिए, एक बग, एक नई सुविधा या एक परियोजना के लिए एक सुझाव हो सकता है -- शाखा: एक शाखा एक नया कार्यक्षेत्र है जो डिफ़ॉल्ट कार्यक्षेत्र (मुख्य या मास्टर) से प्राप्त होता है, यह आपको मूल कोड को प्रभावित किए बिना किसी चीज़ पर काम करने की अनुमति देता है - -अब आप कुछ बुनियादी शर्तों को जानते हैं, तो आइए जानें कि ओपन सोर्स को बेहतर ढंग से समझने के लिए कुछ संसाधनों के साथ कैसे शुरुआत करें: - -- [Git और Github का क्रैश कोर्स](https://www.youtube.com/watch?v=apGV9Kg7ics) - वीडियो -- [ओपन सोर्स के लिए एक पूरी गाइड](https://www.youtube.com/watch?v=yzeVMecydCE) - वीडियो -- [ओपन सोर्स के लिए गाइड](https://www.freecodecamp.org/news/how-to-contribute-to-open-source-projects-beginners-guide/) - लेख - -## डमीग्राम का उपयोग कैसे करें - -[नियंत्रण का प्रवाह](FlowOfControl.md) - -## योगदान - -**हम अपने इंजीनियरिंग मानकों से मेल खाने वाले किसी भी और सभी योगदानों का दिल से स्वागत करते हैं! :raised_hands:** - -यह कहा जा रहा है, यह कोडबेस आपकी विशिष्ट ओपन सोर्स परियोजना नहीं है क्योंकि यह सीमित दायरे वाला पुस्तकालय या पैकेज नहीं है - यह हमारा संपूर्ण उत्पाद है। - -## नियम - -- **किसी भी फ़ाइल में कोई `console.log` नहीं है**: हम केवल डेवलपमेंट में डीबगिंग जानकारी लॉग करने के लिए कोडबेस में `debug` मॉड्यूल का उपयोग करते हैं। कभी भी ऐसी फाइल न करें जिसमें `console.log` हो क्योंकि सीआई आपके निर्माण को विफल कर देगा। केवल अपवाद त्रुटियां हैं, जिन्हें आप लॉग कर सकते हैं, लेकिन इसके बारे में स्पष्ट होने के लिए आपको `console.error` का उपयोग करना होगा -- **कोड समीक्षाएं**: परियोजना सदस्यों द्वारा किए गए सबमिशन सहित सभी सबमिशन के लिए समीक्षा की आवश्यकता होती है। हम इस उद्देश्य के लिए गिटहब पुल अनुरोधों का उपयोग करते हैं। - -### योगदान और चर्चा दिशानिर्देश - -डमीग्राम पर सभी बातचीत और समुदाय गिटहब के [सामुदायिक दिशानिर्देश](https://help.github.com/en/github/site-policy/github-community-guidelines) और [स्वीकार्य उपयोग नीतियों](https://help.github.com/en/github/site-policy/github-acceptable-use-policies) से सहमत हैं। यह आचार संहिता यहां GitHub पर हमारे योगदानकर्ता समुदाय के भीतर होने वाली सभी बातचीत पर भी लागू होती है। हम मुद्दों पर चर्चा की उम्मीद करते हैं और सकारात्मक, उत्पादक और सम्मानजनक बने रहने के लिए अनुरोध करते हैं। **याद रखें**: उस स्क्रीन के दूसरी तरफ वास्तविक लोग हैं:exclamation: - -### किसी बग की रिपोर्ट करना या किसी फीचर विचार पर चर्चा करना - -यदि आपको डमीग्राम पर कोई तकनीकी बग मिला है या आपके पास उन सुविधाओं के लिए विचार हैं जिन्हें हमें लागू करना चाहिए, तो इश्यू ट्रैकर आपके विचारों को साझा करने के लिए सबसे अच्छी जगह है। इश्यू टेम्प्लेट का पालन करना सुनिश्चित करें और आपको सुनहरा होना चाहिए! ([एक नया मुद्दा खोलने के लिए यहां क्लिक करें](https://github.com/narayan954/dummygram/issues/new)) - -### किसी बग को ठीक करना या कोई नई सुविधा लागू करना - -- यदि आप डमीग्राम पर एक बग पाते हैं और इसे ठीक करने वाला पीआर खोलते हैं तो हम यह सुनिश्चित करने के लिए जितनी जल्दी हो सके इसकी समीक्षा करेंगे कि यह हमारे इंजीनियरिंग मानकों से मेल खाता है। -- यदि आप कोई नई सुविधा लागू करना चाहते हैं, तो पहले इस बात पर चर्चा करने के लिए कोई समस्या खोलें कि वह कैसी दिखेगी। -- यदि आप योगदान करना चाहते हैं लेकिन शुरू करने के लिए अनिश्चित हैं, तो हमारे पास [एक "good first issue" लेबल](https://github.com/narayan954/dummygram/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) है जो नवागंतुक-अनुकूल मुद्दों पर लागू होता है। ["good first issues" की पूरी सूची](https://github.com/narayan954/dummygram/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) पर एक नज़र डालें और अपनी पसंद का कुछ चुनें! -- एक बग को ठीक करना चाहते हैं या एक सहमत सुविधा को लागू करना चाहते हैं? बढ़िया, [स्थानीय सेटअप निर्देश](#first-time-setup) पर जाएं! - -## आचार संहिता - -डमीग्राम अब गिटहब का हिस्सा है। आचार संहिता के लिए, कृपया [GitHub के सामुदायिक दिशानिर्देश](https://help.github.com/en/github/site-policy/github-community-guidelines) और [स्वीकार्य उपयोग नीतियां](https://help.github.com/en/github/site-policy/github-acceptable-use-policies) देखें। - -
- -## ओपन सोर्स प्रोग्राम - -

- -hacktoberfest logo - -

-Light -        -Dark -

- -iwoc program - -

- -## सभी योगदानकर्ताओं को धन्यवाद 💪 - -डमीग्राम को बढ़ने में मदद करने के लिए अपना समय बिताने के लिए बहुत-बहुत धन्यवाद। बहुत-बहुत धन्यवाद! 🍻 - -[![Contributors](https://contrib.rocks/image?repo=narayan954/dummygram)](https://github.com/narayan954/dummygram/graphs/contributors) - -## लाइसेंस - -## एमआईटी लाइसेंस, [लाइसेंस](LICENSE) फ़ाइल देखें। diff --git a/README.md b/README.md index 940dfac77..0c550e88d 100644 --- a/README.md +++ b/README.md @@ -1,52 +1,90 @@ +
-Dummygram +Dummygram [See Live!](https://narayan954.github.io/dummygram/) ### _Instagram_, dummified -![Issues](https://img.shields.io/github/issues/narayan954/dummygram?color=brightgreen) -![Pull requests](https://img.shields.io/github/issues-pr/narayan954/dummygram) -![Forks](https://img.shields.io/github/forks/narayan954/dummygram) -![Stars](https://img.shields.io/github/stars/narayan954/dummygram) -![Licence](https://img.shields.io/github/license/narayan954/dummygram?color=orange) +
+ badge + badge + badge +
+ badge + badge + badge + badge +
+ badge + badge + badge +
---
-# What is Dummygram? +

About Dummygram

## Vision -When you learn ReactJs it seems obvious to work on some projects and for the projects you might want to choose something that interests you. How about a clone of the app developed by the company that released ReactJs ? Yes, you might be getting the point, this application is basically a clone of the original Instagram and tends to add features like instagram or in fact the features that could not have been added in the instagram. So what are you waiting for? Use this opportunity to contribute and learn. :smiley: +When you start learning ReactJS, it's crucial to work on projects that interest you. One exciting idea is to create a clone of an app owned by the company that created ReactJS. In this case, let's build an Instagram clone. It will have similar features to the popular social media platform, but we can also add some new functions. + +Creating an Instagram clone is a fantastic chance for learning and improvement. By doing this project, you can contribute to the ReactJS community while also growing your knowledge and skills. It will be a fun way to practice and make something cool! ## Status -Dummygram has been in development since September 2022 and is part of GitHub since the very beginning. Our current priorities and what we are working on is kind of obvious, but still we want to give it a unique look and make it feature rich.:sparkles: +Since September 2022, Dummygram has been a project that the team is passionate about and committed to making excellent. They put the project on GitHub from the beginning to work together with the community and welcome contributions from others. -# Docs +The team has clear priorities and ongoing work to improve Dummygram, but they also focus on making it look unique and attractive. They have a great sense of design and want the app to stand out from other similar apps. Using ReactJS, they can add custom styles and create a fun and exciting experience for users. -- Table of Contents +Overall, the Dummygram team loves what they do and wants to make the app visually stunning and enjoyable for everyone! - - [Codebase](#codebase) +## Features - - [Technologies](#technologies) - - [Folder Structure](#folder-structure) +**User Authentication:** DummyGram includes a user authentication system, allowing users to create accounts, log in, and log out securely. This feature ensures that only authenticated users can access and interact with the app. - - [Project Setup](#project-setup) +**Posts:** Users can create posts and share them with others. Posts can include various types of content, such as images, videos, or text. Users can upload media files from their devices or provide URLs for online content. These posts are displayed in a feed-like format. + +**Commenting:** DummyGram enables users to comment on posts. Users can write and submit comments on individual posts, engaging in conversations and discussions with other users. + +**Like Feature:** Users can express their appreciation for posts by liking them. This feature allows users to show their support and interest in specific content shared on DummyGram. +**Delete Functionality:** DummyGram allows users to delete their own posts. This feature provides users with control over their content, enabling them to remove posts they no longer wish to keep on the platform. + +**Frontend Framework:** The user interface of DummyGram is built using ReactJS, a popular JavaScript library for building interactive user interfaces. ReactJS allows for efficient rendering of components and provides a smooth and responsive user experience. + +**Backend and Data Storage:** DummyGram utilizes Firebase as the backend service for storing user data, posts, and comments. Firebase provides a scalable and reliable platform for handling backend functionalities and offers real-time database capabilities, ensuring efficient data storage and retrieval. + +# Table of Contents + +- [Table of Contents](#table-of-contents) + - [Codebase](#codebase) + - [Technologies](#technologies) + - [Folder structure](#folder-structure) + - [Project Setup](#project-setup) - [First time setup](#first-time-setup) - [Installation](#installation) - [Running the app locally](#running-the-app-locally) - + - [Start the servers](#start-the-servers) - [Testing](#testing) + - [Introduction to Cypress](#introduction-to-cypress) + - [Start Testing](#start-testing) + - [Create New Test Cases](#create-new-test-cases) - [How to get started with Open Source](#how-to-get-started-with-open-source) - [How to use Dummygram](#how-to-use-dummygram) - [Contributing](#contributing) - [Rules](#rules) - - [Open Source Programs](#open-source-programs) + - [Contributions and discussion guidelines](#contributions-and-discussion-guidelines) + - [Reporting a bug or discussing a feature idea](#reporting-a-bug-or-discussing-a-feature-idea) + - [Fixing a bug or implementing a new feature](#fixing-a-bug-or-implementing-a-new-feature) + - [Code of Conduct](#code-of-conduct) + - [Programs](#programs) + - [Feedback](#feedback) + - [👩🏽‍💻 Contributing](#-contributing) + - [Thanks to all Contributors 💪](#thanks-to-all-contributors-) - [License](#license) ## Codebase @@ -56,7 +94,7 @@ Dummygram has been in development since September 2022 and is part of GitHub sin With the ground rules out of the way, let's talk about the coarse architecture of this mono repo: **Frontend JavaScript**: We use React to power our frontend apps. Almost all of the code you'll touch in this codebase will be JavaScript. -JS +badge Here is a list of all the big technologies we use: @@ -82,6 +120,12 @@ dummygram/ The first step to running dummygram locally is downloading the code by cloning the repository: +
Video Demo to run Dummygram in your local under 2 minutes
+ + + +
+ ```sh git clone git@github.com:narayan954/dummygram.git @@ -136,6 +180,9 @@ npm start ## Testing +
+ Instructions + Here we will see, how to run tests and how to setup new test cases. _We will be using Cypress for our testing purposes._ @@ -218,21 +265,22 @@ E2E Files: `/cypress/e2e/` ```
+ --- ## How to get started with Open Source -Here's a quick run down on how to get started with open source, first of all let's know some basic terminologies: +Here's a quick rundown on how to get started with open source. First of all, let's know some basic terminologies: -- Git: is a versioning system that let's you store your code and code history on your local computer preventing loses and allowing sharing of that code -- Github: is a server that let's you store the history in a database -- Open Source: A project is said to be open sourced if you can see the code on GitHub -- Fork: This is a copy that you make of a project on GitHub, it gets added to your repositories -- Repository: A project on GitHub is called a repository -- Pull Request: This is a fix for an issue proposed to be done in a project, this consists of you editing a file in the project. -- Issue: An issue is a change that should be done in a project, can be a bug, a new feature or a suggestion to a project -- Branch: A branch is a new workspace derived from the default workspace(main or master), it allows you to work on something without affecting the original code +- **Git:** This is a versioning system that lets you store your code and code history on your local computer, preventing loss and allowing sharing of that code. +- **Github:** This is a server that lets you store the history in a database. +- **Open Source:** A project is said to be open sourced if you can see the code on GitHub. +- **Fork:** This is a copy that you make of a project on GitHub, it gets added to your repositories. +- **Repository:** A project on GitHub is called a repository. +- **Pull Request:** This is a fix for an issue proposed to be done in a project, this consists of you editing a file in the project. +- **Issue:** An issue is a change that should be done in a project, can be a bug, a new feature or a suggestion to a project. +- **Branch:** A branch is a new workspace derived from the default workspace(main or master) that allows you to work on something without affecting the original code. Now you know some basic terms, let's get into how to get started with some resources to let you understand open source better: @@ -282,29 +330,37 @@ Dummygram is now part of GitHub. For code of conduct, please see [GitHub's Commu
-##

Open Source Programs

+## Programs +
+ List

hacktoberfest logo

-codepeak -        -kwoc +codepeak +  +kwoc +

+ +

+Girlscript Summer of Code Logo +  +jwoc program

iwoc program -jwoc program

+
## Feedback If you have any feedback or suggestions please reach out to the Project-Maintainer [Narayan Soni](https://github.com/narayan954)
-For further queries and whereabouts you can communicate and reach out to the owner through Linkedin & email +For further queries and whereabouts you can communicate and reach out to the owner through Linkedin & email
## 👩🏽‍💻 Contributing @@ -321,7 +377,14 @@ For further queries and whereabouts you can communicate and reach out to the own Thanks a lot for spending your time helping dummygram grow. Thanks a lot! Keep rocking 🍻 -[![Contributors](https://contrib.rocks/image?repo=narayan954/dummygram)](https://github.com/narayan954/dummygram/graphs/contributors) +
+ Contributors +
+ + contributor graph + +
+
## License @@ -333,3 +396,4 @@ Thanks a lot for spending your time helping dummygram grow. Thanks a lot! Keep r

Do checkout the other repos 💫

+

(Back to top)

diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..d0c1cb78d --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,16 @@ +# Security Policy + +## Supported Versions + +All releases are self sufficient. + +| Version | Supported | +| ------- | ------------------ | +| 1.2.x | :white_check_mark: | +| 1.1.x | :white_check_mark: | +| 1.0.x | :white_check_mark: | +| < 0.0 | :x: | + +## Reporting a Vulnerability + +Raise an issue mentioning the changes and if the vulnerability is serious, you can mail me at narayansoni954@gmail.com diff --git a/commitlint.config.cjs b/commitlint.config.cjs new file mode 100644 index 000000000..69b4242cc --- /dev/null +++ b/commitlint.config.cjs @@ -0,0 +1,3 @@ +module.exports = { + extends: ["@commitlint/config-conventional"], +}; diff --git a/cypress.config.js b/cypress.config.js deleted file mode 100644 index 17161e32e..000000000 --- a/cypress.config.js +++ /dev/null @@ -1,9 +0,0 @@ -import { defineConfig } from "cypress"; - -export default defineConfig({ - e2e: { - setupNodeEvents(on, config) { - // implement node event listeners here - }, - }, -}); diff --git a/cypress/e2e/spec.cy.js b/cypress/e2e/spec.cy.js deleted file mode 100644 index 34453dfd0..000000000 --- a/cypress/e2e/spec.cy.js +++ /dev/null @@ -1,29 +0,0 @@ -describe("Dummygram Test Suite", () => { - it("Visit Webpage", () => { - cy.visit("https://narayan954.github.io/dummygram/"); - cy.url().should("include", "/login"); - cy.get('button[class^="darkmode-toggle"]').click(); - }); - - it("Toggle Theme Mode", () => { - cy.visit("https://narayan954.github.io/dummygram/"); - cy.get('button[class^="darkmode-toggle"]').click(); - }); - - it("Logging In", () => { - cy.visit("https://narayan954.github.io/dummygram/"); - - cy.get("input[type=text]").click({ force: true }).should("not.be.visible"); - cy.get("input[type=password]") - .click({ force: true }) - .should("not.be.visible"); - cy.contains("Sign In").should("be.visible"); - }); - - // Add New Test Below - - // it("New Test Part", () => { - // cy.visit("https://narayan954.github.io/dummygram/"); - // // Rest Goes here - // }); -}); diff --git a/cypress/fixtures/example.json b/cypress/fixtures/example.json deleted file mode 100644 index 02e425437..000000000 --- a/cypress/fixtures/example.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "Using fixtures to represent data", - "email": "hello@cypress.io", - "body": "Fixtures are a great way to mock data for responses to routes" -} diff --git a/cypress/support/commands.js b/cypress/support/commands.js deleted file mode 100644 index 119ab03f7..000000000 --- a/cypress/support/commands.js +++ /dev/null @@ -1,25 +0,0 @@ -// *********************************************** -// This example commands.js shows you how to -// create various custom commands and overwrite -// existing commands. -// -// For more comprehensive examples of custom -// commands please read more here: -// https://on.cypress.io/custom-commands -// *********************************************** -// -// -// -- This is a parent command -- -// Cypress.Commands.add('login', (email, password) => { ... }) -// -// -// -- This is a child command -- -// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) -// -// -// -- This is a dual command -- -// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) -// -// -// -- This will overwrite an existing command -- -// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) diff --git a/cypress/support/e2e.js b/cypress/support/e2e.js deleted file mode 100644 index 3a2522438..000000000 --- a/cypress/support/e2e.js +++ /dev/null @@ -1,20 +0,0 @@ -// *********************************************************** -// This example support/e2e.js is processed and -// loaded automatically before your test files. -// -// This is a great place to put global configuration and -// behavior that modifies Cypress. -// -// You can change the location of this file or turn off -// automatically serving support files with the -// 'supportFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/configuration -// *********************************************************** - -// Import commands.js using ES2015 syntax: -import "./commands"; - -// Alternatively you can use CommonJS syntax: -// require('./commands') diff --git a/index.html b/index.html index 22de6327a..f4dea37bd 100644 --- a/index.html +++ b/index.html @@ -1,25 +1,57 @@ - + - + + + + + + + + + + + + + + + + + + + + + + DummyGram - -
- - - -
+
+ diff --git a/package-lock.json b/package-lock.json index 616dc78c9..1fe4f37f1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,42 +1,64 @@ { "name": "dummygram", - "version": "0.1.0", + "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "dummygram", - "version": "0.1.0", + "version": "1.0.0", + "license": "MIT", "dependencies": { - "@emotion/react": "^11.10.6", - "@emotion/styled": "^11.10.6", + "@emailjs/browser": "^3.11.0", + "@emotion/react": "^11.11.1", + "@emotion/styled": "^11.11.0", + "@esbuild/win32-x64": "^0.18.11", "@fortawesome/fontawesome-svg-core": "^6.3.0", "@fortawesome/free-brands-svg-icons": "^6.3.0", "@fortawesome/free-solid-svg-icons": "^6.3.0", "@fortawesome/react-fontawesome": "^0.2.0", "@mui/icons-material": "^5.11.11", - "@mui/material": "^5.11.13", - "@mui/styles": "^5.11.13", - "emoji-picker-react": "^4.4.7", + "@mui/material": "^5.13.6", + "@mui/styles": "^5.13.2", + "emoji-picker-react": "^4.4.10", + "file-saver": "^2.0.5", "firebase": "^9.18.0", "notistack": "^3.0.1", "react": "^18.2.0", + "react-color": "^2.19.3", "react-dom": "^18.2.0", + "react-error-boundary": "^4.0.10", "react-icons": "^4.8.0", "react-lazy-load-image-component": "^1.5.6", "react-router-dom": "^6.9.0", + "react-webcam": "^7.0.1", "uuid": "^9.0.0" }, "devDependencies": { + "@commitlint/cli": "^17.6.7", + "@commitlint/config-conventional": "^17.6.7", "@types/react": "^18.0.28", "@types/react-dom": "^18.0.11", "@vitejs/plugin-react": "^3.1.0", - "cypress": "^12.8.1", + "eslint-config-prettier": "^9.0.0", + "eslint-plugin-prettier": "^5.0.0", "gh-pages": "^5.0.0", + "husky": "^8.0.3", + "prettier": "^2.8.8", "react-error-overlay": "^6.0.11", "vite": "^4.2.0" } }, + "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, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/@ampproject/remapping": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", @@ -51,11 +73,12 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dependencies": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" @@ -101,12 +124,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.21.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.1.tgz", - "integrity": "sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", "dev": true, "dependencies": { - "@babel/types": "^7.21.0", + "@babel/types": "^7.23.0", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -149,45 +172,45 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", - "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, "dependencies": { - "@babel/template": "^7.20.7", - "@babel/types": "^7.21.0" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dev": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz", + "integrity": "sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.21.4" }, "engines": { "node": ">=6.9.0" @@ -234,29 +257,29 @@ } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "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.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "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" } @@ -285,12 +308,12 @@ } }, "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { @@ -298,9 +321,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.2.tgz", - "integrity": "sha512-URpaIJQwEkEC2T9Kn+Ai6Xe/02iNaVCuT/PtoRz3GPVJVDpPd7mLo+VddTbhCRU9TXqW5mSrQfXZyi8kDKOVpQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -340,9 +363,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz", - "integrity": "sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.5.tgz", + "integrity": "sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==", "dependencies": { "regenerator-runtime": "^0.13.11" }, @@ -351,33 +374,33 @@ } }, "node_modules/@babel/template": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", - "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.2.tgz", - "integrity": "sha512-ts5FFU/dSUPS13tv8XiEObDu9K+iagEKME9kAbaP7r0Y9KtZJZ+NGndDvWoRAYNpeWafbpFeki3q9QoMD6gxyw==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.21.1", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.21.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.21.2", - "@babel/types": "^7.21.2", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -386,312 +409,969 @@ } }, "node_modules/@babel/types": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.2.tgz", - "integrity": "sha512-3wRZSs7jiFaB8AjxiiD+VqN5DTG2iRvJGQ+qYFrs/654lg6kGTQWIOFjlBo5RaXuAZjBmP3+OQH4dmhqiiyYxw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", "dependencies": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "node_modules/@commitlint/cli": { + "version": "17.6.7", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-17.6.7.tgz", + "integrity": "sha512-nzZmfO5KIOupYppn1MsnYX/80I+KDlxiwkks3CJT0XT+t34UgqGi3eSyEuzgcIjPlORk5/GMaAEiys78iLfGMg==", "dev": true, - "optional": true, + "dependencies": { + "@commitlint/format": "^17.4.4", + "@commitlint/lint": "^17.6.7", + "@commitlint/load": "^17.6.7", + "@commitlint/read": "^17.5.1", + "@commitlint/types": "^17.4.4", + "execa": "^5.0.0", + "lodash.isfunction": "^3.0.9", + "resolve-from": "5.0.0", + "resolve-global": "1.0.0", + "yargs": "^17.0.0" + }, + "bin": { + "commitlint": "cli.js" + }, "engines": { - "node": ">=0.1.90" + "node": ">=v14" } }, - "node_modules/@cypress/request": { - "version": "2.88.11", - "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.11.tgz", - "integrity": "sha512-M83/wfQ1EkspjkE2lNWNV5ui2Cv7UCv1swW1DqljahbzLVWltcsexQh8jYtuS/vzFXP+HySntGM83ZXA9fn17w==", + "node_modules/@commitlint/cli/node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "http-signature": "~1.3.6", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "performance-now": "^2.1.0", - "qs": "~6.10.3", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^8.3.2" + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" }, "engines": { - "node": ">= 6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/@cypress/request/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "node_modules/@commitlint/cli/node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, - "bin": { - "uuid": "dist/bin/uuid" + "engines": { + "node": ">=10.17.0" } }, - "node_modules/@cypress/xvfb": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", - "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==", + "node_modules/@commitlint/cli/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, - "dependencies": { - "debug": "^3.1.0", - "lodash.once": "^4.1.1" + "engines": { + "node": ">=8" } }, - "node_modules/@cypress/xvfb/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "node_modules/@commitlint/config-conventional": { + "version": "17.6.7", + "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-17.6.7.tgz", + "integrity": "sha512-4oTpEUC0HRM54QRHBPMOJW1pETp7usxXn9RuNYNWHcmu8wi1mpws95hvS20u2n6HtIkTn0jfn7vHioCm4AGUTw==", "dev": true, "dependencies": { - "ms": "^2.1.1" + "conventional-changelog-conventionalcommits": "^5.0.0" + }, + "engines": { + "node": ">=v14" } }, - "node_modules/@emotion/babel-plugin": { - "version": "11.10.6", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.6.tgz", - "integrity": "sha512-p2dAqtVrkhSa7xz1u/m9eHYdLi+en8NowrmXeF/dKtJpU8lCWli8RUAati7NcSl0afsBott48pdnANuD0wh9QQ==", + "node_modules/@commitlint/config-validator": { + "version": "17.6.7", + "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-17.6.7.tgz", + "integrity": "sha512-vJSncmnzwMvpr3lIcm0I8YVVDJTzyjy7NZAeXbTXy+MPUdAr9pKyyg7Tx/ebOQ9kqzE6O9WT6jg2164br5UdsQ==", + "dev": true, "dependencies": { - "@babel/helper-module-imports": "^7.16.7", - "@babel/runtime": "^7.18.3", - "@emotion/hash": "^0.9.0", - "@emotion/memoize": "^0.8.0", - "@emotion/serialize": "^1.1.1", - "babel-plugin-macros": "^3.1.0", - "convert-source-map": "^1.5.0", - "escape-string-regexp": "^4.0.0", - "find-root": "^1.1.0", - "source-map": "^0.5.7", - "stylis": "4.1.3" + "@commitlint/types": "^17.4.4", + "ajv": "^8.11.0" + }, + "engines": { + "node": ">=v14" } }, - "node_modules/@emotion/cache": { - "version": "11.10.5", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.5.tgz", - "integrity": "sha512-dGYHWyzTdmK+f2+EnIGBpkz1lKc4Zbj2KHd4cX3Wi8/OWr5pKslNjc3yABKH4adRGCvSX4VDC0i04mrrq0aiRA==", + "node_modules/@commitlint/ensure": { + "version": "17.6.7", + "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-17.6.7.tgz", + "integrity": "sha512-mfDJOd1/O/eIb/h4qwXzUxkmskXDL9vNPnZ4AKYKiZALz4vHzwMxBSYtyL2mUIDeU9DRSpEUins8SeKtFkYHSw==", + "dev": true, "dependencies": { - "@emotion/memoize": "^0.8.0", - "@emotion/sheet": "^1.2.1", - "@emotion/utils": "^1.2.0", - "@emotion/weak-memoize": "^0.3.0", - "stylis": "4.1.3" + "@commitlint/types": "^17.4.4", + "lodash.camelcase": "^4.3.0", + "lodash.kebabcase": "^4.1.1", + "lodash.snakecase": "^4.1.1", + "lodash.startcase": "^4.4.0", + "lodash.upperfirst": "^4.3.1" + }, + "engines": { + "node": ">=v14" } }, - "node_modules/@emotion/hash": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.0.tgz", - "integrity": "sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ==" - }, - "node_modules/@emotion/is-prop-valid": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", - "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", - "dependencies": { - "@emotion/memoize": "^0.8.0" + "node_modules/@commitlint/execute-rule": { + "version": "17.4.0", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-17.4.0.tgz", + "integrity": "sha512-LIgYXuCSO5Gvtc0t9bebAMSwd68ewzmqLypqI2Kke1rqOqqDbMpYcYfoPfFlv9eyLIh4jocHWwCK5FS7z9icUA==", + "dev": true, + "engines": { + "node": ">=v14" } }, - "node_modules/@emotion/memoize": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", - "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" - }, - "node_modules/@emotion/react": { - "version": "11.10.6", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.10.6.tgz", - "integrity": "sha512-6HT8jBmcSkfzO7mc+N1L9uwvOnlcGoix8Zn7srt+9ga0MjREo6lRpuVX0kzo6Jp6oTqDhREOFsygN6Ew4fEQbw==", + "node_modules/@commitlint/format": { + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-17.4.4.tgz", + "integrity": "sha512-+IS7vpC4Gd/x+uyQPTAt3hXs5NxnkqAZ3aqrHd5Bx/R9skyCAWusNlNbw3InDbAK6j166D9asQM8fnmYIa+CXQ==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.10.6", - "@emotion/cache": "^11.10.5", - "@emotion/serialize": "^1.1.1", - "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", - "@emotion/utils": "^1.2.0", - "@emotion/weak-memoize": "^0.3.0", - "hoist-non-react-statics": "^3.3.1" - }, - "peerDependencies": { - "react": ">=16.8.0" + "@commitlint/types": "^17.4.4", + "chalk": "^4.1.0" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "engines": { + "node": ">=v14" } }, - "node_modules/@emotion/serialize": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.1.tgz", - "integrity": "sha512-Zl/0LFggN7+L1liljxXdsVSVlg6E/Z/olVWpfxUTxOAmi8NU7YoeWeLfi1RmnB2TATHoaWwIBRoL+FvAJiTUQA==", + "node_modules/@commitlint/format/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": { - "@emotion/hash": "^0.9.0", - "@emotion/memoize": "^0.8.0", - "@emotion/unitless": "^0.8.0", - "@emotion/utils": "^1.2.0", - "csstype": "^3.0.2" + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@emotion/sheet": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.1.tgz", - "integrity": "sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA==" - }, - "node_modules/@emotion/styled": { - "version": "11.10.6", - "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.10.6.tgz", - "integrity": "sha512-OXtBzOmDSJo5Q0AFemHCfl+bUueT8BIcPSxu0EGTpGk6DmI5dnhSzQANm1e1ze0YZL7TDyAyy6s/b/zmGOS3Og==", + "node_modules/@commitlint/format/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": { - "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.10.6", - "@emotion/is-prop-valid": "^1.2.0", - "@emotion/serialize": "^1.1.1", - "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", - "@emotion/utils": "^1.2.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, - "peerDependencies": { - "@emotion/react": "^11.0.0-rc.0", - "react": ">=16.8.0" + "engines": { + "node": ">=10" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/@emotion/unitless": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz", - "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==" - }, - "node_modules/@emotion/use-insertion-effect-with-fallbacks": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz", - "integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==", - "peerDependencies": { - "react": ">=16.8.0" + "node_modules/@commitlint/format/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/@emotion/utils": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz", - "integrity": "sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw==" - }, - "node_modules/@emotion/weak-memoize": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz", - "integrity": "sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg==" + "node_modules/@commitlint/format/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/@esbuild/android-arm": { - "version": "0.17.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.12.tgz", - "integrity": "sha512-E/sgkvwoIfj4aMAPL2e35VnUJspzVYl7+M1B2cqeubdBhADV4uPon0KCc8p2G+LqSJ6i8ocYPCqY3A4GGq0zkQ==", - "cpu": [ - "arm" - ], + "node_modules/@commitlint/format/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, - "optional": true, - "os": [ - "android" - ], "engines": { - "node": ">=12" + "node": ">=8" } }, - "node_modules/@esbuild/android-arm64": { - "version": "0.17.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.12.tgz", - "integrity": "sha512-WQ9p5oiXXYJ33F2EkE3r0FRDFVpEdcDiwNX3u7Xaibxfx6vQE0Sb8ytrfQsA5WO6kDn6mDfKLh6KrPBjvkk7xA==", - "cpu": [ - "arm64" - ], + "node_modules/@commitlint/format/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, - "optional": true, - "os": [ - "android" - ], + "dependencies": { + "has-flag": "^4.0.0" + }, "engines": { - "node": ">=12" + "node": ">=8" } }, - "node_modules/@esbuild/android-x64": { - "version": "0.17.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.12.tgz", - "integrity": "sha512-m4OsaCr5gT+se25rFPHKQXARMyAehHTQAz4XX1Vk3d27VtqiX0ALMBPoXZsGaB6JYryCLfgGwUslMqTfqeLU0w==", - "cpu": [ - "x64" - ], + "node_modules/@commitlint/is-ignored": { + "version": "17.6.7", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-17.6.7.tgz", + "integrity": "sha512-vqyNRqtbq72P2JadaoWiuoLtXIs9SaAWDqdtef6G2zsoXqKFc7vqj1f+thzVgosXG3X/5K9jNp+iYijmvOfc/g==", "dev": true, - "optional": true, - "os": [ - "android" - ], + "dependencies": { + "@commitlint/types": "^17.4.4", + "semver": "7.5.2" + }, "engines": { - "node": ">=12" + "node": ">=v14" } }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.17.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.12.tgz", - "integrity": "sha512-O3GCZghRIx+RAN0NDPhyyhRgwa19MoKlzGonIb5hgTj78krqp9XZbYCvFr9N1eUxg0ZQEpiiZ4QvsOQwBpP+lg==", - "cpu": [ - "arm64" - ], + "node_modules/@commitlint/is-ignored/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, - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "yallist": "^4.0.0" + }, "engines": { - "node": ">=12" + "node": ">=10" } }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.17.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.12.tgz", - "integrity": "sha512-5D48jM3tW27h1qjaD9UNRuN+4v0zvksqZSPZqeSWggfMlsVdAhH3pwSfQIFJwcs9QJ9BRibPS4ViZgs3d2wsCA==", - "cpu": [ - "x64" - ], + "node_modules/@commitlint/is-ignored/node_modules/semver": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", + "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", "dev": true, - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, "engines": { - "node": ">=12" + "node": ">=10" } }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.17.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.12.tgz", - "integrity": "sha512-OWvHzmLNTdF1erSvrfoEBGlN94IE6vCEaGEkEH29uo/VoONqPnoDFfShi41Ew+yKimx4vrmmAJEGNoyyP+OgOQ==", - "cpu": [ - "arm64" - ], + "node_modules/@commitlint/is-ignored/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/@commitlint/lint": { + "version": "17.6.7", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-17.6.7.tgz", + "integrity": "sha512-TW+AozfuOFMrHn+jdwtz0IWu8REKFp0eryOvoBp2r8IXNc4KihKB1spAiUB6SFyHD6hVVeolz12aHnJ3Mb+xVQ==", "dev": true, - "optional": true, - "os": [ - "freebsd" - ], + "dependencies": { + "@commitlint/is-ignored": "^17.6.7", + "@commitlint/parse": "^17.6.7", + "@commitlint/rules": "^17.6.7", + "@commitlint/types": "^17.4.4" + }, "engines": { - "node": ">=12" + "node": ">=v14" + } + }, + "node_modules/@commitlint/load": { + "version": "17.6.7", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-17.6.7.tgz", + "integrity": "sha512-QZ2rJTbX55BQdYrCm/p6+hh/pFBgC9nTJxfsrK6xRPe2thiQzHN0AQDBqBwAirn6gIkHrjIbCbtAE6kiDYLjrw==", + "dev": true, + "dependencies": { + "@commitlint/config-validator": "^17.6.7", + "@commitlint/execute-rule": "^17.4.0", + "@commitlint/resolve-extends": "^17.6.7", + "@commitlint/types": "^17.4.4", + "@types/node": "*", + "chalk": "^4.1.0", + "cosmiconfig": "^8.0.0", + "cosmiconfig-typescript-loader": "^4.0.0", + "lodash.isplainobject": "^4.0.6", + "lodash.merge": "^4.6.2", + "lodash.uniq": "^4.5.0", + "resolve-from": "^5.0.0", + "ts-node": "^10.8.1", + "typescript": "^4.6.4 || ^5.0.0" + }, + "engines": { + "node": ">=v14" + } + }, + "node_modules/@commitlint/load/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/@commitlint/load/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/@commitlint/load/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/@commitlint/load/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/@commitlint/load/node_modules/cosmiconfig": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.2.0.tgz", + "integrity": "sha512-3rTMnFJA1tCOPwRxtgF4wd7Ab2qvDbL8jX+3smjIbS4HlZBagTlpERbdN7iAbWlrfxE3M8c27kTwTawQ7st+OQ==", + "dev": true, + "dependencies": { + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + } + }, + "node_modules/@commitlint/load/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/@commitlint/load/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/@commitlint/load/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/@commitlint/message": { + "version": "17.4.2", + "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-17.4.2.tgz", + "integrity": "sha512-3XMNbzB+3bhKA1hSAWPCQA3lNxR4zaeQAQcHj0Hx5sVdO6ryXtgUBGGv+1ZCLMgAPRixuc6en+iNAzZ4NzAa8Q==", + "dev": true, + "engines": { + "node": ">=v14" + } + }, + "node_modules/@commitlint/parse": { + "version": "17.6.7", + "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-17.6.7.tgz", + "integrity": "sha512-ibO03BgEns+JJpohpBZYD49mCdSNMg6fTv7vA5yqzEFWkBQk5NWhEBw2yG+Z1UClStIRkMkAYyI2HzoQG9tCQQ==", + "dev": true, + "dependencies": { + "@commitlint/types": "^17.4.4", + "conventional-changelog-angular": "^5.0.11", + "conventional-commits-parser": "^3.2.2" + }, + "engines": { + "node": ">=v14" + } + }, + "node_modules/@commitlint/read": { + "version": "17.5.1", + "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-17.5.1.tgz", + "integrity": "sha512-7IhfvEvB//p9aYW09YVclHbdf1u7g7QhxeYW9ZHSO8Huzp8Rz7m05aCO1mFG7G8M+7yfFnXB5xOmG18brqQIBg==", + "dev": true, + "dependencies": { + "@commitlint/top-level": "^17.4.0", + "@commitlint/types": "^17.4.4", + "fs-extra": "^11.0.0", + "git-raw-commits": "^2.0.11", + "minimist": "^1.2.6" + }, + "engines": { + "node": ">=v14" + } + }, + "node_modules/@commitlint/read/node_modules/fs-extra": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz", + "integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@commitlint/read/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@commitlint/read/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@commitlint/resolve-extends": { + "version": "17.6.7", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-17.6.7.tgz", + "integrity": "sha512-PfeoAwLHtbOaC9bGn/FADN156CqkFz6ZKiVDMjuC2N5N0740Ke56rKU7Wxdwya8R8xzLK9vZzHgNbuGhaOVKIg==", + "dev": true, + "dependencies": { + "@commitlint/config-validator": "^17.6.7", + "@commitlint/types": "^17.4.4", + "import-fresh": "^3.0.0", + "lodash.mergewith": "^4.6.2", + "resolve-from": "^5.0.0", + "resolve-global": "^1.0.0" + }, + "engines": { + "node": ">=v14" + } + }, + "node_modules/@commitlint/resolve-extends/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/@commitlint/rules": { + "version": "17.6.7", + "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-17.6.7.tgz", + "integrity": "sha512-x/SDwDTN3w3Gr5xkhrIORu96rlKCc8ZLYEMXRqi9+MB33st2mKcGvKa5uJuigHlbl3xm75bAAubATrodVrjguQ==", + "dev": true, + "dependencies": { + "@commitlint/ensure": "^17.6.7", + "@commitlint/message": "^17.4.2", + "@commitlint/to-lines": "^17.4.0", + "@commitlint/types": "^17.4.4", + "execa": "^5.0.0" + }, + "engines": { + "node": ">=v14" + } + }, + "node_modules/@commitlint/rules/node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/@commitlint/rules/node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/@commitlint/to-lines": { + "version": "17.4.0", + "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-17.4.0.tgz", + "integrity": "sha512-LcIy/6ZZolsfwDUWfN1mJ+co09soSuNASfKEU5sCmgFCvX5iHwRYLiIuoqXzOVDYOy7E7IcHilr/KS0e5T+0Hg==", + "dev": true, + "engines": { + "node": ">=v14" + } + }, + "node_modules/@commitlint/top-level": { + "version": "17.4.0", + "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-17.4.0.tgz", + "integrity": "sha512-/1loE/g+dTTQgHnjoCy0AexKAEFyHsR2zRB4NWrZ6lZSMIxAhBJnmCqwao7b4H8888PsfoTBCLBYIw8vGnej8g==", + "dev": true, + "dependencies": { + "find-up": "^5.0.0" + }, + "engines": { + "node": ">=v14" + } + }, + "node_modules/@commitlint/top-level/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/@commitlint/top-level/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": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/top-level/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": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/top-level/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": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@commitlint/types": { + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-17.4.4.tgz", + "integrity": "sha512-amRN8tRLYOsxRr6mTnGGGvB5EmW/4DDjLMgiwK3CCVEmN6Sr/6xePGEpWaspKkckILuUORCwe6VfDBw6uj4axQ==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0" + }, + "engines": { + "node": ">=v14" + } + }, + "node_modules/@commitlint/types/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/@commitlint/types/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/@commitlint/types/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/@commitlint/types/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/@commitlint/types/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/@commitlint/types/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/@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/@emailjs/browser": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/@emailjs/browser/-/browser-3.11.0.tgz", + "integrity": "sha512-RkY3FKZ3fPdK++OeF46mRTFpmmQWCHUVHZH209P3NE4D5sg2Atg7S2wa3gw5062Gl4clt4Wn5SyC4WhlVZC5pA==", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@emotion/babel-plugin": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", + "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/serialize": "^1.1.2", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/cache": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", + "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", + "dependencies": { + "@emotion/memoize": "^0.8.1", + "@emotion/sheet": "^1.2.2", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", + "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", + "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==", + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + }, + "node_modules/@emotion/react": { + "version": "11.11.1", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.1.tgz", + "integrity": "sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/cache": "^11.11.0", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.2.tgz", + "integrity": "sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==", + "dependencies": { + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/unitless": "^0.8.1", + "@emotion/utils": "^1.2.1", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", + "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" + }, + "node_modules/@emotion/styled": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.0.tgz", + "integrity": "sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/is-prop-valid": "^1.2.1", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", + "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", + "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", + "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" + }, + "node_modules/@esbuild/android-arm": { + "version": "0.17.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.12.tgz", + "integrity": "sha512-E/sgkvwoIfj4aMAPL2e35VnUJspzVYl7+M1B2cqeubdBhADV4uPon0KCc8p2G+LqSJ6i8ocYPCqY3A4GGq0zkQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.17.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.12.tgz", + "integrity": "sha512-WQ9p5oiXXYJ33F2EkE3r0FRDFVpEdcDiwNX3u7Xaibxfx6vQE0Sb8ytrfQsA5WO6kDn6mDfKLh6KrPBjvkk7xA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.17.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.12.tgz", + "integrity": "sha512-m4OsaCr5gT+se25rFPHKQXARMyAehHTQAz4XX1Vk3d27VtqiX0ALMBPoXZsGaB6JYryCLfgGwUslMqTfqeLU0w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.17.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.12.tgz", + "integrity": "sha512-O3GCZghRIx+RAN0NDPhyyhRgwa19MoKlzGonIb5hgTj78krqp9XZbYCvFr9N1eUxg0ZQEpiiZ4QvsOQwBpP+lg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.17.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.12.tgz", + "integrity": "sha512-5D48jM3tW27h1qjaD9UNRuN+4v0zvksqZSPZqeSWggfMlsVdAhH3pwSfQIFJwcs9QJ9BRibPS4ViZgs3d2wsCA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.17.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.12.tgz", + "integrity": "sha512-OWvHzmLNTdF1erSvrfoEBGlN94IE6vCEaGEkEH29uo/VoONqPnoDFfShi41Ew+yKimx4vrmmAJEGNoyyP+OgOQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" } }, "node_modules/@esbuild/freebsd-x64": { @@ -935,14 +1615,12 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.17.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.12.tgz", - "integrity": "sha512-JOOxw49BVZx2/5tW3FqkdjSD/5gXYeVGPDcB0lvap0gLQshkh1Nyel1QazC+wNxus3xPlsYAgqU1BUmrmCvWtw==", + "version": "0.18.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.11.tgz", + "integrity": "sha512-rQI4cjLHd2hGsM1LqgDI7oOCYbQ6IBOVsX9ejuRMSze0GqXUG2ekwiKkiBU1pRGSeCqFFHxTrcEydB2Hyoz9CA==", "cpu": [ "x64" ], - "dev": true, - "optional": true, "os": [ "win32" ], @@ -950,10 +1628,110 @@ "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, + "peer": 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.6.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.6.2.tgz", + "integrity": "sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==", + "dev": true, + "peer": 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, + "peer": 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/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@eslint/eslintrc/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, + "peer": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/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, + "peer": true + }, + "node_modules/@eslint/js": { + "version": "8.47.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.47.0.tgz", + "integrity": "sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og==", + "dev": true, + "peer": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/@firebase/analytics": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.9.4.tgz", - "integrity": "sha512-Mb2UaD0cyJ9DrTk4Okz8wqpjZuVRVXHZOjhbQcmGb8VtibXY1+jm/k3eJ21r7NqUKnjWejYM2EX+hI9+dtXGkQ==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.0.tgz", + "integrity": "sha512-Locv8gAqx0e+GX/0SI3dzmBY5e9kjVDtD+3zCFLJ0tH2hJwuCAiL+5WkHuxKj92rqQj/rvkBUCfA1ewlX2hehg==", "dependencies": { "@firebase/component": "0.6.4", "@firebase/installations": "0.6.4", @@ -966,11 +1744,11 @@ } }, "node_modules/@firebase/analytics-compat": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.4.tgz", - "integrity": "sha512-ZN4K49QwOR8EWIUTV03VBdcVkz8sVsfJmve4g2+FEIj0kyTK0MdoVTWNOwWj9TVi2p/7FvKRKkpWxkydmi9x7g==", + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.6.tgz", + "integrity": "sha512-4MqpVLFkGK7NJf/5wPEEP7ePBJatwYpyjgJ+wQHQGHfzaCDgntOnl9rL2vbVGGKCnRqWtZDIWhctB86UWXaX2Q==", "dependencies": { - "@firebase/analytics": "0.9.4", + "@firebase/analytics": "0.10.0", "@firebase/analytics-types": "0.8.0", "@firebase/component": "0.6.4", "@firebase/util": "1.9.3", @@ -986,21 +1764,21 @@ "integrity": "sha512-iRP+QKI2+oz3UAh4nPEq14CsEjrjD6a5+fuypjScisAh9kXKFvdJOZJDwk7kikLvWVLGEs9+kIUS4LPQV7VZVw==" }, "node_modules/@firebase/app": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.9.5.tgz", - "integrity": "sha512-mXO9hrygxCohD8Qy0z8p9ZtuQirmjkjSTuQghH05/kLG1UJqP0TQZBlhP5qwzMTKuu2YpIn3kX2PZoSWti8LDA==", + "version": "0.9.13", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.9.13.tgz", + "integrity": "sha512-GfiI1JxJ7ecluEmDjPzseRXk/PX31hS7+tjgBopL7XjB2hLUdR+0FTMXy2Q3/hXezypDvU6or7gVFizDESrkXw==", "dependencies": { "@firebase/component": "0.6.4", "@firebase/logger": "0.4.0", "@firebase/util": "1.9.3", - "idb": "7.0.1", + "idb": "7.1.1", "tslib": "^2.1.0" } }, "node_modules/@firebase/app-check": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.6.4.tgz", - "integrity": "sha512-M9qyVTWkEkHXmgwGtObvXQqKcOe9iKAOPqm0pCe74mzgKVTNq157ff39+fxHPb4nFbipToY+GuvtabLUzkHehQ==", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.8.0.tgz", + "integrity": "sha512-dRDnhkcaC2FspMiRK/Vbp+PfsOAEP6ZElGm9iGFJ9fDqHoPs0HOPn7dwpJ51lCFi1+2/7n5pRPGhqF/F03I97g==", "dependencies": { "@firebase/component": "0.6.4", "@firebase/logger": "0.4.0", @@ -1012,11 +1790,11 @@ } }, "node_modules/@firebase/app-check-compat": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.4.tgz", - "integrity": "sha512-s6ON0ixPKe99M1DNYMI2eR5aLwQZgy0z8fuW1tnEbzg5p/N/GKFmqiIHSV4gfp8+X7Fw5NLm7qMfh4xrcPgQCw==", + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.7.tgz", + "integrity": "sha512-cW682AxsyP1G+Z0/P7pO/WT2CzYlNxoNe5QejVarW2o5ZxeWSSPAiVEwpEpQR/bUlUmdeWThYTMvBWaopdBsqw==", "dependencies": { - "@firebase/app-check": "0.6.4", + "@firebase/app-check": "0.8.0", "@firebase/app-check-types": "0.5.0", "@firebase/component": "0.6.4", "@firebase/logger": "0.4.0", @@ -1028,9 +1806,9 @@ } }, "node_modules/@firebase/app-check-interop-types": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.2.0.tgz", - "integrity": "sha512-+3PQIeX6/eiVK+x/yg8r6xTNR97fN7MahFDm+jiQmDjcyvSefoGuTTNQuuMScGyx3vYUBeZn+Cp9kC0yY/9uxQ==" + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.0.tgz", + "integrity": "sha512-xAxHPZPIgFXnI+vb4sbBjZcde7ZluzPPaSK7Lx3/nmuVk4TjZvnL8ONnkd4ERQKL8WePQySU+pRcWkh8rDf5Sg==" }, "node_modules/@firebase/app-check-types": { "version": "0.5.0", @@ -1038,11 +1816,11 @@ "integrity": "sha512-uwSUj32Mlubybw7tedRzR24RP8M8JUVR3NPiMk3/Z4bCmgEKTlQBwMXrehDAZ2wF+TsBq0SN1c6ema71U/JPyQ==" }, "node_modules/@firebase/app-compat": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.5.tgz", - "integrity": "sha512-PSEax7UAc1Qxcksq5GHKb8M9rCsXTJWxWUf6pqhGTWO9UbJnI1tv00ogoCicEHgkXBTkOWMLxCs3318HaGZh4g==", + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.13.tgz", + "integrity": "sha512-j6ANZaWjeVy5zg6X7uiqh6lM6o3n3LD1+/SJFNs9V781xyryyZWXe+tmnWNWPkP086QfJoNkWN9pMQRqSG4vMg==", "dependencies": { - "@firebase/app": "0.9.5", + "@firebase/app": "0.9.13", "@firebase/component": "0.6.4", "@firebase/logger": "0.4.0", "@firebase/util": "1.9.3", @@ -1055,9 +1833,9 @@ "integrity": "sha512-AeweANOIo0Mb8GiYm3xhTEBVCmPwTYAu9Hcd2qSkLuga/6+j9b1Jskl5bpiSQWy9eJ/j5pavxj6eYogmnuzm+Q==" }, "node_modules/@firebase/auth": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-0.21.5.tgz", - "integrity": "sha512-Pt/S24qbtJeFPxYxcQHDNgYAuEa9oyCK1XJBQ9Kc3FT1rDMb1OaK6wfnDDrCChQfENdHZVI1pGw4QG6/tO3NWw==", + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-0.23.2.tgz", + "integrity": "sha512-dM9iJ0R6tI1JczuGSxXmQbXAgtYie0K4WvKcuyuSTCu9V8eEDiz4tfa1sO3txsfvwg7nOY3AjoCyMYEdqZ8hdg==", "dependencies": { "@firebase/component": "0.6.4", "@firebase/logger": "0.4.0", @@ -1070,11 +1848,11 @@ } }, "node_modules/@firebase/auth-compat": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.3.5.tgz", - "integrity": "sha512-xEkR4Buuw8NfyJhMVC3HMvyaODfstpMuo55tK03APoP+X9fnZpQE+ASdacq60qBBvpKF78d+gmAhmh0ISTXZ0w==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.4.2.tgz", + "integrity": "sha512-Q30e77DWXFmXEt5dg5JbqEDpjw9y3/PcP9LslDPR7fARmAOTIY9MM6HXzm9KC+dlrKH/+p6l8g9ifJiam9mc4A==", "dependencies": { - "@firebase/auth": "0.21.5", + "@firebase/auth": "0.23.2", "@firebase/auth-types": "0.12.0", "@firebase/component": "0.6.4", "@firebase/util": "1.9.3", @@ -1144,14 +1922,14 @@ } }, "node_modules/@firebase/firestore": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-3.9.0.tgz", - "integrity": "sha512-At8HeTec3y7EfGjtYqvzON/8896igJgE34zjEndYxKPUKyhQ6xtcM+zhfa8C+lUW6W8qQB6lNzTNNXmF4NxdpQ==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-3.13.0.tgz", + "integrity": "sha512-NwcnU+madJXQ4fbLkGx1bWvL612IJN/qO6bZ6dlPmyf7QRyu5azUosijdAN675r+bOOJxMtP1Bv981bHBXAbUg==", "dependencies": { "@firebase/component": "0.6.4", "@firebase/logger": "0.4.0", "@firebase/util": "1.9.3", - "@firebase/webchannel-wrapper": "0.9.0", + "@firebase/webchannel-wrapper": "0.10.1", "@grpc/grpc-js": "~1.7.0", "@grpc/proto-loader": "^0.6.13", "node-fetch": "2.6.7", @@ -1165,12 +1943,12 @@ } }, "node_modules/@firebase/firestore-compat": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.5.tgz", - "integrity": "sha512-gwBFGOqNIgF2TOJ2mKIS1lTQy6I9DytWsmIfvXGV76is53MaZUZXyUZd7oIC8h2Otq6gP3xtvPRQJTMcnQrbFg==", + "version": "0.3.12", + "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.12.tgz", + "integrity": "sha512-mazuNGAx5Kt9Nph0pm6ULJFp/+j7GSsx+Ncw1GrnKl+ft1CQ4q2LcUssXnjqkX2Ry0fNGqUzC1mfIUrk9bYtjQ==", "dependencies": { "@firebase/component": "0.6.4", - "@firebase/firestore": "3.9.0", + "@firebase/firestore": "3.13.0", "@firebase/firestore-types": "2.5.1", "@firebase/util": "1.9.3", "tslib": "^2.1.0" @@ -1189,11 +1967,11 @@ } }, "node_modules/@firebase/functions": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.9.4.tgz", - "integrity": "sha512-3H2qh6U+q+nepO5Hds+Ddl6J0pS+zisuBLqqQMRBHv9XpWfu0PnDHklNmE8rZ+ccTEXvBj6zjkPfdxt6NisvlQ==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.10.0.tgz", + "integrity": "sha512-2U+fMNxTYhtwSpkkR6WbBcuNMOVaI7MaH3cZ6UAeNfj7AgEwHwMIFLPpC13YNZhno219F0lfxzTAA0N62ndWzA==", "dependencies": { - "@firebase/app-check-interop-types": "0.2.0", + "@firebase/app-check-interop-types": "0.3.0", "@firebase/auth-interop-types": "0.2.1", "@firebase/component": "0.6.4", "@firebase/messaging-interop-types": "0.2.0", @@ -1206,12 +1984,12 @@ } }, "node_modules/@firebase/functions-compat": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.4.tgz", - "integrity": "sha512-kxVxTGyLV1MBR3sp3mI+eQ6JBqz0G5bk310F8eX4HzDFk4xjk5xY0KdHktMH+edM2xs1BOg0vwvvsAHczIjB+w==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.5.tgz", + "integrity": "sha512-uD4jwgwVqdWf6uc3NRKF8cSZ0JwGqSlyhPgackyUPe+GAtnERpS4+Vr66g0b3Gge0ezG4iyHo/EXW/Hjx7QhHw==", "dependencies": { "@firebase/component": "0.6.4", - "@firebase/functions": "0.9.4", + "@firebase/functions": "0.10.0", "@firebase/functions-types": "0.6.0", "@firebase/util": "1.9.3", "tslib": "^2.1.0" @@ -1262,6 +2040,11 @@ "@firebase/app-types": "0.x" } }, + "node_modules/@firebase/installations/node_modules/idb": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.0.1.tgz", + "integrity": "sha512-UUxlE7vGWK5RfB/fDwEGgRf84DY/ieqNha6msMV99UsEMQhJ1RwbCd8AYBj3QMgnE3VZnfQvm4oKVCJTYlqIgg==" + }, "node_modules/@firebase/logger": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.0.tgz", @@ -1305,6 +2088,11 @@ "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.0.tgz", "integrity": "sha512-ujA8dcRuVeBixGR9CtegfpU4YmZf3Lt7QYkcj693FFannwNuZgfAYaTmbJ40dtjB81SAu6tbFPL9YLNT15KmOQ==" }, + "node_modules/@firebase/messaging/node_modules/idb": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.0.1.tgz", + "integrity": "sha512-UUxlE7vGWK5RfB/fDwEGgRf84DY/ieqNha6msMV99UsEMQhJ1RwbCd8AYBj3QMgnE3VZnfQvm4oKVCJTYlqIgg==" + }, "node_modules/@firebase/performance": { "version": "0.6.4", "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.6.4.tgz", @@ -1424,9 +2212,9 @@ } }, "node_modules/@firebase/webchannel-wrapper": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.9.0.tgz", - "integrity": "sha512-BpiZLBWdLFw+qFel9p3Zs1jD6QmH7Ii4aTDu6+vx8ShdidChZUXqDhYJly4ZjSgQh54miXbBgBrk0S+jTIh/Qg==" + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.10.1.tgz", + "integrity": "sha512-Dq5rYfEpdeel0bLVN+nfD1VWmzCkK+pJbSjIawGE+RY4+NIJqhbUDDQjvV0NUK84fMfwxvtFoCtEe70HfZjFcw==" }, "node_modules/@fortawesome/fontawesome-common-types": { "version": "6.3.0", @@ -1498,15 +2286,15 @@ } }, "node_modules/@grpc/grpc-js/node_modules/@grpc/proto-loader": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.5.tgz", - "integrity": "sha512-mfcTuMbFowq1wh/Rn5KQl6qb95M21Prej3bewD9dUQMurYGVckGO/Pbe2Ocwto6sD05b/mxZLspvqwx60xO2Rg==", + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.8.tgz", + "integrity": "sha512-GU12e2c8dmdXb7XUlOgYWZ2o2i+z9/VeACkxTA/zzAe2IjclC5PnVL0lpgjhrqfpDYHzM8B1TF6pqWegMYAzlA==", "dependencies": { "@types/long": "^4.0.1", "lodash.camelcase": "^4.3.0", "long": "^4.0.0", - "protobufjs": "^7.0.0", - "yargs": "^16.2.0" + "protobufjs": "^7.2.4", + "yargs": "^17.7.2" }, "bin": { "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" @@ -1516,9 +2304,9 @@ } }, "node_modules/@grpc/grpc-js/node_modules/protobufjs": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.2.tgz", - "integrity": "sha512-++PrQIjrom+bFDPpfmqXfAGSQs40116JRrqqyf53dymUMvvb5d/LMRyicRoF1AUKoXVS1/IgJXlEgcpr4gTF3Q==", + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.4.tgz", + "integrity": "sha512-AT+RJgD2sH8phPmCf7OUZR8xGdcJRga4+1cOaXJ64hvcSkVhNcRHOwIxUatPH15+nj59WAGTDv3LSGZPEQbJaQ==", "hasInstallScript": true, "dependencies": { "@protobufjs/aspromise": "^1.1.2", @@ -1539,9 +2327,9 @@ } }, "node_modules/@grpc/grpc-js/node_modules/protobufjs/node_modules/long": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/long/-/long-5.2.1.tgz", - "integrity": "sha512-GKSNGeNAtw8IryjjkhZxuKB3JzlcLTwjtiQCHKvqQet81I93kXslhDQruGI/QsddO83mcDToBVy7GqGS/zYf/A==" + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" }, "node_modules/@grpc/proto-loader": { "version": "0.6.13", @@ -1561,6 +2349,77 @@ "node": ">=6" } }, + "node_modules/@grpc/proto-loader/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/@grpc/proto-loader/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", + "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", + "dev": true, + "peer": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "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, + "peer": 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, + "peer": true + }, + "node_modules/@icons/material": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@icons/material/-/material-0.2.4.tgz", + "integrity": "sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw==", + "peerDependencies": { + "react": "*" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", @@ -1609,15 +2468,15 @@ } }, "node_modules/@mui/base": { - "version": "5.0.0-alpha.121", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.121.tgz", - "integrity": "sha512-8nJRY76UqlJV+q/Yzo0tgGfPWEOa+4N9rjO81fMmcJqP0I6m54hLDXsjvMg4tvelY5eKHXUK6Tb7en+GHfTqZA==", - "dependencies": { - "@babel/runtime": "^7.21.0", - "@emotion/is-prop-valid": "^1.2.0", - "@mui/types": "^7.2.3", - "@mui/utils": "^5.11.13", - "@popperjs/core": "^2.11.6", + "version": "5.0.0-beta.5", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.5.tgz", + "integrity": "sha512-vy3TWLQYdGNecTaufR4wDNQFV2WEg6wRPi6BVbx6q1vP3K1mbxIn1+XOqOzfYBXjFHvMx0gZAo2TgWbaqfgvAA==", + "dependencies": { + "@babel/runtime": "^7.22.5", + "@emotion/is-prop-valid": "^1.2.1", + "@mui/types": "^7.2.4", + "@mui/utils": "^5.13.6", + "@popperjs/core": "^2.11.8", "clsx": "^1.2.1", "prop-types": "^15.8.1", "react-is": "^18.2.0" @@ -1641,9 +2500,9 @@ } }, "node_modules/@mui/core-downloads-tracker": { - "version": "5.11.13", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.11.13.tgz", - "integrity": "sha512-lx+GXBR9h/ApZsEP728tl0pyZyuajto+VnBgsoAzw1d5+CbmOo8ZWieKwVUGxZlPT1wMYNUYS5NtKzCli0xYjw==", + "version": "5.13.4", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.13.4.tgz", + "integrity": "sha512-yFrMWcrlI0TqRN5jpb6Ma9iI7sGTHpytdzzL33oskFHNQ8UgrtPas33Y1K7sWAMwCrr1qbWDrOHLAQG4tAzuSw==", "funding": { "type": "opencollective", "url": "https://opencollective.com/mui" @@ -1675,19 +2534,19 @@ } }, "node_modules/@mui/material": { - "version": "5.11.13", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.11.13.tgz", - "integrity": "sha512-2CnSj43F+159LbGmTLLQs5xbGYMiYlpTByQhP7c7cMX6opbScctBFE1PuyElpAmwW8Ag9ysfZH1d1MFAmJQkjg==", - "dependencies": { - "@babel/runtime": "^7.21.0", - "@mui/base": "5.0.0-alpha.121", - "@mui/core-downloads-tracker": "^5.11.13", - "@mui/system": "^5.11.13", - "@mui/types": "^7.2.3", - "@mui/utils": "^5.11.13", - "@types/react-transition-group": "^4.4.5", + "version": "5.13.6", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.13.6.tgz", + "integrity": "sha512-/c2ZApeQm2sTYdQXjqEnldaBMBcUEiyu2VRS6bS39ZeNaAcCLBQbYocLR46R+f0S5dgpBzB0T4AsOABPOFYZ5Q==", + "dependencies": { + "@babel/runtime": "^7.22.5", + "@mui/base": "5.0.0-beta.5", + "@mui/core-downloads-tracker": "^5.13.4", + "@mui/system": "^5.13.6", + "@mui/types": "^7.2.4", + "@mui/utils": "^5.13.6", + "@types/react-transition-group": "^4.4.6", "clsx": "^1.2.1", - "csstype": "^3.1.1", + "csstype": "^3.1.2", "prop-types": "^15.8.1", "react-is": "^18.2.0", "react-transition-group": "^4.4.5" @@ -1719,12 +2578,12 @@ } }, "node_modules/@mui/private-theming": { - "version": "5.11.13", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.11.13.tgz", - "integrity": "sha512-PJnYNKzW5LIx3R+Zsp6WZVPs6w5sEKJ7mgLNnUXuYB1zo5aX71FVLtV7geyPXRcaN2tsoRNK7h444ED0t7cIjA==", + "version": "5.13.1", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.13.1.tgz", + "integrity": "sha512-HW4npLUD9BAkVppOUZHeO1FOKUJWAwbpy0VQoGe3McUYTlck1HezGHQCfBQ5S/Nszi7EViqiimECVl9xi+/WjQ==", "dependencies": { "@babel/runtime": "^7.21.0", - "@mui/utils": "^5.11.13", + "@mui/utils": "^5.13.1", "prop-types": "^15.8.1" }, "engines": { @@ -1745,13 +2604,13 @@ } }, "node_modules/@mui/styled-engine": { - "version": "5.11.11", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.11.11.tgz", - "integrity": "sha512-wV0UgW4lN5FkDBXefN8eTYeuE9sjyQdg5h94vtwZCUamGQEzmCOtir4AakgmbWMy0x8OLjdEUESn9wnf5J9MOg==", + "version": "5.13.2", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.13.2.tgz", + "integrity": "sha512-VCYCU6xVtXOrIN8lcbuPmoG+u7FYuOERG++fpY74hPpEWkyFQG97F+/XfTQVYzlR2m7nPjnwVUgATcTCMEaMvw==", "dependencies": { "@babel/runtime": "^7.21.0", - "@emotion/cache": "^11.10.5", - "csstype": "^3.1.1", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.2", "prop-types": "^15.8.1" }, "engines": { @@ -1776,17 +2635,17 @@ } }, "node_modules/@mui/styles": { - "version": "5.11.13", - "resolved": "https://registry.npmjs.org/@mui/styles/-/styles-5.11.13.tgz", - "integrity": "sha512-7NQTTdl8Z54qQBRPLi4cR9LG8tvXQdQE0kVEYVYc5A3e+IFH6xfGzNCNa0X4zz0f9JGaS8e6kK3YYOS2+KyJHg==", + "version": "5.13.2", + "resolved": "https://registry.npmjs.org/@mui/styles/-/styles-5.13.2.tgz", + "integrity": "sha512-gKNkVyk6azQ8wfCamh3yU/wLv1JscYrsQX9huQBwfwtE7kUTq2rgggdfJjRADjbcmT6IPX+oCHYjGfqqFgDIQQ==", "dependencies": { "@babel/runtime": "^7.21.0", - "@emotion/hash": "^0.9.0", - "@mui/private-theming": "^5.11.13", - "@mui/types": "^7.2.3", - "@mui/utils": "^5.11.13", + "@emotion/hash": "^0.9.1", + "@mui/private-theming": "^5.13.1", + "@mui/types": "^7.2.4", + "@mui/utils": "^5.13.1", "clsx": "^1.2.1", - "csstype": "^3.1.1", + "csstype": "^3.1.2", "hoist-non-react-statics": "^3.3.2", "jss": "^10.10.0", "jss-plugin-camel-case": "^10.10.0", @@ -1806,7 +2665,7 @@ "url": "https://opencollective.com/mui" }, "peerDependencies": { - "@types/react": "^17.0.0", + "@types/react": "^17.0.0 || ^18.0.0", "react": "^17.0.0" }, "peerDependenciesMeta": { @@ -1816,17 +2675,17 @@ } }, "node_modules/@mui/system": { - "version": "5.11.13", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.11.13.tgz", - "integrity": "sha512-OWP0Alp6C8ufnGm9+CZcl3d+OoRXL2PnrRT5ohaMLxvGL9OfNcL2t4JOjMmA0k1UAGd6E/Ygbu5lEPrZSDlvCg==", - "dependencies": { - "@babel/runtime": "^7.21.0", - "@mui/private-theming": "^5.11.13", - "@mui/styled-engine": "^5.11.11", - "@mui/types": "^7.2.3", - "@mui/utils": "^5.11.13", + "version": "5.13.6", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.13.6.tgz", + "integrity": "sha512-G3Xr28uLqU3DyF6r2LQkHGw/ku4P0AHzlKVe7FGXOPl7X1u+hoe2xxj8Vdiq/69II/mh9OP21i38yBWgWb7WgQ==", + "dependencies": { + "@babel/runtime": "^7.22.5", + "@mui/private-theming": "^5.13.1", + "@mui/styled-engine": "^5.13.2", + "@mui/types": "^7.2.4", + "@mui/utils": "^5.13.6", "clsx": "^1.2.1", - "csstype": "^3.1.1", + "csstype": "^3.1.2", "prop-types": "^15.8.1" }, "engines": { @@ -1855,9 +2714,9 @@ } }, "node_modules/@mui/types": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.3.tgz", - "integrity": "sha512-tZ+CQggbe9Ol7e/Fs5RcKwg/woU+o8DCtOnccX6KmbBc7YrfqMYEYuaIcXHuhpT880QwNkZZ3wQwvtlDFA2yOw==", + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.4.tgz", + "integrity": "sha512-LBcwa8rN84bKF+f5sDyku42w1NTxaPgPyYKODsh01U1fVstTClbUoSA96oyRBnSNyEiAVjKm6Gwx9vjR+xyqHA==", "peerDependencies": { "@types/react": "*" }, @@ -1868,13 +2727,13 @@ } }, "node_modules/@mui/utils": { - "version": "5.11.13", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.11.13.tgz", - "integrity": "sha512-5ltA58MM9euOuUcnvwFJqpLdEugc9XFsRR8Gt4zZNb31XzMfSKJPR4eumulyhsOTK1rWf7K4D63NKFPfX0AxqA==", + "version": "5.13.6", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.13.6.tgz", + "integrity": "sha512-ggNlxl5NPSbp+kNcQLmSig6WVB0Id+4gOxhx644987v4fsji+CSXc+MFYLocFB/x4oHtzCUlSzbVHlJfP/fXoQ==", "dependencies": { - "@babel/runtime": "^7.21.0", + "@babel/runtime": "^7.22.5", "@types/prop-types": "^15.7.5", - "@types/react-is": "^16.7.1 || ^17.0.0", + "@types/react-is": "^18.2.0", "prop-types": "^15.8.1", "react-is": "^18.2.0" }, @@ -1889,10 +2748,65 @@ "react": "^17.0.0 || ^18.0.0" } }, + "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/@pkgr/utils": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.2.tgz", + "integrity": "sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "fast-glob": "^3.3.0", + "is-glob": "^4.0.3", + "open": "^9.1.0", + "picocolors": "^1.0.0", + "tslib": "^2.6.0" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, "node_modules/@popperjs/core": { - "version": "2.11.6", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz", - "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==", + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" @@ -1960,16 +2874,52 @@ "node": ">=14" } }, + "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/long": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" }, + "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": "18.14.1", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.1.tgz", "integrity": "sha512-QH+37Qds3E0eDlReeboBxfHbX9omAcBCXEzswCu6jySP642jiM3cYSIkU/REqwhCUqXdonHFuBfJDiAJxMNhaQ==" }, + "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/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", @@ -2000,17 +2950,17 @@ } }, "node_modules/@types/react-is": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.3.tgz", - "integrity": "sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw==", + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-1vz2yObaQkLL7YFe/pme2cpvDsCwI1WXIfL+5eLz0MI9gFG24Re16RzUsI8t9XZn9ZWvgLNDrJBmrqXJO7GNQQ==", "dependencies": { "@types/react": "*" } }, "node_modules/@types/react-transition-group": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.5.tgz", - "integrity": "sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA==", + "version": "4.4.6", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.6.tgz", + "integrity": "sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew==", "dependencies": { "@types/react": "*" } @@ -2020,28 +2970,6 @@ "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" }, - "node_modules/@types/sinonjs__fake-timers": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz", - "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==", - "dev": true - }, - "node_modules/@types/sizzle": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz", - "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==", - "dev": true - }, - "node_modules/@types/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", - "dev": true, - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@vitejs/plugin-react": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-3.1.0.tgz", @@ -2061,41 +2989,51 @@ "vite": "^4.1.0-beta.0" } }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "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, - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" + "bin": { + "acorn": "bin/acorn" }, "engines": { - "node": ">=8" + "node": ">=0.4.0" } }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "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, + "peer": true, + "peerDependencies": { + "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": ">=6" + "node": ">=0.4.0" } }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "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": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, "node_modules/ansi-regex": { @@ -2117,25 +3055,23 @@ "node": ">=4" } }, - "node_modules/arch": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", - "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", - "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/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", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", + "dev": true }, "node_modules/array-union": { "version": "1.0.2", @@ -2158,31 +3094,13 @@ "node": ">=0.10.0" } }, - "node_modules/asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "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==", + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", "dev": true, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, "node_modules/async": { @@ -2191,36 +3109,6 @@ "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", "dev": true }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true - }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", - "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==", - "dev": true - }, "node_modules/babel-plugin-macros": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", @@ -2241,47 +3129,27 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "node_modules/big-integer": { + "version": "1.6.51", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", + "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", "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" - } - ] + "engines": { + "node": ">=0.6" + } }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "node_modules/bplist-parser": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz", + "integrity": "sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==", "dev": true, "dependencies": { - "tweetnacl": "^0.14.3" + "big-integer": "^1.6.44" + }, + "engines": { + "node": ">= 5.10.0" } }, - "node_modules/blob-util": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", - "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==", - "dev": true - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -2292,6 +3160,18 @@ "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==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/browserslist": { "version": "4.21.5", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", @@ -2320,67 +3200,53 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "node_modules/bundle-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", + "integrity": "sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==", "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": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" + "run-applescript": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "engines": { - "node": "*" + "node": ">=6" } }, - "node_modules/cachedir": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz", - "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==", + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, "engines": { "node": ">=6" } }, - "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==", + "node_modules/camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" }, - "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==", "engines": { - "node": ">=6" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/caniuse-lite": { @@ -2399,307 +3265,622 @@ } ] }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "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==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk/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==", + "engines": { + "node": ">=0.8.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==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/clsx": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "engines": { + "node": ">=6" + } + }, + "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==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "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==" + }, + "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 + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true + }, + "node_modules/compare-func": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", + "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", + "dev": true, + "dependencies": { + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" + } + }, + "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/conventional-changelog-angular": { + "version": "5.0.13", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz", + "integrity": "sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==", + "dev": true, + "dependencies": { + "compare-func": "^2.0.0", + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-conventionalcommits": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-5.0.0.tgz", + "integrity": "sha512-lCDbA+ZqVFQGUj7h9QBKoIpLhl8iihkO0nCTyRNzuXtcd7ubODpYB04IFy31JloiJgG0Uovu8ot8oxRzn7Nwtw==", + "dev": true, + "dependencies": { + "compare-func": "^2.0.0", + "lodash": "^4.17.15", + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-commits-parser": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz", + "integrity": "sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q==", + "dev": true, + "dependencies": { + "is-text-path": "^1.0.1", + "JSONStream": "^1.0.4", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + }, + "bin": { + "conventional-commits-parser": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cosmiconfig-typescript-loader": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.3.0.tgz", + "integrity": "sha512-NTxV1MFfZDLPiBMjxbHRwSh5LaLcPMwNdCutmnHJCKoVnlvldPWlllonKwrsRJ5pYZBIBGRWWU2tfvzxgeSW5Q==", + "dev": true, + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "peerDependencies": { + "@types/node": "*", + "cosmiconfig": ">=7", + "ts-node": ">=10", + "typescript": ">=3" + } + }, + "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/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "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-vendor": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz", + "integrity": "sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==", + "dependencies": { + "@babel/runtime": "^7.8.3", + "is-in-browser": "^1.0.2" + } + }, + "node_modules/csstype": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" + }, + "node_modules/dargs": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", + "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ms": "2.1.2" }, "engines": { - "node": ">=4" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/chalk/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==", + "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.8.0" + "node": ">=0.10.0" } }, - "node_modules/check-more-types": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", - "integrity": "sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==", + "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.8.0" + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ci-info": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", - "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", + "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, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "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, - "engines": { - "node": ">=6" - } + "peer": true }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "node_modules/default-browser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz", + "integrity": "sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==", "dev": true, "dependencies": { - "restore-cursor": "^3.1.0" + "bundle-name": "^3.0.0", + "default-browser-id": "^3.0.0", + "execa": "^7.1.1", + "titleize": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cli-table3": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", - "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", + "node_modules/default-browser-id": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz", + "integrity": "sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==", "dev": true, "dependencies": { - "string-width": "^4.2.0" + "bplist-parser": "^0.2.0", + "untildify": "^4.0.0" }, "engines": { - "node": "10.* || >= 12.*" + "node": ">=12" }, - "optionalDependencies": { - "@colors/colors": "1.5.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cli-truncate": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", - "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", "dev": true, - "dependencies": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" - }, "engines": { - "node": ">=8" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" + "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/clsx": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", - "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "peer": true, + "dependencies": { + "esutils": "^2.0.2" + }, "engines": { - "node": ">=6" + "node": ">=6.0.0" } }, - "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==", + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", "dependencies": { - "color-name": "1.1.3" + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" } }, - "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==" + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } }, - "node_modules/colorette": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", - "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", + "node_modules/electron-to-chromium": { + "version": "1.4.311", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.311.tgz", + "integrity": "sha512-RoDlZufvrtr2Nx3Yx5MB8jX3aHIxm8nRWPJm3yVvyHmyKaRvn90RjzB6hNnt0AkhS3IInJdyRfQb4mWhPvUjVw==", "dev": true }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, + "node_modules/email-addresses": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-5.0.0.tgz", + "integrity": "sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw==", + "dev": true + }, + "node_modules/emoji-picker-react": { + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/emoji-picker-react/-/emoji-picker-react-4.4.10.tgz", + "integrity": "sha512-/5o57w8BKiCHklyqfYCeUlm00R9tdm2ZmJd0p6Q3/Ul7E7eMh+/FduuRFn3UVQCl5F6i4kOdREMz7EJ7YI1vMg==", "dependencies": { - "delayed-stream": "~1.0.0" + "clsx": "^1.2.1" }, "engines": { - "node": ">= 0.8" + "node": ">=10" + }, + "peerDependencies": { + "react": ">=16" } }, - "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 + "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==" + }, + "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==", + "dependencies": { + "is-arrayish": "^0.2.1" + } }, - "node_modules/common-tags": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", - "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", + "node_modules/esbuild": { + "version": "0.17.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.12.tgz", + "integrity": "sha512-bX/zHl7Gn2CpQwcMtRogTTBf9l1nl+H6R8nUbjk+RuKqAE3+8FDulLA+pHvX7aA7Xe07Iwa+CWvy9I8Y2qqPKQ==", "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, "engines": { - "node": ">=4.0.0" + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.17.12", + "@esbuild/android-arm64": "0.17.12", + "@esbuild/android-x64": "0.17.12", + "@esbuild/darwin-arm64": "0.17.12", + "@esbuild/darwin-x64": "0.17.12", + "@esbuild/freebsd-arm64": "0.17.12", + "@esbuild/freebsd-x64": "0.17.12", + "@esbuild/linux-arm": "0.17.12", + "@esbuild/linux-arm64": "0.17.12", + "@esbuild/linux-ia32": "0.17.12", + "@esbuild/linux-loong64": "0.17.12", + "@esbuild/linux-mips64el": "0.17.12", + "@esbuild/linux-ppc64": "0.17.12", + "@esbuild/linux-riscv64": "0.17.12", + "@esbuild/linux-s390x": "0.17.12", + "@esbuild/linux-x64": "0.17.12", + "@esbuild/netbsd-x64": "0.17.12", + "@esbuild/openbsd-x64": "0.17.12", + "@esbuild/sunos-x64": "0.17.12", + "@esbuild/win32-arm64": "0.17.12", + "@esbuild/win32-ia32": "0.17.12", + "@esbuild/win32-x64": "0.17.12" } }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true + "node_modules/esbuild/node_modules/@esbuild/win32-x64": { + "version": "0.17.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.12.tgz", + "integrity": "sha512-JOOxw49BVZx2/5tW3FqkdjSD/5gXYeVGPDcB0lvap0gLQshkh1Nyel1QazC+wNxus3xPlsYAgqU1BUmrmCvWtw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } }, - "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/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } }, - "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + "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==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true + "node_modules/eslint": { + "version": "8.47.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.47.0.tgz", + "integrity": "sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q==", + "dev": true, + "peer": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "^8.47.0", + "@humanwhocodes/config-array": "^0.11.10", + "@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/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "node_modules/eslint-config-prettier": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz", + "integrity": "sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.0.tgz", + "integrity": "sha512-AgaZCVuYDXHUGxj/ZGu1u8H8CYgDY3iG6w5kUFw4AzMVXzB7VvbKgYR4nATIN+OvUrghMbiDLeimVjVY5ilq3w==", + "dev": true, "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.8.5" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/prettier" }, - "engines": { - "node": ">=10" + "peerDependencies": { + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "prettier": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { + "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==", + "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, + "peer": true, "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "engines": { - "node": ">= 8" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/css-vendor": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz", - "integrity": "sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==", - "dependencies": { - "@babel/runtime": "^7.8.3", - "is-in-browser": "^1.0.2" + "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, + "peer": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/csstype": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", - "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" - }, - "node_modules/cypress": { - "version": "12.8.1", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-12.8.1.tgz", - "integrity": "sha512-lIFbKdaSYAOarNLHNFa2aPZu6YSF+8UY4VRXMxJrFUnk6RvfG0AWsZ7/qle/aIz30TNUD4aOihz2ZgS4vuQVSA==", + "node_modules/eslint/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, - "hasInstallScript": true, + "peer": true, "dependencies": { - "@cypress/request": "^2.88.10", - "@cypress/xvfb": "^1.2.4", - "@types/node": "^14.14.31", - "@types/sinonjs__fake-timers": "8.1.1", - "@types/sizzle": "^2.3.2", - "arch": "^2.2.0", - "blob-util": "^2.0.2", - "bluebird": "^3.7.2", - "buffer": "^5.6.0", - "cachedir": "^2.3.0", - "chalk": "^4.1.0", - "check-more-types": "^2.24.0", - "cli-cursor": "^3.1.0", - "cli-table3": "~0.6.1", - "commander": "^5.1.0", - "common-tags": "^1.8.0", - "dayjs": "^1.10.4", - "debug": "^4.3.4", - "enquirer": "^2.3.6", - "eventemitter2": "6.4.7", - "execa": "4.1.0", - "executable": "^4.1.1", - "extract-zip": "2.0.1", - "figures": "^3.2.0", - "fs-extra": "^9.1.0", - "getos": "^3.2.1", - "is-ci": "^3.0.0", - "is-installed-globally": "~0.4.0", - "lazy-ass": "^1.6.0", - "listr2": "^3.8.3", - "lodash": "^4.17.21", - "log-symbols": "^4.0.0", - "minimist": "^1.2.6", - "ospath": "^1.2.2", - "pretty-bytes": "^5.6.0", - "proxy-from-env": "1.0.0", - "request-progress": "^3.0.0", - "semver": "^7.3.2", - "supports-color": "^8.1.1", - "tmp": "~0.2.1", - "untildify": "^4.0.0", - "yauzl": "^2.10.0" - }, - "bin": { - "cypress": "bin/cypress" + "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": "^14.0.0 || ^16.0.0 || >=18.0.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/cypress/node_modules/@types/node": { - "version": "14.18.37", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.37.tgz", - "integrity": "sha512-7GgtHCs/QZrBrDzgIJnQtuSvhFSwhyYSI2uafSwZoNt1iOGhEN5fwNrQMjtONyHm9+/LoA4453jH0CMYcr06Pg==", - "dev": true - }, - "node_modules/cypress/node_modules/ansi-styles": { + "node_modules/eslint/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, + "peer": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -2710,11 +3891,12 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/cypress/node_modules/chalk": { + "node_modules/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==", "dev": true, + "peer": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -2726,23 +3908,12 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/cypress/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/cypress/node_modules/color-convert": { + "node_modules/eslint/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, + "peer": true, "dependencies": { "color-name": "~1.1.4" }, @@ -2750,368 +3921,351 @@ "node": ">=7.0.0" } }, - "node_modules/cypress/node_modules/color-name": { + "node_modules/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 + "dev": true, + "peer": true }, - "node_modules/cypress/node_modules/commander": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "node_modules/eslint/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, + "peer": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, "engines": { - "node": ">= 6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cypress/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "node_modules/eslint/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, + "peer": true, "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "type-fest": "^0.20.2" }, "engines": { - "node": ">=10" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cypress/node_modules/has-flag": { + "node_modules/eslint/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, + "peer": true, "engines": { "node": ">=8" } }, - "node_modules/cypress/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "node_modules/eslint/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, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } + "peer": true }, - "node_modules/cypress/node_modules/lru-cache": { + "node_modules/eslint/node_modules/locate-path": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, + "peer": true, "dependencies": { - "yallist": "^4.0.0" + "p-locate": "^5.0.0" }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cypress/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "node_modules/eslint/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, + "peer": true, "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" + "yocto-queue": "^0.1.0" }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cypress/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==", + "node_modules/eslint/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, + "peer": true, "dependencies": { - "has-flag": "^4.0.0" + "p-limit": "^3.0.2" }, "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cypress/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "node_modules/eslint/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, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, "engines": { - "node": ">= 10.0.0" + "node": ">=8" } }, - "node_modules/cypress/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/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "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, + "peer": true, "dependencies": { - "assert-plus": "^1.0.0" + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" }, "engines": { - "node": ">=0.10" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/dayjs": { - "version": "1.11.7", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz", - "integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==", - "dev": true - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "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, + "peer": true, "dependencies": { - "ms": "2.1.2" + "estraverse": "^5.1.0" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">=0.10" } }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "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, + "peer": true, + "dependencies": { + "estraverse": "^5.2.0" + }, "engines": { - "node": ">=0.4.0" + "node": ">=4.0" } }, - "node_modules/dom-helpers": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", - "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", - "dependencies": { - "@babel/runtime": "^7.8.7", - "csstype": "^3.0.2" + "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, + "peer": true, + "engines": { + "node": ">=4.0" } }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "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, - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" + "peer": true, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/electron-to-chromium": { - "version": "1.4.311", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.311.tgz", - "integrity": "sha512-RoDlZufvrtr2Nx3Yx5MB8jX3aHIxm8nRWPJm3yVvyHmyKaRvn90RjzB6hNnt0AkhS3IInJdyRfQb4mWhPvUjVw==", - "dev": true - }, - "node_modules/email-addresses": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/email-addresses/-/email-addresses-5.0.0.tgz", - "integrity": "sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw==", - "dev": true - }, - "node_modules/emoji-picker-react": { - "version": "4.4.7", - "resolved": "https://registry.npmjs.org/emoji-picker-react/-/emoji-picker-react-4.4.7.tgz", - "integrity": "sha512-HcB1Fr57W6M+gLLm/W4YhbAnUQqYBUAhZBOHmPlSQODLtsDI8vecyqNIF9RrStZHfZwzUSLlpZMfY07AA6gxmA==", + "node_modules/execa": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", + "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", + "dev": true, "dependencies": { - "clsx": "^1.2.1" + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.1", + "human-signals": "^4.3.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^3.0.7", + "strip-final-newline": "^3.0.0" }, "engines": { - "node": ">=10" + "node": "^14.18.0 || ^16.14.0 || >=18.0.0" }, - "peerDependencies": { - "react": ">=16" + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "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==" - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "node_modules/execa/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true, - "dependencies": { - "once": "^1.4.0" + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "node_modules/execa/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true, - "dependencies": { - "ansi-colors": "^4.1.1" - }, "engines": { - "node": ">=8.6" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "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==", + "node_modules/execa/node_modules/npm-run-path": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", + "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", + "dev": true, "dependencies": { - "is-arrayish": "^0.2.1" + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/esbuild": { - "version": "0.17.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.12.tgz", - "integrity": "sha512-bX/zHl7Gn2CpQwcMtRogTTBf9l1nl+H6R8nUbjk+RuKqAE3+8FDulLA+pHvX7aA7Xe07Iwa+CWvy9I8Y2qqPKQ==", + "node_modules/execa/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" + "dependencies": { + "mimic-fn": "^4.0.0" }, "engines": { "node": ">=12" }, - "optionalDependencies": { - "@esbuild/android-arm": "0.17.12", - "@esbuild/android-arm64": "0.17.12", - "@esbuild/android-x64": "0.17.12", - "@esbuild/darwin-arm64": "0.17.12", - "@esbuild/darwin-x64": "0.17.12", - "@esbuild/freebsd-arm64": "0.17.12", - "@esbuild/freebsd-x64": "0.17.12", - "@esbuild/linux-arm": "0.17.12", - "@esbuild/linux-arm64": "0.17.12", - "@esbuild/linux-ia32": "0.17.12", - "@esbuild/linux-loong64": "0.17.12", - "@esbuild/linux-mips64el": "0.17.12", - "@esbuild/linux-ppc64": "0.17.12", - "@esbuild/linux-riscv64": "0.17.12", - "@esbuild/linux-s390x": "0.17.12", - "@esbuild/linux-x64": "0.17.12", - "@esbuild/netbsd-x64": "0.17.12", - "@esbuild/openbsd-x64": "0.17.12", - "@esbuild/sunos-x64": "0.17.12", - "@esbuild/win32-arm64": "0.17.12", - "@esbuild/win32-ia32": "0.17.12", - "@esbuild/win32-x64": "0.17.12" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "node_modules/execa/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, "engines": { - "node": ">=6" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "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==", + "node_modules/execa/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eventemitter2": { - "version": "6.4.7", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.7.tgz", - "integrity": "sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==", + "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/execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "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": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" + "@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": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + "node": ">=8.6.0" } }, - "node_modules/executable": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", - "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", + "node_modules/fast-glob/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==", "dev": true, "dependencies": { - "pify": "^2.2.0" + "is-glob": "^4.0.1" }, "engines": { - "node": ">=4" + "node": ">= 6" } }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true + "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, + "peer": true }, - "node_modules/extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "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, - "dependencies": { - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" - }, - "engines": { - "node": ">= 10.17.0" - }, - "optionalDependencies": { - "@types/yauzl": "^2.9.1" - } + "peer": true }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "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, - "engines": [ - "node >=0.6.0" - ] + "dependencies": { + "reusify": "^1.0.4" + } }, "node_modules/faye-websocket": { "version": "0.11.4", @@ -3124,38 +4278,23 @@ "node": ">=0.8.0" } }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "dev": true, - "dependencies": { - "pend": "~1.2.0" - } - }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "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, + "peer": true, "dependencies": { - "escape-string-regexp": "^1.0.5" + "flat-cache": "^3.0.4" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/figures/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/file-saver": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz", + "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==" }, "node_modules/filename-reserved-regex": { "version": "2.0.0", @@ -3183,6 +4322,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "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==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/find-cache-dir": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", @@ -3219,25 +4370,25 @@ } }, "node_modules/firebase": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/firebase/-/firebase-9.18.0.tgz", - "integrity": "sha512-CTV5S3mTtn9zodeWkdeTqiQFyS7t+iskA50V9hVKPCQ4TPw4tnoyNgtNzWUmemFnYadzzsTnAaxsR7UaBJgiqw==", - "dependencies": { - "@firebase/analytics": "0.9.4", - "@firebase/analytics-compat": "0.2.4", - "@firebase/app": "0.9.5", - "@firebase/app-check": "0.6.4", - "@firebase/app-check-compat": "0.3.4", - "@firebase/app-compat": "0.2.5", + "version": "9.23.0", + "resolved": "https://registry.npmjs.org/firebase/-/firebase-9.23.0.tgz", + "integrity": "sha512-/4lUVY0lUvBDIaeY1q6dUYhS8Sd18Qb9CgWkPZICUo9IXpJNCEagfNZXBBFCkMTTN5L5gx2Hjr27y21a9NzUcA==", + "dependencies": { + "@firebase/analytics": "0.10.0", + "@firebase/analytics-compat": "0.2.6", + "@firebase/app": "0.9.13", + "@firebase/app-check": "0.8.0", + "@firebase/app-check-compat": "0.3.7", + "@firebase/app-compat": "0.2.13", "@firebase/app-types": "0.9.0", - "@firebase/auth": "0.21.5", - "@firebase/auth-compat": "0.3.5", + "@firebase/auth": "0.23.2", + "@firebase/auth-compat": "0.4.2", "@firebase/database": "0.14.4", "@firebase/database-compat": "0.3.4", - "@firebase/firestore": "3.9.0", - "@firebase/firestore-compat": "0.3.5", - "@firebase/functions": "0.9.4", - "@firebase/functions-compat": "0.3.4", + "@firebase/firestore": "3.13.0", + "@firebase/firestore-compat": "0.3.12", + "@firebase/functions": "0.10.0", + "@firebase/functions-compat": "0.3.5", "@firebase/installations": "0.6.4", "@firebase/installations-compat": "0.2.4", "@firebase/messaging": "0.12.4", @@ -3251,29 +4402,27 @@ "@firebase/util": "1.9.3" } }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, + "peer": true, "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" + "flatted": "^3.1.0", + "rimraf": "^3.0.2" }, "engines": { - "node": ">= 0.12" + "node": "^10.12.0 || >=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, + "peer": true + }, "node_modules/fs-extra": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", @@ -3295,9 +4444,9 @@ "dev": true }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "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, @@ -3330,53 +4479,18 @@ "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/get-intrinsic": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", - "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/getos": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz", - "integrity": "sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==", - "dev": true, - "dependencies": { - "async": "^3.2.0" - } - }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0" - } - }, "node_modules/gh-pages": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/gh-pages/-/gh-pages-5.0.0.tgz", @@ -3399,6 +4513,25 @@ "node": ">=10" } }, + "node_modules/git-raw-commits": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz", + "integrity": "sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==", + "dev": true, + "dependencies": { + "dargs": "^7.0.0", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + }, + "bin": { + "git-raw-commits": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -3419,19 +4552,29 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/global-dirs": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", - "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", + "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, + "peer": true, "dependencies": { - "ini": "2.0.0" + "is-glob": "^4.0.3" }, "engines": { - "node": ">=10" + "node": ">=10.13.0" + } + }, + "node_modules/global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==", + "dev": true, + "dependencies": { + "ini": "^1.3.4" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=4" } }, "node_modules/globals": { @@ -3473,6 +4616,22 @@ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", "dev": true }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "peer": 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", @@ -3492,18 +4651,6 @@ "node": ">=4" } }, - "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==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/hoist-non-react-statics": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", @@ -3517,32 +4664,63 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "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/hosted-git-info/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": ">=10" + } + }, + "node_modules/hosted-git-info/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/http-parser-js": { "version": "0.5.8", "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" }, - "node_modules/http-signature": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz", - "integrity": "sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==", + "node_modules/human-signals": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", + "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", "dev": true, - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^2.0.2", - "sshpk": "^1.14.1" - }, "engines": { - "node": ">=0.10" + "node": ">=14.18.0" } }, - "node_modules/human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "node_modules/husky": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz", + "integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==", "dev": true, + "bin": { + "husky": "lib/bin.js" + }, "engines": { - "node": ">=8.12.0" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" } }, "node_modules/hyphenate-style-name": { @@ -3551,29 +4729,19 @@ "integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==" }, "node_modules/idb": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/idb/-/idb-7.0.1.tgz", - "integrity": "sha512-UUxlE7vGWK5RfB/fDwEGgRf84DY/ieqNha6msMV99UsEMQhJ1RwbCd8AYBj3QMgnE3VZnfQvm4oKVCJTYlqIgg==" + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==" }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "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" - } - ] + "peer": true, + "engines": { + "node": ">= 4" + } }, "node_modules/import-fresh": { "version": "3.3.0", @@ -3590,6 +4758,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.8.19" + } + }, "node_modules/indent-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", @@ -3616,31 +4794,16 @@ "dev": true }, "node_modules/ini": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", - "dev": true, - "engines": { - "node": ">=10" - } + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true }, "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==" }, - "node_modules/is-ci": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", - "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", - "dev": true, - "dependencies": { - "ci-info": "^3.2.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, "node_modules/is-core-module": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", @@ -3652,6 +4815,30 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": 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", @@ -3660,34 +4847,76 @@ "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==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-in-browser": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz", "integrity": "sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g==" }, - "node_modules/is-installed-globally": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", - "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", "dev": true, "dependencies": { - "global-dirs": "^3.0.0", - "is-path-inside": "^3.0.2" + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" }, "engines": { - "node": ">=10" + "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, + "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==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "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, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "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": ">=8" + "node": ">=0.10.0" } }, "node_modules/is-stream": { @@ -3702,19 +4931,40 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true + "node_modules/is-text-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", + "integrity": "sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==", + "dev": true, + "dependencies": { + "text-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "dev": true, + "dependencies": { + "is-docker": "^2.0.0" + }, "engines": { - "node": ">=10" + "node": ">=8" + } + }, + "node_modules/is-wsl/node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -3726,22 +4976,22 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "dev": true - }, "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==" }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "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" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } }, "node_modules/jsesc": { "version": "2.5.2", @@ -3760,17 +5010,18 @@ "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==" }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "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/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "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, + "peer": true }, "node_modules/json5": { "version": "2.2.3", @@ -3793,19 +5044,29 @@ "graceful-fs": "^4.1.6" } }, - "node_modules/jsprim": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", - "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==", + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", "dev": true, "engines": [ - "node >=0.6.0" - ], + "node >= 0.2.0" + ] + }, + "node_modules/JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" } }, "node_modules/jss": { @@ -3890,47 +5151,34 @@ "jss": "10.10.0" } }, - "node_modules/lazy-ass": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", - "integrity": "sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==", + "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.8" + "node": ">=0.10.0" } }, - "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==" - }, - "node_modules/listr2": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz", - "integrity": "sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==", + "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, + "peer": true, "dependencies": { - "cli-truncate": "^2.1.0", - "colorette": "^2.0.16", - "log-update": "^4.0.0", - "p-map": "^4.0.0", - "rfdc": "^1.3.0", - "rxjs": "^7.5.1", - "through": "^2.3.8", - "wrap-ansi": "^7.0.0" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" }, "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "enquirer": ">= 2.3.0 < 3" - }, - "peerDependenciesMeta": { - "enquirer": { - "optional": true - } + "node": ">= 0.8.0" } }, + "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==" + }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -3946,8 +5194,12 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" }, "node_modules/lodash.camelcase": { "version": "4.3.0", @@ -3959,184 +5211,64 @@ "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" }, - "node_modules/lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "node_modules/lodash.isfunction": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz", + "integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==", "dev": true }, - "node_modules/lodash.throttle": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", - "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==" - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-symbols/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/log-symbols/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/log-symbols/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/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "dev": true }, - "node_modules/log-symbols/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==", + "node_modules/lodash.kebabcase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", + "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==", "dev": true }, - "node_modules/log-symbols/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/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/log-symbols/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/lodash.mergewith": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", + "dev": true }, - "node_modules/log-update": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", - "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", - "dev": true, - "dependencies": { - "ansi-escapes": "^4.3.0", - "cli-cursor": "^3.1.0", - "slice-ansi": "^4.0.0", - "wrap-ansi": "^6.2.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "node_modules/lodash.snakecase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==", + "dev": true }, - "node_modules/log-update/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/lodash.startcase": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", + "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", + "dev": true }, - "node_modules/log-update/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/lodash.throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==" }, - "node_modules/log-update/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==", + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", "dev": true }, - "node_modules/log-update/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/log-update/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } + "node_modules/lodash.upperfirst": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", + "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==", + "dev": true }, "node_modules/long": { "version": "4.0.0", @@ -4180,11 +5312,71 @@ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, - "dependencies": { - "semver": "^6.0.0" - }, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/material-colors": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/material-colors/-/material-colors-1.2.6.tgz", + "integrity": "sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg==" + }, + "node_modules/meow": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", + "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", + "dev": true, + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -4196,25 +5388,26 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, - "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==", + "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": ">= 0.6" + "node": ">= 8" } }, - "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==", + "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": { - "mime-db": "1.52.0" + "braces": "^3.0.2", + "picomatch": "^2.3.1" }, "engines": { - "node": ">= 0.6" + "node": ">=8.6" } }, "node_modules/mimic-fn": { @@ -4226,6 +5419,15 @@ "node": ">=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", @@ -4247,6 +5449,20 @@ "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.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -4254,10 +5470,16 @@ "dev": true }, "node_modules/nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "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", + "url": "https://github.com/sponsors/ai" + } + ], "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -4265,6 +5487,13 @@ "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, + "peer": true + }, "node_modules/node-fetch": { "version": "2.6.7", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", @@ -4290,6 +5519,54 @@ "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", "dev": true }, + "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/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": ">=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-package-data/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/notistack": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/notistack/-/notistack-3.0.1.tgz", @@ -4331,15 +5608,6 @@ "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/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -4364,11 +5632,41 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ospath": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", - "integrity": "sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==", - "dev": true + "node_modules/open": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-9.1.0.tgz", + "integrity": "sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==", + "dev": true, + "dependencies": { + "default-browser": "^4.0.0", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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, + "peer": 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/p-limit": { "version": "2.3.0", @@ -4397,21 +5695,6 @@ "node": ">=8" } }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -4489,24 +5772,24 @@ "node": ">=8" } }, - "node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true - }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "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==", "dev": true }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", @@ -4550,9 +5833,9 @@ } }, "node_modules/postcss": { - "version": "8.4.21", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", - "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", "dev": true, "funding": [ { @@ -4562,10 +5845,14 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "nanoid": "^3.3.4", + "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" }, @@ -4573,16 +5860,41 @@ "node": "^10 || ^12 || >=14" } }, - "node_modules/pretty-bytes": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", - "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", + "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, + "peer": true, "engines": { - "node": ">=6" + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" } }, "node_modules/prop-types": { @@ -4601,9 +5913,9 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/protobufjs": { - "version": "6.11.3", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz", - "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==", + "version": "6.11.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz", + "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==", "hasInstallScript": true, "dependencies": { "@protobufjs/aspromise": "^1.1.2", @@ -4625,28 +5937,6 @@ "pbts": "bin/pbts" } }, - "node_modules/proxy-from-env": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", - "integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==", - "dev": true - }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "node_modules/punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", @@ -4656,19 +5946,43 @@ "node": ">=6" } }, - "node_modules/qs": { - "version": "6.10.4", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.4.tgz", - "integrity": "sha512-OQiU+C+Ds5qiH91qh/mg0w+8nwQuLjM4F4M/PbmhDOoYehPh+Fb0bDjtR1sOvy7YKxvj28Y/M0PhP5uVX0kB+g==", + "node_modules/q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", "dev": true, - "dependencies": { - "side-channel": "^1.0.4" - }, "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "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": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true, + "engines": { + "node": ">=8" } }, "node_modules/react": { @@ -4682,6 +5996,23 @@ "node": ">=0.10.0" } }, + "node_modules/react-color": { + "version": "2.19.3", + "resolved": "https://registry.npmjs.org/react-color/-/react-color-2.19.3.tgz", + "integrity": "sha512-LEeGE/ZzNLIsFWa1TMe8y5VYqr7bibneWmvJwm1pCn/eNmrabWDh659JSPn9BuaMpEfU83WTOJfnCcjDZwNQTA==", + "dependencies": { + "@icons/material": "^0.2.4", + "lodash": "^4.17.15", + "lodash-es": "^4.17.15", + "material-colors": "^1.2.1", + "prop-types": "^15.5.10", + "reactcss": "^1.2.0", + "tinycolor2": "^1.4.1" + }, + "peerDependencies": { + "react": "*" + } + }, "node_modules/react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -4694,6 +6025,17 @@ "react": "^18.2.0" } }, + "node_modules/react-error-boundary": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-4.0.10.tgz", + "integrity": "sha512-pvVKdi77j2OoPHo+p3rorgE43OjDWiqFkaqkJz8sJKK6uf/u8xtzuaVfj5qJ2JnDLIgF1De3zY5AJDijp+LVPA==", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "peerDependencies": { + "react": ">=16.13.1" + } + }, "node_modules/react-error-overlay": { "version": "6.0.11", "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", @@ -4780,20 +6122,132 @@ "react-dom": ">=16.6.0" } }, - "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + "node_modules/react-webcam": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/react-webcam/-/react-webcam-7.1.1.tgz", + "integrity": "sha512-2W5WN8wmEv8ZlxvyAlOxVuw6new8Bi7+KSPqoq5oa7z1KSKZ72ucaKqCFRtHSuFjZ5sh5ioS9lp4BGwnaZ6lDg==", + "peerDependencies": { + "react": ">=16.2.0", + "react-dom": ">=16.2.0" + } + }, + "node_modules/reactcss": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz", + "integrity": "sha512-KiwVUcFu1RErkI97ywr8nvx8dNOpT03rbnma0SSalTYjkrPYaEajR4a/MRt6DZ46K6arDRbWMNHF+xH7G7n/8A==", + "dependencies": { + "lodash": "^4.0.1" + } + }, + "node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/read-pkg/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } }, - "node_modules/request-progress": { + "node_modules/redent": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", - "integrity": "sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", "dev": true, "dependencies": { - "throttleit": "^1.0.0" + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -4802,6 +6256,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.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -4826,30 +6289,34 @@ "node": ">=4" } }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "node_modules/resolve-global": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-global/-/resolve-global-1.0.0.tgz", + "integrity": "sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==", "dev": true, "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" + "global-dirs": "^0.1.1" }, "engines": { "node": ">=8" } }, - "node_modules/rfdc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", - "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", - "dev": true + "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, + "peer": true, "dependencies": { "glob": "^7.1.3" }, @@ -4876,13 +6343,74 @@ "fsevents": "~2.3.2" } }, - "node_modules/rxjs": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz", - "integrity": "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==", + "node_modules/run-applescript": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz", + "integrity": "sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==", "dev": true, "dependencies": { - "tslib": "^2.1.0" + "execa": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-applescript/node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/run-applescript/node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "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/safe-buffer": { @@ -4904,12 +6432,6 @@ } ] }, - "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/scheduler": { "version": "0.23.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", @@ -4919,9 +6441,9 @@ } }, "node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "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" @@ -4948,113 +6470,77 @@ "node": ">=8" } }, - "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/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, - "node_modules/slice-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", - "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/slice-ansi/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/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, - "dependencies": { - "color-convert": "^2.0.1" - }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">=0.10.0" } }, - "node_modules/slice-ansi/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/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": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" } }, - "node_modules/slice-ansi/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==", + "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/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "engines": { - "node": ">=0.10.0" + "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/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==", + "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/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", "dev": true, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "readable-stream": "^3.0.0" } }, - "node_modules/sshpk": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", - "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" + "safe-buffer": "~5.2.0" } }, "node_modules/string-width": { @@ -5090,6 +6576,31 @@ "node": ">=6" } }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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, + "peer": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/strip-outer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", @@ -5112,9 +6623,9 @@ } }, "node_modules/stylis": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz", - "integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA==" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" }, "node_modules/supports-color": { "version": "5.5.0", @@ -5138,11 +6649,37 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/throttleit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", - "integrity": "sha512-rkTVqu6IjfQ/6+uNuuc3sZek4CEYxTJom3IktzgdSxcZqdARuebbA/f4QmAxMQIxqq9ZLEUkSYqvuk1I6VKq4g==", - "dev": true + "node_modules/synckit": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.5.tgz", + "integrity": "sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==", + "dev": true, + "dependencies": { + "@pkgr/utils": "^2.3.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/text-extensions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", + "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "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, + "peer": true }, "node_modules/through": { "version": "2.3.8", @@ -5150,21 +6687,35 @@ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, + "node_modules/through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "dependencies": { + "readable-stream": "3" + } + }, "node_modules/tiny-warning": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" }, - "node_modules/tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "node_modules/tinycolor2": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", + "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==" + }, + "node_modules/titleize": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz", + "integrity": "sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==", "dev": true, - "dependencies": { - "rimraf": "^3.0.0" - }, "engines": { - "node": ">=8.17.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/to-fast-properties": { @@ -5175,17 +6726,16 @@ "node": ">=4" } }, - "node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "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==", "dev": true, "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" + "is-number": "^7.0.0" }, "engines": { - "node": ">=0.8" + "node": ">=8.0" } }, "node_modules/tr46": { @@ -5193,6 +6743,15 @@ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, + "node_modules/trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/trim-repeated": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", @@ -5214,34 +6773,73 @@ "node": ">=0.8.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/tslib": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", - "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz", + "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==" }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "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, + "peer": true, "dependencies": { - "safe-buffer": "^5.0.1" + "prelude-ls": "^1.2.1" }, "engines": { - "node": "*" + "node": ">= 0.8.0" } }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true - }, "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "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, + "peer": true, "engines": { "node": ">=10" }, @@ -5249,6 +6847,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/typescript": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", + "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -5293,6 +6904,21 @@ "browserslist": ">= 4.21.0" } }, + "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/uuid": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", @@ -5301,24 +6927,26 @@ "uuid": "dist/bin/uuid" } }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "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", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, - "engines": [ - "node >=0.6.0" - ], "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" } }, "node_modules/vite": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.2.0.tgz", - "integrity": "sha512-AbDTyzzwuKoRtMIRLGNxhLRuv1FpRgdIw+1y6AQG73Q5+vtecmvzKo/yk8X/vrHDpETRTx01ABijqUHIzBXi0g==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.2.3.tgz", + "integrity": "sha512-kLU+m2q0Y434Y1kCy3TchefAdtFso0ILi0dLyFV8Us3InXTU11H/B5ZTqCKIQHzSKNxVG/yEx813EA9f1imQ9A==", "dev": true, "dependencies": { "esbuild": "^0.17.5", @@ -5489,20 +7117,20 @@ } }, "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dependencies": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.0", + "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "yargs-parser": "^21.1.1" }, "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/yargs-parser": { @@ -5513,14 +7141,33 @@ "node": ">=10" } }, - "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "node_modules/yargs/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==", + "engines": { + "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, - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" + "engines": { + "node": ">=6" + } + }, + "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" } } } diff --git a/package.json b/package.json index dc87dccbc..93df1a5f5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dummygram", - "version": "0.1.0", + "version": "1.0.0", "private": true, "type": "module", "homepage": "https://.github.io//", @@ -10,35 +10,65 @@ "predeploy": "npm run build", "deploy": "gh-pages -d dist", "preview": "vite preview", - "cypress:open": "cypress open" + "pretty": "prettier --write \"./**/*.{js,jsx,ts,tsx,json}\"", + "prepare": "husky install" }, "dependencies": { - "@emotion/react": "^11.10.6", - "@emotion/styled": "^11.10.6", + "@emailjs/browser": "^3.11.0", + "@emotion/react": "^11.11.1", + "@emotion/styled": "^11.11.0", + "@esbuild/win32-x64": "^0.18.11", "@fortawesome/fontawesome-svg-core": "^6.3.0", "@fortawesome/free-brands-svg-icons": "^6.3.0", "@fortawesome/free-solid-svg-icons": "^6.3.0", "@fortawesome/react-fontawesome": "^0.2.0", "@mui/icons-material": "^5.11.11", - "@mui/material": "^5.11.13", - "@mui/styles": "^5.11.13", - "emoji-picker-react": "^4.4.7", + "@mui/material": "^5.13.6", + "@mui/styles": "^5.13.2", + "emoji-picker-react": "^4.4.10", + "file-saver": "^2.0.5", "firebase": "^9.18.0", "notistack": "^3.0.1", "react": "^18.2.0", + "react-color": "^2.19.3", "react-dom": "^18.2.0", + "react-error-boundary": "^4.0.10", "react-icons": "^4.8.0", "react-lazy-load-image-component": "^1.5.6", "react-router-dom": "^6.9.0", + "react-webcam": "^7.0.1", "uuid": "^9.0.0" }, "devDependencies": { + "@commitlint/cli": "^17.6.7", + "@commitlint/config-conventional": "^17.6.7", "@types/react": "^18.0.28", "@types/react-dom": "^18.0.11", "@vitejs/plugin-react": "^3.1.0", - "cypress": "^12.8.1", + "eslint-config-prettier": "^9.0.0", + "eslint-plugin-prettier": "^5.0.0", "gh-pages": "^5.0.0", + "husky": "^8.0.3", + "prettier": "^2.8.8", "react-error-overlay": "^6.0.11", "vite": "^4.2.0" + }, + "description": "A social media app built with React, Firebase, and Material-UI.", + "main": "index.js", + "keywords": [ + "dummygram", + "react", + "firebase", + "material-ui", + "social-media" + ], + "author": "narayan954", + "license": "MIT", + "repository": { + "type": "git", + "url": "git+https://github.com/narayan954/dummygram.git" + }, + "bugs": { + "url": "https://github.com/narayan954/dummygram/issues" } } diff --git a/public/assets/postbg.webp b/public/assets/postbg.webp new file mode 100644 index 000000000..867889a3f Binary files /dev/null and b/public/assets/postbg.webp differ diff --git a/public/favicon.png b/public/favicon.webp similarity index 100% rename from public/favicon.png rename to public/favicon.webp diff --git a/src/App.jsx b/src/App.jsx index 3a46c9b67..6538a3ccd 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,30 +1,52 @@ -import React, { useState, useEffect } from "react"; -import Post from "./components/Post"; -import { db, auth } from "./lib/firebase"; -import { Button, Dialog, Modal, DialogContent } from "@mui/material"; -import { makeStyles } from "@mui/styles"; -import ImgUpload from "./components/ImgUpload"; -import Loader from "./components/Loader"; +import { Darkmode, ErrorBoundary } from "./reusableComponents"; +import { Outlet, Route, Routes, useNavigate } from "react-router-dom"; +import React, { useEffect, useState } from "react"; + +import { ChatPage } from "./pages"; import { FaArrowCircleUp } from "react-icons/fa"; +import { RowModeContext } from "./hooks/useRowMode"; +import { auth } from "./lib/firebase"; +import { makeStyles } from "@mui/styles"; import { useSnackbar } from "notistack"; -import logo from "./assets/logo.png"; -import { Routes, Route, useNavigate } from "react-router-dom"; -import LoginScreen from "./pages/Login"; -import SignupScreen from "./pages/Signup"; -import AnimatedButton from "./components/AnimatedButton"; -import NotFoundPage from "./components/NotFound"; -import ShareModal from "./components/ShareModal"; + +// ------------------------------------ Pages ---------------------------------------------------- +const Home = React.lazy(() => import("./pages/Home")); +const About = React.lazy(() => import("./pages/FooterPages/About")); +const Guidelines = React.lazy(() => import("./pages/FooterPages/Guidelines")); +const Feedback = React.lazy(() => import("./pages/FooterPages/Feedback")); +const LoginScreen = React.lazy(() => import("./pages/Login")); +const PostView = React.lazy(() => import("./pages/PostView")); +const Profile = React.lazy(() => import("./pages/Profile")); +const SignupScreen = React.lazy(() => import("./pages/Signup")); +const ForgotPassword = React.lazy(() => import("./pages/ForgotPassword")); +const Friends = React.lazy(() => import("./pages/Friends")); +const NotFound = React.lazy(() => import("./pages/NotFound")); +const Contributors = React.lazy( + () => import("./pages/FooterPages/ContributorPage"), +); +const HelpCenter = React.lazy(() => import("./pages/FooterPages/HelpCenter")); +// ------------------------------------- Components ------------------------------------------------ +const Notifications = React.lazy(() => import("./components/Notification")); +const SideBar = React.lazy(() => import("./components/SideBar")); +const Navbar = React.lazy(() => import("./components/Navbar")); +const DeleteAccount = React.lazy( + () => import("./components/SettingsComponents/DeleteAccount"), +); +const SettingsSidebar = React.lazy( + () => import("./components/SettingsComponents/Sidebar"), +); +const SoundSetting = React.lazy( + () => import("./components/SettingsComponents/Sounds"), +); export function getModalStyle() { - const top = 50; - const left = 50; + const top = 0; const padding = 2; const radius = 3; return { top: `${top}%`, - left: `${left}%`, - transform: `translate(-${top}%, -${left}%)`, + transform: `translate(-${top}%, -50%)`, padding: `${padding}%`, borderRadius: `${radius}%`, textAlign: "center", @@ -34,376 +56,315 @@ export function getModalStyle() { export const useStyles = makeStyles((theme) => ({ paper: { - position: "absolute", width: 250, + marginTop: 300, borderRadius: theme.shape.borderRadius, - boxShadow: "var(--color-shadow) 0px 5px 15px", + boxShadow: "var(--profile-box-shadow)", padding: theme.spacing(2, 4, 3), color: "var(--color)", + margin: "auto", + }, + logout: { + display: "flex", + justifyContent: "space-between", }, })); -function App() { - const classes = useStyles(); - - const navigate = useNavigate(); - - const [posts, setPosts] = useState([]); +export default function App() { const [user, setUser] = useState(null); - const [loadingPosts, setLoadingPosts] = useState(true); - const [pageSize, setPageSize] = useState(10); - const [loadMorePosts, setLoadMorePosts] = useState(false); - const [openNewUpload, setOpenNewUpload] = useState(false); - const [logout, setLogout] = useState(false); - const [openShareModal, setOpenShareModal] = useState(false); - const [currentPostLink, setCurrentPostLink] = useState(""); - const [postText, setPostText] = useState(""); - - const buttonStyle = { - background: "linear-gradient(40deg, #e107c1, #59afc7)", - borderRadius: "20px", - ":hover": { - background: "linear-gradient(-40deg, #59afc7, #e107c1)", - }, - }; + const [rowMode, setRowMode] = useState(false); + const navigate = useNavigate(); const { enqueueSnackbar } = useSnackbar(); - const [showScroll, setShowScroll] = useState(false); - const checkScrollTop = () => { - if (!showScroll && window.pageYOffset > 400) { - setShowScroll(true); - } else if (showScroll && window.pageYOffset <= 400) { - setShowScroll(false); - } - }; + useEffect(() => { + const showOfflineNotification = () => { + enqueueSnackbar("You are offline", { + variant: "error", + }); + }; - const scrollTop = () => { - window.scrollTo({ top: 0, behavior: "smooth" }); - }; + const showOnlineNotification = () => { + enqueueSnackbar("You are online", { + variant: "success", + }); + }; + + window.addEventListener("offline", showOfflineNotification); + window.addEventListener("online", showOnlineNotification); - window.addEventListener("scroll", checkScrollTop); + return () => { + window.removeEventListener("offline", showOfflineNotification); + window.removeEventListener("online", showOnlineNotification); + }; + }, []); useEffect(() => { const unsubscribe = auth.onAuthStateChanged((authUser) => { if (authUser) { setUser(authUser); - navigate("/dummygram/"); } else { setUser(null); - navigate("/dummygram/login"); + navigate("/login"); } }); - return () => { unsubscribe(); }; - }, [user]); - - useEffect(() => { - if (document.body.classList.contains("darkmode--activated")) { - window.document.body.style.setProperty("--bg-color", "black"); - window.document.body.style.setProperty( - "--color-shadow", - "rgba(255, 255, 255, 0.35)" - ); - window.document.body.style.setProperty("--color", "white"); - window.document.body.style.setProperty("--val", 1); - document.getElementsByClassName("app__header__img").item(0).style.filter = - "invert(100%)"; - } else { - window.document.body.style.setProperty("--bg-color", "white"); - window.document.body.style.setProperty( - "--color-shadow", - "rgba(0, 0, 0, 0.35)" - ); - window.document.body.style.setProperty("--color", "#2B1B17"); - window.document.body.style.setProperty("--val", 0); - document.getElementsByClassName("app__header__img").item(0).style.filter = - "invert(0%)"; - } - - window.addEventListener("scroll", handleMouseScroll); - db.collection("posts") - .orderBy("timestamp", "desc") - .limit(pageSize) - .onSnapshot((snapshot) => { - setLoadingPosts(false); - setPosts( - snapshot.docs.map((doc) => ({ - id: doc.id, - post: doc.data(), - })) - ); - }); }, []); - const handleMouseScroll = (event) => { - if ( - window.innerHeight + event.target.documentElement.scrollTop + 1 >= - event.target.documentElement.scrollHeight - ) { - setLoadMorePosts(true); - } - }; - - useEffect(() => { - if (loadMorePosts && posts.length) { - db.collection("posts") - .orderBy("timestamp", "desc") - .startAfter(posts[posts.length - 1].post.timestamp) - .limit(pageSize) - .onSnapshot((snapshot) => { - setPosts((loadedPosts) => { - return [ - ...loadedPosts, - ...snapshot.docs.map((doc) => ({ - id: doc.id, - post: doc.data(), - })), - ]; - }); - }); - } - setLoadMorePosts(false); - }, [loadMorePosts]); - - const signOut = () => { - auth.signOut().finally(); - enqueueSnackbar("Logged out Successfully !", { - variant: "info", - }); - }; - return ( -
-
- dummygram { - window.scrollTo({ top: 0, left: 0, behavior: "smooth" }); - navigate("/dummygram/"); - }} - style={{ - cursor: "pointer", - }} - /> - {user ? ( - <> - - - - ) : ( -
- - - -
- )} -
+ } + /> + + + + } + /> - + + + + } + /> - setOpenNewUpload(false)} - > -
- instagram -

- New Post -

+ + + + } + /> - + + + } + /> + + + + + } + /> + + + + + } + /> + + + + + } + /> + } /> + + + + + } + /> + + + + + } + /> + + + + + } + /> + + + + + } + /> + + + + + + } + > + + + + } + /> + + + + } + /> + Empty... + } + /> + + + + + } - } - > - {!loadingPosts && - (user ? ( - setOpenNewUpload(false)} - /> - ) : ( -

Sorry you need to login to upload posts

- ))} -
-
-
- setLogout(false)}> -
-
- dummygram -

- Are you sure you want to Logout? -

- - - Logout - -
-
-
- - - -
- {loadingPosts ? ( - - ) : ( -
- {posts.map(({ id, post }) => ( - - ))} -
- )} -
-
- ) : ( - <> - ) - } - /> - - } /> - - } /> - - } /> - + + + + } + /> + + } /> + + + + + ); +} + +function Wrapper({ user, setUser, setRowMode }) { + const [showScroll, setShowScroll] = useState(false); + const scrollTop = () => { + window.scrollTo({ top: 0, behavior: "smooth" }); + }; + + useEffect(() => { + const checkScrollTop = () => { + if (!showScroll && window.scrollY > 400) { + setShowScroll(true); + } else if (showScroll && window.scrollY <= 400) { + setShowScroll(false); + } + }; + window.addEventListener("scroll", checkScrollTop); + return () => { + window.removeEventListener("scroll", checkScrollTop); + }; + }, []); + + const isCenteredScroll = + location.href.includes("favourites") || + location.href.includes("about") || + location.href.includes("guidelines") || + location.href.includes("contributors"); + + return ( +
+ setRowMode((prev) => !prev)} + user={user} + setUser={setUser} + /> + {(location.href.includes("login") || + location.href.includes("signup")) && ( + + )} + + {/* All the children element will come here */} +
); } -export default App; +function SideBarWrapper() { + return ( +
+ + + +
+ +
+
+ ); +} diff --git a/src/assets/1.png b/src/assets/1.webp similarity index 100% rename from src/assets/1.png rename to src/assets/1.webp diff --git a/src/assets/10.png b/src/assets/10.webp similarity index 100% rename from src/assets/10.png rename to src/assets/10.webp diff --git a/src/assets/11.png b/src/assets/11.webp similarity index 100% rename from src/assets/11.png rename to src/assets/11.webp diff --git a/src/assets/2.png b/src/assets/2.webp similarity index 100% rename from src/assets/2.png rename to src/assets/2.webp diff --git a/src/assets/3.png b/src/assets/3.webp similarity index 100% rename from src/assets/3.png rename to src/assets/3.webp diff --git a/src/assets/4.png b/src/assets/4.webp similarity index 100% rename from src/assets/4.png rename to src/assets/4.webp diff --git a/src/assets/404/404_1.png b/src/assets/404/404_1.png new file mode 100644 index 000000000..714e7f2cb Binary files /dev/null and b/src/assets/404/404_1.png differ diff --git a/src/assets/404/404_2.png b/src/assets/404/404_2.png new file mode 100644 index 000000000..efa6fefc2 Binary files /dev/null and b/src/assets/404/404_2.png differ diff --git a/src/assets/404/404_3.jpeg b/src/assets/404/404_3.jpeg new file mode 100644 index 000000000..2ea7fd581 Binary files /dev/null and b/src/assets/404/404_3.jpeg differ diff --git a/src/assets/404/404_4.jpeg b/src/assets/404/404_4.jpeg new file mode 100644 index 000000000..9c8835927 Binary files /dev/null and b/src/assets/404/404_4.jpeg differ diff --git a/src/assets/5.png b/src/assets/5.webp similarity index 100% rename from src/assets/5.png rename to src/assets/5.webp diff --git a/src/assets/6.png b/src/assets/6.webp similarity index 100% rename from src/assets/6.png rename to src/assets/6.webp diff --git a/src/assets/7.png b/src/assets/7.webp similarity index 100% rename from src/assets/7.png rename to src/assets/7.webp diff --git a/src/assets/8.png b/src/assets/8.webp similarity index 100% rename from src/assets/8.png rename to src/assets/8.webp diff --git a/src/assets/9.png b/src/assets/9.webp similarity index 100% rename from src/assets/9.png rename to src/assets/9.webp diff --git a/src/assets/NotFound.jpg b/src/assets/NotFound.jpg deleted file mode 100644 index eaab9fb21..000000000 Binary files a/src/assets/NotFound.jpg and /dev/null differ diff --git a/src/assets/NotFound.webp b/src/assets/NotFound.webp new file mode 100644 index 000000000..8606fc859 Binary files /dev/null and b/src/assets/NotFound.webp differ diff --git a/src/assets/about-us.webp b/src/assets/about-us.webp new file mode 100644 index 000000000..cb112ebad Binary files /dev/null and b/src/assets/about-us.webp differ diff --git a/src/assets/app-logo.png b/src/assets/app-logo.png deleted file mode 100644 index 0f5bea028..000000000 Binary files a/src/assets/app-logo.png and /dev/null differ diff --git a/src/assets/app-logo.webp b/src/assets/app-logo.webp new file mode 100644 index 000000000..fe9cde175 Binary files /dev/null and b/src/assets/app-logo.webp differ diff --git a/src/assets/blank-profile.webp b/src/assets/blank-profile.webp new file mode 100644 index 000000000..71730f0e0 Binary files /dev/null and b/src/assets/blank-profile.webp differ diff --git a/src/assets/contributors.webp b/src/assets/contributors.webp new file mode 100644 index 000000000..f9560527c Binary files /dev/null and b/src/assets/contributors.webp differ diff --git a/src/assets/gssoc.webp b/src/assets/gssoc.webp new file mode 100644 index 000000000..a9838858b Binary files /dev/null and b/src/assets/gssoc.webp differ diff --git a/src/assets/guidelines.webp b/src/assets/guidelines.webp new file mode 100644 index 000000000..bc695935e Binary files /dev/null and b/src/assets/guidelines.webp differ diff --git a/src/assets/lock.png b/src/assets/lock.png new file mode 100644 index 000000000..f4480cf5b Binary files /dev/null and b/src/assets/lock.png differ diff --git a/src/assets/logo.png b/src/assets/logo.png index 00270d27c..b3aa261f3 100644 Binary files a/src/assets/logo.png and b/src/assets/logo.png differ diff --git a/src/assets/postbg.webp b/src/assets/postbg.webp new file mode 100644 index 000000000..867889a3f Binary files /dev/null and b/src/assets/postbg.webp differ diff --git a/src/assets/preview.png b/src/assets/preview.png deleted file mode 100644 index 7bc1f5a52..000000000 Binary files a/src/assets/preview.png and /dev/null differ diff --git a/src/assets/preview.webp b/src/assets/preview.webp new file mode 100644 index 000000000..8843c68aa Binary files /dev/null and b/src/assets/preview.webp differ diff --git a/src/assets/profile-background.webp b/src/assets/profile-background.webp new file mode 100644 index 000000000..9a5df864a Binary files /dev/null and b/src/assets/profile-background.webp differ diff --git a/src/assets/sounds/backBtn.mp3 b/src/assets/sounds/backBtn.mp3 new file mode 100644 index 000000000..5b1a4291b Binary files /dev/null and b/src/assets/sounds/backBtn.mp3 differ diff --git a/src/assets/sounds/error.mp3 b/src/assets/sounds/error.mp3 new file mode 100644 index 000000000..744ea9806 Binary files /dev/null and b/src/assets/sounds/error.mp3 differ diff --git a/src/assets/sounds/index.js b/src/assets/sounds/index.js new file mode 100644 index 000000000..db08c1724 --- /dev/null +++ b/src/assets/sounds/index.js @@ -0,0 +1,7 @@ +import backBtnSound from "./backBtn.mp3"; +import errorSound from "./error.mp3"; +import lightOffSound from "./lightOff.mp3"; +import lightOnSound from "./lightOn.mp3"; +import successSound from "./success.mp3"; + +export { backBtnSound, errorSound, lightOffSound, lightOnSound, successSound }; diff --git a/src/assets/sounds/lightOff.mp3 b/src/assets/sounds/lightOff.mp3 new file mode 100644 index 000000000..4e6772943 Binary files /dev/null and b/src/assets/sounds/lightOff.mp3 differ diff --git a/src/assets/sounds/lightOn.mp3 b/src/assets/sounds/lightOn.mp3 new file mode 100644 index 000000000..3dfbd3e97 Binary files /dev/null and b/src/assets/sounds/lightOn.mp3 differ diff --git a/src/assets/sounds/success.mp3 b/src/assets/sounds/success.mp3 new file mode 100644 index 000000000..2dd27675c Binary files /dev/null and b/src/assets/sounds/success.mp3 differ diff --git a/src/components/Caption.jsx b/src/components/Caption.jsx new file mode 100644 index 000000000..0103da3cf --- /dev/null +++ b/src/components/Caption.jsx @@ -0,0 +1,40 @@ +import React from "react"; + +/** + * Renders a caption with clickable links for URLs. + * @param {string} caption - The input caption string. + * @returns {JSX.Element} + */ +export default function Caption({ caption }) { + const urlRegex = /(https?:\/\/\S+(? urlRegex.test(part); + + // Render each part of the caption + const RenderCaptionParts = () => { + return parts.map((part, index) => { + if (isUrl(part)) { + // If the part is a URL, render it as a clickable link. + return ( + + {part} + + ); + } else { + // If the part is not a URL, render it as plain text. + return {part}; + } + }); + }; + + return ; +} diff --git a/src/components/CommunityChat/Reaction/index.css b/src/components/CommunityChat/Reaction/index.css new file mode 100644 index 000000000..78a3d8710 --- /dev/null +++ b/src/components/CommunityChat/Reaction/index.css @@ -0,0 +1,26 @@ +.msg-reaction-icon { + transform: scale(0.8); + color: #59afc7; + cursor: pointer; +} + +.msg-reaction-container { + display: flex; + border: 1px solid; + background-color: var(--dark-post-bg); + position: absolute; + border-radius: 33px; + padding: 0px 15px; + z-index: 99; + right: 6px; + top: -50px; +} +.msg-reaction-container > p { + padding: 8px; + border-radius: 50%; + cursor: pointer; +} +.msg-reaction-container > p:hover { + transition: all 0.3s ease; + scale: 1.5; +} diff --git a/src/components/CommunityChat/Reaction/index.jsx b/src/components/CommunityChat/Reaction/index.jsx new file mode 100644 index 000000000..d1ae4e1ea --- /dev/null +++ b/src/components/CommunityChat/Reaction/index.jsx @@ -0,0 +1,76 @@ +import "./index.css"; + +import AddReactionIcon from "@mui/icons-material/AddReaction"; +import { ClickAwayListener } from "@mui/material"; +import { db } from "../../../lib/firebase"; +import { useSnackbar } from "notistack"; +import { useState } from "react"; + +const Reaction = ({ message, currentUid }) => { + const [reactionOpen, setReactionOpen] = useState(false); + const { id, reaction } = message; + const { enqueueSnackbar } = useSnackbar(); + + async function addReaction(type) { + let updatedData = { ...reaction }; // Create a copy of the existing reactions + const msgDocRef = db.collection("messages").doc(id); + + if (updatedData[type]) { + // Check if the user has already reacted with this emoji + const userIndex = updatedData[type].indexOf(currentUid); + + if (userIndex !== -1) { + // If the user's reaction already exists, remove it + updatedData[type].splice(userIndex, 1); + } else { + // If the user's reaction doesn't exist, toggle off any existing reaction + // for (const existingType in updatedData) { + // const existingUserIndex = + // updatedData[existingType].indexOf(currentUid); + // if (existingUserIndex !== -1) { + // updatedData[existingType].splice(existingUserIndex, 1); + // break; // Exit the loop after toggling off the existing reaction + // } + // } + + updatedData[type].push(currentUid); // Add the new reaction + } + } else { + // If the reaction type doesn't exist, create a new array with the user's UID + updatedData[type] = [currentUid]; + } + + // Update the reaction data in the message document + try { + await msgDocRef.update({ + reaction: updatedData, + }); + setReactionOpen(false); + } catch (error) { + enqueueSnackbar("Error while reacting", { + variant: "error", + }); + } + } + + return ( + setReactionOpen(false)}> +
+ setReactionOpen((prev) => !prev)} + /> + {reactionOpen && ( + +

addReaction("smiley")}>😅

+

addReaction("like")}>❤️

+

addReaction("laughing")}>😂

+

addReaction("thumbsUp")}>👍

+
+ )} +
+
+ ); +}; + +export default Reaction; diff --git a/src/components/CommunityChat/index.css b/src/components/CommunityChat/index.css new file mode 100644 index 000000000..6449131de --- /dev/null +++ b/src/components/CommunityChat/index.css @@ -0,0 +1,292 @@ +.flex-center { + display: flex; + align-items: center; +} + +.chat-main-container { + position: relative; + min-height: 100vh; + padding: 15px; + padding-bottom: 40px; +} + +.all-chat-msg-container { + margin-bottom: 60px; +} + +.chat-loader-container { + width: 100%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; +} + +.chat-input-container { + position: fixed; + width: 80%; + bottom: 10px; + display: flex; + justify-content: center; + align-items: center; + gap: 2rem; + border-top: 1px solid #1a1a1a; + background-color: var(--input-bg); +} + +.chat-input { + flex: 1; + margin-top: 0; + font-size: 1em; + width: 70%; + font-weight: normal; + padding: 10px 0; + color: var(--text-grey); + background-color: var(--input-bg); +} + +.chat-msg-send-btn-container { + background-color: transparent; + border: none; + padding: 10px 15px; + padding-right: 20px; +} + +.chat-msg-send-btn { + color: var(--color); + margin-top: 7px; + transform: scale(1.3); + cursor: pointer; +} + +.chat-msg-container { + padding-inline: 0; +} + +.chat-message { + list-style: none; + display: flex; + align-items: center; + gap: 10px; + margin-bottom: 18px; +} + +.chat-message:hover { + background: none; +} + +.chat-user-img { + width: 40px; + aspect-ratio: 1; + border-radius: 50%; + cursor: pointer; + border: 1px solid #eee; + box-shadow: 1px 1px 5px #888585; + align-self: flex-start; + transition: 0.2s ease-in-out; +} + +.chat-user-img:hover { + transform: scale(1.1); +} + +.name-and-date-container { + display: flex; + justify-content: space-between; + gap: 20px; + align-items: center; +} + +.time-reaction-container { + display: flex; + align-items: center; + gap: 8px; +} + +.message-time { + font-weight: 600; + font-size: 12px; + color: var(--profile-color); +} + +.current-user-msg { + flex-direction: row-reverse; + margin-left: auto; + padding-left: 20px; +} + +.chat-msg-text { + position: relative; + color: var(--text-secondary); + border-radius: 6px; + padding: 8px 12px; + width: fit-content; + max-width: 70%; + box-shadow: 1px 1px 5px #59afc7; +} + +.chat-msg-text p { + max-width: 95%; + padding: 4px 0; +} + +.chat-msg-sender-name { + color: #59afc7; + cursor: pointer; +} + +.chat-msg-sender-name:hover { + text-decoration: underline; +} + +.current-user-msg > img { + align-self: flex-start; +} + +.chat-msg-send-btn:hover { + color: var(--btn-hover); +} + +.hide { + display: none; +} + +.communitychat-emoji-btn { + cursor: pointer; + transition: 0.2s ease-in-out; + padding: 10px 15px; +} + +.communitychat-emoji-btn:hover { + transform: scale(1.1); +} + +.rxn-main-container { + position: absolute; + padding: 0; + bottom: -13px; + left: 12px; + display: flex; + gap: 8px; +} + +.rxn-container { + list-style: none; + position: relative; + width: fit-content; + cursor: default; +} + +.rxn-count { + position: absolute; + bottom: -6px; + right: 0px; + font-size: 11px; + font-weight: 600; +} + +.message-options { + position: relative; + cursor: pointer; +} + +.delete-message-container { + display: flex; + flex-direction: column; + gap: 1rem; + border: 1px solid; + background-color: var(--dark-post-bg); + border-radius: 6px; + position: absolute; + bottom: 20px; + right: 0; + min-width: 100px; + padding: 14px 20px; +} + +.delete-message-container span { + cursor: pointer; + display: flex; + align-items: center; + gap: 1rem; +} + +.delete-message-container .delete-option:hover { + color: red; + transition: all 0.2s ease; +} + +.delete-message-container .edit-option:hover { + color: rgb(22 163 74); + transition: all 0.2s ease; +} + +.edit-state { + display: flex; + justify-content: flex-end; + padding-bottom: 4px; + padding-right: 4px; +} + +.edit-state span { + color: var(--text-light); + font-size: 12px; + font-weight: 500; +} + +@media screen and (min-width: 1200px) { + .chat-input-container { + width: 83vw; + } +} + +@media screen and (max-width: 1200px) { + .chat-input-container { + width: 92vw; + } + .chat-msg-text { + padding: 8px 12px; + } +} + +@media screen and (max-width: 800px) { + .all-chat-msg-container { + margin-bottom: 120px; + } + .chat-input-container { + width: 100vw; + bottom: 72px; + } + .chat-msg-text { + max-width: 60%; + } +} + +.closeBtn { + position: absolute; + position: fixed; + cursor: pointer; + color: var(--color); + padding: 2px; + right: 3%; + transform: scale(2); +} + +.closeBtn:hover { + color: var(--btn-hover); +} + +@media screen and (max-width: 600px) { + .chat-msg-text { + padding: 6px 9px; + } + + .chat-msg-text p { + font-size: 14px; + } + + .scrollTop { + margin-left: 83%; + bottom: 15%; + } +} diff --git a/src/components/CommunityChat/index.jsx b/src/components/CommunityChat/index.jsx new file mode 100644 index 000000000..eccf8921a --- /dev/null +++ b/src/components/CommunityChat/index.jsx @@ -0,0 +1,417 @@ +import "./index.css"; + +import { auth, db } from "../../lib/firebase"; +import { playErrorSound, playSuccessSound } from "../../js/sounds"; +import { useEffect, useRef, useState } from "react"; + +import { ClickAwayListener } from "@mui/material"; +import CloseIcon from "@mui/icons-material/Close"; +import DeleteIcon from "@mui/icons-material/DeleteOutlineOutlined"; +import EditIcon from "@mui/icons-material/EditOutlined"; +import EmojiPicker from "emoji-picker-react"; +import HighlightOffRoundedIcon from "@mui/icons-material/HighlightOffRounded"; +import { Loader } from "../../reusableComponents"; +import OptionIcon from "@mui/icons-material/MoreVert"; +import Reaction from "./Reaction"; +import SendIcon from "@mui/icons-material/Send"; +import SentimentVerySatisfiedIcon from "@mui/icons-material/SentimentVerySatisfied"; +import firebase from "firebase/compat/app"; +import profileAvatar from "../../assets/blank-profile.webp"; +import { useNavigate } from "react-router-dom"; +import { useSnackbar } from "notistack"; + +const ChatBox = () => { + const [showEmojis, setShowEmojis] = useState(false); + const [messages, setMessages] = useState([]); + const [loadMoreMsgs, setLoadMoreMsgs] = useState(false); + const [isLoading, setIsLoading] = useState(true); + const [newMessage, setNewMessage] = useState(""); + const [user, setUser] = useState(null); + const [isLastMsgRecieved, setIsLastMsgRecieved] = useState(false); + const chatMsgContainerRef = useRef(null); + const [openOptions, setOpenOptions] = useState(false); + const [isEditing, setIsEditing] = useState(false); + const [editingMessageId, setEditingMessageId] = useState(null); + + const navigate = useNavigate(); + const { enqueueSnackbar } = useSnackbar(); + + const handleEmojiClick = () => { + setShowEmojis((prevShowEmojis) => !prevShowEmojis); + }; + + const onEmojiClick = (emojiObject, event) => { + setNewMessage((prevInput) => prevInput + emojiObject.emoji); + setShowEmojis(false); + }; + + const handleOpenOptions = (messageId) => { + setOpenOptions(messageId); + }; + + const handleCancel = () => { + setIsEditing(false); + setNewMessage(""); + }; + + const handleEditMsg = (messageId) => { + const messageToEdit = messages.find((message) => message.id === messageId); + if (messageToEdit) { + setNewMessage(messageToEdit.text); + setIsEditing(true); + setEditingMessageId(messageId); + } + }; + + const handleDeletMsg = async (messageId) => { + try { + await db.collection("messages").doc(messageId).delete(); + playSuccessSound(); + enqueueSnackbar("Message deleted successfully.", { + variant: "success", + }); + } catch (error) { + playErrorSound(); + enqueueSnackbar("Failed to delete the message. Please try again.", { + variant: "error", + }); + } + }; + + function handleChange(e) { + e.preventDefault(); + setNewMessage(e.target.value); + } + + function handleOnSubmit(e) { + e.preventDefault(); + if (newMessage.trim()) { + if (isEditing && editingMessageId) { + // If user is in edit mode, update the existing message + db.collection("messages") + .doc(editingMessageId) + .update({ + text: newMessage, + edited: true, + }) + .then(() => { + setNewMessage(""); + setIsEditing(false); + setEditingMessageId(null); + }) + .catch((error) => { + enqueueSnackbar(`Error Occurred: ${error}`, { + variant: "error", + }); + }); + } else { + // If not in edit mode, send a new message + db.collection("messages").add({ + text: newMessage, + createdAt: firebase.firestore.FieldValue.serverTimestamp(), + uid: user.uid, + displayName: user.displayName, + photoURL: user.photoURL, + }); + + setNewMessage(""); + } + } else { + enqueueSnackbar("Enter something!", { + variant: "error", + }); + } + } + + function goToUserProfile(uid) { + async function getUsername() { + const docRef = db.collection("users").doc(uid); + docRef + .get() + .then((doc) => { + navigate(`/user/${doc.data().username}`); + }) + .catch((error) => { + enqueueSnackbar(`Error Occured: ${error}`, { + variant: "error", + }); + }); + } + getUsername(); + } + + function getTime(timestamp) { + const timeInMilliSec = timestamp * 1000; + const date = new Date(timeInMilliSec); + const timeWithSec = date.toLocaleTimeString(); + const [time, timePeriod] = timeWithSec.split(" "); + const formattedTime = time.split(":").slice(0, 2).join(":") + timePeriod; + return formattedTime; + } + + function getReaction(reaction) { + const reactionsArr = Object.keys(reaction); + let emoji = ""; + + const rxnList = reactionsArr.map((rxn) => { + switch (rxn) { + case "smiley": + emoji = "😅"; + break; + case "like": + emoji = "❤️"; + break; + case "laughing": + emoji = "😂"; + break; + default: + emoji = "👍"; + } + + return ( + reaction[rxn].length > 0 && ( +
  • + {emoji} + {reaction[rxn].length} +
  • + ) + ); + }); + return rxnList; + } + + useEffect(() => { + const unsubscribe = auth.onAuthStateChanged((user) => { + if (user) { + setUser(user); + } else { + navigate("/login"); + } + }); + + return () => { + unsubscribe(); + }; + }, []); + + useEffect(() => { + const scrollTop = () => { + window.scrollTo({ top: window.innerHeight + 800 }); + }; + if (!isLastMsgRecieved) { + scrollTop(); + } + }, [messages]); + + //Load messages for the first time + useEffect(() => { + const handleMouseScroll = (event) => { + if (event.target.documentElement.scrollTop === 0 && !isLastMsgRecieved) { + setLoadMoreMsgs(true); + } + }; + window.addEventListener("scroll", handleMouseScroll); + const unsubscribe = db + .collection("messages") + .orderBy("createdAt") + .limitToLast(20) + .onSnapshot((querySnapshot) => { + const data = querySnapshot.docs.map((doc) => ({ + ...doc.data(), + id: doc.id, + })); + setMessages(data); + setIsLoading(false); + }); + + return () => { + window.removeEventListener("scroll", handleMouseScroll); + unsubscribe(); + }; + }, []); + + useEffect(() => { + let unsubscribed = false; + + if (loadMoreMsgs && messages.length) { + const lastMessageCreatedAt = messages[0].createdAt; + db.collection("messages") + .orderBy("createdAt") + .endBefore(lastMessageCreatedAt) + .limitToLast(20) + .onSnapshot((querySnapshot) => { + if (!unsubscribed) { + setMessages((loadedMsgs) => { + return [ + ...querySnapshot.docs.map((doc) => ({ + id: doc.id, + ...doc.data(), + })), + ...loadedMsgs, + ]; + }); + + if (querySnapshot.empty) { + setIsLastMsgRecieved(true); + } + } + }); + } + + return () => { + setLoadMoreMsgs(false); + unsubscribed = true; + }; + }, [loadMoreMsgs]); + + return ( + <> +
    +
    + navigate("/")} /> +
    + + {isLoading ? ( +
    + +
    + ) : ( +
    +
      + {messages.map((message) => ( +
    • + {message.displayName} goToUserProfile(message.uid)} + /> +
      + +
      goToUserProfile(message.uid)} + > + {user?.uid === message?.uid + ? "You" + : message.displayName} +
      + +
      + {getTime(message?.createdAt?.seconds)} +
      + + {user.uid === message.uid && ( + + { + setOpenOptions(true); + handleOpenOptions(message.id); + }} + /> + {openOptions && openOptions === message.id && ( + setOpenOptions(false)} + > +
      + handleDeletMsg(message.id)} + > + + Delete + + handleEditMsg(message.id)} + > + + Edit + +
      +
      + )} +
      + )} +
      +
      +

      {message.text}

      + {message.edited && ( +
      + Edited +
      + )} + {message.reaction && ( +
        + {getReaction(message.reaction)} +
      + )} +
      +
    • + ))} +
    +
    + )} +
    +
    + {showEmojis && ( + setShowEmojis(false)}> +
    + +
    +
    + )} + + + {isEditing && ( + + )} + + + + ); +}; + +export default ChatBox; diff --git a/src/components/EditProfile/index.css b/src/components/EditProfile/index.css new file mode 100644 index 000000000..ff6439bbe --- /dev/null +++ b/src/components/EditProfile/index.css @@ -0,0 +1,207 @@ +.edit-profile-container { + z-index: 990; + position: absolute; + top: 150px; + left: 50%; + width: 50%; + transform: translate(-50%, 0%); + padding: 30px; + background: var(--btn-color); + border-radius: 22px; +} + +.edit-profile-sub-container { + position: relative; + display: flex; + justify-content: center; + flex-direction: column; + gap: 30px; + width: 98%; + margin: auto; +} + +.edit-profile-header { + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + margin: auto; +} + +.edit-profile-image { + position: relative; + left: 50%; + transform: translateX(-50%); + height: 160px; + width: 160px; + display: flex; + flex-direction: column; + cursor: pointer; +} + +.edit-profile-image img { + height: 100%; + width: 100%; + object-fit: cover; +} + +.edit-profile-image-icon { + position: absolute; + left: 98%; + transform: translate(-98%); + color: rgba(8, 17, 123, 0.69); + background-color: rgb(255, 255, 255, 0.7); + border-radius: 50%; + padding: 10px; + cursor: pointer; +} + +.cancel-editing-icon { + position: absolute; + top: -30px; + right: -20px; + transform: scale(1.4); + cursor: pointer; +} + +.edit-user-details { + display: flex; + justify-content: space-between; + flex-wrap: wrap; + flex-direction: row; +} + +.user-field { + width: 30%; +} + +.edit-profile-label { + font-weight: 600; + font-size: 17px; + color: var(--text-light-black); + padding: 22px 0 8px; +} + +.edit-profile-input { + margin-top: 0; + width: 95% !important; + background-color: transparent; + border: 0; + box-shadow: none; + border-bottom: 1px solid rgba(104, 85, 224, 0.5); + padding-bottom: 5px; + border-radius: 0; +} + +.name-input, +.username-input, +.country-input { + width: 85% !important; +} + +.delete_dp_btn { + display: flex; + justify-content: center; + align-items: center; + margin-top: 10px; + padding: 5px; + cursor: pointer; + border-radius: 8px; + border: none; + background-color: transparent; + color: red; + font-weight: 600; + transition: 0.2s ease-in-out; +} + +.delete_dp_btn:hover { + box-shadow: var(--post-box-shadow); + background-color: rgb(223, 219, 219); +} + +.delete_dp_btn:active { + background-color: rgb(194, 190, 190); +} + +.edit-profile-img { + width: 120px; + aspect-ratio: 1; + border-radius: 50%; +} + +.edit-profile-bio { + padding: 10px; + font-size: 16px; + height: 100px; + border-bottom: 1px solid rgba(104, 85, 224, 1); + border-top: 0; + /* border-radius: 4px; */ +} + +.edit-profile-save-btn { + width: 100%; + background-color: transparent; + color: rgba(8, 17, 123, 0.69); + font-size: 20px; + font-weight: 600; + border: none; + cursor: pointer; +} + +.edit-profile-save-btn:hover { + color: rgba(8, 17, 123, 0.9); +} + +.edit-profile-save-btn:active { + background: linear-gradient(blue, blue); +} + +.error-border { + border: 2px solid red; +} + +@media only screen and (max-width: 900px) { + .edit-profile-sub-container { + gap: 20px; + } + .edit-profile-image { + height: 140px; + width: 140px; + } + .edit-user-details { + flex-direction: column; + } + .edit-profile-label { + padding: 0; + padding-top: 18px; + } + .name-input, + .username-input, + .country-input, + .user-field { + width: 98% !important; + } + + .edit-user-details label { + padding-bottom: 15px; + } + .edit-profile-container { + width: 60%; + left: 50%; + top: 120px; + } +} +@media only screen and (max-width: 600px) { + .edit-profile-container { + width: 75%; + left: 50%; + } + .edit-profile-image { + height: 120px; + width: 120px; + } +} +.edit-profile-container .errorMsg { + color: red; + font-size: small; +} diff --git a/src/components/EditProfile/index.jsx b/src/components/EditProfile/index.jsx new file mode 100644 index 000000000..152accec8 --- /dev/null +++ b/src/components/EditProfile/index.jsx @@ -0,0 +1,345 @@ +import "./index.css"; + +import { auth, db, storage } from "../../lib/firebase"; +import { playErrorSound, playSuccessSound } from "../../js/sounds"; +import { useRef, useState } from "react"; + +import BackIcon from "@mui/icons-material/ArrowBackIosNew"; +import { ClickAwayListener } from "@mui/material"; +import DeleteIcon from "@mui/icons-material/Delete"; +import EditIcon from "@mui/icons-material/Edit"; +import blankImg from "../../assets/blank-profile.webp"; +import deleteImg from "../../js/deleteImg"; +import { setUserSessionData } from "../../js/userData"; +import { useNavigate } from "react-router-dom"; +import { useSnackbar } from "notistack"; + +const EditProfile = ({ userData, username, setIsEditing, setUserData }) => { + const [editedData, setEditedData] = useState({ + name: userData.name, + newUsername: username, + bio: userData.bio, + country: userData.country, + avatar: userData.avatar, + uid: userData.uid, + }); + + const user = auth?.currentUser; + + const [image, setImage] = useState(null); + const [isUploading, setIsUploading] = useState(false); + const [usernameAvailable, setUsernameAvailable] = useState(true); + const [error, setError] = useState({}); + + const { enqueueSnackbar } = useSnackbar(); + const usernameRef = useRef(""); + const { name, newUsername, bio, country, uid, avatar } = editedData; + const navigate = useNavigate(); + + function debounce(func, timeout = 500) { + let timer; + return (...args) => { + clearTimeout(timer); + timer = setTimeout(() => { + func.apply(this, args); + }, timeout); + }; + } + + const checkUsername = () => { + const name = usernameRef.current; + const regex = /^[a-z][a-z0-9_]{4,20}$/; + if (!regex.test(name)) { + setUsernameAvailable(false); + } else { + const debouncedFunction = debounce(findUsernameInDB); + debouncedFunction(); + } + }; + + const findUsernameInDB = async () => { + const newName = usernameRef.current; // Assuming `usernameRef.current` contains the document ID + const usersRef = db.collection("users"); + const querySnapshot = await usersRef.where("username", "==", newName).get(); + if (querySnapshot.empty) { + setUsernameAvailable(true); + } else { + setUsernameAvailable(false); + } + }; + + function handleChange(e) { + setEditedData((prevFormData) => { + return { + ...prevFormData, + [e.target.name]: e.target.value, + }; + }); + } + const handleImgChange = (e) => { + if (e.target.files[0]) { + setImage(e.target.files[0]); + setEditedData((prevData) => ({ + ...prevData, + avatar: URL.createObjectURL(e.target.files[0]), + })); + } + }; + + function handleImgDelete() { + setImage(""); + setEditedData((prevData) => ({ + ...prevData, + avatar: "", + })); + } + + async function updateUser(url) { + try { + const batch = db.batch(); + + // Update profile data in authentication (auth) + await auth.currentUser.updateProfile({ + displayName: name, + photoURL: url, + }); + + // Update profile data in users collection + const userRef = db.collection("users").doc(uid); + const userData = { + photoURL: url, + name: name, + username: newUsername, + bio: bio, + country: country, + }; + setUserSessionData(userData); + batch.update(userRef, userData); + + // Update profile data in all posts + const postsRef = db.collection("posts").where("uid", "==", uid); + const postsSnapshot = await postsRef.get(); + postsSnapshot.forEach((post) => { + const postRef = post.ref; + batch.update(postRef, { + avatar: url, + displayName: name, + username: newUsername, + }); + }); + + // Commit the batch + await batch.commit(); + } catch (error) { + console.error("Error updating profile:", error); + setIsUploading(false); + throw error; + } + } + function validInputs() { + if (editedData.name === "") { + setError("**Name is Required!"); + } else if (editedData.newUsername === "") { + setError("**User name is Required!"); + } else { + setError(""); + return true; + } + } + const handleProfileUpdate = () => { + if (!validInputs()) { + return; + } + const oldImg = user.photoURL; + if (image && typeof image === "object") { + const uploadTask = storage.ref(`images/${image?.name}`).put(image); + uploadTask.on( + "state_changed", + () => {}, + (error) => { + playErrorSound(); + enqueueSnackbar(error.message, { + variant: "error", + }); + }, + () => { + storage + .ref("images") + .child(image?.name) + .getDownloadURL() + .then(async (url) => { + oldImg && (await deleteImg(oldImg)); + await updateUser(url); + }) + .then(() => { + setUserData(editedData); + playSuccessSound(); + enqueueSnackbar("Upload Successfull", { + variant: "success", + }); + }) + .finally(() => { + setIsEditing(false); + setIsUploading(false); + }); + }, + ); + } else if (image?.length === 0) { + async function removeImg() { + oldImg && (await deleteImg(oldImg)); + await updateUser(image) + .then(() => { + setUserData(editedData); + playSuccessSound(); + enqueueSnackbar("Upload Successfull", { + variant: "success", + }); + }) + .finally(() => { + setIsEditing(false); + setIsUploading(false); + }); + } + removeImg(); + } else { + async function upload() { + await updateUser(oldImg) + .then(() => { + setUserData(editedData); + navigate(`/user/${newUsername}`); + playSuccessSound(); + enqueueSnackbar("Upload Successfull", { + variant: "success", + }); + }) + .finally(() => { + setIsEditing(false); + setIsUploading(false); + }); + } + upload(); + } + }; + + return ( + setIsEditing(false)}> +
    +
    +
    + setIsEditing(false)} + style={{ display: "flex", marginTop: "6px", cursor: "pointer" }} + /> +

    Edit Profile

    +
    + +
    +
    +
    + + + 0 ? avatar : blankImg} + alt={name} + className="edit-profile-img" + /> + {user?.photoURL?.length > 0 && ( + + )} +
    +
    + {/* name */} +
    + +
    + {/* username */} +
    + +
    + {/* country */} +
    + +
    +
    + {/* bio */} + +
    +
    +
    + ); +}; + +export default EditProfile; diff --git a/src/components/FriendsComponent/Locked/index.css b/src/components/FriendsComponent/Locked/index.css new file mode 100644 index 000000000..d3c755502 --- /dev/null +++ b/src/components/FriendsComponent/Locked/index.css @@ -0,0 +1,12 @@ +.lock_profile_container { + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; +} + +.profile_lock_img { + width: 100%; + max-width: 270px; + filter: drop-shadow(2px 2px 5px var(--color)); +} diff --git a/src/components/FriendsComponent/Locked/index.jsx b/src/components/FriendsComponent/Locked/index.jsx new file mode 100644 index 000000000..7b2aae7e5 --- /dev/null +++ b/src/components/FriendsComponent/Locked/index.jsx @@ -0,0 +1,22 @@ +import "./index.css"; + +import { Link } from "react-router-dom"; +import lockImg from "../../../assets/lock.png"; + +const LockedFriendPage = ({ name }) => { + return ( +
    + User Profile Locked +

    + Add {name} as friend to unlock their + friend list! +

    +
    + ); +}; + +export default LockedFriendPage; diff --git a/src/components/FriendsComponent/index.css b/src/components/FriendsComponent/index.css new file mode 100644 index 000000000..0683c4e19 --- /dev/null +++ b/src/components/FriendsComponent/index.css @@ -0,0 +1,72 @@ +.friends_page_main_container { + display: flex; + justify-content: center; + align-items: center; + min-height: calc(100vh - 85px); + margin: 10px; +} + +.friends_page_sub_container { + padding: 15px; + border-radius: 10px; + max-width: 700px; + width: 100%; + border: 2px solid var(--profile-color); + box-shadow: var(--post-box-shadow); +} + +.friend_page_header { + text-align: center; + font-size: 30px; + font-weight: 700; + padding: 20px; + color: var(--text-dim); +} + +.friend_page_friend_list_container { + padding: 0; +} + +.friend_page_friend_list_item { + list-style: none; + display: flex; + align-items: center; + gap: 10px; + padding: 8px; + border-bottom: 1px solid #eee; +} + +.friend_page_friend_avatar { + width: 50px; + height: 50px; + border-radius: 50%; + border: 1px solid #eee; +} + +.friend_page_friend_name { + font-weight: 600; + color: var(--text-secondary); + cursor: pointer; +} + +.friend_page_friend_name:hover { + text-decoration: underline; +} + +.friend_page_friend_bio { + color: var(--profile-color); + cursor: default; +} + +@media only screen and (max-width: 840px) { + .friends_page_main_container { + padding-top: 20px; + } +} + +@media only screen and (max-width: 450px) { + .friend_page_header { + font-size: 23px; + padding: 15px; + } +} diff --git a/src/components/FriendsComponent/index.jsx b/src/components/FriendsComponent/index.jsx new file mode 100644 index 000000000..f672ce388 --- /dev/null +++ b/src/components/FriendsComponent/index.jsx @@ -0,0 +1,121 @@ +import "./index.css"; + +import { auth, db } from "../../lib/firebase"; +import { useEffect, useState } from "react"; +import { useNavigate, useParams } from "react-router-dom"; + +import LockedFriendPage from "./Locked"; +import blankImg from "../../assets/blank-profile.webp"; +import { useSnackbar } from "notistack"; + +const FriendsComponent = () => { + const { username } = useParams(); + const [friendsArr, setFriendsArr] = useState([]); + const [name, setName] = useState("user"); + const [isFriend, setIsFriend] = useState(true); + const currentUserUid = auth?.currentUser?.uid; + + const navigate = useNavigate(); + const { enqueueSnackbar } = useSnackbar(); + + const getFriendData = async (friendUid) => { + try { + const docRef = db.collection("users").doc(friendUid); + const snapshot = await docRef.get(); + return snapshot.exists ? snapshot.data() : null; + } catch (error) { + console.error("Error fetching doc: ", error); + return null; + } + }; + + async function checkCurrentUser() { + const docRef = db.collection("users").doc(currentUserUid); + const docSnap = await docRef.get(); + const data = docSnap.data(); + + return data.username === username; + } + + useEffect(() => { + async function getFriendsArr() { + let docRef; + if (checkCurrentUser) { + docRef = db + .collection("users") + .where("username", "==", username) + .limit(1); + } else { + docRef = db + .collection("users") + .where("username", "==", username) + .where("Friends", "array-contains", currentUserUid) + .limit(1); + } + const snapshot = await docRef.get().catch((err) => { + enqueueSnackbar(`Error getting friends: ${err}`, { + variant: "error", + }); + }); + if (snapshot.empty) { + setIsFriend(false); + } else { + const userData = snapshot.docs[0].data(); + const fetchedFriends = []; + setName(userData.displayName); + for (const friendUid of userData.Friends) { + const friendData = await getFriendData(friendUid); + if (friendData) { + fetchedFriends.push({ + ...friendData, + }); + } + } + + setFriendsArr(fetchedFriends); + } + } + currentUserUid && getFriendsArr(); + }, [currentUserUid]); + + return ( +
    + {isFriend ? ( +
    +

    {name}'s Friend List

    +
      + {friendsArr.length > 0 && + friendsArr.map((friend) => { + const { displayName, photoURL, bio, username } = friend; + return ( +
    • + {"user navigate(`/user/${username}`)} + /> +
      +

      navigate(`/user/${username}`)} + > + {displayName ? displayName : "user"} +

      + + {bio ? bio : "..."} + +
      +
    • + ); + })} +
    +
    + ) : ( + + )} +
    + ); +}; + +export default FriendsComponent; diff --git a/src/components/Guest/GuestSignInBtn/index.css b/src/components/Guest/GuestSignInBtn/index.css new file mode 100644 index 000000000..759d4ef5b --- /dev/null +++ b/src/components/Guest/GuestSignInBtn/index.css @@ -0,0 +1,10 @@ +.guest-sign-in-button { + background-color: lightgray; + color: #000 !important; +} + +.guest-sign-in-button:hover { + color: grey; + background-color: white; + border: 1px solid grey; +} diff --git a/src/components/Guest/GuestSignInBtn/index.jsx b/src/components/Guest/GuestSignInBtn/index.jsx new file mode 100644 index 000000000..8214df3ef --- /dev/null +++ b/src/components/Guest/GuestSignInBtn/index.jsx @@ -0,0 +1,44 @@ +import "./index.css"; + +import { playErrorSound, playSuccessSound } from "../../../js/sounds"; + +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { auth } from "../../../lib/firebase"; +import { faRedditAlien } from "@fortawesome/free-brands-svg-icons"; +import { useNavigate } from "react-router-dom"; +import { useSnackbar } from "notistack"; + +const GuestSignInBtn = ({ show }) => { + const navigate = useNavigate(); + const { enqueueSnackbar } = useSnackbar(); + + function guestSignIn() { + auth + .signInAnonymously() + .then(() => { + playSuccessSound(); + enqueueSnackbar("Guest Sign In successfull", { + variant: "success", + }); + navigate("/"); + }) + .catch((error) => { + playErrorSound(); + enqueueSnackbar(error.message, { + variant: "error", + }); + }); + } + + return ( + + ); +}; + +export default GuestSignInBtn; diff --git a/src/components/Guest/GuestSignUpBtn/index.css b/src/components/Guest/GuestSignUpBtn/index.css new file mode 100644 index 000000000..d975ba59e --- /dev/null +++ b/src/components/Guest/GuestSignUpBtn/index.css @@ -0,0 +1,23 @@ +.guest-sign-up-button-container { + position: fixed; + z-index: 9999; + top: 90px; + right: 30px; +} + +.guest-sign-up-button { + padding: 10px 30px; + font-size: 20px; + border-radius: 1rem; + cursor: pointer; + font-weight: 600; + background: var(--btn-color); + border: none; + transition: 0.3s ease-in-out; + color: #ffffff; +} + +.guest-sign-up-button:hover { + transform: scale(1.1); + color: var(----btn-color-hover); +} diff --git a/src/components/Guest/GuestSignUpBtn/index.jsx b/src/components/Guest/GuestSignUpBtn/index.jsx new file mode 100644 index 000000000..45e9b7eb1 --- /dev/null +++ b/src/components/Guest/GuestSignUpBtn/index.jsx @@ -0,0 +1,19 @@ +import "./index.css"; + +import { useNavigate } from "react-router-dom"; + +const GuestSignUpBtn = () => { + const navigate = useNavigate(); + return ( +
    + +
    + ); +}; + +export default GuestSignUpBtn; diff --git a/src/components/ImgUpload.jsx b/src/components/ImgUpload.jsx deleted file mode 100644 index e37bc8696..000000000 --- a/src/components/ImgUpload.jsx +++ /dev/null @@ -1,202 +0,0 @@ -import React, { useRef, useState } from "react"; -import { db, handleMultiUpload, storage } from "../lib/firebase"; -import firebase from "firebase/compat/app"; -import AnimatedButton from "./AnimatedButton"; -import { LinearProgress, TextField } from "@mui/material"; -import { useSnackbar } from "notistack"; -import "./imgPreview.css"; - -function ImgUpload(props) { - const [image, setImage] = useState(null); - const [caption, setCaption] = useState(""); - const [progress, setProgress] = useState(0); - const [uploadingPost, setUploadingPost] = useState(false); - const imgInput = useRef(null); - const [imagePreviews, setImagePreviews] = useState([]); - const [isValidimage, setisValidimage] = useState(true); - - const handleChange = (e) => { - if (!e.target.files[0]) { - enqueueSnackbar("Select min 1 image!", { - variant: "error", - }); - setisValidimage(false); - return false; - } - for (let i = 0; i < e.target.files.length; i++) { - const img = e.target.files[i]; - if (!img.name.match(/\.(jpg|jpeg|png|gif)$/)) { - enqueueSnackbar("Select a valid image!", { - variant: "error", - }); - setisValidimage(false); - return false; - } - } - setisValidimage(true); - - const images = []; - - if (e.target.files?.length) { - setImage(Array.from(e.target.files)); - setImagePreviews(image); - } - for (let i = 0; i < e.target.files.length; i++) { - images.push(URL.createObjectURL(e.target.files[i])); - } - - setImagePreviews(images); - }; - - const { enqueueSnackbar } = useSnackbar(); - - const savePost = (imageUrl = "") => { - db.collection("posts") - .add({ - timestamp: firebase.firestore.FieldValue.serverTimestamp(), - caption: caption, - imageUrl, - username: props.user.displayName, - avatar: props.user.photoURL, - likecount: [], - }) - .then(() => { - enqueueSnackbar("Post was uploaded successfully!", { - variant: "success", - }); - setProgress(0); - setCaption(""); - setImage(null); - if (imgInput.current) { - imgInput.current.value = null; - } - - if (props.onUploadComplete) { - props.onUploadComplete(); - } - }) - .catch((err) => { - enqueueSnackbar(err.message, { - variant: "error", - }); - - if (props.onUploadError) { - props.onUploadError(err); - } - }) - .finally(() => { - setUploadingPost(false); - }); - }; - - const handleUpload = () => { - if ((!image && !caption) || !isValidimage) { - enqueueSnackbar("Upload valid image and caption!", { - variant: "error", - }); - return false; - } - - setUploadingPost(true); - if (props.onUploadStart) { - props.onUploadStart(); - } - - if (!image) { - savePost(); - return; - } - - handleMultiUpload(image, { - generateThumbnails: true, - onUploadProgress(percentage) { - setProgress(percentage); - - if (props.onUploadProgress) { - props.onUploadProgress(percentage); - } - }, - }) - .then((urls) => { - savePost(JSON.stringify(urls)); - }) - .catch((err) => { - enqueueSnackbar(err.message, { - variant: "error", - }); - setUploadingPost(false); - - if (props.onUploadError) { - props.onUploadError(err); - } - }) - .finally(() => { - if (props.onUploadEnd) { - props.onUploadEnd(); - } - }); - }; - - return ( -
    - {uploadingPost && image && ( - - )} - {(!uploadingPost || (uploadingPost && image)) && ( - <> -
    -
    - - -
    -
    - - )} - {imagePreviews && ( -
    - {imagePreviews.map((img, i) => { - return ( -
    - {`image-${i}`} -
    - ); - })} -
    - )} - setCaption(e.target.value)} - value={caption} - placeholder="Enter a Caption.." - label="Caption" - multiline - rows={4} - disabled={uploadingPost} - sx={{ - backgroundColor: "white", - borderRadius: "8px", - }} - /> - - Upload - -
    - ); -} - -export default ImgUpload; diff --git a/src/components/ImgUpload/Camera/index.css b/src/components/ImgUpload/Camera/index.css new file mode 100644 index 000000000..545818381 --- /dev/null +++ b/src/components/ImgUpload/Camera/index.css @@ -0,0 +1,59 @@ +.buttonControls { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + margin-top: 10px; +} + +.cameraBtn { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + font-size: large; + margin-bottom: 10px; +} + +.cameraBtn button { + margin: 6px; + padding: 10px; + background: linear-gradient(40deg, #5f85db 30%, #fff 100%); + border: none; + box-shadow: 0 4px 7px rgba(0, 0, 0, 0.4); + border-radius: 10px; + cursor: pointer; + font-size: large; +} + +.cameraBtn button:hover { + background: linear-gradient(-40deg, #fff, #5f85db); +} + +.takePic { + margin-top: 15px; + font-size: 25px; + font-family: monospace; + color: black; +} + +.outputContainer { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + margin-top: 20px; +} + +.outputContainer button { + margin: 6px; + padding: 10px; + background: #5f85db; + background: linear-gradient(40deg, #5f85db 30%, rgb(219, 247, 252) 100%); + /* border: 1px solid var(--color); */ + border: none; + box-shadow: 0 4px 7px rgba(0, 0, 0, 0.4); + border-radius: 10px; + cursor: pointer; + font-size: large; +} diff --git a/src/components/ImgUpload/Camera/index.jsx b/src/components/ImgUpload/Camera/index.jsx new file mode 100644 index 000000000..a00f590eb --- /dev/null +++ b/src/components/ImgUpload/Camera/index.jsx @@ -0,0 +1,59 @@ +import "./index.css"; + +import React, { useCallback, useRef, useState } from "react"; + +import Webcam from "react-webcam"; + +const videoConstraints = { + width: 300, + facingMode: "enviroment", +}; + +export default function Camera() { + const webcamRef = useRef(null); + const [url, setUrl] = useState(null); + + const capturePhoto = useCallback(async () => { + const imgeSrc = webcamRef.current.getScreenshot(); + setUrl(imgeSrc); + }, [webcamRef]); + + const onUserMedia = (e) => {}; + + const handleSave = () => { + const downloadLink = document.createElement("a"); + downloadLink.href = url; + downloadLink.download = "captured_image.png"; + downloadLink.click(); + }; + + return ( + <> +
    +

    Take Picture

    +
    + +
    +
    + + +
    + + {url && ( +
    + Screenshot + +
    + )} +
    + + ); +} diff --git a/src/components/ImgUpload/index.css b/src/components/ImgUpload/index.css new file mode 100644 index 000000000..35f7ed48c --- /dev/null +++ b/src/components/ImgUpload/index.css @@ -0,0 +1,366 @@ +.post-header { + display: flex; + flex-wrap: wrap; + padding: 15px 10px; + align-items: center; +} + +.caption-container { + width: 95%; + margin: auto; + display: flex; + flex-direction: column; + margin-bottom: 10px; +} + +.share__button { + background: var(--btn-color); + width: 100%; + color: white; + padding: 6px; + font-size: 1rem; + cursor: pointer; + border-radius: 25px; + border: none; + margin: 5px; +} + +.share__button:hover { + background: var(--btn-color-hover); +} + +.back_button { + display: inline-flex; + justify-content: center; + align-items: center; + border-radius: 1rem; + font-size: 1rem; + background: var(--btn-color); + color: white; + padding: 5px 10px; + cursor: pointer; +} + +.back_button:hover { + background: var(--btn-color-hover); +} + +.post__username { + font-size: 14px; + font-weight: 600; +} + +.post__header { + display: flex; + align-items: center; + padding-inline: 8px; + flex-wrap: wrap; +} + +.post__upload__avatar { + margin-right: 10px; + border-radius: 50%; + width: 30px !important; + height: 30px !important; + object-fit: contain; +} + +.upload-picture:hover { + opacity: 0.8; +} + +.openpopup:hover { + opacity: 0.8; +} + +.file { + opacity: 0; + width: 0.1px; + height: 0.1px; + position: absolute; +} + +.file-input { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + font-weight: 500; + font-size: 1rem; + width: 90%; + margin: auto; + min-height: 60px; + padding-bottom: 15px; + gap: 2rem; +} + +.file-input label { + position: relative; + border-radius: 20px; + background: linear-gradient(40deg, #5f85db, #daf1f7); + box-shadow: 0 4px 7px rgba(0, 0, 0, 0.4); + display: flex; + align-items: center; + justify-content: center; + color: #ffffff; + font-weight: 500; + cursor: pointer; + transition: transform 0.2s ease-out; +} + +.slider__View { + display: flex; + flex-direction: row; + text-align: center; + justify-content: center; + align-items: center; + margin: auto; +} + +.sliders_button { + position: absolute; + display: flex; + justify-content: space-between; + width: 98%; +} + +.slider_circle { + color: var(--btn-hover); + font-size: 1.2rem; +} + +.slider_chevron { + color: var(--btn-hover); + font-size: 1.2rem; +} + +.button { + cursor: pointer; + border-radius: 4px; + font-weight: 600; + width: 100%; + padding: 10px 0; + box-shadow: 0 0 20px rgba(104, 85, 224, 0.2); + transition: 0.4s; +} + +.button:hover { + color: white; + box-shadow: 0 0 20px rgba(104, 85, 224, 0.6); + background-color: rgba(104, 85, 224, 1); +} + +input { + width: 230px; + cursor: pointer; + border-radius: 4px; + font-weight: 600; + padding: 10px; + margin-top: 10px; + box-shadow: 0 0 20px rgba(104, 85, 224, 0.2); + border: 1px solid rgba(104, 85, 224, 1); + transition: 0.4s; +} + +.popupMain { + display: flex; + flex-direction: column-reverse; + align-items: center; + justify-content: center; + /* min-height: 20vh; */ + box-sizing: border-box; +} + +.openpopup { + top: 46%; + left: 41.5%; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); + /* Semi-transparent black overlay */ + z-index: 999; +} + +.popupMain button { + border-radius: 20px; + background: var(--btn-color); + box-shadow: 0 4px 7px rgba(0, 0, 0, 0.4); + display: flex; + align-items: center; + justify-content: center; + color: #ffffff; + font-weight: 500; + cursor: pointer; + transition: transform 0.2s ease-out; + border: none; +} + +.close-btn { + margin: 6px; + padding: 10px; + background: #5f85db; + background: var(--btn-color); + border: none; + box-shadow: 0 4px 7px rgba(0, 0, 0, 0.4); + border-radius: 10px; + cursor: pointer; + font-size: large; +} + +.shareBtnContainer { + width: 100%; + display: flex; + gap: 6rem; + padding: 6px 0; +} + +.disable_post_btn { + background: grey; + cursor: not-allowed; +} + +.disable_post_btn:hover { + background: grey; + cursor: not-allowed; +} + +@media only screen and (min-width: 800px) { + .dialogStyle { + width: 60vw; + margin: auto; + } + + .app__posts { + display: flex; + flex-wrap: wrap; + gap: 2rem; + justify-content: center; + } + + .file-input { + gap: 5rem; + } + + .slider__View { + width: 45%; + } + + .small_post_view { + display: none; + width: 100%; + } +} + +@media only screen and (max-width: 800px) { + .dialogStyle { + width: 60vw !important; + } + + .file-input { + margin: auto; + display: flex; + justify-content: center; + align-items: center; + flex-direction: column !important; + gap: 1.2rem; + } + + .next_button { + display: block; + background: linear-gradient(40deg, #5f85db, #daf1f7); + width: 100%; + color: white; + padding: 0.6rem; + font-size: 0.8rem; + position: absolute; + bottom: 0px; + left: 0px; + margin-bottom: -20px; + cursor: pointer; + } + + .slider__View { + margin: auto; + margin-bottom: 20px; + } + + .shareBtnContainer { + gap: 2rem; + } + .popupMain button, + .file-input label, + .share__button { + font-size: 0.8rem; + } +} + +@media only screen and (max-width: 500px) { + .dialogStyle { + width: 70vw !important; + } + + .createNewPost { + font-size: 1rem; + font-weight: 500; + color: var(--color); + margin-top: 10px; + margin-bottom: 8px; + } + + .popupMain button { + font-size: 0.8rem; + padding: 0.4rem 1rem; + } + + .file-input label { + font-size: 0.8rem; + padding: 0.4rem 0.6rem; + } + .file-input, + .shareBtnContainer { + gap: 0.8rem; + } +} + +@media only screen and (min-width: 500px) { + .createNewPost { + font-size: 1rem; + font-weight: 500; + color: var(--color); + margin-top: 10px; + margin-bottom: 8px; + } + + .crossIcon { + position: absolute; + right: 1rem; + top: 1rem; + cursor: pointer; + } + + .popupMain button { + font-size: 1.1rem; + padding: 0.5rem 1rem; + } + + .file-input label { + font-size: 1.1rem; + padding: 0.5rem 0.9rem; + } +} + +@media only screen and (max-width: 500px) { + .crossIcon { + position: absolute; + right: 0.6rem; + top: 0.7rem; + cursor: pointer; + } +} + +@media screen and (max-width: 500px) { + .close-btn { + margin-right: 50px; + font-size: 1.2em !important; + } +} diff --git a/src/components/ImgUpload/index.jsx b/src/components/ImgUpload/index.jsx new file mode 100644 index 000000000..6ef3e5160 --- /dev/null +++ b/src/components/ImgUpload/index.jsx @@ -0,0 +1,387 @@ +import "./index.css"; + +import { Avatar, LinearProgress, TextField } from "@mui/material"; +import { FaChevronCircleLeft, FaChevronCircleRight } from "react-icons/fa"; +import React, { useEffect, useRef, useState } from "react"; +import { auth, db, handleMultiUpload } from "../../lib/firebase"; +import getUserSessionData, { setUserSessionData } from "../../js/userData"; +import { playErrorSound, playSuccessSound } from "../../js/sounds"; + +import Camera from "./Camera"; +import { HuePicker } from "react-color"; +import { LazyLoadImage } from "react-lazy-load-image-component"; +import { Link } from "react-router-dom"; +import Popup from "../../reusableComponents/Popup"; +import firebase from "firebase/compat/app"; +import { useSnackbar } from "notistack"; + +export default function ImgUpload(props) { + const [current, setCurrent] = useState(0); + const [image, setImage] = useState(null); + const [caption, setCaption] = useState(""); + const [progress, setProgress] = useState(0); + const [uploadingPost, setUploadingPost] = useState(false); + const [imagePreviews, setImagePreviews] = useState([]); + const [isValidimage, setisValidimage] = useState(true); + const [buttonPopup, setButtonPopup] = useState(false); + const [isStoryUploaded, setIsStoryUploaded] = useState(false); + const [username, setUsername] = useState(""); + const [background, setBackground] = useState("#fff"); + + const displayName = auth?.currentUser?.displayName; + const avatar = auth?.currentUser?.photoURL; + + const imgInput = useRef(null); + const { enqueueSnackbar } = useSnackbar(); + + const prevStep = () => { + setCurrent(current === 0 ? imagePreviews.length - 1 : current - 1); + }; + const nextStep = () => { + setCurrent(current === imagePreviews.length - 1 ? 0 : current + 1); + }; + + const handleBackgroundChange = (color) => { + setBackground(color.hex); + }; + + useEffect(() => { + async function getUsername() { + const data = await getUserSessionData(); + setUsername(data.username); + if (data.hasOwnProperty("storyTimestamp")) { + setIsStoryUploaded(true); + } + } + if (auth?.currentUser.isAnonymous) { + setUsername("guest"); + } else { + getUsername(); + } + }, []); + + const handleChange = (e) => { + let filesSelected = e.target.files; + if (filesSelected.length < 1) { + enqueueSnackbar("Select min 1 image!", { + variant: "error", + }); + setisValidimage(false); + e.stopPropagation(); + return; + } + for (let img of filesSelected) { + if (!img.name.match(/\.(jpg|jpeg|png|gif|svg)$/)) { + enqueueSnackbar("Select a valid image!", { + variant: "error", + }); + setisValidimage(false); + return false; + } + } + setisValidimage(true); + + setImage(Array.from(filesSelected)); + + const images = []; + for (let file of filesSelected) { + images.push(URL.createObjectURL(file)); + } + + setImagePreviews(images); + setBackground("#fff"); + }; + + const savePost = async (type, imageUrl = "") => { + const bg = background === "#fff" ? null : background; + try { + if (type === "Post") { + const postRef = await db.collection("posts").add({ + timestamp: firebase.firestore.FieldValue.serverTimestamp(), + caption: caption, + imageUrl, + username: username, + background: bg, + displayName: props.user.displayName, + avatar: props.user.photoURL, + likecount: [], + uid: auth?.currentUser?.uid, + }); + + const postId = postRef.id; // Store post ID in a separate variable + + await db + .collection("users") + .doc(props.user.uid) + .update({ + posts: firebase.firestore.FieldValue.arrayUnion(postId), // Use postId instead of postRef.id + }); + setUserSessionData({ + posts: firebase.firestore.FieldValue.arrayUnion(postId), + }); + } else { + await db.collection("story").add({ + caption: caption, + imageUrl, + background: bg, + username: username, + uid: auth?.currentUser?.uid, + }); + + const querySnapshot = await db + .collection("users") + .where("username", "==", username) + .get(); + if (!querySnapshot.empty) { + const userRef = querySnapshot.docs[0].ref; + // Update the 'storyTimestamp' field + await userRef.update({ + storyTimestamp: firebase.firestore.FieldValue.serverTimestamp(), + }); + setUserSessionData({ + storyTimestamp: firebase.firestore.FieldValue.serverTimestamp(), + }); + } + } + + playSuccessSound(); + enqueueSnackbar(`${type} uploaded successfully!`, { + variant: "success", + }); + + setProgress(0); + setCaption(""); + setImage(null); + if (imgInput.current) { + imgInput.current.value = null; + } + + if (props.onUploadComplete) { + props.onUploadComplete(); + } + } catch (err) { + playErrorSound(); + enqueueSnackbar(err.message, { + variant: "error", + }); + + if (props.onUploadError) { + props.onUploadError(err); + } + } finally { + setUploadingPost(false); + } + }; + + function handleUpload(type) { + if ((!image && !caption) || !isValidimage) { + enqueueSnackbar("Upload valid image and caption!", { + variant: "error", + }); + return false; + } + + setUploadingPost(true); + if (props.onUploadStart) { + props.onUploadStart(); + } + + if (!image) { + savePost(type); + return; + } + + handleMultiUpload(image, { + generateThumbnails: true, + onUploadProgress(percentage) { + setProgress(percentage); + + if (props.onUploadProgress) { + props.onUploadProgress(percentage); + } + }, + }) + .then((urls) => { + savePost(type, JSON.stringify(urls)); + }) + .catch((err) => { + enqueueSnackbar(err.message, { + variant: "error", + }); + setUploadingPost(false); + + if (props.onUploadError) { + props.onUploadError(err); + } + }) + .finally(() => { + if (props.onUploadEnd) { + props.onUploadEnd(); + } + }); + } + + return ( + <> +
    + {uploadingPost && image && ( + + )} +
    +
    + {avatar && displayName && ( + <> + {" "} + + +

    {displayName}

    + + + )} +
    + {!image && ( +
    +
    + + +
    +
    + + + + +
    +
    + )} + {image && ( +
    + {imagePreviews.map((imageUrl, index) => ( +
    + + {imagePreviews.length > 1 ? ( +
    + + +
    + ) : ( + <> + )} +
    + ))} +
    + )} +
    +
    + setCaption(e.target.value)} + value={caption} + variant="filled" + label="Write a caption..." + multiline + rows={8} + disabled={uploadingPost} + inputProps={{ maxLength: 200 }} + sx={{ + width: "100%", + "& .MuiFormLabel-root.Mui-focused": { + fontWeight: "bold", + }, + "& .MuiFilledInput-root": { + background: background, + color: "var(--color)", + }, + }} + style={{ color: "var(--color) !important" }} + /> +
    + {!image && ( + + )} +
    +
    +
    +
    + + +
    +
    +
    + + ); +} diff --git a/src/components/LandingAnimation.jsx b/src/components/LandingAnimation.jsx deleted file mode 100644 index acbd8d1d7..000000000 --- a/src/components/LandingAnimation.jsx +++ /dev/null @@ -1,35 +0,0 @@ -import { useState, useEffect } from "react"; - -export default function LandingAnimation() { - const [showAnimation, setShowAnimation] = useState(true); - - useEffect(() => { - const timer = setTimeout(() => { - setShowAnimation(false); - }, 2500); - return () => clearTimeout(timer); - }, []); - - return ( -
    - {showAnimation && ( -
    - -
    - )} -
    - ); -} diff --git a/src/components/Loader.css b/src/components/Loader.css deleted file mode 100644 index 7257285af..000000000 --- a/src/components/Loader.css +++ /dev/null @@ -1,93 +0,0 @@ -/** - * Credits: https://codepen.io/feirer/pen/zovgae - * Patrick Feirer - * -*/ - -body { - background-color: #fbfbfb; -} - -.loader { - box-sizing: border-box; - display: flex; - position: relative; - justify-content: center; - perspective-origin: 60px 60px; - transform-origin: 60px 60px; - border: 0px solid #000000; - flex: 0 0 auto; - flex-flow: column nowrap; -} - -.loader:after, -.loader:before { - height: 100%; - width: 100%; - border-radius: 50%; - border-style: solid; - border-width: 2px; - box-sizing: border-box; - content: ""; - left: 0; - position: absolute; - top: 0; -} - -.loader:after { - -webkit-animation: rotate 1s infinite ease; - animation: rotate 1s infinite ease; - border-color: #3897f0 transparent transparent; - -webkit-transform-origin: 50%; - transform-origin: 50%; -} - -.loader:before { - border-color: #c7c7c7; -} - -.loader a { - display: block; - font-size: 14px; - margin: -60px 0; - padding: 60px 9px; - position: relative; - text-align: center; - vertical-align: middle; - z-index: 1; - color: #c7c7c7; - text-decoration: none; - font: normal normal 600 normal 14px / 14px proxima-nova, "Helvetica Neue", - Arial, Helvetica, sans-serif; -} - -@-webkit-keyframes rotate { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - to { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } -} - -@keyframes rotate { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - to { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } -} - -.note { - color: #c7c7c7; - text-decoration: none; - font: normal normal 600 normal 12px / 12px proxima-nova, "Helvetica Neue", - Arial, Helvetica, sans-serif; - text-align: center; - width: 100%; -} diff --git a/src/components/Loader.jsx b/src/components/Loader.jsx deleted file mode 100644 index d468d4c16..000000000 --- a/src/components/Loader.jsx +++ /dev/null @@ -1,36 +0,0 @@ -import "./Loader.css"; - -/** - * - * @param {{ - * width: number, - * height:number - * }} props - */ -export default function Loader(props) { - const { width, height } = Object.assign( - { - width: 30, - height: 30, - }, - props - ); - - return ( -
    -
    -
    - ); -} diff --git a/src/components/Navbar/index.css b/src/components/Navbar/index.css new file mode 100644 index 000000000..a89c163a5 --- /dev/null +++ b/src/components/Navbar/index.css @@ -0,0 +1,221 @@ +@import url("https://fonts.googleapis.com/css2?family=Dancing+Script:wght@700&display=swap"); + +.app__header { + position: fixed; + width: 100%; + top: 0; + z-index: 999; + padding-top: 10px; + padding-bottom: 10px; + object-fit: contain; + display: flex; + align-items: center; + background-color: var(--dark-post-bg); + justify-content: space-between; +} + +.navSpace { + display: flex; + align-items: center; + width: 100%; +} + +.container { + display: flex; + flex-direction: row; + justify-content: center; +} + +.nav-menu { + background-color: #fff; + color: black; + padding: 2px; + width: fit-content; + position: absolute; + border-radius: 4px; + margin-top: 10rem; + margin-right: 4rem; + vertical-align: top; + border: 1px solid black; +} + +.nav-menu-item { + display: flex; + padding: 0.5rem; + cursor: pointer; +} + +.chatIcon { + transform: scale(1.2); + margin-top: 11px; +} + +#chat-icon { + display: inline-block; + margin-left: 5px; +} + +/* search file css */ + +.searched_user_name { + font-size: 16px; + color: var(--text-secondary); + cursor: pointer; +} + +.searched_user_username { + font-size: 13px; + color: var(--text-secondary); + cursor: pointer; +} + +.search_bar_main_container { + margin-left: auto; + width: 100%; + position: relative; +} + +.hidden_search_bar_container { + transition: 0.4s ease-in-out; + width: 34px; + border-radius: 40px; + display: flex; + justify-content: center; + align-items: center; + background: var(--profile-container); + margin-right: 13px; + margin-left: auto; +} + +.show_search_bar { + width: 100%; + max-width: 600px; + border: 1px solid var(--btn-color); + box-shadow: var(--post-box-shadow); +} + +@media screen and (min-width: 1221px) { + .show_search_bar { + width: 40%; + } +} + +.search_bar_input { + border: none; + width: 100%; + border-radius: 40px; + margin: 0; + padding-inline: 25px; + font-size: 20px; + color: var(--text-secondary); + background: var(--profile-container); + box-shadow: none; +} + +.searched_user_container { + position: absolute; + border-radius: 20px; + background-color: var(--profile-container); + width: 100%; + max-width: 600px; + right: 10px; + margin-top: 5px; + box-shadow: var(--post-box-shadow); +} + +.searched_user_sub_container { + padding: 0; + width: 100%; + max-height: 70vh; + overflow: scroll; +} + +.searched_user_avatar { + width: 40px; + aspect-ratio: 1; + border-radius: 50%; + border: 1px solid grey; +} + +.searched_user_li { + display: flex; + gap: 10px; + width: 100%; + padding: 10px; + align-items: center; + cursor: pointer; + border-radius: 22px; + margin-right: 0; + transition: 0.3s ease-in-out; + box-sizing: border-box; +} + +.search_icon { + margin-left: auto; + transform: scale(1.3); + border-radius: 50%; + padding: 6px; + background: var(--profile-container); +} + +.search_close_icon { + margin-left: auto; +} + +.searchbar { + color: var(--text-secondary); + display: flex; + justify-content: space-evenly; + align-items: center; + width: 100%; + gap: 20px; +} + +.searchbar:hover { + transform: scale(1); +} + +.nav_img_logo { + width: 80px; + display: inline-block; +} + +@media only screen and (max-width: 900px) { + .searched_user_container { + right: 0; + } +} + +@media only screen and (max-width: 600px) { + .search_bar_input { + padding-inline: 10px; + font-size: 15px; + } + + .searched_user_container { + width: 84vw; + right: 50%; + transform: translateX(40%); + } + + .search_icon { + transform: scale(1.1); + } + .searched_user_name { + font-size: 14px; + } + + .searched_user_username { + font-size: 10px; + } +} + +@media only screen and (max-width: 450px) { + .nav_img_logo { + width: 60px; + } + + #chat-icon { + margin-right: 0; + } +} diff --git a/src/components/Navbar/index.jsx b/src/components/Navbar/index.jsx new file mode 100644 index 000000000..c072a868b --- /dev/null +++ b/src/components/Navbar/index.jsx @@ -0,0 +1,197 @@ +import "./index.css"; + +import { Darkmode, Logo } from "../../reusableComponents"; +import React, { useEffect, useState } from "react"; +import { auth, db } from "../../lib/firebase"; + +import { AiOutlineInsertRowAbove } from "react-icons/ai"; +import ChatIcon from "@mui/icons-material/Chat"; +import { ClickAwayListener } from "@mui/material"; +import CloseIcon from "@mui/icons-material/Close"; +import SearchIcon from "@mui/icons-material/Search"; +import appLogo from "../../assets/app-logo.webp"; +import blankImg from "../../assets/blank-profile.webp"; +import { useNavigate } from "react-router-dom"; + +const PAGESIZE = 7; + +function Navbar({ onClick, user, setUser }) { + const navigate = useNavigate(); + const [open, setOpen] = useState(false); + const [searchQuery, setSearchQuery] = useState(""); + const [expandSearchBar, setExpandSearchBar] = useState(false); + const [searchResults, setSearchResults] = useState([]); + const [windowWidth, setWindowWidth] = useState(700); + const [debouncedQuery, setDebouncedQuery] = useState(""); + + const handleSearchModal = () => { + setOpen(!open); + }; + + function getWindowDimensions() { + const { innerWidth: width } = window; + return width; + } + + useEffect(() => { + function handleResize() { + setWindowWidth(getWindowDimensions()); + } + + window.addEventListener("resize", handleResize); + return () => window.removeEventListener("resize", handleResize); + }, []); + + useEffect(() => { + const timerId = setTimeout(() => { + setDebouncedQuery(searchQuery); + }, 1000); + + return () => { + clearTimeout(timerId); + }; + }, [searchQuery]); + + useEffect(() => { + const fetchUsers = async () => { + const value = searchQuery; + if (value.length > 0) { + const usersCollection = await db + .collection("users") + .orderBy("name", "asc") + .startAt(value.toUpperCase()) + .endAt(value.toLowerCase()) + .limit(PAGESIZE) + .get(); + + const fetchedUsers = usersCollection.docs.map((doc) => ({ + id: doc.id, + user: doc.data(), + })); + setSearchResults(fetchedUsers); + } else { + setSearchResults([]); + } + }; + // Call fetchUsers function whenever debouncedQuery changes after the 1-second delay + fetchUsers(); + }, [debouncedQuery]); + + const handleSearch = (e) => { + setSearchQuery(e.target.value); + }; + + useEffect(() => { + const unsubscribe = auth.onAuthStateChanged((authUser) => { + if (authUser) { + setUser(authUser); + } else { + setUser(null); + navigate("/login"); + } + }); + return () => { + unsubscribe(); + }; + }, [user]); + + return ( + !location.href.includes("login") && + !location.href.includes("signup") && ( +
    + {windowWidth > 600 ? ( + + + + ) : ( + navigate("/")}> + dummygram + + )} +
    +
    +
    + setExpandSearchBar(false)}> +
    + {expandSearchBar ? ( + <> + + setExpandSearchBar(false)} + className="icon search_icon" + /> + + ) : ( + setExpandSearchBar(true)} + /> + )} +
    +
    +
    + {expandSearchBar && searchResults.length > 0 && ( +
    +
      + {searchResults.map(({ id, user }) => { + return ( +
    • navigate(`/user/${user.username}`)} + > + {user.name} + +
      {user.name}
      +

      + @{user.username} +

      +
      +
    • + ); + })} +
    +
    + )} +
    + +
    +
    + +
    +
    navigate("/chat")} + > + +
    +
    + +
    +
    + ) + ); +} + +export default Navbar; diff --git a/src/components/NotFound.jsx b/src/components/NotFound.jsx deleted file mode 100644 index fca1105b3..000000000 --- a/src/components/NotFound.jsx +++ /dev/null @@ -1,36 +0,0 @@ -import React from "react"; -import { Box, Button, Container, Typography } from "@mui/material"; -import Grid from "@mui/material/Grid"; - -export default function Error() { - return ( - - - - - 404 - - The page you’re looking for doesn’t exist. - - - - - - - - - - ); -} diff --git a/src/components/Notification/index.css b/src/components/Notification/index.css new file mode 100644 index 000000000..223bc4341 --- /dev/null +++ b/src/components/Notification/index.css @@ -0,0 +1,118 @@ +.loader-container { + width: 100%; + height: 100vh; + display: flex; + justify-content: center; + align-items: center; +} + +.notification-container { + min-height: 100vh; +} + +.notification-heading { + color: var(--color); + font-size: 50px; + margin-bottom: 50px; +} + +.notification-count { + position: relative; + border: 1px solid gray; + padding: 10px 20px; + border-radius: 50%; + font-size: 25px; + top: -10px; + background-color: var(--color); + color: var(--bg-color); + font-family: cursive; +} + +.notif-message-container { + width: 80%; + padding: 15px 20px; + text-align: left; + font-size: 20px; + color: var(--color); + border-radius: 10px; + margin-bottom: 20px; + box-shadow: + 0 10px 15px -3px rgb(0 0 0 / 0.1), + 0 4px 6px -4px rgb(0 0 0 / 0.1); + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 10px; +} + +.notif-message { + display: inline-block; + margin-left: 30px; +} + +.notif-type { + color: rgb(3, 3, 110); +} + +.friend-request-sender-name { + font-weight: 600; + cursor: pointer; + color: var(--text-primary); + text-decoration: none; +} + +.friend-request-sender-name:hover { + text-decoration: underline; +} + +.notif-btn { + margin-right: 10px; + padding: 8px 25px; + font-size: 18px; + border-radius: 5px; + color: white; + font-weight: 600; + border: none; + cursor: pointer; + transition: 0.3s all ease-in-out; +} + +.accept-btn { + background-color: rgb(9, 153, 9); +} +.accept-btn:hover { + background-color: rgb(3, 117, 3); +} + +.decline-btn { + background-color: rgb(230, 26, 26); +} +.decline-btn:hover { + background-color: rgb(167, 13, 13); +} + +@media screen and (max-width: 800px) { + .notification-heading { + font-size: 30px; + } + + .notification-count { + padding: 5px 10px; + border-radius: 50%; + font-size: 15px; + top: -5px; + } + + .notif-message-container { + font-size: 15px; + } + + .notif-message { + margin-right: 0px; + } + + .notif-btn { + padding: 5px 20px; + font-size: 13px; + } +} diff --git a/src/components/Notification/index.jsx b/src/components/Notification/index.jsx new file mode 100644 index 000000000..f13e94c88 --- /dev/null +++ b/src/components/Notification/index.jsx @@ -0,0 +1,208 @@ +import "./index.css"; + +import React, { useEffect, useState } from "react"; +import { auth, db } from "../../lib/firebase"; + +import { Box } from "@mui/material"; +import { Link } from "react-router-dom"; +import { Loader } from "../../reusableComponents"; +import { SideBar } from "../index"; +import firebase from "firebase/compat/app"; +import { useSnackbar } from "notistack"; + +function Notifications() { + const [notifications, setNotifications] = useState([]); + const [loading, setLoading] = useState(true); + + const { enqueueSnackbar } = useSnackbar(); + + const getNotifUserData = async (senderUid) => { + try { + const docRef = db.collection("users").doc(senderUid); + const snapshot = await docRef.get(); + return snapshot.exists ? snapshot.data() : null; + } catch (error) { + console.error("Error fetching doc: ", error); + return null; + } + }; + + useEffect(() => { + const unsubscribe = db + .collection("users") + .doc(auth?.currentUser?.uid) + .collection("notifications") + .orderBy("timestamp", "desc") + .onSnapshot(async (snapshot) => { + const fetchedNotifications = []; + + for (const doc of snapshot.docs) { + const { sender, recipient, message } = doc.data(); + const userData = await getNotifUserData(sender); + if (userData) { + const { photoURL, username, name } = userData; + fetchedNotifications.push({ + id: doc.id, + sender: sender, + recipient: recipient, + photoURL: photoURL, + username: username, + name: name, + message: message, + }); + } + } + + setNotifications(fetchedNotifications); + setLoading(false); + }); + + return () => unsubscribe(); + }, []); + + async function handleRemoveNotifiction( + currentUserUid, + targetUserUid, + accept, + ) { + const batch = db.batch(); + const friendRequestRef = db + .collection("users") + .doc(currentUserUid) + .collection("friendRequests") + .doc(targetUserUid); + + const notificationRef = db + .collection("users") + .doc(currentUserUid) + .collection("notifications") + .doc(targetUserUid); + + // Queue the delete operations in the batch + batch.delete(friendRequestRef); + batch.delete(notificationRef); + + // Commit the batch + batch + .commit() + .then(() => { + enqueueSnackbar(`Friend Request ${accept ? "Accepted" : "Declined"}!`, { + variant: "success", + }); + }) + .catch((error) => { + enqueueSnackbar(`Error Occurred: ${error}`, { + variant: "error", + }); + }); + } + + async function handleAcceptRequest(currentUserUid, targetUserUid) { + const batch = db.batch(); + + const currentUserRef = db.collection("users").doc(currentUserUid); + const targetUserRef = db.collection("users").doc(targetUserUid); + + batch.update(currentUserRef, { + Friends: firebase.firestore.FieldValue.arrayUnion(targetUserUid), + }); + + batch.update(targetUserRef, { + Friends: firebase.firestore.FieldValue.arrayUnion(currentUserUid), + }); + + await handleRemoveNotifiction(currentUserUid, targetUserUid, true); + await batch.commit().catch((error) => { + enqueueSnackbar(`Error Occurred: ${error}`, { + variant: "error", + }); + }); + } + + return ( + <> + + {loading ? ( +
    + +
    + ) : ( +
    + +
    + {notifications.length ? ( + <> +

    + Notifications{" "} + + {notifications.length} + +

    + {notifications.map((notification) => { + const { id, message, username, name, photoURL } = + notification; + return ( +
    + {name} + +
    + {message} from{" "} + + {name ? name : ""}. + +
    + + +
    +
    +
    + ); + })} + + ) : ( +

    No notifications

    + )} +
    +
    +
    + )} + + ); +} + +export default Notifications; diff --git a/src/components/Post.jsx b/src/components/Post.jsx deleted file mode 100644 index 98bb6d2c5..000000000 --- a/src/components/Post.jsx +++ /dev/null @@ -1,524 +0,0 @@ -import { useEffect, useState } from "react"; -import FavoriteBorderIcon from "@mui/icons-material/FavoriteBorder"; -import FavoriteOutlinedIcon from "@mui/icons-material/FavoriteOutlined"; -import CommentIcon from "@mui/icons-material/Comment"; -import { red } from "@mui/material/colors"; -import SentimentSatisfiedAltOutlinedIcon from "@mui/icons-material/SentimentSatisfiedAltOutlined"; -import MoreHorizOutlinedIcon from "@mui/icons-material/MoreHorizOutlined"; -import DeleteTwoToneIcon from "@mui/icons-material/DeleteTwoTone"; -import Scroll from "../reusableComponents/Scroll"; -import { - Avatar, - Grid, - Menu, - MenuItem, - IconButton, - Button, - Dialog, - DialogTitle, - DialogActions, - DialogContent, - DialogContentText, - useMediaQuery, - Box, - Paper, - styled, - SvgIcon, -} from "@mui/material"; -import { useTheme } from "@mui/material/styles"; -import { db } from "../lib/firebase"; -import firebase from "firebase/compat/app"; -import "react-lazy-load-image-component/src/effects/blur.css"; -import EmojiPicker from "emoji-picker-react"; -import { doc, updateDoc } from "firebase/firestore"; -import DialogBox from "../reusableComponents/DialogBox"; -import ImageSlider from "../reusableComponents/ImageSlider"; -import ReadMore from "./ReadMore"; -import ReplyRoundedIcon from "@mui/icons-material/ReplyRounded"; - -const ITEM_HEIGHT = 48; - -function Post(prop) { - const { postId, user, post, shareModal, setLink, setPostText } = prop; - const { username, caption, imageUrl, avatar, likecount } = post; - const [comments, setComments] = useState([]); - const [comment, setComment] = useState(""); - const [likesNo, setLikesNo] = useState(likecount ? likecount.length : 0); - const [anchorEl, setAnchorEl] = useState(null); - const [showEmojis, setShowEmojis] = useState(false); - const [Open, setOpen] = useState(false); - const [isCommentOpen, setisCommentOpen] = useState(false); - const theme = useTheme(); - const fullScreen = useMediaQuery(theme.breakpoints.down("md")); - const open = Boolean(anchorEl); - const docRef = doc(db, "posts", postId); - - useEffect(() => { - let unsubscribe; - - if (postId) { - unsubscribe = db - .collection("posts") - .doc(postId) - .collection("comments") - .orderBy("timestamp", "desc") - .onSnapshot((snapshot) => { - setComments( - snapshot.docs.map((doc) => ({ - id: doc.id, - content: doc.data(), - })) - ); - }); - } - - return () => { - if (unsubscribe) { - unsubscribe(); - } - }; - }, [postId]); - - const Item = styled(Paper)(({ theme }) => ({ - backgroundColor: theme.palette.mode === "dark" ? "#1A2027" : "#fff", - ...theme.typography.body2, - padding: theme.spacing(1), - textAlign: "center", - color: theme.palette.text.secondary, - })); - - const postComment = (event) => { - event.preventDefault(); - db.collection("posts").doc(postId).collection("comments").add({ - text: comment, - username: user.displayName, - timestamp: firebase.firestore.FieldValue.serverTimestamp(), - }); - setComment(""); - }; - - const deleteComment = async (event, commentRef) => { - event.preventDefault(); - await db - .collection("posts") - .doc(postId) - .collection("comments") - .doc(commentRef.id) - .delete(); - }; - - const onEmojiClick = (emojiObject, event) => { - setComment((prevInput) => prevInput + emojiObject.emoji); - setShowEmojis(false); - }; - - /** - * @type {{ - * imageUrl: null|string, - * imageWidth: number, - * imageHeight: number, - * thumbnail: null | string - * }[]} - * - */ - let postImages; - - try { - postImages = JSON.parse(imageUrl); - } catch { - postImages = imageUrl.split(",").map((url) => ({ - imageUrl: url, - imageWidth: 0, - imageHeight: 0, - thumbnail: null, - })); - } - - // const computeGridSize = (imagesLength, imageIndex) => { - // if (imageIndex === imagesLength - 1 && (imageIndex + 1) % 2 !== 0) { - // return 12; - // } - // return 6; - // }; - - const postHasImages = postImages.some((image) => Boolean(image.imageUrl)); - const tempLikeCount = likecount ? [...likecount] : []; - const buttonStyle = { - ":hover": { - color: "#ff4d4d", - fontSize: "29px", - }, - }; - - async function likesHandler() { - if (user && likecount !== undefined) { - let ind = tempLikeCount.indexOf(user.uid); - - if (ind !== -1) { - tempLikeCount.splice(ind, 1); - setLikesNo((currLikesNo) => currLikesNo - 1); - } else { - tempLikeCount.push(user.uid); - setLikesNo((currLikesNo) => currLikesNo + 1); - } - - // console.log(tempLikeCount); - const data = { - likecount: tempLikeCount, - }; - await updateDoc(docRef, data) - // .then((docRef) => { - // console.log("like added"); - // }) - .catch((error) => { - // console.log(error); - }); - } - } - - async function deletePost() { - await db.collection("posts").doc(postId).delete(); - } - - const handleClickOpen = () => { - setOpen(true); - setAnchorEl(null); - }; - - // const handleCommentOpen = () => { - // setisCommentOpen(true); - // }; - - const handleClose = () => { - setOpen(false); - }; - - const handleCommentClose = () => { - setisCommentOpen(false); - }; - - return ( -
    -
    - -

    {username}

    -
    - setAnchorEl(event.currentTarget)} - sx={{ - color: "var(--color)", - }} - > - - - {user && username == user.displayName && ( - setAnchorEl(null)} - PaperProps={{ - style: { - maxHeight: ITEM_HEIGHT * 4.5, - width: "20ch", - }, - }} - > - Delete - - )} - - - {"Delete Post?"} - - - - Are you sure you want to delete this post? - - - - - - - -
    -
    - -
    - {postHasImages ? ( - - ) : ( -
    {caption}
    - )} -
    -
    - {user ? ( - tempLikeCount.indexOf(user.uid) != -1 ? ( - - ) : ( - - ) - ) : ( - - )} -
    - - - {likecount !== 0 ? `${likesNo} Likes` : " "}{" "} - {/* Likes */} - - - { - setLink(`https://narayan954.github.io/dummygram/${postId}`); - setPostText(caption); - shareModal(true); - }} - sx={{ - color: "var(--color)", - marginX: "4px", - }} - > - - - - {/* comment button */} - {/*
    - -
    */} - {/* share button */} - {/*
    - -
    */} - {/* save button */} - {/*
    - -
    */} -
    - -
    - {caption && postHasImages && ( - <> - {username} - - - )} -
    - - {comments.length ? ( - <> - - - - - - - - {postHasImages ? ( - - ) : ( -
    {caption}
    - )} -
    -
    - - - -
    - {comments.map((userComment) => ( -

    - {userComment.content.username}{" "} - {userComment.content.text} - - deleteComment(event, userComment) - } - > - {user && - userComment.content.username === - user.displayName ? ( - - ) : ( - <> - )} - -


    -

    - ))} -
    -
    -
    -
    -
    -
    - - {user && ( -
    -
    - { - setShowEmojis((val) => !val); - }} - /> - {showEmojis && ( -
    - -
    - )} -
    - - setComment(e.target.value)} - style={{ - backgroundColor: "var(--bg-color)", - color: "var(--color)", - borderRadius: "22px", - marginTop: "4px", - }} - /> - -
    - )} -
    - - ) : ( - <> - )} - - {user && ( -
    -
    - { - setShowEmojis((val) => !val); - }} - /> - {showEmojis && ( -
    - -
    - )} -
    - setComment(e.target.value)} - style={{ - backgroundColor: "var(--bg-color)", - color: "var(--color)", - borderRadius: "22px", - margin: "4px 0px", - }} - /> - -
    - )} -
    -
    - ); -} - -export default Post; diff --git a/src/components/Post/CommentBox.jsx b/src/components/Post/CommentBox.jsx new file mode 100644 index 000000000..5f3e9c926 --- /dev/null +++ b/src/components/Post/CommentBox.jsx @@ -0,0 +1,86 @@ +import EmojiPicker from "emoji-picker-react"; +import { IconButton } from "@mui/material"; +import React from "react"; +import { Send } from "@mui/icons-material"; +import SentimentSatisfiedAltOutlinedIcon from "@mui/icons-material/SentimentSatisfiedAltOutlined"; +import { useNavigate } from "react-router-dom"; + +const CommentBox = ({ + user, + showEmojis, + setShowEmojis, + onEmojiClick, + comment, + setComment, + postComment, +}) => { + const { isAnonymous } = user; + const navigate = useNavigate(); + return ( +
    + {user && ( +
    +
    + { + setShowEmojis((val) => !val); + }} + /> + {showEmojis && ( +
    + +
    + )} +
    + + setComment(e.target.value)} + maxLength={300} + style={{ + // backgroundColor: "var(--bg-color)", + background: "transparent", + color: "var(--color)", + borderRadius: "11px", + marginTop: "4px", + }} + /> + + + isAnonymous ? navigate("/signup") : postComment(e) + } + style={{ + padding: 0, + paddingRight: "5px", + }} + > + + +
    + )} +
    + ); +}; + +export default CommentBox; diff --git a/src/components/Post/CommentDialogBox.jsx b/src/components/Post/CommentDialogBox.jsx new file mode 100644 index 000000000..441397321 --- /dev/null +++ b/src/components/Post/CommentDialogBox.jsx @@ -0,0 +1,158 @@ +import { + Box, + Button, + Dialog, + DialogActions, + DialogContent, + DialogContentText, + DialogTitle, + Divider, +} from "@mui/material"; +import React, { useEffect, useState } from "react"; +import { auth, db } from "../../lib/firebase"; +import { doc, getDoc } from "firebase/firestore"; + +import AccountCircleIcon from "@mui/icons-material/AccountCircle"; +import DeleteTwoToneIcon from "@mui/icons-material/DeleteTwoTone"; +import { Link } from "react-router-dom"; +import ReadMore from "../ReadMore"; +import { deleteComment } from "../../js/postFn"; +import { useSnackbar } from "notistack"; + +const CommentDialogBox = ({ postId, comments, user, fullScreen }) => { + const { enqueueSnackbar } = useSnackbar(); + + const { isAnonymous } = user; + const [username, setUsername] = useState(""); + const [openToDeleteComment, setOpenToDeleteComment] = useState(false); + const [selectedCommentId, setSelectedCommentId] = useState(null); + + useEffect(() => { + async function getUsername() { + const docRef = doc(db, "users", auth?.currentUser?.uid); + const docSnap = await getDoc(docRef); + if (docSnap.exists()) { + setUsername(docSnap.data().username); + } else { + setUsername("guest"); // Handle the case when the user document doesn't exist + } + } + if (isAnonymous) { + setUsername("guest"); + } else { + getUsername().catch((error) => { + console.error("Error fetching username:", error); // Handle any error that might occur during username fetching + }); + } + }, []); + + const handleDelete = (postId, commentid) => { + deleteComment(postId, commentid, enqueueSnackbar); + }; + + /****************************************** */ + const handleDeleteIconClick = (commentId) => { + setSelectedCommentId(commentId); + setOpenToDeleteComment(true); + }; + + // Function to clear the selected comment ID when the delete confirmation dialog is closed + const handleCloseDeleteDialog = () => { + setSelectedCommentId(null); + setOpenToDeleteComment(false); + }; + + return ( + + {comments.length ? ( + <> + {comments.map((userComment) => ( +
    +
    +
    + + {userComment.content.avatar ? ( + profile picture + ) : ( + + )}{" "} + + {userComment.content.displayName} + + +

    + + {userComment.content.text} + +

    +
    +
    + {user && userComment?.content?.username == username && ( + handleDeleteIconClick(userComment.id)} + /> + )} + { + setOpenToDeleteComment(false)} + aria-labelledby="responsive-dialog-title" + > + + Delete Comment? + + + + Are you sure you want to delete this Comment? + + + + + + + + } +
    +
    + +
    + ))} + + ) : ( + No Comments + )} +
    + ); +}; + +export default CommentDialogBox; diff --git a/src/components/Post/DialogBoxSkeleton.jsx b/src/components/Post/DialogBoxSkeleton.jsx new file mode 100644 index 000000000..0e39e828d --- /dev/null +++ b/src/components/Post/DialogBoxSkeleton.jsx @@ -0,0 +1,26 @@ +import Skeleton from "@mui/material/Skeleton"; + +const DialogBoxSkeleton = () => { + return ( +
    + + + + +
    + ); +}; + +export default DialogBoxSkeleton; + +function SkeletonStructure() { + return ( +
    + +
    + + +
    +
    + ); +} diff --git a/src/components/Post/ImgBox.jsx b/src/components/Post/ImgBox.jsx new file mode 100644 index 000000000..eca371442 --- /dev/null +++ b/src/components/Post/ImgBox.jsx @@ -0,0 +1,68 @@ +import Caption from "./../Caption.jsx"; +import { ImageSlider } from "../../reusableComponents"; +import React from "react"; +import { ReadMore } from "../index"; + +const ImgBox = ({ + postHasImages, + postImages, + likesHandler, + caption, + postId, + background, +}) => { + const defaultBg = `linear-gradient(130deg, #dee2ed, #dee2ed, #9aa9d1, #b6c8e3, #b6afd0, #d3c0d8)`; + return ( +
    + {postHasImages ? ( + + ) : ( +
    + {caption.length >= 300 ? ( + <> +

    + + {caption} + +

    + + ) : ( +

    + +

    + )} +
    + )} + +
    + {caption && postHasImages ? ( +

    = 100 ? "postCaption" : "postCaptiontext" + }`} + > + {caption} +

    + ) : ( +

    + )} +
    +
    + ); +}; + +export default ImgBox; diff --git a/src/components/Post/LikesDialogBox.jsx b/src/components/Post/LikesDialogBox.jsx new file mode 100644 index 000000000..3e27cc56b --- /dev/null +++ b/src/components/Post/LikesDialogBox.jsx @@ -0,0 +1,97 @@ +import "./index.css"; + +import { useEffect, useState } from "react"; + +import { Box } from "@mui/material"; +import DialogBoxSkeleton from "./DialogBoxSkeleton"; +import { Link } from "react-router-dom"; +import blankProfileImg from "../../assets/blank-profile.webp"; +import { db } from "../../lib/firebase"; +import { useSnackbar } from "notistack"; + +const trimBio = (bio, maxLength = 90) => { + return bio.length > maxLength ? bio.substr(0, maxLength) + " ..." : bio; +}; + +const renderUser = ({ uid, username, photoURL, name, bio }) => ( +
    + + {name} + +
    +
    + +

    {name}

    + +
    @{username}
    +
    +

    {bio ? trimBio(bio) : "..."}

    +
    +
    +); + +const LikesDialogBox = ({ likecountArr }) => { + const [userData, setUserData] = useState([]); + const [isLoading, setIsLoading] = useState(true); + const { enqueueSnackbar } = useSnackbar(); + + useEffect(() => { + const fetchData = async () => { + const fetchUserDocsByUID = async (uid) => { + try { + const docRef = db.collection("users").doc(uid); + const docSnapshot = await docRef.get(); + if (docSnapshot.exists) { + return docSnapshot.data(); + } else { + enqueueSnackbar("User not found", { + variant: "error", + }); + } + } catch (error) { + enqueueSnackbar(error, { + variant: "error", + }); + } + }; + + const userData = await Promise.all( + likecountArr?.map((uid) => fetchUserDocsByUID(uid)), + ); + setUserData(userData); + setIsLoading(false); + }; + + fetchData(); + }, []); + + return ( + <> + + {!isLoading ? ( +
    + {userData.map(renderUser)} +
    + ) : ( + + )} +
    + + ); +}; + +export default LikesDialogBox; diff --git a/src/components/Post/PostHeader.jsx b/src/components/Post/PostHeader.jsx new file mode 100644 index 000000000..d51d4af72 --- /dev/null +++ b/src/components/Post/PostHeader.jsx @@ -0,0 +1,266 @@ +import "./index.css"; + +import { + Avatar, + Button, + Dialog, + DialogActions, + DialogContent, + DialogContentText, + DialogTitle, + IconButton, + Menu, + MenuItem, +} from "@mui/material"; +import { doc, updateDoc } from "firebase/firestore"; +import { useEffect, useState } from "react"; +import { useLocation, useNavigate } from "react-router-dom"; + +import MoreHorizOutlinedIcon from "@mui/icons-material/MoreHorizOutlined"; +import ProfileDialogBox from "../ProfileDialogBox"; +import TextField from "@mui/material/TextField"; +import { db } from "../../lib/firebase"; +import { deletePost } from "../../js/postFn"; +import { saveAs } from "file-saver"; +import useCreatedAt from "../../hooks/useCreatedAt"; +import { useSnackbar } from "notistack"; + +const PostHeader = ({ postId, user, postData, postHasImages, timestamp }) => { + const time = useCreatedAt(timestamp); + const { fullScreen, isAnonymous } = user; // TODO: needs fixing + const { username, caption, imageUrl, displayName, avatar } = postData; + const [Open, setOpen] = useState(false); + const [anchorEl, setAnchorEl] = useState(false); + const [openEditCaption, setOpenEditCaption] = useState(false); + const [editCaption, setEditCaption] = useState(caption); + const [mouseOnProfileImg, setMouseOnProfileImg] = useState(false); + const [userData, setUserData] = useState({}); + + const { enqueueSnackbar } = useSnackbar(); + const open = Boolean(anchorEl); + const ITEM_HEIGHT = 48; + const navigate = useNavigate(); + const location = useLocation(); + + useEffect(() => { + async function getUserData() { + try { + const docRef = db + .collection("users") + .where("uid", "==", postData.uid) + .limit(1); + const snapshot = await docRef.get(); + + if (!snapshot.empty) { + const doc = snapshot.docs[0]; + const data = doc.data(); + setUserData({ + name: data.name, + username: data.username, + avatar: data.photoURL, + uid: data.uid, + posts: data.posts.length, + bio: data.bio ? data.bio : "Hey there! I am using Dummygram.", + followers: "", + following: "", + country: data.country ? data.country : "", + storyTimestamp: data.storyTimestamp, + }); + } else { + setUserExists(false); + } + } catch (error) { + enqueueSnackbar(`Error Occurred: ${error}`, { + variant: "error", + }); + } + } + getUserData(); + }, []); + + const handleClickOpen = () => { + setOpen(true); + setAnchorEl(null); + }; + + const handleClickOpenCaption = async () => { + setOpenEditCaption(true); + }; + + const handleClickClosedCaption = () => { + setEditCaption(caption); + setOpenEditCaption(false); + }; + + const handleDownload = () => { + const urlimg = JSON.parse(imageUrl)[0].imageUrl; + saveAs(urlimg, "image"); + }; + + const handleSubmitCaption = async () => { + const taskDocRef = doc(db, "posts", postId); + + try { + await updateDoc(taskDocRef, { + caption: editCaption, + }); + } catch (err) { + alert(err); + } + setOpenEditCaption(false); + }; + + const handleClose = () => { + setOpen(false); + }; + + function showProfileDialogBox() { + setMouseOnProfileImg(true); + } + + function hideProfileDialogBox() { + setTimeout(() => { + setMouseOnProfileImg(false); + }, 1200); + } + + return ( +
    + + navigate("/" + (isAnonymous ? "signup" : "user/" + username)) + } + onMouseEnter={showProfileDialogBox} + onMouseLeave={hideProfileDialogBox} + /> + +
    +

    { + navigate("/" + (isAnonymous ? "signup" : "posts/" + postId)); + }} + className="post__username" + > + {displayName} +

    +

    {time}

    +
    +
    + {!location.pathname.includes("/user") && ( + + isAnonymous + ? navigate("/signup") + : setAnchorEl(event.currentTarget) + } + sx={{ + color: "var(--color)", + }} + > + + + )} + + setAnchorEl(null)} + PaperProps={{ + style: { + maxHeight: ITEM_HEIGHT * 4, + width: "18ch", + }, + }} + > + {user && displayName === user.displayName && ( + Delete + )} + {user && displayName === user.displayName && ( + Edit + )} + {postHasImages && ( + Download + )} + navigate(`/user/${username}`)}> + Visit Profile + + + <> + + Change Caption + + setEditCaption(e.target.value)} + value={editCaption} + /> + + + + + + + + + + + {"Delete Post?"} + + + + Are you sure you want to delete this post? + + + + + + + +
    +
    + ); +}; + +export default PostHeader; diff --git a/src/components/Post/PostNav.jsx b/src/components/Post/PostNav.jsx new file mode 100644 index 000000000..183c2fee1 --- /dev/null +++ b/src/components/Post/PostNav.jsx @@ -0,0 +1,132 @@ +import { + ChatBubbleOutlineRounded, + FavoriteBorderOutlined, + FavoriteOutlined, + ShareOutlined, +} from "@mui/icons-material"; +import { IconButton, Typography } from "@mui/material"; +import React, { useState } from "react"; + +import BookmarkBorderIcon from "@mui/icons-material/BookmarkBorder"; +import BookmarksIcon from "@mui/icons-material/Bookmarks"; +import Flexbetween from "../../reusableComponents/Flexbetween"; +import { ShareModal } from "../../reusableComponents"; +import { savePost } from "../../js/postFn"; +import { useNavigate } from "react-router-dom"; + +const PostNav = ({ + caption, + postId, + fullScreen, + likesHandler, + user, + tempLikeCount, + setisCommentOpen, +}) => { + const [openShareModal, setOpenShareModal] = useState(false); + const [favoritePosts, setFavoritePosts] = useState( + JSON.parse(localStorage.getItem("posts")) || [], + ); + + const navigate = useNavigate(); + const { isAnonymous } = user; + + const handleOnClick = async () => { + if (isAnonymous) { + navigate("/signup"); + } else { + try { + const data = await savePost(postId); + setFavoritePosts(data); + } catch (error) { + console.error("Error saving post:", error); + } + } + }; + + return ( + <> + + (isAnonymous ? navigate("/signup") : likesHandler())} + > + + {tempLikeCount.indexOf(user?.uid) != -1 ? ( + + ) : ( + + )} + + + Like + + + + { + isAnonymous ? navigate("/signup") : setisCommentOpen(true); + }} + > + + + + + Comment + + + + { + if (isAnonymous) { + navigate("/signup"); + } else { + setOpenShareModal((prev) => !prev); + } + }} + > + + + + + Share + + + + + + {favoritePosts.indexOf(postId) !== -1 ? ( + + ) : ( + + )} + + + Save + + + + + {openShareModal && ( + + )} + + ); +}; + +export default PostNav; diff --git a/src/components/Post/index.css b/src/components/Post/index.css new file mode 100644 index 000000000..0cef4ee2b --- /dev/null +++ b/src/components/Post/index.css @@ -0,0 +1,415 @@ +.p-0 { + padding: 0%; +} + +.post, +.postColumn { + max-width: 400px; + margin-block: 20px; + border: 2px solid #90b8f8; + border-radius: 5px; + word-wrap: break-word; + transition: all; + transition-duration: 200ms; + transition-timing-function: cubic-bezier(0.4, 0, 1, 1); +} + +.post { + padding: 5px; +} + +.post:hover { + transform: scale(1.01); +} + +.avatar { + border: 2px solid rgb(221, 221, 90); + cursor: pointer; + transition: all 0.2s; +} + +.avatar:hover { + box-shadow: rgba(100, 100, 111, 0.2) 0px 7px 17px 0px; + border: 2px solid black; + scale: 1.1; +} + +.post__username, +.post__time { + color: var(--text-primary); +} + +.post__username { + font-size: 18px; +} + +.post__time { + font-size: 12px; + color: var(--profile-color); +} + +.postColumn:hover { + transform: scale(1.01); +} + +.social__icon__last { + padding: 10px; + padding-right: 0; + margin-left: auto !important; +} + +.post__background { + height: 350px; + background: linear-gradient( + 130deg, + #dee2ed, + #dee2ed, + #9aa9d1, + #b6c8e3, + #b6afd0, + #d3c0d8 + ); + + background-size: cover; + color: black; + display: flex; + justify-content: center; + align-items: center; + font-weight: 600; + position: relative; +} + +.post-nav-item { + color: var(--color); +} + +.post_caption { + text-align: center; + padding: 8px; + font-weight: 400; + font-size: 15px; + color: var(--text-black-only); + white-space: pre-line; + overflow: hidden; +} + +.post__btn { + position: absolute; + right: 15px; + background: transparent; + border: none; + cursor: pointer; + font-weight: bold; +} + +.post__less_btn { + background: transparent; + border: none; + cursor: pointer; + font-weight: bold; +} + +.post__text { + padding-top: 2px; + padding-bottom: 2px; + /* height: 1.5rem; */ + font-weight: normal; + font-size: 15px; + text-align: left; + white-space: pre-line; + overflow: hidden; + height: 27px; + line-height: 1.2em; +} + +.post__commentBox { + display: flex; + align-items: center; + flex-direction: row; + margin-bottom: 10px; + margin-inline: auto; + flex-wrap: wrap; +} + +.modal__commentBox { + width: 100%; + display: flex; + justify-content: space-around; + align-items: center; + gap: 1rem; +} + +.commentCard { + padding: 0.4rem 1rem; + margin-top: 0.3rem; + margin-bottom: 0.3rem; + display: flex; + justify-content: space-between; + background: lightgray; + border-radius: 10px; +} + +.commentCard .comment span { + color: var(--text-black-only) !important; +} + +.comment-box-title-style { + display: inline-block; + width: 10px; + aspect-ratio: 1; + margin-left: 5px; + margin-bottom: 0; + border-radius: 50%; + background-color: var(--clr); +} + +.comment-doer { + font-size: 1rem; + font-weight: 600; + display: flex; + align-items: center; + gap: 5px; + margin-bottom: 5px; + text-decoration: none; + color: black; +} + +.comment-doer-name { + color: rgb(42, 42, 135); + cursor: pointer; +} + +.comment-doer-name:hover { + text-decoration: underline; +} + +.comment { + color: black; + font-weight: 400; +} + +.comment-delete-icon { + color: red; + cursor: pointer; + border-radius: 50%; + padding: 5px; + transition: 0.3s ease-in-out; +} + +.comment-delete-icon:hover { + background-color: rgb(187, 187, 187); +} + +.comment-box { + width: 100%; +} + +.send-comment-btn { + font-weight: bold; + color: #5f85db; + border-radius: 50%; + padding: 5px; +} + +.comment-input { + background-color: var(--dark-post-bg) !important; + color: var(--color); + border-radius: 22px; + margin-top: 4px; + width: 100%; + box-shadow: var(--post-box-shadow); +} + +.emoji-picker-btn { + color: var(--emoji-btn); +} + +.social__icon { + padding: 10px; + width: 24px; + height: 28px; +} + +.emoji__icon:hover { + opacity: 60%; + cursor: pointer; + padding-top: auto; +} + +.post__input { + border: none; + flex: 1; + padding: 10px; + padding-bottom: 7px; + padding-top: 7px; + font-size: 16px; + box-shadow: none; +} + +.post__button { + flex: 0; + border: none; + margin-right: 2px; + color: #0a66c2; + margin-top: 3px; + cursor: pointer; + background: transparent; +} + +.post__comments { + padding: 0 15px; + display: flex; + flex-direction: column; + align-items: flex-start; + font-size: 15px; + text-align: left; + word-break: break-word; +} + +.social__icons__wrapper { + display: flex; + align-items: center; +} + +.post-profile-picture { + height: 30px; + width: 30px; + border-radius: 100%; +} + +.dialog_box_skeleton { + display: flex; + align-items: center; + gap: 15px; + width: 100%; + margin-bottom: 20px; +} + +.dialog_box_text_skeleton { + width: 80%; +} + +.dialog_box_text_skeleton > * { + width: 100%; +} + +.likedby_list_container { + margin: 0; + display: flex; + flex-direction: column; + padding: 3px; + gap: 8px; +} + +.likedby_list_item { + display: flex; + gap: 10px; + padding: 10px; + border-radius: 8px; + color: black; + background: lightgray; +} + +.like_user_img { + width: 50px !important; + aspect-ratio: 1; + border-radius: 50%; + border: 1px solid; + transition: 0.3s ease-in-out; +} + +.like_user_img:hover { + transform: scale(1.1); +} + +.like_user_data { + display: flex; + align-items: center; + gap: 8px; +} + +.like_user_name { + cursor: pointer; + font-weight: 600; + color: rgb(42, 42, 135); + text-decoration: none; +} + +.like_user_name:hover { + text-decoration: underline; +} + +.like_user_username { + font-weight: 500; + color: var(--text-black-only); +} + +@media only screen and (max-width: 800px) { + .post__commentBox input { + width: 200px; + } + + .modal__commentBox { + gap: 0; + } + + .modal__commentBox input { + width: 100px; + } +} + +@media only screen and (max-width: 460px) { + .post { + max-width: 320px; + padding: 5px; + margin-top: 25px; + } + + .epr-emoji-category { + width: 300px; + } + + .postColumn { + max-width: 320px; + padding: 5px; + margin-top: 25px; + } + + .post__text, + .postCaption, + .postCaptiontext { + height: 50px !important; + } + + .like_user_data { + flex-direction: column; + gap: 0; + align-items: flex-start; + } + + .like_user_name { + font-size: 16px; + } + + .like_user_username { + margin-top: -5px; + } + + .like_user_bio { + font-size: 14px; + } +} + +.postCaption { + color: var(--color); + padding-inline: 8px; + height: 27px; +} + +.postCaptiontext { + color: var(--color); + padding-inline: 8px; + height: 27px; + display: flex; + align-items: flex-end; +} diff --git a/src/components/Post/index.jsx b/src/components/Post/index.jsx new file mode 100644 index 000000000..0e586509d --- /dev/null +++ b/src/components/Post/index.jsx @@ -0,0 +1,301 @@ +import "react-lazy-load-image-component/src/effects/blur.css"; +import "./index.css"; + +import { + DialogBox, + ErrorBoundary, + Flexbetween, +} from "../../reusableComponents"; +import { + DialogTitle, + Divider, + Paper, + Typography, + styled, + useMediaQuery, +} from "@mui/material"; +import { auth, db } from "../../lib/firebase"; +import { doc, updateDoc } from "firebase/firestore"; +import { lazy, useEffect, useState } from "react"; + +import firebase from "firebase/compat/app"; +import getUserSessionData from "../../js/userData"; +import { useSnackbar } from "notistack"; +import { useTheme } from "@mui/material/styles"; + +const PostHeader = lazy(() => import("./PostHeader")); +const CommentBox = lazy(() => import("./CommentBox")); +const CommentDialogBox = lazy(() => import("./CommentDialogBox")); +const LikesDialogBox = lazy(() => import("./LikesDialogBox")); +const ImgBox = lazy(() => import("./ImgBox")); +const PostNav = lazy(() => import("./PostNav")); + +function Post(prop) { + const { postId, user, post, rowMode } = prop; + const { caption, imageUrl, likecount, timestamp, background } = post; + + const [comments, setComments] = useState([]); + const [comment, setComment] = useState(""); + const [likesNo, setLikesNo] = useState(likecount ? likecount.length : 0); + const [showEmojis, setShowEmojis] = useState(false); + const [showCommentEmojis, setShowCommentEmojis] = useState(false); + const [isCommentOpen, setisCommentOpen] = useState(false); + const [isLikesOpen, setIsLikesOpen] = useState(false); + const [username, setUsername] = useState(""); + + const theme = useTheme(); + const { enqueueSnackbar } = useSnackbar(); + const fullScreen = useMediaQuery(theme.breakpoints.down("md")); + + const docRef = doc(db, "posts", postId); + + useEffect(() => { + async function getUsername() { + const data = await getUserSessionData(); + setUsername(data.username); + } + if (auth?.currentUser?.isAnonymous) { + setUsername("guest"); + } else { + getUsername(); + } + }, []); + + useEffect(() => { + let unsubscribe; + + if (postId) { + unsubscribe = db + .collection("posts") + .doc(postId) + .collection("comments") + .orderBy("timestamp", "desc") + .onSnapshot((snapshot) => { + setComments( + snapshot.docs.map((doc) => ({ + id: doc.id, + content: doc.data(), + })), + ); + }); + } + + return () => { + if (unsubscribe) { + unsubscribe(); + } + }; + }, [postId]); + + const postComment = (event) => { + event.preventDefault(); + try { + db.collection("posts").doc(postId).collection("comments").add({ + text: comment, + username: username, + displayName: auth?.currentUser?.displayName, + avatar: auth?.currentUser?.photoURL, + timestamp: firebase.firestore.FieldValue.serverTimestamp(), + }); + } catch (err) { + console.error(err); + } finally { + setComment(""); + } + }; + + const onEmojiClick = (emojiObject, event) => { + setComment((prevInput) => prevInput + emojiObject.emoji); + setShowEmojis(false); + setShowCommentEmojis(false); + }; + + /** + * @type {{ + * imageUrl: null|string, + * imageWidth: number, + * imageHeight: number, + * thumbnail: null | string + * }[]} + * + */ + let postImages; + + try { + postImages = JSON.parse(imageUrl); + } catch { + postImages = imageUrl.split(",").map((url) => ({ + imageUrl: url, + imageWidth: 0, + imageHeight: 0, + thumbnail: null, + })); + } + + const postHasImages = postImages.some((image) => Boolean(image.imageUrl)); + + const tempLikeCount = likecount ? [...likecount] : []; + + async function likesHandler() { + if (user && likecount !== undefined) { + let ind = tempLikeCount.indexOf(user.uid); + + if (ind !== -1) { + tempLikeCount.splice(ind, 1); + setLikesNo((currLikesNo) => currLikesNo - 1); + } else { + tempLikeCount.push(user.uid); + setLikesNo((currLikesNo) => currLikesNo + 1); + } + + const data = { + likecount: tempLikeCount, + }; + await updateDoc(docRef, data) + // .then((docRef) => { + // console.log("like added"); + // }) + .catch((error) => { + enqueueSnackbar(error, { + variant: "error", + }); + }); + } + } + + const handleCommentClose = () => { + setisCommentOpen(false); + }; + + return ( +
    + + + + +
    + + + + + + setIsLikesOpen((prev) => !prev)} + > + {likesNo} {likesNo > 1 ? "Likes" : "Like"} + + setisCommentOpen((prev) => !prev)} + > + {comments.length} {comments.length > 1 ? "comments" : "comment"} + + + + {user && ( +
    + + + + + + + + {/* Comments dialog box */} + + + Comments + + + + +
    + + + + + + +
    + + {/* Likes Dialog Box */} + setIsLikesOpen(false)} + title="Likes ❤" + > + {likesNo === 0 ? ( +

    No likes!!

    + ) : ( + + )} +
    +
    + )} +
    +
    + ); +} + +export default Post; diff --git a/src/components/ProfileDialogBox/index.css b/src/components/ProfileDialogBox/index.css new file mode 100644 index 000000000..7a68bfa48 --- /dev/null +++ b/src/components/ProfileDialogBox/index.css @@ -0,0 +1,110 @@ +.profile-dialog-box-container { + background: var(--profile-container); + color: var(--text-secondary); + box-shadow: var(--post-box-shadow); + position: absolute; + top: -30px; + left: 60px; + z-index: 333; + border-radius: 20px; + padding: 20px; + padding-bottom: 30px; + display: flex; + flex-direction: column; + width: 80%; + gap: 10px; + animation: fade-in 0.4s linear; +} + +@keyframes fade-in { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +.dialog-box-img { + border-radius: 50%; + width: 75px; + height: 75px; + cursor: pointer; + transition: 0.2s ease-in-out; + border: 1px solid #eee; + box-shadow: + 1px 1px 3px #bcbbbb, + -1px -1px 3px #bcbbbb; +} + +.dialog-box-img:hover { + transform: scale(1.1); + box-shadow: + 2px 2px 5px #faf7f7, + -2px -2px 5px #faf7f7; +} + +.dialog-box-display-name { + font-size: 20px; + font-weight: 600; + cursor: pointer; + width: fit-content; +} +.dialog-box-name-container span.dialog-box-username { + display: flex; + padding-top: 5px; + font-size: 13px; +} +.dialog-box-display-name:hover { + text-decoration: underline; +} + +.dialog-box-username { + font-weight: 500; + color: var(--profile-color); + max-width: 210px; +} + +.dialog-box-bio { + color: var(--profile-color); + font-size: 15px; + font-weight: 600; +} + +.dialog-box-follow-container { + display: flex; + gap: 40px; + margin-top: 20px; +} + +.dialog-box-follow-container > p > span { + font-weight: 600; +} + +@media only screen and (max-width: 460px) { + .dialog-box-img { + width: 45px; + height: 45px; + } + .dialog-box-display-name { + font-size: 14px; + } + + .dialog-box-bio { + font-size: 10px; + } + + .profile-dialog-box-container { + padding: 10px; + width: 75%; + } + + .dialog-box-name-container span.dialog-box-username { + padding-top: 4px; + font-size: 12px; + } + + .dialog-box-username { + max-width: 150px; + } +} diff --git a/src/components/ProfileDialogBox/index.jsx b/src/components/ProfileDialogBox/index.jsx new file mode 100644 index 000000000..c2f176168 --- /dev/null +++ b/src/components/ProfileDialogBox/index.jsx @@ -0,0 +1,85 @@ +import "./index.css"; + +import LocationOnIcon from "@mui/icons-material/LocationOn"; +import profileAvatar from "../../assets/blank-profile.webp"; +import { useNavigate } from "react-router-dom"; +import { useState } from "react"; + +const ProfileDialogBox = ({ mouseOnProfileImg, userData }) => { + const [isHoverActive, setIsHoverActive] = useState(false); + const { name, username, avatar, posts, bio, followers, following, country } = + userData; + const navigate = useNavigate(); + + function hoverOver() { + setIsHoverActive(true); + } + + function hoverOut() { + setTimeout(() => { + setIsHoverActive(false); + }, 1000); + } + + function trimBio(bio) { + const str = bio.substr(0, 90) + " ..."; + return str; + } + + return ( +
    +
    + {name} navigate(`/user/${username}`)} + /> +
    +

    navigate(`/user/${username}`)} + > + {name} +

    +
    @{username}
    + + {" "} + {country} + +
    +
    +

    + Bio:{" "} + + {bio?.length > 90 ? trimBio(bio) : bio} + +

    +

    Posts: {posts}

    + {followers && following && ( +
    +

    + {following} Following +

    +

    + {followers} Followers +

    +
    + )} +
    + ); +}; + +export default ProfileDialogBox; diff --git a/src/components/ReadMore.jsx b/src/components/ReadMore.jsx deleted file mode 100644 index 3d0838c0b..000000000 --- a/src/components/ReadMore.jsx +++ /dev/null @@ -1,61 +0,0 @@ -import React from "react"; -import { useState, useEffect } from "react"; - -function ReadMore({ caption }) { - const [desc, setDesc] = useState(""); - const [size, setSize] = useState(""); - const [expand, setExpand] = useState(false); - - const handleReadMore = (e) => { - e.preventDefault(); - setExpand(true); - setDesc(caption); - }; - - const handleReadLess = (e) => { - e.preventDefault(); - setExpand(false); - setDesc(caption.split(" ").splice(0, 14).join(" ")); - }; - - useEffect(() => { - const split_desc = caption.split(" "); - const sz = split_desc.length; - setSize(sz); - if (sz > 14) { - setDesc(split_desc.splice(0, 14).join(" ")); - } else { - setDesc(caption); - } - }, [caption]); - - return ( - - {size > 14 ? ( - <> - {expand === false ? ( - <> - {desc}... - - {" "} - Read More - - - ) : ( - <> - {caption} - - {" "} - Read Less - - - )} - - ) : ( - <>{caption} - )} - - ); -} - -export default ReadMore; diff --git a/src/components/ReadMore/index.css b/src/components/ReadMore/index.css new file mode 100644 index 000000000..86870dff2 --- /dev/null +++ b/src/components/ReadMore/index.css @@ -0,0 +1,15 @@ +.read__more__less { + text-decoration: underline; + cursor: pointer; + color: rgba(17, 3, 46, 0.4); +} + +.read__more__less:hover { + color: rgb(6, 33, 115); +} + +.caption_container { + z-index: 1; + background-color: white; + opacity: 0.7; +} diff --git a/src/components/ReadMore/index.jsx b/src/components/ReadMore/index.jsx new file mode 100644 index 000000000..e872a5e4c --- /dev/null +++ b/src/components/ReadMore/index.jsx @@ -0,0 +1,47 @@ +import "./index.css"; + +import React, { useState } from "react"; +import { useNavigate, useParams } from "react-router-dom"; + +import Caption from "../Caption.jsx"; + +const ReadMore = ({ children, postId, picCap = false, readMore = true }) => { + const { id } = useParams(); + + const [isReadMore, setIsReadMore] = useState(readMore); + const navigate = useNavigate(); + let text = children; + const toggleReadMore = () => setIsReadMore((prev) => !prev); + + const captionText = isReadMore + ? picCap + ? text.slice(0, 100) + : text.slice(0, 40) + : text; + + return ( + + + {text.length >= 40 && ( + { + toggleReadMore(); + if (!id) { + navigate(`/posts/${postId}`); + } + }} + style={{ + color: "var(--profile-color)", + fontWeight: "bold", + cursor: "pointer", + fontSize: "12px", + }} + > + {isReadMore ? " ...read more" : " ...show less"} + + )} + + ); +}; + +export default ReadMore; diff --git a/src/components/SettingsComponents/DeleteAccount/index.css b/src/components/SettingsComponents/DeleteAccount/index.css new file mode 100644 index 000000000..7eee791b5 --- /dev/null +++ b/src/components/SettingsComponents/DeleteAccount/index.css @@ -0,0 +1,103 @@ +.delete_account_main_container { + width: 100%; + height: 100%; + margin-top: 20px; + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + text-align: left; + color: var(--text-secondary); +} + +.delete_account_sub_container { + padding: 40px; + display: flex; + justify-content: center; + flex-direction: column; + gap: 30px; +} + +/* .delete_account_heading { +} */ + +.delete_account_heading > h1 { + font-weight: 600; +} + +/* .delete_account_body { +} */ + +.delete_account_body_heading { + font-weight: 600; + margin-bottom: 8px; +} + +.delete_account_body_list { + display: flex; + flex-direction: column; + gap: 8px; +} + +.delete_account_action_btn_container { + display: flex; + gap: 15px; +} + +.delete_account_action_btn { + padding: 10px 20px; + border-radius: 10px; + cursor: pointer; + color: white; + font-weight: bold; + font-size: 18px; + border: none; + /* background-color: #ff0000; */ +} + +.delete_account_action_btn:hover { + background-color: #ff0000; +} + +.delete_acc_btn { + margin-right: 10px !important; +} + +.delete_account_action_delete_btn { + background-color: gray; +} + +.delete_acc_pass { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + border: 1px solid black; + display: flex; + flex-direction: column; + padding: 15px; + border-radius: 10px; + background-color: var(--bg-color); + gap: 10px; + font-size: 20px; +} + +.confirm_delete_acc_btn { + padding: 10px; + border-radius: 10px; + background-color: #5f85db; + color: var(--text-secondary); + cursor: pointer; + font-size: 18px; + box-shadow: var(--post-box-shadow); +} + +.disable_confirm_btn { + background-color: rgb(161, 161, 161) !important; +} + +@media screen and (max-width: 800px) { + .delete_account_sub_container { + padding: 15px; + } +} diff --git a/src/components/SettingsComponents/DeleteAccount/index.jsx b/src/components/SettingsComponents/DeleteAccount/index.jsx new file mode 100644 index 000000000..de554a254 --- /dev/null +++ b/src/components/SettingsComponents/DeleteAccount/index.jsx @@ -0,0 +1,202 @@ +import "./index.css"; + +import { Link, useNavigate } from "react-router-dom"; + +import { ClickAwayListener } from "@mui/material"; +import { db } from "../../../lib/firebase"; +import deleteImg from "../../../js/deleteImg"; +import firebase from "firebase/compat/app"; +import getUserSessionData from "../../../js/userData"; +import { useSnackbar } from "notistack"; +import { useState } from "react"; + +const DeleteAccount = ({ user }) => { + const [deleteAcc, setDeleteAcc] = useState(false); + const [pass, setPass] = useState(""); + const [isDeleting, setIsDeleting] = useState(false); + const navigate = useNavigate(); + const { enqueueSnackbar } = useSnackbar(); + + // Function to handle delete account in firebase auth + async function handleConfirmDelete() { + const providerName = user?.providerData[0]?.providerId; + if (providerName) { + //Signed in using OAuth Provider + let provider; + setIsDeleting(true); + + if (providerName === "google.com") { + provider = new firebase.auth.GoogleAuthProvider(); + } else { + provider = new firebase.auth.FacebookAuthProvider(); + } + try { + await user.reauthenticateWithPopup(provider); + await handleDeleteAcc(); + } catch (err) { + enqueueSnackbar(`Error: ${err}`, { + variant: "error", + }); + setIsDeleting(false); + } + } else if (user?.email && pass !== "") { + //Signed In using Email and Password + setIsDeleting(true); + const credential = firebase.auth.EmailAuthProvider.credential( + user.email, + pass, + ); + try { + await user.reauthenticateWithCredential(credential); + await handleDeleteAcc(); + } catch (err) { + enqueueSnackbar(`Error: ${err}`, { + variant: "error", + }); + setIsDeleting(false); + } + } else { + enqueueSnackbar(`Error: Invalid credentials`, { + variant: "error", + }); + } + } + + async function handleDeleteAcc() { + let imagesArr = []; + try { + const batch = db.batch(); + + const userData = await getUserSessionData(); + + if (userData) { + if (userData.photoURL) imagesArr.push(userData.photoURL); + if (userData.bgImageUrl) imagesArr.push(userData.bgImageUrl); + } + batch.delete(userDocRef); + + // Step 2: Delete all posts where uid === user.uid from the posts collection + const postsSnapshot = await db + .collection("posts") + .where("uid", "==", user?.uid) + .get(); + + if (!postsSnapshot.empty) { + postsSnapshot.forEach((postDoc) => { + const postImages = postDoc.data().imageUrl; + if (postImages && postImages !== "") { + const arr = JSON.parse(postImages); + if (arr) { + arr.forEach((img) => { + imagesArr.push(img.imageUrl); + }); + } + } + batch.delete(postDoc.ref); + }); + } + + // Commit the batch + await batch.commit(); + + // Step 3: Delete user from authentication + await user.delete(); + + // Step 4: Delete images from cloud + const deleteImagePromises = imagesArr.map(async (img) => { + if (img === "") return; + try { + await deleteImg(img); + } catch (err) { + console.error(`Error deleting image: ${err}`); + } + }); + + await Promise.all(deleteImagePromises); + + localStorage.removeItem("user"); + navigate("/login"); + enqueueSnackbar("User deleted successfully", { + variant: "success", + }); + } catch (err) { + console.error(`Error handling delete: ${err}`); + enqueueSnackbar(`Error: ${err}`, { + variant: "error", + }); + } finally { + setIsDeleting(false); + } + } + + return ( + <> +
    +
    +
    +

    Delete Your Account

    +

    We're sorry to see you leaving

    +
    + +
    +

    Before you go...

    +
      +
    • + If you're sick of getting email notification{" "} + disable them here. +
    • +
    • + If you want to change username you can{" "} + do that here. +
    • +
    • + Account deletion is final. There will be no way to restore your + account. +
    • +
    +
    +
    + +
    +
    +
    + + {deleteAcc && ( + setDeleteAcc(false)}> +
    + + setPass(e.target.value)} + /> + +
    +
    + )} + + ); +}; + +export default DeleteAccount; diff --git a/src/components/SettingsComponents/Sidebar/index.css b/src/components/SettingsComponents/Sidebar/index.css new file mode 100644 index 000000000..df55ee862 --- /dev/null +++ b/src/components/SettingsComponents/Sidebar/index.css @@ -0,0 +1,100 @@ +.settings-container { + display: flex; + justify-content: center; + align-items: flex-start; + min-height: 100vh; + margin-top: 60px; +} + +.settings-sidebar-container { + background: var(--bg-color); + position: fixed; + width: 25vw; + height: 100vh; + top: 4.5em; + left: 0; + border-right: 1px solid rgb(219, 219, 219); +} + +.settings-sidebar-sub-container { + display: flex; + flex-direction: column; + min-height: 100vh; + list-style: none; + padding: 0 20px; +} + +.active { + background: rgba(0, 0, 0, 0.05); + border: 2px solid #0cc; +} + +.settings-sidebar-sub-container li { + cursor: pointer; + padding: 10px; + margin: 10px 0; + border-radius: 10px; + transition: all 0.5s ease; +} + +li:hover { + background: rgba(0, 0, 0, 0.05); +} + +.settings-sidebar-sub-container li a, +.settings-sidebar-item { + display: flex; + align-items: center; + color: var(--color); + text-decoration: none; +} +.icon { + font-size: 30px; + transition: all 0.2s ease; +} + +li:hover .icon { + transform: scale(1.1); +} + +.settings-sidebar-sub-container li span { + margin-left: 15px; +} + +.settings_child_container { + margin-left: 25vw; + width: 100%; + height: 100%; +} + +@media screen and (max-width: 800px) { + .settings-sidebar-container { + bottom: 0; + top: auto; + width: 100vw; + height: 80px; + border-right: none; + margin: 0; + } + .settings-sidebar-sub-container span { + display: none; + } + .settings-sidebar-sub-container { + border-top: 1px solid rgb(219, 219, 219); + flex-direction: row; + padding: 0 5px; + height: 80px; + min-height: auto; + justify-content: space-around; + } + + .settings_child_container { + margin-left: 0; + } +} +@media screen and (max-width: 800px) { + .settings-container { + min-height: calc(100vh - 180px) !important; + margin-top: 80px; + } +} diff --git a/src/components/SettingsComponents/Sidebar/index.jsx b/src/components/SettingsComponents/Sidebar/index.jsx new file mode 100644 index 000000000..99db9a4bb --- /dev/null +++ b/src/components/SettingsComponents/Sidebar/index.jsx @@ -0,0 +1,79 @@ +import "./index.css"; + +import { Link, Outlet } from "react-router-dom"; + +import ContactSupportOutlinedIcon from "@mui/icons-material/ContactSupportOutlined"; +import DarkModeOutlinedIcon from "@mui/icons-material/DarkModeOutlined"; +import InfoOutlinedIcon from "@mui/icons-material/InfoOutlined"; +import ManageAccountsOutlinedIcon from "@mui/icons-material/ManageAccountsOutlined"; +import NotificationsIcon from "@mui/icons-material/Notifications"; +import SecurityOutlinedIcon from "@mui/icons-material/SecurityOutlined"; +import VolumeUpOutlinedIcon from "@mui/icons-material/VolumeUpOutlined"; + +const SettingsSidebar = () => { + return ( +
    +
    +
      +
    • + + Sound + +
    • +
    • + + Notification + +
    • +
    • + + About + +
    • +
    • + + + Theme + +
    • +
    • + + + Privacy and Security + +
    • +
    • + + Help + +
    • +
    • + + {" "} + Account + +
    • +
    +
    +
    + +
    +
    + ); +}; + +export default SettingsSidebar; diff --git a/src/components/SettingsComponents/Sounds/index.css b/src/components/SettingsComponents/Sounds/index.css new file mode 100644 index 000000000..307a10730 --- /dev/null +++ b/src/components/SettingsComponents/Sounds/index.css @@ -0,0 +1,100 @@ +.sounds-setting-container { + display: flex; + justify-content: center; + align-items: flex-start; + min-height: 92vh; + width: 100%; + padding-top: 40px; +} + +.sounds-setting-sub-container { + border: 1px solid rgb(206, 206, 206); + background-color: rgb(255, 255, 255); + max-width: 850px; + margin-inline: 15px; + padding: 25px; + border-radius: 12px; + display: flex; + flex-direction: column; + gap: 3rem; + padding-bottom: 65px; + box-shadow: 0 0 0px 10px rgba(0, 0, 0, 0.2); + position: relative; +} + +.sound-setting-page-heading { + font-weight: 500; +} + +.sound-page-para { + font-size: 15px; + margin-top: 5px; + color: rgb(50, 49, 49); +} + +.sound-setting-button-container { + display: flex; + justify-content: space-between; + align-items: center; +} + +.sound-btn-label { + font-size: 18px; + color: rgb(87, 86, 86); + user-select: none; +} + +#sound-btn { + padding: 10px 20px; + font-size: 18px; + border-radius: 8px; + cursor: pointer; + border: none; + /* background-color: rgb(62, 62, 62); */ + background-color: rgb(4, 202, 202); + color: white; +} +#sound-btn:hover { + background-color: aqua; +} +.sound-page-note { + font-size: 13px; + max-width: 95%; + font-weight: 300; +} + +.closeIcon { + cursor: pointer; + font-size: 25px; + font-weight: 700; + position: absolute; + top: 10px; + right: 10px; +} + +.sound-toggle-switch-container { + display: flex; + align-items: center; +} + +.sound-toggle-switch > span > input:hover { + cursor: pointer; +} + +@media only screen and (max-width: 1400px) { + .sounds-setting-sub-container { + margin-left: 160px; + } +} + +@media only screen and (max-width: 1200px) { + .sounds-setting-sub-container { + margin-inline: 20px; + } +} + +@media only screen and (max-width: 350px) { + .sounds-setting-sub-container { + margin-top: 80px; + } +} diff --git a/src/components/SettingsComponents/Sounds/index.jsx b/src/components/SettingsComponents/Sounds/index.jsx new file mode 100644 index 000000000..d1f409ddb --- /dev/null +++ b/src/components/SettingsComponents/Sounds/index.jsx @@ -0,0 +1,69 @@ +import "./index.css"; + +import React, { useState } from "react"; + +import { Switch } from "@mui/material"; +import { VscChromeClose } from "react-icons/vsc"; +import { useNavigate } from "react-router-dom"; + +const SoundSetting = () => { + const [sound, setSound] = useState(localStorage.getItem("sound")); + const [showDiv, setShowDiv] = useState(true); + const navigate = useNavigate(); + + function toggleSound() { + if (sound) { + localStorage.removeItem("sound"); + } else { + localStorage.setItem("sound", "disable"); + } + setSound(localStorage.getItem("sound")); + // window.location.reload(true) + } + const closeHandler = () => { + setShowDiv(false); + navigate("/"); + }; + + return ( +
    + {showDiv && ( +
    +
    + +
    +
    +

    Sound Effects

    +

    + Do you want sound effects to play for certain actions while using + DummyGram? +

    +
    +
    + + +

    Off

    + +

    On

    +
    +
    +
    +

    + Occasionally we'll play a sound effect to draw your attention to + something that's happened, such as receiving a message or when you + saved a post. +

    +
    +
    + )} +
    + ); +}; + +export default SoundSetting; diff --git a/src/components/SettingsComponents/index.js b/src/components/SettingsComponents/index.js new file mode 100644 index 000000000..1c7354cf6 --- /dev/null +++ b/src/components/SettingsComponents/index.js @@ -0,0 +1,5 @@ +import DeleteAccount from "./DeleteAccount"; +import SettingsSidebar from "./Sidebar"; +import SoundSetting from "./Sounds"; + +export { DeleteAccount, SettingsSidebar, SoundSetting }; diff --git a/src/components/SideBar/Footer.jsx b/src/components/SideBar/Footer.jsx new file mode 100644 index 000000000..b46cc789f --- /dev/null +++ b/src/components/SideBar/Footer.jsx @@ -0,0 +1,62 @@ +import ContributorsIcon from "@mui/icons-material/Diversity3"; +import FeedbackIcon from "@mui/icons-material/Feedback"; +import GuidelinesIcon from "@mui/icons-material/LibraryBooks"; +import HelpIcon from "@mui/icons-material/Help"; +import InfoIcon from "@mui/icons-material/Info"; +import { Link } from "react-router-dom"; + +const Footer = () => { + return ( +
    +
      +
    • + + + + About + + +
    • +
    • + + + + Feedback + + +
    • +
    • + + + + Contributors + + +
    • +
    • + + + + Help-center + + +
    • +
    • + + + + Guidelines + + +
    • +
    +

    © MIT license since 2022

    +
    + ); +}; + +export default Footer; diff --git a/src/components/SideBar/index.css b/src/components/SideBar/index.css new file mode 100644 index 000000000..8bf9eb0ac --- /dev/null +++ b/src/components/SideBar/index.css @@ -0,0 +1,314 @@ +/* sidebar styling */ + +.sidebar { + background: var(--dark-post-bg); + position: fixed; + width: 17vw; + height: 100vh; + left: 0; + z-index: 99; + /* border-right: 1px solid rgb(219, 219, 219); */ +} + +.sidebar-container { + display: flex; + flex-direction: column; + justify-content: space-between; + height: 100vh; + overflow-y: scroll; +} + +.sidebar-container::-webkit-scrollbar { + display: none; +} + +.sidebar_design { + padding: 0; + display: flex; + width: fit-content; +} + +.sidebar_design > span { + width: 10px; + height: 10px; + display: inline-block; + border-radius: 50%; + margin-left: 5px; +} + +.sidebar_menu_icon { + position: absolute; + top: -10px; + right: -10px; + border-radius: 50%; + padding: 5px; + color: var(--text-secondary); +} + +.sidebar_menu_icon:hover { + background: var(--sidebar-link-hover); +} + +.sidebar-links { + display: flex; + flex-direction: column; + list-style: none; + padding: 0 20px; +} + +.active { + background: rgba(0, 0, 0, 0.05); +} + +.sidebar-links li { + cursor: pointer; + padding: 10px; + margin: 0 0 10px; + border-radius: 10px; + transition: all 0.5s ease; + position: relative; +} + +#sidebar-home-link { + margin-top: 20px; +} + +.sidebar-links li:hover { + background-color: #5f85db; +} + +.sidebar-links li a, +.sidebar_align { + display: flex; + align-items: center; + color: var(--color); + text-decoration: none; +} + +#sidebar_profile_link:hover { + background: transparent; +} + +.sidebar_profile { + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + position: relative; +} + +.profile-picture { + width: 80px; + height: 80px; + transition: 0.2s ease-in-out; + border-radius: 50%; + border: 1px solid #eee; + box-shadow: + 1px 1px 3px #bcbbbb, + -1px -1px 3px #bcbbbb; +} + +.sidebar_user_name { + opacity: 0.9; + color: var(--text-grey); + margin-top: 5px; +} + +.sidebar .icon { + font-size: 30px; + transition: all 0.2s ease; +} + +.sidebar-links li:hover .icon { + transform: scale(1.1); +} + +.sidebar-links li span { + margin-left: 15px; +} + +.sidebar_user_dropdown { + display: flex; +} + +.sidebar_user_dropdown_container { + position: absolute; + top: 41px; + left: 200px; + padding: 0; + border-radius: 10px; + width: 170px; + z-index: 999; +} + +.sidebar_user_dropdown_sub_container { + border: 1px solid grey; + background-color: var(--dark-post-bg); + color: var(--color); + padding-inline: 0px; + list-style-type: none; + border-radius: inherit; + box-shadow: var(--post-box-shadow); +} + +.sidebar_user_dropdown_sub_container > li { + padding: 10px 25px; + margin: 0; + border-radius: 8px; + border-bottom: 1px solid #eee; + display: flex; + align-items: center; + gap: 5px; + cursor: pointer; +} + +.sidebar_user_dropdown_sub_container > li:hover { + background: var(--btn-color-hover); +} +.dropdown-list-profile-picture { + width: 30px; + aspect-ratio: 1; + border-radius: 50%; + border: 1px solid #eee; + margin-left: -3px; +} + +footer { + display: absolute; + bottom: 0; + margin-bottom: 6em; + font-size: 13px; + background-color: var(--dark-post-bg); + padding-left: 12px; +} + +.sidebar-footer-container { + display: flex; + list-style-type: none; + flex-direction: column; + padding: 0; + text-align: start; + margin-right: 20px; + margin-top: 20px; +} + +.footer-link { + text-decoration: none; + color: #898787; +} + +.footer-link:hover { + color: #5f85db; +} + +.copyright { + margin-top: 10px; + color: var(--color); + text-align: start; +} + +.activeTab { + border: 2px solid #5f85db; +} +.sidebar-footer-container li a { + text-decoration: none; + color: #898787; +} + +/* media query */ +@media screen and (min-width: 1200px) { + .sidebar-footer-container li { + padding-bottom: 5px; + } +} + +@media screen and (max-width: 1200px) { + .sidebar { + width: 8vw; + } + .sidebar-footer-container .footer-icons { + display: none; + } + .sidebar-links { + padding: 0 5px; + } + .sidebar-links li a, + .sidebar_align { + justify-content: center; + } + + .sidebar-links li a span, + .sidebar_align span { + display: none; + } + + .sidebar_user_name { + display: none; + } + + .profile-picture { + width: 30px; + height: 30px; + } + + .sidebar_user_dropdown_container { + width: 150px; + left: 50px; + } + + #sidebar_profile_link:hover { + background-color: #5f85db; + } + + .sidebar_user_dropdown_sub_container > li { + padding-right: 0; + } + + footer { + font-size: 10px; + } +} +@media screen and (max-width: 800px) { + .sidebar { + border-top: 1px solid rgb(219, 219, 219); + border-right: none; + width: 100vw; + height: 60px; + position: fixed; + padding-block: 5px; + bottom: 0; + margin: 0; + } + + .sidebar hr { + display: none; + } + + .sidebar_design { + display: none; + } + + #sidebar-home-link { + margin-top: auto; + } + + .sidebar-links { + justify-content: space-around; + flex-direction: row-reverse; + height: 60px; + } + + .sidebar-links li { + margin: auto; + } + + .sidebar_user_dropdown_container { + left: initial; + top: -140px; + right: 5px; + } + + footer { + display: none; + } +} diff --git a/src/components/SideBar/index.jsx b/src/components/SideBar/index.jsx new file mode 100644 index 000000000..39a756aa2 --- /dev/null +++ b/src/components/SideBar/index.jsx @@ -0,0 +1,277 @@ +import "./index.css"; + +import { AccountCircle, AddCircleOutlined } from "@mui/icons-material"; +import { AnimatedButton, ErrorBoundary, Logo } from "../../reusableComponents"; +import { ClickAwayListener, Dialog, Modal } from "@mui/material"; +import { + Home, + Logout, + MoreVert, + Notifications, + Settings, +} from "@mui/icons-material"; +import React, { useEffect, useState } from "react"; +import { getModalStyle, useStyles } from "../../App"; +import { useLocation, useNavigate } from "react-router-dom"; + +import { AiOutlineClose } from "react-icons/ai"; +import { auth } from "../../lib/firebase"; +import blankImg from "../../assets/blank-profile.webp"; +import getUserSessionData from "../../js/userData"; +import { playSuccessSound } from "../../js/sounds"; +import { useSnackbar } from "notistack"; + +const Footer = React.lazy(() => import("./Footer")); +const ImgUpload = React.lazy(() => import("../ImgUpload")); + +function SideBar() { + const classes = useStyles(); + const navigate = useNavigate(); + const user = auth.currentUser; + const anonymous = auth?.currentUser?.isAnonymous; + const location = useLocation(); + const { enqueueSnackbar } = useSnackbar(); + + const [logout, setLogout] = useState(false); + const [openMenu, setOpenMenu] = useState(false); + const [openNewUpload, setOpenNewUpload] = useState(false); + const [userData, setUserData] = useState({ + name: "", + username: "", + }); + + const windowWidth = window.innerWidth; + + useEffect(() => { + async function getUsername() { + try { + const data = await getUserSessionData(); + if (data) { + setUserData({ + name: data?.displayName || auth.currentUser?.displayName, + username: data?.username || auth.currentUser?.uid, + }); + } else { + setUserData({ + name: auth.currentUser?.displayName, + username: auth.currentUser?.uid, + }); + } + } catch (error) { + console.error("Error fetching user data:", error); + setUserData({ + name: auth.currentUser?.displayName, + username: auth.currentUser?.uid, + }); + } + } + + if (anonymous) { + setUserData({ + name: "Guest", + username: "guest", + }); + } else { + getUsername(); + } + }, [user, anonymous]); + + const signOut = () => { + auth.signOut().finally(() => { + playSuccessSound(); + enqueueSnackbar("Logged out Successfully !", { + variant: "info", + }); + }); + }; + + return ( +
    +
    +
      +
    • 1200 ? "default" : "pointer", + }} + id="sidebar_profile_link" + onClick={() => { + if (windowWidth < 1200) { + setOpenMenu((prev) => !prev); + } + }} + > +
      + {windowWidth > 1200 && ( + setOpenMenu((prev) => !prev)} + style={{ cursor: "pointer" }} + /> + )} + 0 ? user.photoURL : blankImg} + alt="profile picture" + className="profile-picture" + /> +

      {user?.displayName}

      +
      +
    • + +
    • + anonymous ? navigate("/signup") : setOpenNewUpload(true) + } + > +
      + Create +
      +
    • +
    • + navigate(`/${anonymous ? "signup" : "notifications"}`) + } + className={ + location.pathname.includes("/notifications") ? "activeTab" : "" + } + > +
      + Notifications +
      +
    • +
    + +
    + +
    + + setLogout(false)}> +
    +
    + +

    + Are you sure you want to Logout? +

    + +
    + + Logout + + setLogout(false)} + variant="contained" + color="primary" + className="button-style" + > + Cancel + +
    + +
    +
    + + {openMenu && ( + setOpenMenu(false)}> +
    setOpenMenu(false)} + > +
      +
    • + navigate( + `/${anonymous ? "signup" : `user/${userData.username}`}`, + ) + } + > + {user?.photoURL ? ( + profile picture + ) : ( + + )}{" "} + Profile +
    • +
    • + navigate(`/${anonymous ? "signup" : "settings"}`) + } + > + Settings +
    • +
    • setLogout(true)}> + Logout +
    • +
    +
    +
    + )} + + setOpenNewUpload(false)} + > +
    + { + setOpenNewUpload(false); + }} + size={"1rem"} + className="crossIcon" + /> +

    Create new post

    +
    + setOpenNewUpload(false)} + /> +
    +
    +
    + ); +} + +export default SideBar; diff --git a/src/components/Story/index.css b/src/components/Story/index.css new file mode 100644 index 000000000..76be4cac8 --- /dev/null +++ b/src/components/Story/index.css @@ -0,0 +1,91 @@ +.story_main_container { + width: 100vw; + height: 100vh; + position: fixed; + z-index: 999; + background-color: rgba(0, 0, 0, 0.9); + display: flex; + justify-content: center; + align-items: center; +} + +.story_icons { + position: absolute; + top: -40px; + z-index: 99; + transform: scale(1.4); + cursor: pointer; + border-radius: 50%; + padding: 10px; +} + +.story_close_icon { + right: 30px; + color: white; +} + +.story_icons:hover { + background: rgba(255, 255, 255, 0.4); +} + +.story_delete_icon { + right: 80px; + color: red; +} + +.story-container-outer { + position: relative; + display: flex; + flex-direction: column; + padding: 30px; + justify-content: flex-start; + align-items: center; + max-width: 500px; + max-height: 500px; +} + +.story_container-inner { + display: flex; + width: 100%; +} +.story-cont-with-img .story_container-inner { + flex-direction: column; +} + +.story-image-container { + width: 100%; + height: 100%; +} + +.story-caption { + width: 100%; + padding: 20px 0 20px 10px; + font-size: 16px; + color: #fff; +} + +.story_bg { + width: 500px; + height: 300px; + display: flex; + justify-content: center; + align-items: center; + background-size: contain; + border-radius: 22px; +} + +.story_without_image { + position: relative; + max-width: 500px; +} + +.caption_without_image { + font-size: 18px; +} + +.story_image { + width: 100%; + height: 100%; + border-radius: 22px; + aspect-ratio: initial; +} diff --git a/src/components/Story/index.jsx b/src/components/Story/index.jsx new file mode 100644 index 000000000..32c60cea1 --- /dev/null +++ b/src/components/Story/index.jsx @@ -0,0 +1,138 @@ +import "./index.css"; + +import { useEffect, useState } from "react"; + +import CloseIcon from "@mui/icons-material/Close"; +import DeleteIcon from "@mui/icons-material/Delete"; +import { db } from "../../lib/firebase"; +import { deleteField } from "firebase/firestore"; + +const StoryView = ({ username, setViewStory, setUserData }) => { + const [storyData, setStoryData] = useState({}); + const [storyImage, setStoryImage] = useState(""); + const { imageUrl, caption, background } = storyData; + + const defaultBg = `linear-gradient(130deg, #dee2ed, #dee2ed, #9aa9d1, #b6c8e3, #b6afd0, #d3c0d8)`; + + useEffect(() => { + async function getStory() { + try { + const docRef = db + .collection("story") + .where("username", "==", username) + .limit(1); + + const snapshot = await docRef.get(); + if (!snapshot.empty) { + const doc = snapshot.docs[0]; + const data = doc.data(); + setStoryData({ + ...data, + }); + setStoryImage(data?.imageUrl || []); + } else { + // Handle the case when the story document is not found for the provided username + setStoryData(null); + setStoryImage([]); + } + } catch (error) { + console.error("Error fetching story data:", error); + // Handle any other error that might occur during data fetching + setStoryData(null); + setStoryImage([]); + } + } + + getStory(); + }, [username]); + + async function deleteStory() { + // Delete the story from story collection + const querySnapshot = await db + .collection("story") + .where("username", "==", username) + .get(); + + querySnapshot?.forEach((doc) => { + doc.ref.delete().catch((error) => { + console.error("Error deleting document: ", error); + }); + }); + + // Delete story timestamp from user Doc + const userDocSnapshot = await db + .collection("users") + .where("username", "==", username) + .get(); + + userDocSnapshot?.forEach((doc) => { + doc.ref + .update({ + storyTimestamp: deleteField(), + }) + .then(() => { + setUserData((prevData) => ({ + ...prevData, + storyTimestamp: null, + })); + }) + .catch((error) => { + console.error("Error deleting document: ", error); + }); + }); + } + + return ( +
    +
    + setViewStory(false)} + /> + {storyData ? ( + <> + { + deleteStory(); + setViewStory(false); + }} + /> + {imageUrl == "" ? ( +
    +
    +

    {caption}

    +
    +
    + ) : ( +
    +
    + {username} +
    +

    {caption}

    +
    + )} + + ) : ( +

    Sorry😓 No story!

    + )} +
    +
    + ); +}; + +export default StoryView; diff --git a/src/components/Suggestions/index.css b/src/components/Suggestions/index.css new file mode 100644 index 000000000..044b881a5 --- /dev/null +++ b/src/components/Suggestions/index.css @@ -0,0 +1,143 @@ +.suggestion-main-container { + width: 100%; + overflow: scroll; + display: flex; + justify-content: center; + align-items: center; + position: relative; +} + +.suggestion-scroll-btn { + display: none; + width: 40px; + aspect-ratio: 1; + border-radius: 50%; + cursor: pointer; + justify-content: center; + align-items: center; + position: absolute; +} + +.suggestion-scroll-btn-left { + left: 0; +} + +.suggestion-scroll-btn-right { + right: 0; +} + +.suggestion-user-container { + display: flex; + flex-direction: row; + overflow: scroll; + padding: 0; + margin: 0; + scroll-behavior: smooth; +} + +.suggestion-user-list-item { + list-style: none; + padding: 10px; + padding-block: 20px; + transition: 0.3s ease-in-out; + display: flex; + align-items: center; + flex-direction: column; + flex-shrink: 0; + gap: 10px; + /* margin-block: 20px; */ + width: 200px; + height: 200px; + border-right: 1px solid #eee; +} + +.suggestion-user-img { + width: 80px; + aspect-ratio: 1; + border-radius: 50%; + border: 1px solid #eee; + cursor: default; +} + +.suggestion-user-data { + text-align: center; + color: var(--text-secondary); +} + +.suggestion-user-name { + font-size: 16px; + font-weight: 600; + cursor: default; +} + +.suggestion-user-bio { + font-size: 14px; + margin-bottom: 10px; + color: var(--text-secondary); +} + +.suggestion-user-btn { + padding: 6px 15px; + border-radius: 8px; + border: none; + width: 150px; + box-shadow: 0 0 6px rgba(104, 85, 224, 0.2); +} + +@media screen and (min-width: 550px) { + .suggestion-scroll-btn { + display: flex; + } +} + +@media screen and (min-width: 800px) { + .suggestion-user-list-item { + width: 300px; + height: 250px; + } + + .suggestion-user-img { + width: 120px; + } +} + +@media only screen and (min-width: 1300px) { + .suggestion-main-container { + position: fixed; + top: 65px; + right: 0; + width: 17vw; + height: calc(100vh - 80px); + display: flex; + justify-content: center; + overflow: scroll; + margin-left: 17vw; + align-items: flex-start; + } + + .suggestion-user-container { + flex-direction: column; + width: 100%; + /* margin-top: 7rem; */ + } + + .suggestion-user-list-item { + border-bottom: 1px solid #eee; + flex-direction: row; + align-items: flex-start; + width: 100%; + height: auto; + } + + .suggestion-user-img { + width: 40px; + } + + .suggestion-scroll-btn { + display: none; + } + + .top-margin { + margin-top: 5rem; + } +} diff --git a/src/components/Suggestions/index.jsx b/src/components/Suggestions/index.jsx new file mode 100644 index 000000000..3fe89695b --- /dev/null +++ b/src/components/Suggestions/index.jsx @@ -0,0 +1,209 @@ +import "./index.css"; + +import { auth, db } from "../../lib/firebase"; +import { useEffect, useRef, useState } from "react"; + +import ArrowBackIosIcon from "@mui/icons-material/ArrowBackIos"; +import ArrowForwardIosIcon from "@mui/icons-material/ArrowForwardIos"; +import blankImg from "../../assets/blank-profile.webp"; +import firebase from "firebase/compat/app"; +import { useNavigate } from "react-router-dom"; +import { useSnackbar } from "notistack"; + +const Suggestion = () => { + const [randomDocs, setRandomDocs] = useState([]); + const navigate = useNavigate(); + const scrollRef = useRef(null); + const currentUser = auth.currentUser; + const { enqueueSnackbar } = useSnackbar(); + + const checkFriendRequestSent = async (uid) => { + const currentUserUid = currentUser?.uid; + const targetUserUid = uid; + + if (targetUserUid) { + const friendRequestsRef = db + .collection("users") + .doc(targetUserUid) + .collection("friendRequests"); + const query = friendRequestsRef + .where("sender", "==", currentUserUid) + .where("recipient", "==", targetUserUid) + .limit(1); + + const snapshot = await query.get(); + if (!snapshot.empty) { + return true; + } + } + return false; + }; + + useEffect(() => { + const fetchRandomDocument = async () => { + try { + const collectionRef = db.collection("users"); + + // Generate a new auto-id (random value) + const randomValue = collectionRef.doc().id; + + const snapshot = await collectionRef + .orderBy(firebase.firestore.FieldPath.documentId()) + .startAt(randomValue) + .limit(5) + .get(); + if (!snapshot.empty) { + const randomDocuments = await Promise.all( + snapshot.docs.map(async (doc) => { + const data = doc.data(); + const isFriendRequestSent = await checkFriendRequestSent( + data.uid, + ); + return { ...data, friendRequestSent: isFriendRequestSent }; + }), + ); + setRandomDocs(randomDocuments); + } else { + // Handle the case when there are no documents in the snapshot + console.log("No random documents found."); + } + } catch (error) { + // Handle any errors that may occur during data retrieval + console.error("Error fetching random documents:", error); + } + }; + fetchRandomDocument(); + }, []); + + const handleSendFriendRequest = (friendRequestSent, uid, idx) => { + const currentUserUid = currentUser?.uid; + const targetUserUid = uid; + const batch = db.batch(); + + const friendRequestRef = db + .collection("users") + .doc(targetUserUid) + .collection("friendRequests") + .doc(currentUserUid); + + const notificationRef = db + .collection("users") + .doc(targetUserUid) + .collection("notifications") + .doc(currentUserUid); + + if (friendRequestSent) { + batch.delete(friendRequestRef); + batch.delete(notificationRef); + + batch + .commit() + .then(() => { + const updatedDocuments = [...randomDocs]; + updatedDocuments[idx].friendRequestSent = false; + setRandomDocs(updatedDocuments); + enqueueSnackbar("Friend Request Declined", { + variant: "success", + }); + }) + .catch((error) => { + enqueueSnackbar(`Error Occurred: ${error}`, { + variant: "error", + }); + }); + } else { + const friendRequestData = { + sender: currentUserUid, + recipient: targetUserUid, + timestamp: firebase.firestore.FieldValue.serverTimestamp(), + }; + + const notificationData = { + recipient: targetUserUid, + sender: currentUserUid, + message: "You have received a friend request", + timestamp: firebase.firestore.FieldValue.serverTimestamp(), + }; + + batch.set(friendRequestRef, friendRequestData); + batch.set(notificationRef, notificationData); + + batch + .commit() + .then(() => { + const updatedDocuments = [...randomDocs]; + updatedDocuments[idx].friendRequestSent = true; + setRandomDocs(updatedDocuments); + enqueueSnackbar("Friend Request Sent", { + variant: "success", + }); + }) + .catch((error) => { + enqueueSnackbar(`Error Occurred: ${error}`, { + variant: "error", + }); + }); + } + }; + + const scroll = (scrollOffset) => { + scrollRef.current.scrollLeft += scrollOffset; + }; + + return ( +
    + +
      + {randomDocs.map((user, idx) => { + const { photoURL, username, name, uid, bio, friendRequestSent } = + user; + return ( +
    • navigate(`/user/${username}`)} + key={uid} + > + {name +
      +

      {name}

      +

      {bio ? bio : "..."}

      + {uid !== currentUser?.uid && ( + + )} +
      +
    • + ); + })} +
    + +
    + ); +}; + +export default Suggestion; diff --git a/src/components/imgPreview.css b/src/components/imgPreview.css deleted file mode 100644 index 68723a0be..000000000 --- a/src/components/imgPreview.css +++ /dev/null @@ -1,5 +0,0 @@ -.preview { - width: 150px; - height: auto; - padding: 50px; -} diff --git a/src/components/index.js b/src/components/index.js new file mode 100644 index 000000000..deede940a --- /dev/null +++ b/src/components/index.js @@ -0,0 +1,36 @@ +import NotFound from "../pages/NotFound"; + +import Caption from "./Caption"; +import ChatBox from "./CommunityChat"; +import EditProfile from "./EditProfile"; +import FriendsComponent from "./FriendsComponent"; +import GuestSignInBtn from "./Guest/GuestSignInBtn"; +import GuestSignUpBtn from "./Guest/GuestSignUpBtn"; +import ImgUpload from "./ImgUpload"; +import Navbar from "./Navbar"; +import Notifications from "./Notification"; +import Post from "./Post"; +import ReadMore from "./ReadMore"; +import SideBar from "./SideBar"; +import StoryView from "./Story"; +import Suggestion from "./Suggestions"; + +export { + Caption, + ChatBox, + EditProfile, + FriendsComponent, + GuestSignInBtn, + GuestSignUpBtn, + ImgUpload, + Navbar, + NotFound, + Notifications, + Post, + ReadMore, + SideBar, + StoryView, + Suggestion, +}; + +export default Post; diff --git a/src/components/postView/PostDetails.jsx b/src/components/postView/PostDetails.jsx new file mode 100644 index 000000000..cdd1ea655 --- /dev/null +++ b/src/components/postView/PostDetails.jsx @@ -0,0 +1,148 @@ +import { + Button, + Dialog, + DialogActions, + DialogContent, + DialogContentText, + DialogTitle, + IconButton, + Typography, +} from "@mui/material"; +import { + FavoriteBorderOutlined, + FavoriteOutlined, + ShareOutlined, +} from "@mui/icons-material"; +import { deletePost, savePost } from "../../js/postFn.js"; + +import BookmarkBorderIcon from "@mui/icons-material/BookmarkBorder"; +import BookmarksIcon from "@mui/icons-material/Bookmarks"; +import DeleteIcon from "@mui/icons-material/Delete"; +import Flexbetween from "../../reusableComponents/Flexbetween"; +import { ShareModal } from "../../reusableComponents"; +import { useNavigate } from "react-router-dom"; +import { useSnackbar } from "notistack"; +import { useState } from "react"; + +const PostDetails = ({ + user, + postId, + postUserUid, + likecount, + likesHandler, + imageUrl, + caption, + fullScreen, +}) => { + const [open, setOpen] = useState(false); + const [openShareModal, setOpenShareModal] = useState(false); + const [favoritePosts, setFavoritePosts] = useState( + JSON.parse(localStorage.getItem("posts")) || [], + ); + const tempLikeCount = likecount ? [...likecount] : []; + const { enqueueSnackbar } = useSnackbar(); + const currentUserUid = user.uid; + const navigate = useNavigate(); + + return ( + <> + {" "} + + + + {tempLikeCount.indexOf(user?.uid) !== -1 ? ( + + ) : ( + + )} + + + {likecount?.length} {likecount.length > 1 ? "likes" : "like"} + + + + { + setOpenShareModal((prev) => !prev); + }} + > + + + + Share + + + { + const data = await savePost(postId); + setFavoritePosts(data); + }} + > + + {favoritePosts.indexOf(postId) !== -1 ? ( + + ) : ( + + )} + + Save + + + {currentUserUid === postUserUid && ( + setOpen((prev) => !prev)} + > + + + + Delete + + )} + + setOpen(false)} + aria-labelledby="responsive-dialog-title" + > + {"Delete Post?"} + + + Are you sure you want to delete this post? + + + + + + + + {openShareModal && ( + + )} + + ); +}; + +export default PostDetails; diff --git a/src/components/postView/index.css b/src/components/postView/index.css new file mode 100644 index 000000000..bf7877876 --- /dev/null +++ b/src/components/postView/index.css @@ -0,0 +1,108 @@ +.post-page-container { + height: auto !important; +} + +.post_view_container { + border: 1px solid #eee; + box-shadow: var(--post-box-shadow); + border-radius: 10px; + width: 100%; + max-width: 750px; + padding: 10px; + margin-bottom: 100px; +} + +.post_view_sub_container { + width: 100%; + display: flex; + flex-direction: column; + gap: 10px; +} + +.post_view_header_container { + display: flex; + align-items: center; + gap: 20px; +} + +.post_view_avatar { + width: 50px; + height: 50px; + border-radius: 8px; + box-shadow: var(--post-box-shadow); + transition: 0.1s ease-in-out; +} + +.post_view_avatar:hover { + transform: scale(1.04); +} + +.post_view_user_name { + font-weight: 600; + cursor: pointer; +} + +.post_view_user_name:hover { + text-decoration: underline; +} + +.post_view_time { + color: var(--profile-color); +} + +.post_view_img_container { + height: 500px; + border-radius: 8px; +} + +.post_view_post_without_img { + width: 100%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; + border-radius: 8px; +} + +.post_view_post_nav_container { + padding: 15px; + z-index: 99; +} + +.post_view_comment_container { + padding: 0; +} + +.post_view_comment_list_item { + list-style: none; + display: flex; + /* border: 1px solid #eee; */ + padding: 10px; + border-radius: 8px; + gap: 15px; +} + +.post_view_comment_img { + width: 40px; + height: 40px; + border-radius: 50%; + border: 1px solid #eee; +} + +.post_view_comment_img_name { + cursor: pointer; +} + +.post_view_comment_img_name:hover { + text-decoration: underline; +} + +@media only screen and (max-width: 500px) { + .post_view_avatar { + margin-left: 10px; + } + + .post_view_post_nav_container { + padding: 0; + } +} diff --git a/src/components/postView/index.jsx b/src/components/postView/index.jsx new file mode 100644 index 000000000..b81390199 --- /dev/null +++ b/src/components/postView/index.jsx @@ -0,0 +1,312 @@ +import "./index.css"; + +import { + Button, + Dialog, + DialogActions, + DialogContent, + DialogContentText, + DialogTitle, +} from "@mui/material"; +import React, { useEffect, useState } from "react"; +import { doc, updateDoc } from "firebase/firestore"; + +import BlankImg from "../../assets/blank-profile.webp"; +import CommentBox from "../Post/CommentBox"; +import DeleteTwoToneIcon from "@mui/icons-material/DeleteTwoTone"; +import { db } from "../../lib/firebase.js"; +import { deleteComment } from "../../js/postFn"; +import firebase from "firebase/compat/app"; +import useCreatedAt from "../../hooks/useCreatedAt.jsx"; +import { useNavigate } from "react-router-dom"; + +const ImageSlider = React.lazy( + () => import("../../reusableComponents/ImageSlider"), +); +const PostDetails = React.lazy(() => import("./PostDetails.jsx")); + +const PostCommentView = ({ setFetchAgain, fetchAgain, postId, user, post }) => { + const navigate = useNavigate(); + const [openToDeleteComment, setOpenToDeleteComment] = useState(false); + const { + username, + caption, + imageUrl, + avatar, + likecount, + timestamp, + uid, + displayName, + background, + } = post; + const time = useCreatedAt(timestamp); + const defaultBg = `linear-gradient(130deg, #dee2ed, #dee2ed, #9aa9d1, #b6c8e3, #b6afd0, #d3c0d8)`; + + const [comments, setComments] = React.useState(null); + const [comment, setComment] = useState(""); + const [tempLikeCount, setTempLikeCount] = useState(post.likecount || []); + const [userData, setUserData] = useState({}); + const [showEmojis, setShowEmojis] = React.useState(false); + const docRef = doc(db, "posts", postId); + + async function likesHandler() { + if (user && likecount !== undefined) { + const tempArr = tempLikeCount; + let ind = tempLikeCount.indexOf(user.uid); + + if (ind !== -1) { + tempArr.splice(ind, 1); + setTempLikeCount(tempArr); + } else { + tempArr.push(user.uid); + setTempLikeCount(tempArr); + } + + const data = { + likecount: tempArr, + }; + await updateDoc(docRef, data) + .then(() => setFetchAgain(!fetchAgain)) + .catch((error) => { + console.error("Error updating document: ", error); + }); + } + } + + useEffect(() => { + async function getUsername() { + try { + const docRef = db.collection("users").doc(user?.uid); + const docSnap = await docRef.get(); + if (docSnap.exists) { + const data = docSnap.data(); + setUserData({ + username: data?.username || auth.currentUser?.uid, + }); + } + } catch (error) { + console.error("Error fetching user data:", error); + setUserData({ + username: user?.uid, + }); + } + } + getUsername(); + }, []); + + const postComment = (event) => { + event.preventDefault(); + try { + db.collection("posts").doc(postId).collection("comments").add({ + text: comment, + username: userData?.username, + displayName: user?.displayName, + avatar: user?.photoURL, + timestamp: firebase.firestore.FieldValue.serverTimestamp(), + }); + } catch (err) { + console.error(err); + } finally { + setComment(""); + } + }; + + useEffect(() => { + setFetchAgain(!fetchAgain); + }, []); + + useEffect(() => { + let unsubscribe; + + if (postId) { + unsubscribe = db + .collection("posts") + .doc(postId) + .collection("comments") + .orderBy("timestamp", "desc") + .onSnapshot((snapshot) => { + setComments( + snapshot.docs.map((doc) => ({ + id: doc.id, + content: doc.data(), + })), + ); + }); + } + return () => { + if (unsubscribe) { + unsubscribe(); + } + }; + }, [postId]); + + /** + * @type {{ + * imageUrl: null|string, + * imageWidth: number, + * imageHeight: number, + * thumbnail: null | string + * }[]} + * + */ + let postImages; + + try { + postImages = JSON.parse(imageUrl); + } catch { + postImages = imageUrl.split(",").map((url) => ({ + imageUrl: url, + imageWidth: 0, + imageHeight: 0, + thumbnail: null, + })); + } + + const postHasImages = postImages.some((image) => Boolean(image.imageUrl)); + const onEmojiClick = (emojiObject) => { + setComment((prevInput) => prevInput + emojiObject.emoji); + setShowEmojis(false); + }; + + return ( +
    +
    +
    + 0 ? avatar : BlankImg} + alt={displayName} + className="post_view_avatar" + onClick={() => navigate(`/user/${username}`)} + /> + +

    navigate(`/user/${username}`)} + > + {displayName} +

    +

    {time}

    +
    +
    +
    + {postHasImages ? ( + <> +

    {caption}

    + + + ) : ( +
    + {caption} +
    + )} +
    +
    + +
    +
    + +
    +
    + {comments?.length ? ( +
      + {comments.map(({ id, content }) => ( +
    • + {content.displayName} navigate(`/user/${content.username}`)} + /> +
      +

      navigate(`/user/${content.username}`)} + > + {content.displayName} +

      +

      {content.text}

      +
      +
      { + setOpenToDeleteComment(!openToDeleteComment); + }} + style={{ marginLeft: "auto" }} + > + {userData?.username == content.username && ( + + )} + { + setOpenToDeleteComment(false)} + aria-labelledby="responsive-dialog-title" + > + + {"Delete Comment?"} + + + + Are you sure you want to delete this Comment? + + + + + + + + } +
      +
    • + ))} +
    + ) : ( +

    + No Comments to Show!! +

    + )} +
    +
    +
    + ); +}; +export default PostCommentView; diff --git a/src/hooks/useCreatedAt.jsx b/src/hooks/useCreatedAt.jsx new file mode 100644 index 000000000..6ea55f624 --- /dev/null +++ b/src/hooks/useCreatedAt.jsx @@ -0,0 +1,40 @@ +import { useEffect, useState } from "react"; + +const useCreatedAt = (postTimestamp) => { + const [time, setTime] = useState(""); + + useEffect(() => { + const calculateTime = () => { + if (!postTimestamp) return ""; // Handle null or undefined case + + const postDate = postTimestamp.toDate(); + const currentDate = new Date(); + const timeDiff = currentDate.getTime() - postDate.getTime(); + const seconds = Math.floor(timeDiff / 1000); + const minutes = Math.floor(seconds / 60); + const hours = Math.floor(minutes / 60); + const days = Math.floor(hours / 24); + + if (days > 0) { + if (days === 1) { + return "Yesterday"; + } else { + const options = { year: "numeric", month: "long", day: "numeric" }; + return postDate.toLocaleDateString(undefined, options); + } + } else if (hours > 0) { + return `${hours} hour${hours !== 1 ? "s" : ""} ago`; + } else if (minutes > 0) { + return `${minutes} minute${minutes !== 1 ? "s" : ""} ago`; + } else { + return `${seconds} second${seconds !== 1 ? "s" : ""} ago`; + } + }; + + setTime(calculateTime()); + }, [postTimestamp]); + + return time; +}; + +export default useCreatedAt; diff --git a/src/hooks/useRowMode.jsx b/src/hooks/useRowMode.jsx new file mode 100644 index 000000000..29353de7c --- /dev/null +++ b/src/hooks/useRowMode.jsx @@ -0,0 +1,3 @@ +import { createContext } from "react"; + +export const RowModeContext = createContext(false); diff --git a/src/index.css b/src/index.css index a5b32a6dc..f9ba9640a 100644 --- a/src/index.css +++ b/src/index.css @@ -1,244 +1,272 @@ @import url("https://fonts.googleapis.com/css2?family=Poppins:wght@100;200;300;400;500;600;700;800;900&display=swap"); +:root { + --bg-color: rgb(255, 255, 255); + --text-primary: blue; + --text-secondary: black; + --color: rgb(0, 0, 0); + --logo-text-shadow: none; + --filter-img: none; + --sidebar-link-hover: rgba(0, 0, 0, 0.05); + --post-box-shadow: 0px 0px 5px 1px rgba(0, 0, 0, 0.4); + --post-nav-icons: ""; + --emoji-btn: black; + --profile-container: #f4eeff; + --profile-box-shadow: 0 0 6px 0 black; + --logo-text-shadow: none; + --btn-color: linear-gradient(-40deg, #72cbf7, #5f85db); + --btn-color-hover: linear-gradient(40deg, #5f85db, #72cbf7); + --btn-hover: #5f85db; + --page-over-color: #00bfff; + --slide-color: #dfffd8; + --label-color: rgb(200, 246, 248); + --profile-color: #7d7575; + --text-light: rgba(0, 0, 0, 0.6); + --text-light-black: rgba(0, 0, 0, 0.6); + --text-dim: rgba(0, 0, 0, 0.8); + --post-error-boundary: rgba(0, 0, 0, 0.54); + --text-black-only: black; + --dark-post-bg: rgb(255, 255, 255); + --link-color: #068fff; + --pagination-border: rgba(0, 0, 0, 0.23); + --text-grey: rgba(0, 0, 0, 0.8); + --theme-hover: rgba(8, 17, 123, 0.69); + --shimmer-bg: #e1dede; + --input-bg: #eee; +} + +.darkmode { + --bg-color: black; + --text-primary: rgb(255, 255, 255); + --text-secondary: white; + --color: rgb(226, 226, 226); + /* --logo-text-shadow: 0 0 7px #eeeeee, 0 0 10px #ff4da6, 0 0 20px #ff4da6; */ + --logo-text-shadow: none; + --filter-img: invert(100%); + --sidebar-link-hover: rgba(255, 255, 255, 0.15); + --post-box-shadow: 0px 0px 5px 1px rgba(255, 255, 255, 0.4); + --post-nav-icons: white; + --emoji-btn: rgb(240, 240, 123); + --profile-container: rgb(50, 48, 48); + --profile-box-shadow: 0 0 6px white; + /* --logo-text-shadow: 0 0 10px #eeeeee, 0 0 20px #5F85DB, 0 0 30px #fff; */ + --btn-color: linear-gradient(40deg, #5f85db, #72cbf7); + --btn-color-hover: linear-gradient(-40deg, #72cbf7, #5f85db); + --btn-hover: #5f85db; + --page-over-color: #26282b; + --slide-color: #041c32; + --label-color: #6a656b; + --profile-color: #c8c6c6; + --text-black-only: black; + --text-light: rgba(255, 255, 255, 0.6); + --text-light-black: rgba(0, 0, 0, 0.6); + --text-dim: rgba(255, 255, 255, 0.8); + --post-error-boundary: rgba(255, 255, 255, 0.54); + --darkmode-white: white; + --dark-post-bg: #191919; + --link-color: #068fff; + --pagination-border: rgba(255, 255, 255, 0.23); + --text-grey: rgba(255, 255, 255, 0.8); + --theme-hover: rgb(244, 210, 41); + --shimmer-bg: #535256; + --input-bg: #191919; +} + * { - margin: 0; font-family: "Poppins", sans-serif; + margin: 0; +} + +body { + background-color: var(--bg-color) !important; } /* App styles */ .app { - /* background-color: var(--bg-color); */ - justify-content: center; align-items: center; + justify-content: center; overflow-x: auto; + overflow: hidden; } -.app__header__img { - object-fit: contain; - width: 150px; -} - -.app__header { - position: fixed; - width: 100%; - top: 0; - z-index: 1; - padding-top: 10px; - padding-bottom: 10px; - object-fit: contain; - border-bottom: 1px solid var(--color); - display: flex; - justify-content: space-between; - align-items: center; - flex-wrap: wrap; - background-color: var(--bg-color); +.sidebar_wrapper { + margin-top: 72px; + margin-left: 17vw; } -.app__posts { - padding: 20px; - padding-top: 5.5em; +@media screen and (max-width: 1200px) { + .sidebar_wrapper { + margin-left: 8vw; + } } -/* Post style */ -.post { - max-width: 400px; - border: 1px solid rgba(0, 0, 0, 0.373); - border-radius: 5px; - margin-bottom: 20px; - word-wrap: break-word; +@media screen and (max-width: 800px) { + .sidebar_wrapper { + margin-left: 0; + } } -.post__img { - object-position: top; - max-width: 100%; - width: 100%; - object-fit: contain; +.shimmer_bg { + background-color: var(--shimmer-bg) !important; } -.post__img_container { - overflow-x: hidden; +input:hover { + cursor: text; } -.post__img_container:only-of-type .post__img { - border-top: 1px solid rgba(215, 208, 208, 0.845); - border-bottom: 1px solid rgba(72, 6, 91, 0.281); +input:focus { + outline: none; } -.post__text { - font-weight: normal; - padding: 5px 15px; - font-size: 15px; - text-align: left; +/* Add media query in navbar for responsiveness */ +@media only screen and (max-width: 460px) { + .app__header { + font-size: 8px; + padding: 10px; + width: 100%; + } } -.post__username { - font-size: 14px; - font-weight: 600; +/* Post style */ +.app_posts { + padding: 1.5em 17vw 20px 0vw; } -.post__header { - display: flex; +.app_posts_column { align-items: center; - justify-content: space-between; - padding: 10px; - flex-wrap: wrap; + display: flex; + flex-direction: column; + justify-content: center; } -.social__icons__wrapper { +.rowConvert, +.searchbar { + color: var(--text-secondary); display: flex; - align-items: center; + margin-right: 12px; + transition: all; + transition-duration: 200ms; + transition-timing-function: cubic-bezier(0.4, 0, 1, 1); } -.social__icon { - padding: 10px; - width: 24px; - height: 28px; +.rowConvert:hover, +.searchbar:hover { + color: var(--btn-hover); + cursor: pointer; + transform: scale(1.04); } -.social__icon__last { - padding: 10px; - margin-left: auto !important; +@media only screen and (max-width: 1300px) { + .home-posts-container .app_posts { + padding: 1.5em 15px 20px 10px; + } + .post-card { + margin: 50px auto !important; + } +} +@media only screen and (max-width: 800px) { + .app_posts, + .home-posts-container .app_posts_column { + padding: 5.5em 15px 5.5em 15px; + display: flex; + flex-direction: column; + align-items: center; + gap: 1em; + } } -.post__avatar { - margin-right: 10px; - border-radius: 50%; - width: 30px !important; - height: 30px !important; +@media only screen and (max-width: 900px) { + .rowConvert { + display: none; + } +} +@media only screen and (max-width: 700px) { + .app_posts { + padding-inline: auto; + } +} +.post__img { + max-width: 100%; object-fit: contain; + object-position: top; + width: 100%; } -.post__commentBox { - display: flex; - margin-top: 10px; - border-top: 1px solid rgba(0, 0, 0, 0.373); - flex-wrap: wrap; +.post__img_container { + overflow-x: hidden; } -.post__input { - border: none; - flex: 1; - padding: 10px; - font-size: 16px; - background-color: rgb(145, 237, 203); +.post__img_container:only-of-type .post__img { + border-bottom: 1px solid rgba(5, 132, 132, 0.281); + border-top: 1px solid rgba(215, 208, 208, 0.845); } -.post__button { - flex: 0; - border: none; - - color: #0a66c2; - /* color: #6082a3; */ - cursor: pointer; - background: transparent; -} - -.post__background { - min-height: 250px; - background: linear-gradient( - 45deg, - #abdb10, - #cbdb51, - #ce2a11, - #e263ab, - #30e19d, - #a1d9c9 - ); - color: rgb(145, 230, 227); - justify-content: center; - display: flex; - align-items: center; +.post__username { + font-size: 14px; font-weight: 600; - position: relative; } -.post__comments { - padding: 0 15px; - display: flex; - flex-direction: column; - align-items: flex-start; - font-size: 15px; -} - -/* signup modal */ -.img-outer { - display: flex; +.post__header { + position: relative; align-items: center; - justify-content: center; - height: 120px; - width: 120px; - border-radius: 50%; - box-shadow: 0 0 20px var(--color-shadow); - cursor: pointer; -} - -.img-outer .img-inner { - font-size: 13px; display: flex; - align-items: center; - justify-content: center; - height: calc(100% - 15px); - width: calc(100% - 15px); - border-radius: 50%; - overflow: hidden; - transition: 1s ease-in-out; -} - -.img-inner:hover { - background-color: #ddd; - transition: 0.5s ease-in-out; + flex-wrap: wrap; + padding-inline: 10px; + padding-top: 0; } -.img-inner img { +.post__avatar { border-radius: 50%; + height: 40px !important; + width: 40px !important; + margin-right: 10px; + object-fit: contain; } .modal__signup__img { width: 80%; + border-radius: 0.3rem; + margin-bottom: 10px; } .modal__signup { display: flex; + justify-content: center; flex-direction: column; - align-items: center; } .modal__signup button { margin-top: 10px; } -/* image upload css */ -.imageUpload { - position: sticky; - bottom: 0px; - display: flex; - flex-direction: column; +/* notification card */ +.notification_card { width: 100%; - gap: 10px; - margin-left: auto; - margin-right: auto; - margin-top: 10px; - margin-bottom: 10px; + margin: 5px 10px; + background-color: rgb(193, 0, 0); + color: white; + border-radius: 10px; + padding: 5px; } +/* image upload css */ .imageUpload-progress { width: 100%; } .scrollTop { position: fixed; - width: 60px; - bottom: 20px; - left: 50%; - align-self: center; - height: 60px; - justify-content: center; - z-index: 1000; + position: relative; + bottom: 12%; + height: 50px; + width: 50px; + margin-left: 90%; cursor: pointer; - animation: fadeIn 0.2s; - transition: opacity 0.4s; - display: flex; - opacity: 0.9; + opacity: 0.7; +} + +.centeredScroll { + margin-left: 40%; } .scrollTop:hover { @@ -246,58 +274,78 @@ } /* Extra small devices (phones, 600px and down) */ -@media only screen and (max-width: 600px) { +@media only screen and (max-width: 790px) { .scrollTop { - left: 43%; + margin-bottom: 8%; + } + .app__newpost__button { + left: -6%; + } + .home-posts-container .app_posts { + padding: 1.5em 15px 5em 15px; + } + .search-modal { + width: 80vw; + } + .search-bar { + width: 80%; } } /* Small devices (portrait tablets and large phones, 600px and up) */ @media only screen and (min-width: 600px) { - .scrollTop { - left: 45.6%; + .app__newpost__button { + left: -4.8%; } } /* Medium devices (landscape tablets, 768px and up) */ @media only screen and (min-width: 768px) { - .scrollTop { - left: 46.6%; + .app__newpost__button { + left: -4.2%; + } + .search-modal { + width: 600px; + } + .search-bar { + width: 60%; } } /* Large devices (laptops/desktops, 992px and up) */ -@media only screen and (min-width: 992px) { - .scrollTop { - left: 47.2%; +@media only screen and (min-width: 911px) { + .app__newpost__button { + left: -2.5%; } } /* Extra large devices (large laptops and desktops, 1200px and up) */ -@media only screen and (min-width: 1200px) { - .scrollTop { - left: 47.7%; +@media only screen and (min-width: 800px) { + .app_posts { + display: flex; + flex-wrap: wrap; + gap: 2rem; + justify-content: center; + } + .post-card { + margin: 50px auto !important; + } + .app__newpost__button { + left: -1.2%; } } -.read__more__less { - text-decoration: underline; - cursor: pointer; - color: rgba(17, 3, 46, 0.4); -} - -.read__more__less:hover { - color: rgb(6, 33, 115); +@media (min-width: 1200px) { + .scrollTop { + margin-left: 94%; + bottom: 11%; + } } .darkmode-toggle { z-index: 1; } -.app { - overflow: hidden; -} - @keyframes fadeIn { 0% { opacity: 0; @@ -309,62 +357,45 @@ } div#picker { + left: -7px; position: relative; top: -353px; - left: -7px; transform: scale(0.9); } /* profile pic upload input */ .file { - opacity: 0; - width: 0.1px; height: 0.1px; + opacity: 0; position: absolute; -} - -.file-input label { - display: block; - position: relative; - margin-top: 15px; - width: 200px; - height: 40px; - border-radius: 20px; - background: linear-gradient(40deg, #e107c1, #59afc7); - box-shadow: 0 4px 7px rgba(0, 0, 0, 0.4); - display: flex; - align-items: center; - justify-content: center; - color: #ffffff; - font-weight: bold; - cursor: pointer; - transition: transform 0.2s ease-out; + width: 0.1px; + display: none; } ::-webkit-scrollbar { - width: 0.8rem; + border-radius: 0.3rem; + width: 0.3rem; } ::-webkit-scrollbar-track { - background-color: black; + background-color: rgb(255, 255, 255); + border-radius: 0.8rem; } ::-webkit-scrollbar-thumb { - background: linear-gradient(40deg, #e107c1, #59afc7); - border-radius: 10px; - border: 2px black solid; + background: var(--color); + border-radius: 2em; } /* landing animation */ - #logo { - width: 0px; + animation: animate 4s ease forwards; + filter: invert(0.5) sepia(1) saturate(5) hue-rotate(175deg); + left: 50%; position: absolute; top: 50%; - left: 50%; transform: translate(-50%, -50%); - animation: animate 4s ease forwards; - filter: invert(0.5) sepia(1) saturate(5) hue-rotate(175deg); + width: 0px; z-index: 1; } @@ -377,93 +408,194 @@ div#picker { /* Login button */ .button { - cursor: pointer; border: 0; border-radius: 4px; + box-shadow: 0 0 20px rgba(104, 85, 224, 0.2); + cursor: pointer; font-weight: 600; - width: 100%; padding: 10px 0; - box-shadow: 0 0 20px rgba(104, 85, 224, 0.2); transition: 0.4s; + width: 100%; } .button:hover { - color: white; - box-shadow: 0 0 20px rgba(104, 85, 224, 0.6); background-color: rgba(104, 85, 224, 1); + box-shadow: 0 0 20px rgba(104, 85, 224, 0.6); + color: white; } -/* sign in button */ .reg:hover { - color: black; - box-shadow: 0 0 20px rgba(104, 85, 224, 0.6); background-color: rgba(255, 255, 255, 1); + box-shadow: 0 0 20px rgba(104, 85, 224, 0.6); + color: black; } .reg span { - color: rgb(104, 85, 224); border-bottom: 2px solid rgb(104, 85, 224); -} - -/* login button */ -.log { color: rgb(104, 85, 224); - background-color: rgba(255, 255, 255, 1); - border: 1px solid rgba(104, 85, 224, 1); -} - -.signup { - color: white; - box-shadow: 0 0 20px rgba(104, 85, 224, 0.6); - background-color: rgba(104, 85, 224, 1); -} - -.signup:hover { - color: rgb(104, 85, 224); - box-shadow: 0 0 20px rgba(104, 85, 224, 0.6); - background-color: rgb(255, 255, 255); } /* Input */ input { - width: 230px; - cursor: pointer; - border: 0; + border: 1px solid rgba(104, 85, 224, 1); border-radius: 4px; + box-shadow: 0 0 20px rgba(104, 85, 224, 0.2); + cursor: pointer; font-weight: 600; - padding: 10px; margin-top: 10px; - box-shadow: 0 0 20px rgba(104, 85, 224, 0.2); - border: 1px solid rgba(104, 85, 224, 1); + padding: 10px; transition: 0.4s; + width: 230px; } -/*login screen sapration line */ +/*login screen separation line */ .or { - width: 230px; - display: flex; align-items: center; + display: flex; + width: 230px; } .line { - width: 100%; border-bottom: 2px solid rgb(104, 85, 224); + width: 100%; } /* login with google or facebook button */ + .google-fb-login button { font-size: 22px; + height: 50px; margin: 5px; width: 50px; - height: 50px; } + .have-account { color: var(--color); - font-size: 13px; + font-size: 15px; margin: 10px 0; + font-weight: bold; } + .have-account span { color: rgb(104, 85, 224); - border-bottom: 2px solid rgb(104, 85, 224); cursor: pointer; + font-weight: bold; +} + +.have-account span:hover { + color: var(--btn-color-hover); +} + +.login-footer { + align-items: center; + display: flex; + flex-direction: row; + justify-content: space-between; +} + +.button-style { + background: var(--btn-color); + border-radius: 20px; + margin: 10px; +} + +.button-style:hover { + background: var(--btn-color-hover); +} + +.no-comments, +.light-text, +.post-page-caption span { + color: var(--text-light); +} +.create-post-input label { + color: var(--darkmode-white); +} + +/* end */ + +/* login sign up forms */ +.page-over { + height: 100%; + width: 100%; + display: flex; + align-items: center; + justify-content: center; + min-height: 100vh; +} +.login__section { + max-width: 1360px; + min-width: 300px; + width: calc(100vw - 40px); + /* border: 1px solid red; */ + margin-inline: 20px; +} +.other__login { + margin: 0 auto; +} + +/* POST COMMENT */ +.post_comment_text span:nth-child(2) { + font-weight: 600 !important; +} +.post_comment_header, +.post_comment_area { + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; +} +.post_comment_area .post_comment_text { + width: 88%; +} +.post_comment_area button { + width: 10%; +} +.post_comment_header p { + font-size: 0.9rem; +} +.post_comment_area { + padding-top: 6px; +} +.post_comment_header button, +.post_comment_area p { + display: none; +} +.post_comment_area span:first-of-type { + font-weight: normal; +} + +/* auth container */ + +.login__left { + overflow-y: scroll; +} + +@media only screen and (max-width: 840px) { + .page-over { + align-items: flex-start; + } +} + +@media only screen and (max-width: 700px) { + .login__left { + height: 100%; + overflow-y: visible; + padding: 0; + } +} + +@media only screen and (min-height: 900px) and (min-width: 840px) { + .login__right__sub__container { + top: 230px !important; + } + + .login__left { + align-items: flex-start !important; + } +} + +.post, +.postColumn { + background-color: var(--dark-post-bg); } diff --git a/src/js/deleteImg.js b/src/js/deleteImg.js new file mode 100644 index 000000000..4b89bee1a --- /dev/null +++ b/src/js/deleteImg.js @@ -0,0 +1,14 @@ +import { storage } from "../lib/firebase"; + +export default async function deleteImg(imageUrl) { + if (imageUrl && imageUrl !== "") { + const imageRef = storage.refFromURL(imageUrl); + try { + await imageRef.delete(); + return true; + } catch (err) { + return false; + } + } + return false; +} diff --git a/src/js/postFn.js b/src/js/postFn.js new file mode 100644 index 000000000..bd94f4eed --- /dev/null +++ b/src/js/postFn.js @@ -0,0 +1,80 @@ +import firebase from "firebase/compat/app"; + +import { db, storage } from "../lib/firebase"; + +import { playErrorSound, playSuccessSound } from "./sounds"; + +export const deletePost = async ( + uid, + postId, + imageUrl, + enqueueSnackbar, + setOpen, +) => { + try { + await db + .runTransaction(async (transaction) => { + // Delete doc ref from user doc + const docRef = db.collection("users").doc(uid); + transaction.update(docRef, { + posts: firebase.firestore.FieldValue.arrayRemove(postId), + }); + + // Delete the post document + const postRef = db.collection("posts").doc(postId); + transaction.delete(postRef); + }) + .then(async () => { + if (imageUrl !== "") { + const url = JSON.parse(imageUrl); + const deleteImagePromises = url.map(({ imageUrl }) => { + const imageRef = storage.refFromURL(imageUrl); + return imageRef.delete(); + }); + await Promise.all(deleteImagePromises); + } + }) + .then(() => { + playSuccessSound(); + enqueueSnackbar("Post deleted successfully!", { variant: "success" }); + setOpen(false); + }); + } catch (error) { + playErrorSound(); + enqueueSnackbar(`Error deleting post: ${error}`, { variant: "error" }); + } +}; + +export const savePost = async (postId) => { + let localStoragePosts = JSON.parse(localStorage.getItem("posts")) || []; + const postIdExists = localStoragePosts.includes(postId); + + if (!postIdExists) { + localStoragePosts.push(postId); + localStorage.setItem("posts", JSON.stringify(localStoragePosts)); + } else { + localStoragePosts = localStoragePosts.filter((post) => post !== postId); + localStorage.setItem("posts", JSON.stringify(localStoragePosts)); + } + return JSON.parse(localStorage.getItem("posts")); +}; + +export const deleteComment = async (postId, commentId, enqueueSnackbar) => { + try { + await db + .collection("posts") + .doc(postId) + .collection("comments") + .doc(commentId) + .delete() + .then(() => { + playSuccessSound(); + enqueueSnackbar("Comment deleted successfully!", { + variant: "success", + }); + }); + } catch (error) { + playErrorSound(); + enqueueSnackbar(`Error deleting comment: ${error}`, { variant: "error" }); + } +}; diff --git a/src/js/signIn.js b/src/js/signIn.js new file mode 100644 index 000000000..e3a5e29fe --- /dev/null +++ b/src/js/signIn.js @@ -0,0 +1,51 @@ +import { auth, db, facebookProvider, googleProvider } from "../lib/firebase"; + +import { playErrorSound, playSuccessSound } from "./sounds"; + +const signInWithOAuth = (e, enqueueSnackbar, navigate, google = true) => { + e.preventDefault(); + const provider = google ? googleProvider : facebookProvider; + auth + .signInWithPopup(provider) + .then(async (val) => { + const userRef = db.collection("users").where("uid", "==", val?.user?.uid); + + const docSnap = await userRef.get(); + if (docSnap.docs.length < 1) { + const usernameDoc = db.collection("users"); + await usernameDoc.doc(auth.currentUser.uid).set({ + uid: val.user.uid, + username: val.user.uid, + name: val.user.displayName, + photoURL: val.user.photoURL, + displayName: val.user.displayName, + Friends: [], + posts: [], + }); + } else if (!docSnap.docs[0].data().username) { + docSnap.docs[0].ref.update({ + username: doc.data().uid, + }); + } + playSuccessSound(); + enqueueSnackbar("Login successful!", { + variant: "success", + }); + navigate("/"); + }) + .catch((error) => { + if (error.code === "auth/account-exists-with-different-credential") { + playErrorSound(); + enqueueSnackbar("Account exists with a different credential", { + variant: "error", + }); + } else { + playErrorSound(); + enqueueSnackbar(error.message, { + variant: "error", + }); + } + }); +}; + +export default signInWithOAuth; diff --git a/src/js/sounds.jsx b/src/js/sounds.jsx new file mode 100644 index 000000000..f4ef947ee --- /dev/null +++ b/src/js/sounds.jsx @@ -0,0 +1,42 @@ +import { + errorSound, + successSound, + backBtnSound, + lightOnSound, + lightOffSound, +} from "../assets/sounds"; + +export function playSuccessSound() { + const sound = localStorage.getItem("sound"); + if (!sound) { + new Audio(successSound).play(); + } +} + +export function playErrorSound() { + const sound = localStorage.getItem("sound"); + if (!sound) { + new Audio(errorSound).play(); + } +} + +export function playTapSound() { + const sound = localStorage.getItem("sound"); + if (!sound) { + new Audio(backBtnSound).play(); + } +} + +export function playLightOnSound() { + const sound = localStorage.getItem("sound"); + if (!sound) { + new Audio(lightOnSound).play(); + } +} + +export function playLightOffSound() { + const sound = localStorage.getItem("sound"); + if (!sound) { + new Audio(lightOffSound).play(); + } +} diff --git a/src/js/userData.js b/src/js/userData.js new file mode 100644 index 000000000..bd50ae698 --- /dev/null +++ b/src/js/userData.js @@ -0,0 +1,35 @@ +import { auth, db } from "../lib/firebase"; + +export default async function getUserSessionData(getRef) { + const user = auth?.currentUser; + let userData = sessionStorage.getItem("userData"); + let userDocRef = sessionStorage.getItem("userDataDocRef"); + if (getRef && userDocRef) { + return JSON.parse(userDocRef); + } + if (userData) { + userData = JSON.parse(userData); + return userData; + } else { + const docRef = db.collection("users").doc(user?.uid); + const docSnap = await docRef.get(); + sessionStorage.setItem("userDataDocRef", JSON.stringify(docSnap)); + if (docSnap.exists) { + const data = docSnap.data(); + sessionStorage.setItem("userData", JSON.stringify(data)); + return getRef ? docSnap : data; + } + } + return userData; +} + +export function setUserSessionData(newData) { + let oldData = sessionStorage.getItem("userData"); + oldData = oldData ? JSON.parse(oldData) : {}; + + const data = { + ...oldData, + ...newData, + }; + sessionStorage.setItem("userData", JSON.stringify(data)); +} diff --git a/src/lib/firebase.js b/src/lib/firebase.js index a251d4f97..ea6a47f95 100644 --- a/src/lib/firebase.js +++ b/src/lib/firebase.js @@ -1,7 +1,8 @@ -import firebase from "firebase/compat/app"; import "firebase/compat/auth"; import "firebase/compat/firestore"; import "firebase/compat/storage"; + +import firebase from "firebase/compat/app"; import { v4 as uuid } from "uuid"; const firebaseApp = firebase.initializeApp({ @@ -11,7 +12,6 @@ const firebaseApp = firebase.initializeApp({ storageBucket: import.meta.env.VITE_DUMMYGRAM_STORAGEBUCKET, messagingSenderId: import.meta.env.VITE_DUMMYGRAM_MESSAGINGSENDERID, appId: import.meta.env.VITE_DUMMYGRAM_APPID, - measurementId: import.meta.env.VITE_DUMMYGRAM_MEASUREMENTID, }); // Use these for db & auth @@ -27,6 +27,7 @@ const storage = firebase.storage(); * onUploadProgress: (percentage: number) => void * }} options */ + function handleMultiUpload(files, options = {}) { const _options = Object.assign( { @@ -38,7 +39,7 @@ function handleMultiUpload(files, options = {}) { onUploadProgress: (_percentage) => {}, generateThumbnails: false, }, - options + options, ); let totalSize = 0; @@ -70,7 +71,7 @@ function handleMultiUpload(files, options = {}) { lastUploadedSize = snapshot.bytesTransferred; _options.onUploadProgress( - Math.round((totalUploaded / totalSize) * 100) + Math.round((totalUploaded / totalSize) * 100), ); }, (error) => { @@ -128,7 +129,7 @@ function handleMultiUpload(files, options = {}) { .catch((error) => { reject(error); }); - } + }, ); }); }); diff --git a/src/main.jsx b/src/main.jsx index 2011f6cbe..15f9a272f 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -1,23 +1,23 @@ +import "./index.css"; + +import { SnackbarProvider, useSnackbar } from "notistack"; +import { ThemeProvider, createTheme } from "@mui/material/styles"; + +import App from "./App"; +import { HashRouter } from "react-router-dom"; import { Close } from "@mui/icons-material"; import { IconButton } from "@mui/material"; -import { createTheme, ThemeProvider } from "@mui/material/styles"; -import { SnackbarProvider, useSnackbar } from "notistack"; import React from "react"; import ReactDOM from "react-dom/client"; -import { BrowserRouter } from "react-router-dom"; -import App from "./App"; -import "./index.css"; -import LandingAnimation from "./components/LandingAnimation"; const theme = createTheme(); ReactDOM.createRoot(document.getElementById("root")).render( - - + - + - + , ); diff --git a/src/pages/Chat/index.css b/src/pages/Chat/index.css new file mode 100644 index 000000000..e69de29bb diff --git a/src/pages/Chat/index.jsx b/src/pages/Chat/index.jsx new file mode 100644 index 000000000..a26604aa1 --- /dev/null +++ b/src/pages/Chat/index.jsx @@ -0,0 +1,14 @@ +import { ChatBox, SideBar } from "../../components"; + +const ChatPage = () => { + return ( + <> + +
    + +
    + + ); +}; + +export default ChatPage; diff --git a/src/pages/FooterPages/About/index.css b/src/pages/FooterPages/About/index.css new file mode 100644 index 000000000..84e0a7086 --- /dev/null +++ b/src/pages/FooterPages/About/index.css @@ -0,0 +1,94 @@ +.about-us-section p { + font-size: 20px; +} + +.stat-btns { + display: flex; + flex-direction: row; + margin: 0 auto; + justify-content: center; + flex-wrap: wrap; + gap: 2rem; +} +.btn1, +.btn2, +.btn3 { + height: 150px; + width: 320px; + border-radius: 32px; + position: relative; + display: flex; +} +.btn1 { + background-color: #d9ffe7; +} +.btn2 { + background-color: #ffe0ba; +} +.btn3 { + background-color: #daf6ff; + margin-right: 0; +} + +.btn-content { + display: flex; + flex-direction: column; + align-items: center; + position: absolute; + padding: 20px; + height: 110px; + width: 280px; + justify-content: center; + font-size: 24px; +} +.btn-content span { + color: var(--text-black-only); +} +.back-icon { + display: flex; + align-items: center; + margin-left: 40px; + padding-left: 10px; + height: 120px; + color: var(--link-color); + margin-top: 20px; +} +.back-icon span { + padding-left: 2.5rem; + font-size: 1.5rem; +} +.back-icon .icon { + font-size: 5rem; +} + +@media only screen and (min-width: 1000px) { + .btn-content { + font-size: 28px; + } +} + +@media only screen and (max-width: 600px) { + .about-us-section { + margin: 20px 20px; + padding: 20px; + padding-top: 0; + margin-top: 0; + gap: 1.5rem; + } + .about-us-section p { + font-size: 13px; + } + .btn1, + .btn2, + .btn3 { + height: 100px; + width: 180px; + border-radius: 32px; + } + .btn-content { + padding: 10px; + height: 80px; + width: 160px; + font-size: 18px; + } +} diff --git a/src/pages/FooterPages/About/index.jsx b/src/pages/FooterPages/About/index.jsx new file mode 100644 index 000000000..87710e61c --- /dev/null +++ b/src/pages/FooterPages/About/index.jsx @@ -0,0 +1,173 @@ +import "./index.css"; +import "../design.css"; + +import { useEffect, useState } from "react"; + +import Footer from "../Footer"; +import KeyboardBackspaceIcon from "@mui/icons-material/KeyboardBackspace"; +import about from "../../../assets/about-us.webp"; +import { useNavigate } from "react-router-dom"; + +const About = () => { + const [forks, setForks] = useState(0); + const [stars, setStars] = useState(0); + const [commits, setCommits] = useState(0); + const [contributors, setContributors] = useState(0); + const navigate = useNavigate(); + + const getCount = (url) => { + return fetch(url) + .then((response) => { + const linkHeader = response.headers.get("link"); + const regex = /<([^>]*)>; rel="last"/; + const match = regex.exec(linkHeader); + if (match) { + const lastPageUrl = match[1]; + const pageCount = new URLSearchParams( + new URL(lastPageUrl).search, + ).get("page"); + return parseInt(pageCount); + } else { + throw new Error("Unable to retrieve the link header"); + } + }) + .catch((error) => { + console.error("Error:", error); + }); + }; + + useEffect(() => { + getCount( + "https://api.github.com/repos/narayan954/dummygram/commits?sha=master&per_page=1&page=1", + ).then((count) => { + setCommits(count); + }); + getCount( + "https://api.github.com/repos/narayan954/dummygram/contributors?per_page=1&anon=true", + ).then((count) => { + setContributors(count); + }); + }, []); + + useEffect(() => { + fetch("https://api.github.com/repos/narayan954/dummygram") + .then((res) => { + if (!res.ok) { + throw new Error("Network response was not ok"); + } + return res.json(); + }) + .then((data) => { + setForks(data.forks_count); + setStars(data.stargazers_count); + }) + .catch((error) => { + console.error("Error fetching data:", error); + // Handle the error or display an error message to the user + }); + }, []); + + return ( +
    +
    +
    + +
    +
    +
    navigate("/")} + > + Back to Home +
    +
    +
    +

    + Who we are? +

    +

    + Welcome to Dummygram, an exciting platform that aims to reimagine + and revolutionize the way we connect and share moments with others. + A creative space where you can showcase your unique perspective, + explore diverse content, and foster meaningful connections with + like-minded individuals from around the globe. +

    +
    +
    +

    + Vision +

    +

    + Combine the best features of Instagram while adding a touch of + innovation and uniqueness. We strive to create a platform that + encourages creativity, authenticity, and positive interactions. +

    +
    +
    +

    + Creators +

    +

    + Dummygram's development has been started by{" "} + + Narayan Soni + {" "} + in September 2022 and now has over {contributors} contributors to + success. Together let's move ahead and make dummygram a huge + success. Join us today on{" "} + + GitHub! + +

    +
    +
    +

    + Stats +

    +
    +
    +
    + {commits} + + Total Commits + +
    +
    +
    +
    + {forks} + + Forks + +
    +
    +
    +
    + {stars} + + Stars + +
    +
    +
    +
    +
    +
    +
    + ); +}; + +export default About; diff --git a/src/pages/FooterPages/ContributorPage/ContributorCard.jsx b/src/pages/FooterPages/ContributorPage/ContributorCard.jsx new file mode 100644 index 000000000..91e4f977f --- /dev/null +++ b/src/pages/FooterPages/ContributorPage/ContributorCard.jsx @@ -0,0 +1,81 @@ +import { Box, Button, Typography, useMediaQuery } from "@mui/material"; + +import { GitHub } from "@mui/icons-material"; +import { Link } from "react-router-dom"; +import React from "react"; + +function ContributorCard(props) { + const { image, title, commits, profile } = props; + const isNonMobileScreen = useMediaQuery("(max-width: 800px)"); + + return ( + + + {title} + + +
    + + + + + {title} + +
    + + + +
    + ); +} + +export default ContributorCard; diff --git a/src/pages/FooterPages/ContributorPage/index.css b/src/pages/FooterPages/ContributorPage/index.css new file mode 100644 index 000000000..371712028 --- /dev/null +++ b/src/pages/FooterPages/ContributorPage/index.css @@ -0,0 +1,114 @@ +.navigation nav ul li button { + border-radius: 50%; + margin: 0 0.5rem; + color: var(--color); + border: 1px solid var(--pagination-border); +} +.contributors-outer { + width: 90vw; + margin: 0 auto; +} + +.search-container { + margin: auto; + margin-bottom: 3em; + height: 40px; + border-radius: 2px; + display: flex; + align-items: center; + padding: 0; + position: relative; + background: #fff; + justify-content: center; +} + +.search-input { + border: none; + height: 25px; + width: 350px; + color: #1b1b1b; + font-size: 15px; + outline: none; +} + +.search-input:not(:placeholder-shown) + .label { + font-size: 9px; + top: 3px; + color: #00c853; +} + +.search-input:focus ~ .label { + font-size: 9px; + top: 3px; + color: #4279a3; + transition: all 0.5s ease; +} + +.search-input:focus ~ .highlight { + width: 260px; + margin-left: 2px; + transition: all 0.5s ease; +} + +.label { + color: #aaaaaa; + position: absolute; + top: 13px; + pointer-events: none; + transition: all 0.5s ease; +} + +.highlight { + height: 1px; + background: #4279a3; + position: absolute; + bottom: 0px; + width: 95% !important; + transition: all 1s ease; +} + +@media only screen and (max-width: 640px) { + .contributors-container { + width: 80%; + margin: auto; + } + .contributors-card { + width: 100%; + padding: 1.5rem; + } + .navigation nav ul li button { + height: 2.2rem; + width: 2.2rem; + margin: 0 0.3rem; + } +} +@media only screen and (min-width: 640px) { + .contributors-card { + min-width: 260px; + padding: 1.5rem; + } + .contributors-container { + gap: 1rem; + row-gap: 2rem; + } + .navigation nav ul li button { + height: 2.8rem; + width: 2.8rem; + } +} +@media only screen and (min-width: 768px) { + .contributors-container { + /* gap: 2rem !important; */ + row-gap: 0; + } + .contributors-outer { + width: 85vw; + } + .navigation nav ul li button { + height: 3.2rem; + width: 3.2rem; + } + .contributors-card button { + font-size: 1rem; + } +} diff --git a/src/pages/FooterPages/ContributorPage/index.jsx b/src/pages/FooterPages/ContributorPage/index.jsx new file mode 100644 index 000000000..6fa0e9249 --- /dev/null +++ b/src/pages/FooterPages/ContributorPage/index.jsx @@ -0,0 +1,138 @@ +import "./index.css"; +import "../design.css"; + +import { Box, Pagination } from "@mui/material"; +import React, { useEffect, useState } from "react"; + +import ContributorCard from "./ContributorCard"; +import Footer from "../Footer"; +import KeyboardBackspaceIcon from "@mui/icons-material/KeyboardBackspace"; +import backgroundimg from "../../../assets/contributors.webp"; +import { useNavigate } from "react-router-dom"; + +function Contributor() { + const [currentPage, setCurrentPage] = useState(1); + const [contributors, setContributors] = useState([]); + const [searchResult, setSearchResult] = useState(""); + + const navigate = useNavigate(); + + const handleChange = (event, value) => { + setCurrentPage(value); + }; + + useEffect(() => { + const getData = async () => { + try { + const res = await fetch( + `https://api.github.com/repos/narayan954/dummygram/contributors?page=${currentPage}&&per_page=${ + searchResult.length < 1 ? 10 : "" + }`, + ); + + if (!res.ok) { + throw new Error("Network response was not ok"); + } + + const data = await res.json(); + const contributorsData = data.filter( + (contributor) => + !contributor.login.includes("deepsource-autofix[bot]"), + ); + const value = contributorsData.filter((item) => + item.login.toLowerCase().includes(searchResult.toLowerCase()), + ); + if (searchResult.length > 0) { + setContributors(value); + } else { + setContributors(contributorsData); + } + } catch (error) { + console.error("Error fetching data:", error); + // Handle the error or display an error message to the user + // For example, you could set an error state to display an error message on the UI + setContributors([]); + } + }; + getData(); + }, [currentPage, searchResult]); + + return ( +
    +
    +
    + +
    +
    +
    navigate("/")} + > + Back to Home +
    +
    +

    + Our Contributors +

    +
    +
    + setSearchResult(e.target.value)} + /> + Search Contributor + +
    +
    + + {contributors.map((contributor) => ( + + ))} + + + {searchResult < 1 && ( + + )} + + {contributors.length == 0 && ( +

    Sorry no result matches your query

    + )} +
    +
    +
    + ); +} + +export default Contributor; diff --git a/src/pages/FooterPages/Feedback/index.css b/src/pages/FooterPages/Feedback/index.css new file mode 100644 index 000000000..fc5763c16 --- /dev/null +++ b/src/pages/FooterPages/Feedback/index.css @@ -0,0 +1,62 @@ +.feedback-form-container { + position: relative; + min-height: 100vh; + display: flex; + justify-content: center; + align-items: center; + margin-top: 18px; +} + +#feedback_form { + display: flex; + justify-content: center; + align-items: flex-start; + flex-direction: column; + padding: 80px; + border-radius: 20px; +} + +.feedback_input, +.feedback_textarea { + margin-bottom: 20px; + width: 40vw; +} + +.feedback_textarea { + border: 1px solid rgba(104, 85, 224, 1); + border-radius: 4px; + box-shadow: 0 0 20px rgba(104, 85, 224, 0.2); + font-weight: 600; + margin-top: 10px; + padding: 10px; + transition: 0.4s; + resize: none; +} + +.feedback_sent_btn { + color: white; + width: 100%; + padding: 10px 0px; + font-size: 20px; + margin-left: 0; + margin-top: 50px; + border: none; + cursor: pointer; +} + +@media only screen and (max-width: 720px) { + .feedback-form-container { + align-items: flex-start; + padding-top: 50px; + } + + #feedback_form { + padding: 20px; + } + + .feedback_input, + .feedback_textarea { + margin-bottom: 20px; + width: 70vw; + } +} diff --git a/src/pages/FooterPages/Feedback/index.jsx b/src/pages/FooterPages/Feedback/index.jsx new file mode 100644 index 000000000..06b7b2315 --- /dev/null +++ b/src/pages/FooterPages/Feedback/index.jsx @@ -0,0 +1,95 @@ +import "./index.css"; +import "../design.css"; + +import React, { useRef } from "react"; + +import Footer from "../Footer"; +import KeyboardBackspaceIcon from "@mui/icons-material/KeyboardBackspace"; +import Scroll from "../../../reusableComponents"; +import emailjs from "@emailjs/browser"; +import { playSuccessSound } from "../../../js/sounds"; +import { useSnackbar } from "notistack"; + +export const Feedback = () => { + const form = useRef(null); + const { enqueueSnackbar } = useSnackbar(); + + const sendEmail = (e) => { + e.preventDefault(); + emailjs + .sendForm( + "service_hg3vdpg", + "dummygram_feedback", + form.current, + "OV1vxF7lxYkw_RRWy", + ) + .then( + (result) => { + playSuccessSound(); + enqueueSnackbar("Thanks For Your Feedback!", { + variant: "success", + }); + }, + (error) => { + console.error("Error:", error); + }, + ); + }; + + return ( + <> +
    navigate("/")} + > + +
    +

    + Your opinion matters to us ! +

    +
    + + +
    + + + + + +