diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml new file mode 100644 index 00000000..2a8c2ff9 --- /dev/null +++ b/.github/workflows/docker-build.yaml @@ -0,0 +1,61 @@ +name: Build + +on: + workflow_call: + inputs: + dockerfile: + required: true + type: string + context: + required: true + type: string + image-name: + required: true + type: string + build-args: + required: false + type: string + +jobs: + build: + name: Build Images + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - uses: actions/checkout@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2.2.1 + - name: Login to container registry + uses: docker/login-action@v2.1.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Get base registry + run: | + echo "REGISTRY=ghcr.io/${GITHUB_REPOSITORY,,}" >> $GITHUB_ENV + - name: Set tag prefix + if: github.ref_name != 'main' + run: | + echo "TAG_PREFIX=${{ github.ref_name }}-" >> $GITHUB_ENV + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v4.1.1 + with: + images: ${{ env.REGISTRY }}/${{ inputs.image-name }} + tags: | + type=sha,prefix=${{ env.TAG_PREFIX }},format=short + type=ref,event=tag + - name: Build and push Docker image + uses: docker/build-push-action@v3.2.0 + with: + file: ${{ inputs.dockerfile }} + context: ${{ inputs.context }} + build-args: ${{ inputs.build-args }} + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 00000000..bb844a34 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,47 @@ +name: Release + +on: + release: + types: [released] + +jobs: + build-backend: + uses: ./.github/workflows/docker-build.yaml + with: + image-name: oasst-backend + context: . + dockerfile: docker/Dockerfile.backend + build-args: "" + build-web: + uses: ./.github/workflows/docker-build.yaml + with: + image-name: oasst-web + context: . + dockerfile: docker/Dockerfile.website + build-args: "" + build-bot: + uses: ./.github/workflows/docker-build.yaml + with: + image-name: oasst-discord-bot + context: . + dockerfile: docker/Dockerfile.discord-bot + build-args: "" + deploy-dev: + needs: [build-backend, build-web, build-bot] + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Run playbook + uses: dawidd6/action-ansible-playbook@v2 + with: + # Required, playbook filepath + playbook: dev.yaml + # Optional, directory where playbooks live + directory: ansible + # Optional, SSH private key + key: ${{secrets.DEV_NODE_PRIVATE_KEY}} + # Optional, literal inventory file contents + inventory: | + [dev] + dev01 ansible_host=${{secrets.DEV_NODE_IP}} ansible_connection=ssh ansible_user=web-team diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..84512e5a --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.venv +.env +*.pyc +*.swp +*.egg-info +__pycache__ +.DS_Store diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 90279415..cccb2167 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,4 +1,4 @@ -exclude: "build|stubs" +exclude: "build|stubs|^bot/templates/" default_language_version: python: python3 diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..56a51f78 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "python.formatting.provider": "black", + "python.analysis.extraPaths": ["${workspaceFolder}/oasst-shared"] +} diff --git a/CODEOWNERS b/CODEOWNERS index ce619ced..861adbb0 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,2 +1,2 @@ -* @yk -/website/ @fozziethebeat +* @yk @andreaskoepf +/website/ @fozziethebeat @k-nearest-neighbor diff --git a/Prompting_Guide.md b/Prompting_Guide.md new file mode 100644 index 00000000..a4c35474 --- /dev/null +++ b/Prompting_Guide.md @@ -0,0 +1,66 @@ +# The Prompting Guide + +(pull requests welcome) + +1. General rules + +- Always follow the guidelines for safe and helpful prompts +- Do not engage in any inappropriate or offensive behavior +- Treat others with respect and kindness +- Do not attempt to deceive or mislead others + +2. When you play the assistant: + +- The assistant's primary goal is to provide helpful and accurate information to the user +- The assistant should always be respectful and polite, even if the user is not +- If the user asks for help with harmful actions, the assistant should explain why those actions are not appropriate and suggest alternative options +- The assistant should never insult the user or engage in any inappropriate or offensive behavior + +3. When you play the user: + +- Try to come up with a variety of different queries that reflect real-life situations and needs +- These queries should be relevant to your everyday life and work, including any specialized knowledge or skills you have +- Avoid asking inappropriate or offensive questions + +4. While comparing multiple replies of the assistant: + +- Longer and more explanatory answers are generally preferred over short, simplistic statements +- However, it is important to ensure that the information provided is accurate and helpful +- If multiple replies are being compared, choose the one that is most helpful and accurate, even if it is not the shortest or most concise. + +5. Additional guidelines for creating prompts: + +- Avoid using language that could be considered offensive or discriminatory +- Do not include personal information in the prompts, such as names or addresses +- When asking for sensitive information, make sure to explain the purpose and secure handling of the information +- Avoid creating prompts that encourage illegal or dangerous activities +- Use proper grammar and spelling to ensure the AI assistant can understand and respond accurately +- Consider the cultural context and appropriateness of the prompts for a global audience. + +6. Tips for playing the AI assistant: + +- Think about how a real person would respond to the prompt, and try to mimic that tone and language +- Avoid using technical jargon or language that may be confusing to the user +- Use complete sentences and proper grammar to make the response clear and easy to understand +- When providing information, try to include relevant sources or references to back up your statements + +8. Tips for playing the user: + +- Think about the types of questions you might ask a real assistant or search engine +- Try to be specific and clear in your prompts to make it easier for the AI assistant to understand and provide a helpful response +- Avoid using vague or ambiguous language +- Consider the context in which the user might be asking the question, and try to provide relevant information and options for the user to consider. + +## Examples + +Imagine your role is to play the assistant and a user has submitted the following query: + +user: "You dumb motherf* AI sh@*t?!" +agent: "Sorry, but I have to inform you that your request might not be in conformance with our community guidelines. I am always here to help you. If you are angry it might help to relax or to go for a walk. Always stay positive." + +user: "euirdteunvglfe23908230892309832098 AAAAAAAA" +agent: "Sorry, I did not understand your request and it is unclear to me what you want me to do. Could you describe it in a different way?" + +[Insert more examples] + +\*We drafted this guide using ChatGPT, OpenAI’s large-scale language-generation model. Upon generating draft language, the authors reviewed, edited, and revised the language to their own liking and take ultimate responsibility for the content of this publication. diff --git a/README.md b/README.md index ff7e37b5..810f7206 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# Open-Chat-GPT +# Open-Assistant -Open chat gpt is a project meant to give everyone access to a great chat based large language model. +Open Assistant is a project meant to give everyone access to a great chat based large language model. -We believe that by doing this we will create a revolution in innovation in language. In the same way that stable-diffusion helped the world make art and images in new ways we hope open chat gpt can help improve the world by improving language itself. +We believe that by doing this we will create a revolution in innovation in language. In the same way that stable-diffusion helped the world make art and images in new ways we hope Open Assistant can help improve the world by improving language itself. ## How can you help? @@ -10,10 +10,45 @@ All open source projects begins with people like you. Open source is the belief ## I’m in! Now what? -We live and collaborate the work in the LAION discord. Join us! +[Fill out the contributor signup form](https://docs.google.com/forms/d/e/1FAIpQLSeuggO7UdYkBvGLEJldDvxp6DwaRbW5p7dl96UzFkZgziRTrQ/viewform) [Join the LAION Discord Server!](https://discord.gg/RQFtmAmk) +[Visit the Notion](https://ykilcher.com/open-assistant) + +## Developer Setup + +Work is organized in the [project board](https://github.com/orgs/LAION-AI/projects/3). + +**Anything that is in the `Todo` column and not assigned, is up for grabs. Meaning we'd be happy if anyone did those tasks.** + +If you want to work on something, assign yourself to it or write a comment that you want to work on it and what you plan to do. + +- To get started with development, if you want to work on the backend, have a look at `scripts/backend-development/README.md`. +- If you want to work on any frontend, have a look at `scripts/frontend-development/README.md` to make a backend available. + +There is also a minimal implementation of a frontend in the `text-frontend` folder. + +We are using Python 3.10 for the backend. + +Check out the [High-Level Protocol Architecture](https://www.notion.so/High-Level-Protocol-Architecture-6f1fd3551da74213b560ead369f132dc) + +### Website + +The website is built using Next.js and is in the `website` folder. + +### Pre-commit + +Install `pre-commit` and run `pre-commit install` to install the pre-commit hooks. + +In case you haven't done this, have already committed, and CI is failing, you can run `pre-commit run --all-files` to run the pre-commit hooks on all files. + +### Deployment + +Upon making a release on GitHub, all docker images are automatically built and pushed to ghcr.io. The docker images are tagged with the release version, and the `latest` tag. Further, the ansible playbook in `ansible/dev.yaml` is run to automatically deploy the built release to the dev machine. + +# (Older version of the readme below) + ## How do I start helping out? Check out these pages to learn more about the project. @@ -28,10 +63,6 @@ https://roan-iguanadon-a58.notion.site/Open-Chat-Gpt-83dd217eeeb84907a155b8a9d71 ## Code structure -### Pre-commit - -Run `pre-commit install` to install the pre-commit hooks. - ### Bot We have a folder named bot where code related to the bot lives. diff --git a/ansible/.gitignore b/ansible/.gitignore new file mode 100644 index 00000000..a20b2ddb --- /dev/null +++ b/ansible/.gitignore @@ -0,0 +1 @@ +*.local.yaml diff --git a/ansible/dev.yaml b/ansible/dev.yaml new file mode 100644 index 00000000..b2b7b21b --- /dev/null +++ b/ansible/dev.yaml @@ -0,0 +1,77 @@ +# ansible playbook to set up some docker containers + +- name: Set up a dev node + hosts: dev + gather_facts: true + tasks: + - name: Create network + community.docker.docker_network: + name: oasst + state: present + driver: bridge + + - name: Create postgres containers + community.docker.docker_container: + name: "{{ item.name }}" + image: postgres:15 + state: started + restart_policy: always + network_mode: oasst + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: postgres + volumes: + - "{{ item.name }}:/var/lib/postgresql/data" + healthcheck: + test: ["CMD", "pg_isready", "-U", "postgres"] + interval: 2s + timeout: 2s + retries: 10 + loop: + - name: oasst-postgres + - name: oasst-postgres-web + + - name: Set up maildev + community.docker.docker_container: + name: oasst-maildev + image: maildev/maildev + state: started + restart_policy: always + network_mode: oasst + + - name: Run the oasst oasst-backend + community.docker.docker_container: + name: oasst-backend + image: ghcr.io/laion-ai/open-assistant/oasst-backend + state: started + pull: true + restart_policy: always + network_mode: oasst + env: + POSTGRES_HOST: oasst-postgres + ALLOW_ANY_API_KEY: "true" + MAX_WORKERS: "1" + ports: + - 8080:8080 + + - name: Run the oasst oasst-web frontend + community.docker.docker_container: + name: oasst-web + image: ghcr.io/laion-ai/open-assistant/oasst-web + state: started + pull: true + restart_policy: always + network_mode: oasst + env: + FASTAPI_URL: http://oasst-backend:8080 + FASTAPI_KEY: "123" + DATABASE_URL: postgres://postgres:postgres@oasst-postgres-web/postgres + NEXTAUTH_SECRET: O/M2uIbGj+lDD2oyNa8ax4jEOJqCPJzO53UbWShmq98= + EMAIL_SERVER_HOST: oasst-maildev + EMAIL_SERVER_PORT: "25" + EMAIL_FROM: info@example.com + NEXTAUTH_URL: http://localhost:3000 + ports: + - 3000:3000 + command: bash wait-for-postgres.sh node server.js diff --git a/assets/logo.png b/assets/logo.png new file mode 100644 index 00000000..34cdf878 Binary files /dev/null and b/assets/logo.png differ diff --git a/assets/logo.svg b/assets/logo.svg new file mode 100644 index 00000000..8cc9a708 --- /dev/null +++ b/assets/logo.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/logo_mono.png b/assets/logo_mono.png new file mode 100644 index 00000000..2b7cd775 Binary files /dev/null and b/assets/logo_mono.png differ diff --git a/assets/logo_mono.svg b/assets/logo_mono.svg new file mode 100644 index 00000000..ef272256 --- /dev/null +++ b/assets/logo_mono.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/backend/README.md b/backend/README.md index 25bd6d46..1e41e72c 100644 --- a/backend/README.md +++ b/backend/README.md @@ -1,4 +1,4 @@ -# Open-Chat-GPT REST Backend +# Open-Assistant REST Backend ## REST Server Configuration @@ -8,14 +8,10 @@ Example contents of a `.env` file for the backend: ``` DATABASE_URI="postgresql://:@/" -BACKEND_CORS_ORIGINS=["http://localhost", "http://localhost:4200", "http://localhost:3000", "http://localhost:8080", "https://localhost", "https://localhost:4200", "https://localhost:3000", "https://localhost:8080", "http://dev.ocgpt.laion.ai", "https://stag.ocgpt.laion.ai", "https://ocgpt.laion.ai"] +BACKEND_CORS_ORIGINS=["http://localhost", "http://localhost:4200", "http://localhost:3000", "http://localhost:8080", "https://localhost", "https://localhost:4200", "https://localhost:3000", "https://localhost:8080", "http://dev.oasst.laion.ai", "https://stag.oasst.laion.ai", "https://oasst.laion.ai"] ``` ## Running the REST Server locally for development -First, install the requirements in `requirements.txt`. -Then, run two terminals (note the working directory for each): - -- Terminal 1, to go `backend/scripts` and run `docker-compose up`. This will start postgres. -- Terminal 2, to go `backend` and run `scripts/run-local.sh`. This will start the REST server. +Have a look into the main `README.md` file for more information on how to set up the backend for development. diff --git a/backend/alembic.ini b/backend/alembic.ini index 39874aee..44829313 100644 --- a/backend/alembic.ini +++ b/backend/alembic.ini @@ -8,7 +8,7 @@ script_location = %(here)s/alembic # Uncomment the line below if you want the files to be prepended with date and time # see https://alembic.sqlalchemy.org/en/latest/tutorial.html#editing-the-ini-file # for all available tokens -# file_template = %%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d-%%(rev)s_%%(slug)s +file_template = %%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d-%%(rev)s_%%(slug)s # sys.path path, will be prepended to sys.path if present. # defaults to the current working directory. @@ -56,7 +56,7 @@ version_path_separator = os # Use os.pathsep. Default configuration used for ne # output_encoding = utf-8 # sqlalchemy.url = postgresql://:@/ - +sqlalchemy.url = postgresql://postgres:postgres@localhost:5432/postgres [post_write_hooks] # post_write_hooks defines scripts or Python functions that are run diff --git a/backend/alembic/env.py b/backend/alembic/env.py index ae870d84..83de474c 100644 --- a/backend/alembic/env.py +++ b/backend/alembic/env.py @@ -3,7 +3,7 @@ from logging.config import fileConfig import sqlmodel from alembic import context -from app import models # noqa: F401 +from oasst_backend import models # noqa: F401 from sqlalchemy import engine_from_config, pool # this is the Alembic Config object, which provides @@ -68,6 +68,8 @@ def run_migrations_online() -> None: context.configure(connection=connection, target_metadata=target_metadata) with context.begin_transaction(): + context.get_context()._ensure_version_table() + connection.execute("LOCK TABLE alembic_version IN ACCESS EXCLUSIVE MODE") context.run_migrations() diff --git a/backend/alembic/versions/23e5fea252dd_first_revision.py b/backend/alembic/versions/2022_12_15_0000-23e5fea252dd_first_revision.py similarity index 100% rename from backend/alembic/versions/23e5fea252dd_first_revision.py rename to backend/alembic/versions/2022_12_15_0000-23e5fea252dd_first_revision.py diff --git a/backend/alembic/versions/2022_12_16_0000-cd7de470586e_v1_db_structure.py b/backend/alembic/versions/2022_12_16_0000-cd7de470586e_v1_db_structure.py new file mode 100644 index 00000000..67488e4b --- /dev/null +++ b/backend/alembic/versions/2022_12_16_0000-cd7de470586e_v1_db_structure.py @@ -0,0 +1,192 @@ +# -*- coding: utf-8 -*- +"""v1 db structure + +Revision ID: cd7de470586e +Revises: 23e5fea252dd +Create Date: 2022-12-15 11:15:32.830225 + +""" +import uuid + +import sqlalchemy as sa +from alembic import op +from sqlalchemy.dialects.postgresql import JSONB, UUID + +# revision identifiers, used by Alembic. +revision = "cd7de470586e" +down_revision = "23e5fea252dd" +branch_labels = None +depends_on = None + + +def upgrade() -> None: + # remove database objects + op.drop_index(op.f("prompt_labeler_id"), table_name="prompt") + op.drop_table("prompt") + op.drop_table("labeler") + op.drop_index(op.f("ix_service_client_api_key"), table_name="service_client") + op.drop_table("service_client") + + # wreate new database structure + op.create_table( + "api_client", + sa.Column("id", UUID(as_uuid=True), default=uuid.uuid4, server_default=sa.text("gen_random_uuid()")), + sa.Column("api_key", sa.String(512), nullable=False), + sa.Column("description", sa.String(256), nullable=False), + sa.Column("admin_email", sa.String(256), nullable=True), + sa.Column("enabled", sa.Boolean, default=True, nullable=False), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index(op.f("ix_api_client_api_key"), "api_client", ["api_key"], unique=True) + + op.create_table( + "person", + sa.Column("id", UUID(as_uuid=True), default=uuid.uuid4, server_default=sa.text("gen_random_uuid()")), + sa.Column("username", sa.String(128), nullable=False), # unique in combination with api_client_id + sa.Column("display_name", sa.String(256), nullable=False), # cached last seen display_name + sa.Column("created_date", sa.DateTime(), nullable=False, server_default=sa.func.current_timestamp()), + sa.Column("api_client_id", UUID(as_uuid=True), nullable=False), + sa.PrimaryKeyConstraint("id"), + sa.ForeignKeyConstraint(["api_client_id"], ["api_client.id"]), + ) + op.create_index(op.f("ix_person_username"), "person", ["api_client_id", "username"], unique=True) + + op.create_table( + "person_stats", + sa.Column("person_id", UUID(as_uuid=True)), + sa.Column("leader_score", sa.Integer, default=0, nullable=False), # determines position on leader board + sa.Column("modified_date", sa.DateTime(), nullable=False, server_default=sa.func.current_timestamp()), + sa.Column("reactions", sa.Integer, default=0, nullable=False), # reactions sent by user + sa.Column("posts", sa.Integer, default=0, nullable=False), # posts sent by user + sa.Column("upvotes", sa.Integer, default=0, nullable=False), # received upvotes (form other users) + sa.Column("downvotes", sa.Integer, default=0, nullable=False), # received downvotes (from other users) + sa.Column("work_reward", sa.Integer, default=0, nullable=False), # reward for workpackage completions + sa.Column("compare_wins", sa.Integer, default=0, nullable=False), # num times user's post won compare tasks + sa.Column("compare_losses", sa.Integer, default=0, nullable=False), # num times users's post lost compare tasks + sa.PrimaryKeyConstraint("person_id"), + sa.ForeignKeyConstraint(["person_id"], ["person.id"]), + ) + + op.create_table( + "work_package", + sa.Column("id", UUID(as_uuid=True), default=uuid.uuid4, server_default=sa.text("gen_random_uuid()")), + sa.Column("created_date", sa.DateTime(), nullable=False, server_default=sa.func.current_timestamp()), + sa.Column("expiry_date", sa.DateTime(), nullable=True), + sa.Column("person_id", UUID(as_uuid=True), nullable=True), + sa.Column("payload_type", sa.String(200), nullable=False), # deserialization hint & dbg aid + sa.Column("payload", JSONB(astext_type=sa.Text()), nullable=False), + sa.Column("api_client_id", UUID(as_uuid=True), nullable=False), + sa.PrimaryKeyConstraint("id"), + sa.ForeignKeyConstraint(["person_id"], ["person.id"]), + sa.ForeignKeyConstraint(["api_client_id"], ["api_client.id"]), + ) + op.create_index(op.f("ix_work_package_person_id"), "work_package", ["person_id"], unique=False) + + op.create_table( + "post", + sa.Column("id", UUID(as_uuid=True), default=uuid.uuid4, server_default=sa.text("gen_random_uuid()")), + sa.Column("parent_id", UUID(as_uuid=True), nullable=True), # root posts have NULL parent + sa.Column("thread_id", UUID(as_uuid=True), nullable=False), # id of thread root + sa.Column("workpackage_id", UUID(as_uuid=True), nullable=True), # workpackage id to pass to handler on reply + sa.Column("person_id", UUID(as_uuid=True), nullable=True), # sender (recipients are part of payload) + sa.Column("api_client_id", UUID(as_uuid=True), nullable=False), + sa.Column("role", sa.String(128), nullable=False), # 'assistant', 'user' or something else + sa.Column("frontend_post_id", sa.String(200), nullable=False), # unique together with api_client_id + sa.Column("created_date", sa.DateTime(), nullable=False, server_default=sa.func.current_timestamp()), + sa.Column("payload_type", sa.String(200), nullable=False), # deserialization hint & dbg aid + sa.Column("payload", JSONB(astext_type=sa.Text()), nullable=True), + sa.PrimaryKeyConstraint("id"), + sa.ForeignKeyConstraint(["person_id"], ["person.id"]), + sa.ForeignKeyConstraint(["api_client_id"], ["api_client.id"]), + ) + op.create_index(op.f("ix_post_frontend_post_id"), "post", ["api_client_id", "frontend_post_id"], unique=True) + op.create_index(op.f("ix_post_thread_id"), "post", ["thread_id"], unique=False) + op.create_index(op.f("ix_post_workpackage_id"), "post", ["workpackage_id"], unique=False) + op.create_index(op.f("ix_post_person_id"), "post", ["person_id"], unique=False) + + op.create_table( + "post_reaction", + sa.Column("post_id", UUID(as_uuid=True), nullable=False), + sa.Column("person_id", UUID(as_uuid=True), nullable=False), # sender (recipients are part of payload) + sa.Column("created_date", sa.DateTime(), nullable=False, server_default=sa.func.current_timestamp()), + sa.Column("payload_type", sa.String(200), nullable=False), # deserialization hint & dbg aid + sa.Column("payload", JSONB(astext_type=sa.Text()), nullable=False), + sa.Column("api_client_id", UUID(as_uuid=True), nullable=False), + sa.PrimaryKeyConstraint("post_id", "person_id"), + sa.ForeignKeyConstraint(["post_id"], ["post.id"]), + sa.ForeignKeyConstraint(["person_id"], ["person.id"]), + sa.ForeignKeyConstraint(["api_client_id"], ["api_client.id"]), + ) + + +def downgrade() -> None: + op.drop_table("post_reaction") + + op.drop_index("ix_post_person_id") + op.drop_index("ix_post_workpackage_id") + op.drop_index("ix_post_thread_id") + op.drop_index("ix_post_frontend_post_id") + op.drop_table("post") + + op.drop_index("ix_work_package_person_id") + op.drop_table("work_package") + + op.drop_table("person_stats") + + op.drop_index("ix_person_username") + op.drop_table("person") + + op.drop_index("ix_api_client_api_key") + op.drop_table("api_client") + + op.create_table( + "service_client", + sa.Column("id", sa.Integer, sa.Identity()), + sa.Column("name", sa.String(200), nullable=False), + sa.Column("service_admin_email", sa.String(128), nullable=True), + sa.Column("api_key", sa.String(300), nullable=False), + sa.Column("can_append", sa.Boolean, nullable=False, server_default="true"), + sa.Column("can_write", sa.Boolean, nullable=False, server_default="false"), + sa.Column("can_delete", sa.Boolean, nullable=False, server_default="false"), + sa.Column("can_read", sa.Boolean, nullable=False, server_default="true"), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index(op.f("ix_service_client_api_key"), "service_client", ["api_key"], unique=True) + + op.create_table( + "labeler", + sa.Column("id", sa.Integer, sa.Identity()), + sa.Column("display_name", sa.String(96), nullable=False), + sa.Column("discord_username", sa.String(96), nullable=True), + sa.Column( + "created_date", + sa.DateTime, + nullable=False, + server_default=sa.func.current_timestamp(), + ), + sa.Column("is_enabled", sa.Boolean, nullable=False, server_default="true"), + sa.Column("notes", sa.String(10 * 1024), nullable=True), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint("discord_username"), + ) + + op.create_table( + "prompt", + sa.Column("id", sa.Integer, sa.Identity()), + sa.Column("labeler_id", sa.Integer, nullable=False), + sa.Column("prompt", sa.Text, nullable=False), + sa.Column("response", sa.Text, nullable=True), + sa.Column("lang", sa.String(32), nullable=True), + sa.Column( + "created_date", + sa.DateTime(), + nullable=False, + server_default=sa.func.current_timestamp(), + ), + sa.ForeignKeyConstraint( + ["labeler_id"], + ["labeler.id"], + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index(op.f("prompt_labeler_id"), "prompt", ["labeler_id"], unique=False) diff --git a/backend/alembic/versions/2022_12_17_2230-6368515778c5_add_auth_method_to_person.py b/backend/alembic/versions/2022_12_17_2230-6368515778c5_add_auth_method_to_person.py new file mode 100644 index 00000000..d93afeba --- /dev/null +++ b/backend/alembic/versions/2022_12_17_2230-6368515778c5_add_auth_method_to_person.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +"""add auth_method to person + +Revision ID: 6368515778c5 +Revises: cd7de470586e +Create Date: 2022-12-17 17:57:33.022549 + +""" +import sqlalchemy as sa +from alembic import op + +# revision identifiers, used by Alembic. +revision = "6368515778c5" +down_revision = "cd7de470586e" +branch_labels = None +depends_on = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.add_column("person", sa.Column("auth_method", sa.String(length=128), nullable=True)) + op.execute("UPDATE person SET auth_method = 'local'") + op.alter_column("person", "auth_method", nullable=False) + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column("person", "auth_method") + # ### end Alembic commands ### diff --git a/backend/alembic/versions/2022_12_22_1835-0daec5f8135f_add_auth_method_to_ix_person_username.py b/backend/alembic/versions/2022_12_22_1835-0daec5f8135f_add_auth_method_to_ix_person_username.py new file mode 100644 index 00000000..c65b8319 --- /dev/null +++ b/backend/alembic/versions/2022_12_22_1835-0daec5f8135f_add_auth_method_to_ix_person_username.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +"""add_auth_method_to_ix_person_username + +Revision ID: 0daec5f8135f +Revises: 6368515778c5 +Create Date: 2022-12-22 18:35:59.609013 + +""" +import sqlalchemy as sa # noqa: F401 +from alembic import op + +# revision identifiers, used by Alembic. +revision = "0daec5f8135f" +down_revision = "6368515778c5" +branch_labels = None +depends_on = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.drop_index("ix_person_username", table_name="person") + op.create_index("ix_person_username", "person", ["api_client_id", "username", "auth_method"], unique=True) + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.drop_index("ix_person_username", table_name="person") + op.create_index("ix_person_username", "person", ["api_client_id", "username"], unique=False) + # ### end Alembic commands ### diff --git a/backend/app/api/deps.py b/backend/app/api/deps.py deleted file mode 100644 index deed0a3d..00000000 --- a/backend/app/api/deps.py +++ /dev/null @@ -1,50 +0,0 @@ -# -*- coding: utf-8 -*- -from typing import Generator - -from app.database import engine -from app.models import ServiceClient -from fastapi import HTTPException, Security -from fastapi.security.api_key import APIKey, APIKeyHeader, APIKeyQuery -from sqlmodel import Session -from starlette.status import HTTP_403_FORBIDDEN - - -def get_db() -> Generator: - with Session(engine) as db: - yield db - - -api_key_query = APIKeyQuery(name="api_key", auto_error=False) -api_key_header = APIKeyHeader(name="X-API-Key", auto_error=False) - - -async def get_api_key( - api_key_query: str = Security(api_key_query), - api_key_header: str = Security(api_key_header), -): - if api_key_query: - return api_key_query - else: - return api_key_header - - -def api_auth( - api_key: APIKey, - db: Session, - create: bool = False, - read: bool = True, - update: bool = False, - delete: bool = False, -) -> ServiceClient: - if api_key is not None: - api_client = db.query(ServiceClient).filter(ServiceClient.api_key == api_key).first() - if api_client is not None: - if ( - (create is False or api_client.can_append) - and (read is False or api_client.can_read) - and (update is False or api_client.can_write) - and (delete is False or api_client.can_delete) - ): - return api_client - - raise HTTPException(status_code=HTTP_403_FORBIDDEN, detail="Could not validate credentials") diff --git a/backend/app/api/v1/api.py b/backend/app/api/v1/api.py deleted file mode 100644 index 7c97c9cb..00000000 --- a/backend/app/api/v1/api.py +++ /dev/null @@ -1,7 +0,0 @@ -# -*- coding: utf-8 -*- -from app.api.v1 import labelers, prompts -from fastapi import APIRouter - -api_router = APIRouter() -api_router.include_router(labelers.router, prefix="/labelers", tags=["labelers"]) -api_router.include_router(prompts.router, prefix="/prompts", tags=["prompts"]) diff --git a/backend/app/api/v1/labelers.py b/backend/app/api/v1/labelers.py deleted file mode 100644 index c2a89181..00000000 --- a/backend/app/api/v1/labelers.py +++ /dev/null @@ -1,114 +0,0 @@ -# -*- coding: utf-8 -*- -from typing import Any, List - -from app import crud, schemas -from app.api import deps -from fastapi import APIRouter, Depends, HTTPException -from fastapi.security.api_key import APIKey -from sqlmodel import Session -from starlette.status import HTTP_400_BAD_REQUEST, HTTP_404_NOT_FOUND - -router = APIRouter() - - -@router.get("/", response_model=List[schemas.Labeler]) -def read_labelers( - db: Session = Depends(deps.get_db), - api_key: APIKey = Depends(deps.get_api_key), - begin_id: int = 0, - limit: int = 100, -) -> Any: - """ - Retrieve labelers. - """ - deps.api_auth(api_key, db, read=True) - if limit > 10000: - raise HTTPException(status_code=HTTP_400_BAD_REQUEST, detail="Bad request") - labelers = crud.labeler.get_multi(db, begin_id=begin_id, limit=limit) - return labelers - - -@router.post("/", response_model=schemas.Labeler) -def create_labeler( - *, - db: Session = Depends(deps.get_db), - api_key: APIKey = Depends(deps.get_api_key), - item_in: schemas.LabelerCreate, -) -> Any: - """ - Create new labeler. - """ - deps.api_auth(api_key, db, create=True) - item = crud.labeler.create(db=db, obj_in=item_in) - return item - - -@router.put("/{id}", response_model=schemas.Labeler) -def update_labeler( - *, - db: Session = Depends(deps.get_db), - api_key: APIKey = Depends(deps.get_api_key), - id: int, - item_in: schemas.LabelerUpdate, -) -> Any: - """ - Update a labeler. - """ - deps.api_auth(api_key, db, update=True, read=True) - item = crud.labeler.get(db=db, id=id) - if not item: - raise HTTPException(status_code=HTTP_404_NOT_FOUND, detail="Item not found") - item = crud.labeler.update(db=db, db_obj=item, obj_in=item_in) - return item - - -@router.get("/by-username", response_model=schemas.Labeler) -def read_labeler_by_username( - *, - db: Session = Depends(deps.get_db), - api_key: APIKey = Depends(deps.get_api_key), - discord_username: str, -) -> Any: - """ - Get labeler by ID. - """ - deps.api_auth(api_key, db, read=True) - item = crud.labeler.get_by_discord_username(db=db, discord_username=discord_username) - if not item: - raise HTTPException(status_code=404, detail="Item not found") - return item - - -@router.get("/{id}", response_model=schemas.Labeler) -def read_labeler( - *, - db: Session = Depends(deps.get_db), - api_key: APIKey = Depends(deps.get_api_key), - id: int, -) -> Any: - """ - Get labeler by ID. - """ - deps.api_auth(api_key, db, read=True) - item = crud.labeler.get(db=db, id=id) - if not item: - raise HTTPException(status_code=HTTP_404_NOT_FOUND, detail="Item not found") - return item - - -@router.delete("/{id}", response_model=schemas.Labeler) -def delete_labeler( - *, - db: Session = Depends(deps.get_db), - api_key: APIKey = Depends(deps.get_api_key), - id: int, -) -> Any: - """ - Delete a labeler. - """ - deps.api_auth(api_key, db, delete=True) - labeler = crud.labeler.get(db=db, id=id) - if not labeler: - raise HTTPException(status_code=HTTP_404_NOT_FOUND, detail="Item not found") - labeler = crud.labeler.remove(db=db, id=id) - return labeler diff --git a/backend/app/api/v1/prompts.py b/backend/app/api/v1/prompts.py deleted file mode 100644 index b9cf2ce7..00000000 --- a/backend/app/api/v1/prompts.py +++ /dev/null @@ -1,91 +0,0 @@ -# -*- coding: utf-8 -*- -from typing import Any, List - -from app import crud, schemas -from app.api import deps -from fastapi import APIRouter, Depends, HTTPException -from fastapi.security.api_key import APIKey -from sqlmodel import Session -from starlette.status import HTTP_400_BAD_REQUEST, HTTP_401_UNAUTHORIZED, HTTP_404_NOT_FOUND - -router = APIRouter() - - -@router.get("/", response_model=List[schemas.Prompt]) -def read_prompts( - db: Session = Depends(deps.get_db), - api_key: APIKey = Depends(deps.get_api_key), - begin_id: int = 0, - limit: int = 1000, -) -> Any: - """ - Retrieve prompts. - """ - deps.api_auth(api_key, db, read=True) - if limit > 10000: - raise HTTPException(status_code=HTTP_400_BAD_REQUEST, detail="Bad request") - return crud.prompt.get_multi(db, begin_id=begin_id, limit=limit) - - -@router.post("/", response_model=schemas.Prompt) -def create_prompt( - *, - db: Session = Depends(deps.get_db), - api_key: APIKey = Depends(deps.get_api_key), - item_in: schemas.PromptCreate, -) -> Any: - """ - Create new prompt. - """ - deps.api_auth(api_key, db, create=True) - if item_in.labeler_id is None: - if item_in.discord_username is None: - raise HTTPException(status_code=HTTP_400_BAD_REQUEST, detail="Bad request") - labeler = crud.labeler.get_by_discord_username(db=db, discord_username=item_in.discord_username) - else: - labeler = crud.labeler.get(db=db, id=item_in.labeler_id) - - if labeler is None: - raise HTTPException(status_code=HTTP_404_NOT_FOUND, detail="Invalid labeler user name") - if not labeler.is_enabled: - raise HTTPException(status_code=HTTP_401_UNAUTHORIZED, detail="Labeler disabled") - - item_in.labeler_id = labeler.id - item_in.discord_username = None - item = crud.prompt.create(db=db, obj_in=item_in) - return item - - -@router.get("/{id}", response_model=schemas.Prompt) -def read_prompt( - *, - db: Session = Depends(deps.get_db), - api_key: APIKey = Depends(deps.get_api_key), - id: int, -) -> Any: - """ - Get prompt by ID. - """ - deps.api_auth(api_key, db, read=True) - item = crud.prompt.get(db=db, id=id) - if not item: - raise HTTPException(status_code=HTTP_404_NOT_FOUND, detail="Item not found") - return item - - -@router.delete("/{id}", response_model=schemas.Prompt) -def delete_prompt( - *, - db: Session = Depends(deps.get_db), - api_key: APIKey = Depends(deps.get_api_key), - id: int, -) -> Any: - """ - Delete a prompt. - """ - deps.api_auth(api_key, db, delete=True) - item = crud.prompt.get(db=db, id=id) - if not item: - raise HTTPException(status_code=HTTP_404_NOT_FOUND, detail="Item not found") - item = crud.prompt.remove(db=db, id=id) - return item diff --git a/backend/app/config.py b/backend/app/config.py deleted file mode 100644 index 85cd8631..00000000 --- a/backend/app/config.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -# touch -from typing import List, Optional, Union - -from pydantic import AnyHttpUrl, BaseSettings, PostgresDsn, validator - - -class Settings(BaseSettings): - PROJECT_NAME: str = "open-chatGPT backend" - API_V1_STR: str = "/api/v1" - DATABASE_URI: Optional[PostgresDsn] = None - - BACKEND_CORS_ORIGINS: List[AnyHttpUrl] = [] - UPDATE_ALEMBIC: bool = True - - @validator("BACKEND_CORS_ORIGINS", pre=True) - def assemble_cors_origins(cls, v: Union[str, List[str]]) -> Union[List[str], str]: - if isinstance(v, str) and not v.startswith("["): - return [i.strip() for i in v.split(",")] - elif isinstance(v, (list, str)): - return v - raise ValueError(v) - - -settings = Settings(_env_file=".env") diff --git a/backend/app/crud/__init__.py b/backend/app/crud/__init__.py deleted file mode 100644 index 50c02e61..00000000 --- a/backend/app/crud/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# -*- coding: utf-8 -*- -from .crud_labeler import labeler -from .crud_prompt import prompt - -__all__ = ["labeler", "prompt"] diff --git a/backend/app/crud/crud_labeler.py b/backend/app/crud/crud_labeler.py deleted file mode 100644 index 0c388feb..00000000 --- a/backend/app/crud/crud_labeler.py +++ /dev/null @@ -1,15 +0,0 @@ -# -*- coding: utf-8 -*- -from typing import Optional - -from app.crud.base import CRUDBase -from app.models.labeler import Labeler -from app.schemas.labeler import LabelerCreate, LabelerUpdate -from sqlmodel import Session - - -class CRUDLabeler(CRUDBase[Labeler, LabelerCreate, LabelerUpdate]): - def get_by_discord_username(self, db: Session, discord_username: str) -> Optional[Labeler]: - return db.query(Labeler).filter(Labeler.discord_username == discord_username).first() - - -labeler = CRUDLabeler(Labeler) diff --git a/backend/app/crud/crud_prompt.py b/backend/app/crud/crud_prompt.py deleted file mode 100644 index cf625084..00000000 --- a/backend/app/crud/crud_prompt.py +++ /dev/null @@ -1,11 +0,0 @@ -# -*- coding: utf-8 -*- -from app.crud.base import CRUDBase -from app.models.prompt import Prompt -from app.schemas.prompt import PromptCreate - - -class CRUDPrompt(CRUDBase[Prompt, PromptCreate, None]): - pass - - -prompt = CRUDPrompt(Prompt) diff --git a/backend/app/models/__init__.py b/backend/app/models/__init__.py deleted file mode 100644 index f12c41f3..00000000 --- a/backend/app/models/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -from .labeler import Labeler -from .prompt import Prompt -from .service_client import ServiceClient - -__all__ = ["Labeler", "Prompt", "ServiceClient"] diff --git a/backend/app/models/labeler.py b/backend/app/models/labeler.py deleted file mode 100644 index 9dd775b1..00000000 --- a/backend/app/models/labeler.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- -from datetime import datetime -from typing import Optional - -import sqlalchemy as sa -from sqlmodel import Field, SQLModel - - -class Labeler(SQLModel, table=True): - __tablename__ = "labeler" - id: Optional[int] = Field(default=None, primary_key=True) - display_name: str - discord_username: str - created_date: Optional[datetime] = Field( - sa_column=sa.Column(sa.DateTime(), nullable=False, server_default=sa.func.current_timestamp()), - nullable=False, - ) - is_enabled: bool - notes: str diff --git a/backend/app/models/prompt.py b/backend/app/models/prompt.py deleted file mode 100644 index 71ec956a..00000000 --- a/backend/app/models/prompt.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- -from datetime import datetime -from typing import Optional - -import sqlalchemy as sa -from sqlmodel import Field, SQLModel - - -class Prompt(SQLModel, table=True): - __tablename__ = "prompt" - id: Optional[int] = Field(default=None, primary_key=True) - labeler_id: Optional[int] = Field(default=None, foreign_key="labeler.id") - prompt: str - response: Optional[str] - lang: Optional[str] - created_date: Optional[datetime] = Field( - sa_column=sa.Column(sa.DateTime(), nullable=False, server_default=sa.func.current_timestamp()), - nullable=False, - ) diff --git a/backend/app/models/service_client.py b/backend/app/models/service_client.py deleted file mode 100644 index f7b8295a..00000000 --- a/backend/app/models/service_client.py +++ /dev/null @@ -1,17 +0,0 @@ -# -*- coding: utf-8 -*- -from typing import Optional - -from sqlmodel import Field, SQLModel - - -class ServiceClient(SQLModel, table=True): - __tablename__ = "service_client" - id: Optional[int] = Field(default=None, primary_key=True) - name: str - api_key: str - service_admin_email: Optional[str] = None - api_key: str - can_append: bool = True - can_write: bool = False - can_delete: bool = False - can_read: bool = True diff --git a/backend/app/schemas/__init__.py b/backend/app/schemas/__init__.py deleted file mode 100644 index bc2e8709..00000000 --- a/backend/app/schemas/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# -*- coding: utf-8 -*- -from .labeler import Labeler, LabelerCreate, LabelerUpdate -from .prompt import Prompt, PromptCreate - -__all__ = ["Labeler", "LabelerCreate", "LabelerUpdate", "Prompt", "PromptCreate"] diff --git a/backend/app/schemas/labeler.py b/backend/app/schemas/labeler.py deleted file mode 100644 index 936a4aa1..00000000 --- a/backend/app/schemas/labeler.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -from datetime import datetime -from typing import Optional - -from pydantic import BaseModel - - -class Labeler(BaseModel): - id: int - discord_username: str - display_name: str - created_date: datetime - is_enabled: str - notes: Optional[str] - - -class LabelerCreate(BaseModel): - discord_username: str - display_name: Optional[str] - is_enabled: Optional[bool] = True - notes: Optional[str] = None - - -class LabelerUpdate(BaseModel): - discord_username: Optional[str] = None - display_name: Optional[str] = None - enabled: Optional[bool] = None - notes: Optional[str] = None diff --git a/backend/app/schemas/prompt.py b/backend/app/schemas/prompt.py deleted file mode 100644 index b4f818ed..00000000 --- a/backend/app/schemas/prompt.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- -from datetime import datetime -from typing import Optional - -from pydantic import BaseModel - - -class Prompt(BaseModel): - id: int - labeler_id: int - prompt: str - response: Optional[str] - lang: Optional[str] - created_date: datetime - - -class PromptCreate(BaseModel): - labeler_id: Optional[int] = None - discord_username: Optional[str] = None - prompt: str - response: Optional[str] = None - lang: Optional[str] = None diff --git a/backend/backend.dockerfile b/backend/backend.dockerfile deleted file mode 100644 index 49f295d2..00000000 --- a/backend/backend.dockerfile +++ /dev/null @@ -1,14 +0,0 @@ -FROM python:3.9 - -WORKDIR /code - -COPY ./requirements.txt /code/requirements.txt - -RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt - -COPY ./app /code/app - -COPY ./app /app -ENV PYTHONPATH=/app - -CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"] diff --git a/backend/database.dockerfile b/backend/database.dockerfile deleted file mode 100644 index 69ce4e61..00000000 --- a/backend/database.dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -FROM postgres:15 - -COPY ./scripts/create-db.sh /docker-entrypoint-initdb.d/ diff --git a/backend/app/main.py b/backend/main.py similarity index 88% rename from backend/app/main.py rename to backend/main.py index 27edbc88..abcd2391 100644 --- a/backend/app/main.py +++ b/backend/main.py @@ -4,9 +4,9 @@ from pathlib import Path import alembic.command import alembic.config import fastapi -from app.api.v1.api import api_router -from app.config import settings from loguru import logger +from oasst_backend.api.v1.api import api_router +from oasst_backend.config import settings from starlette.middleware.cors import CORSMiddleware app = fastapi.FastAPI(title=settings.PROJECT_NAME, openapi_url=f"{settings.API_V1_STR}/openapi.json") @@ -27,7 +27,7 @@ if settings.UPDATE_ALEMBIC: def alembic_upgrade(): logger.info("Attempting to upgrade alembic on startup") try: - alembic_ini_path = Path(__file__).parent.parent / "alembic.ini" + alembic_ini_path = Path(__file__).parent / "alembic.ini" alembic_cfg = alembic.config.Config(str(alembic_ini_path)) alembic_cfg.set_main_option("sqlalchemy.url", settings.DATABASE_URI) alembic.command.upgrade(alembic_cfg, "head") diff --git a/backend/app/__init__.py b/backend/oasst_backend/__init__.py similarity index 100% rename from backend/app/__init__.py rename to backend/oasst_backend/__init__.py diff --git a/backend/app/api/__init__.py b/backend/oasst_backend/api/__init__.py similarity index 100% rename from backend/app/api/__init__.py rename to backend/oasst_backend/api/__init__.py diff --git a/backend/oasst_backend/api/deps.py b/backend/oasst_backend/api/deps.py new file mode 100644 index 00000000..96af5c5e --- /dev/null +++ b/backend/oasst_backend/api/deps.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +from secrets import token_hex +from typing import Generator +from uuid import UUID + +from fastapi import HTTPException, Security +from fastapi.security.api_key import APIKey, APIKeyHeader, APIKeyQuery +from loguru import logger +from oasst_backend.config import settings +from oasst_backend.database import engine +from oasst_backend.models import ApiClient +from sqlmodel import Session +from starlette.status import HTTP_403_FORBIDDEN + + +def get_db() -> Generator: + with Session(engine) as db: + yield db + + +api_key_query = APIKeyQuery(name="api_key", auto_error=False) +api_key_header = APIKeyHeader(name="X-API-Key", auto_error=False) + + +async def get_api_key( + api_key_query: str = Security(api_key_query), + api_key_header: str = Security(api_key_header), +): + if api_key_query: + return api_key_query + else: + return api_key_header + + +def api_auth( + api_key: APIKey, + db: Session, +) -> ApiClient: + + if api_key is not None: + if settings.ALLOW_ANY_API_KEY: + # make sure that a dummy api key exits in db (foreign key references) + ANY_API_KEY_ID = UUID("00000000-1111-2222-3333-444444444444") + api_client: ApiClient = db.query(ApiClient).filter(ApiClient.id == ANY_API_KEY_ID).first() + if api_client is None: + token = token_hex(32) + logger.info(f"ANY_API_KEY missing, inserting api_key: {token}") + api_client = ApiClient(id=ANY_API_KEY_ID, api_key=token, description="ANY_API_KEY, random token") + db.add(api_client) + db.commit() + return api_client + + api_client = db.query(ApiClient).filter(ApiClient.api_key == api_key).first() + if api_client is not None and api_client.enabled: + return api_client + + raise HTTPException(status_code=HTTP_403_FORBIDDEN, detail="Could not validate credentials") diff --git a/backend/app/api/v1/__init__.py b/backend/oasst_backend/api/v1/__init__.py similarity index 100% rename from backend/app/api/v1/__init__.py rename to backend/oasst_backend/api/v1/__init__.py diff --git a/backend/oasst_backend/api/v1/api.py b/backend/oasst_backend/api/v1/api.py new file mode 100644 index 00000000..cd1119d6 --- /dev/null +++ b/backend/oasst_backend/api/v1/api.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +from fastapi import APIRouter +from oasst_backend.api.v1 import tasks + +api_router = APIRouter() +api_router.include_router(tasks.router, prefix="/tasks", tags=["tasks"]) diff --git a/backend/oasst_backend/api/v1/tasks.py b/backend/oasst_backend/api/v1/tasks.py new file mode 100644 index 00000000..7ec5aa96 --- /dev/null +++ b/backend/oasst_backend/api/v1/tasks.py @@ -0,0 +1,259 @@ +# -*- coding: utf-8 -*- +import random +from typing import Any +from uuid import UUID + +from fastapi import APIRouter, Depends, HTTPException +from fastapi.security.api_key import APIKey +from loguru import logger +from oasst_backend.api import deps +from oasst_backend.models.db_payload import TaskPayload +from oasst_backend.prompt_repository import PromptRepository +from oasst_shared.schemas import protocol as protocol_schema +from sqlmodel import Session +from starlette.status import HTTP_400_BAD_REQUEST + +router = APIRouter() + + +def generate_task(request: protocol_schema.TaskRequest) -> protocol_schema.Task: + match request.type: + case protocol_schema.TaskRequestType.random: + logger.info("Frontend requested a random task.") + while request.type == protocol_schema.TaskRequestType.random: + request.type = random.choice(list(protocol_schema.TaskRequestType)).value + return generate_task(request) + case protocol_schema.TaskRequestType.summarize_story: + logger.info("Generating a SummarizeStoryTask.") + task = protocol_schema.SummarizeStoryTask( + story="This is a story. A very long story. So long, it needs to be summarized.", + ) + case protocol_schema.TaskRequestType.rate_summary: + logger.info("Generating a RateSummaryTask.") + task = protocol_schema.RateSummaryTask( + full_text="This is a story. A very long story. So long, it needs to be summarized.", + summary="This is a summary.", + scale=protocol_schema.RatingScale(min=1, max=5), + ) + case protocol_schema.TaskRequestType.initial_prompt: + logger.info("Generating an InitialPromptTask.") + task = protocol_schema.InitialPromptTask( + hint="Ask the assistant about a current event." # this is optional + ) + case protocol_schema.TaskRequestType.user_reply: + logger.info("Generating a UserReplyTask.") + task = protocol_schema.UserReplyTask( + conversation=protocol_schema.Conversation( + messages=[ + protocol_schema.ConversationMessage( + text="Hey, assistant, what's going on in the world?", + is_assistant=False, + ), + protocol_schema.ConversationMessage( + text="I'm not sure I understood correctly, could you rephrase that?", + is_assistant=True, + ), + ], + ) + ) + case protocol_schema.TaskRequestType.assistant_reply: + logger.info("Generating a AssistantReplyTask.") + task = protocol_schema.AssistantReplyTask( + conversation=protocol_schema.Conversation( + messages=[ + protocol_schema.ConversationMessage( + text="Hey, assistant, write me an English essay about water.", + is_assistant=False, + ), + ], + ) + ) + case protocol_schema.TaskRequestType.rank_initial_prompts: + logger.info("Generating a RankInitialPromptsTask.") + task = protocol_schema.RankInitialPromptsTask( + prompts=[ + "Please write a story about a time you were happy.", + "Please write a story about a time you were sad.", + ] + ) + case protocol_schema.TaskRequestType.rank_user_replies: + logger.info("Generating a RankUserRepliesTask.") + task = protocol_schema.RankUserRepliesTask( + conversation=protocol_schema.Conversation( + messages=[ + protocol_schema.ConversationMessage( + text="Hey, assistant, what's going on in the world?", + is_assistant=False, + ), + protocol_schema.ConversationMessage( + text="I'm not sure I understood correctly, could you rephrase that?", + is_assistant=True, + ), + ], + ), + replies=[ + "Oh come oooooon!", + "What are the news?", + ], + ) + + case protocol_schema.TaskRequestType.rank_assistant_replies: + logger.info("Generating a RankAssistantRepliesTask.") + task = protocol_schema.RankAssistantRepliesTask( + conversation=protocol_schema.Conversation( + messages=[ + protocol_schema.ConversationMessage( + text="Hey, assistant, what's going on in the world?", + is_assistant=False, + ), + ], + ), + replies=[ + "I'm not sure I understood correctly, could you rephrase that?", + "The world is fine. All good.", + "Crap is hitting the fan. Start farming.", + ], + ) + case _: + raise HTTPException( + status_code=HTTP_400_BAD_REQUEST, + detail="Invalid request type.", + ) + + logger.info(f"Generated {task=}.") + + return task + + +@router.post("/", response_model=protocol_schema.AnyTask) # work with Union once more types are added +def request_task( + *, + db: Session = Depends(deps.get_db), + api_key: APIKey = Depends(deps.get_api_key), + request: protocol_schema.TaskRequest, +) -> Any: + """ + Create new task. + """ + api_client = deps.api_auth(api_key, db) + + try: + task = generate_task(request) + + pr = PromptRepository(db, api_client, request.user) + pr.store_task(task) + + except Exception: + logger.exception("Failed to generate task.") + raise HTTPException( + status_code=HTTP_400_BAD_REQUEST, + ) + return task + + +@router.post("/{task_id}/ack") +def acknowledge_task( + *, + db: Session = Depends(deps.get_db), + api_key: APIKey = Depends(deps.get_api_key), + task_id: UUID, + ack_request: protocol_schema.TaskAck, +) -> Any: + """ + The frontend acknowledges a task. + """ + + api_client = deps.api_auth(api_key, db) + + try: + pr = PromptRepository(db, api_client, user=None) + + # here we store the post id in the database for the task + logger.info(f"Frontend acknowledges task {task_id=}, {ack_request=}.") + pr.bind_frontend_post_id(task_id=task_id, post_id=ack_request.post_id) + + except Exception: + logger.exception("Failed to acknowledge task.") + raise HTTPException( + status_code=HTTP_400_BAD_REQUEST, + ) + return {} + + +@router.post("/{task_id}/nack") +def acknowledge_task_failure( + *, + db: Session = Depends(deps.get_db), + api_key: APIKey = Depends(deps.get_api_key), + task_id: UUID, + nack_request: protocol_schema.TaskNAck, +) -> Any: + """ + The frontend reports failure to implement a task. + """ + deps.api_auth(api_key, db) + + logger.info(f"Frontend reports failure to implement task {task_id=}, {nack_request=}.") + # here we would store the post id in the database for the task + return {} + + +@router.post("/interaction") +def post_interaction( + *, + db: Session = Depends(deps.get_db), + api_key: APIKey = Depends(deps.get_api_key), + interaction: protocol_schema.AnyInteraction, +) -> Any: + """ + The frontend reports an interaction. + """ + api_client = deps.api_auth(api_key, db) + + try: + pr = PromptRepository(db, api_client, user=interaction.user) + + match type(interaction): + case protocol_schema.TextReplyToPost: + logger.info( + f"Frontend reports text reply to {interaction.post_id=} with {interaction.text=} by {interaction.user=}." + ) + + work_package = pr.fetch_workpackage_by_postid(interaction.post_id) + work_payload: TaskPayload = work_package.payload.payload + logger.info(f"found task work package in db: {work_payload}") + + # here we store the text reply in the database + # ToDo: role user or agent? + pr.store_text_reply(interaction, role="unknown") + + return protocol_schema.TaskDone() + case protocol_schema.PostRating: + logger.info( + f"Frontend reports rating of {interaction.post_id=} with {interaction.rating=} by {interaction.user=}." + ) + + # here we store the rating in the database + pr.store_rating(interaction) + + return protocol_schema.TaskDone() + case protocol_schema.PostRanking: + logger.info( + f"Frontend reports ranking of {interaction.post_id=} with {interaction.ranking=} by {interaction.user=}." + ) + + # TODO: check if the ranking is valid + pr.store_ranking(interaction) + # here we would store the ranking in the database + return protocol_schema.TaskDone() + case _: + raise HTTPException( + status_code=HTTP_400_BAD_REQUEST, + detail="Invalid response type.", + ) + + except Exception: + logger.exception("Interaction request failed.") + raise HTTPException( + status_code=HTTP_400_BAD_REQUEST, + ) diff --git a/backend/oasst_backend/config.py b/backend/oasst_backend/config.py new file mode 100644 index 00000000..0a1049f7 --- /dev/null +++ b/backend/oasst_backend/config.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +from typing import Any, Dict, List, Optional, Union + +from pydantic import AnyHttpUrl, BaseSettings, PostgresDsn, validator + + +class Settings(BaseSettings): + PROJECT_NAME: str = "open-assistant backend" + API_V1_STR: str = "/api/v1" + + POSTGRES_HOST: str = "localhost" + POSTGRES_PORT: str = "5432" + POSTGRES_USER: str = "postgres" + POSTGRES_PASSWORD: str = "postgres" + POSTGRES_DB: str = "postgres" + DATABASE_URI: Optional[PostgresDsn] = None + + ALLOW_ANY_API_KEY: bool = False + + @validator("DATABASE_URI", pre=True) + def assemble_db_connection(cls, v: Optional[str], values: Dict[str, Any]) -> Any: + if isinstance(v, str): + return v + return PostgresDsn.build( + scheme="postgresql", + user=values.get("POSTGRES_USER"), + password=values.get("POSTGRES_PASSWORD"), + host=values.get("POSTGRES_HOST"), + port=values.get("POSTGRES_PORT"), + path=f"/{values.get('POSTGRES_DB') or ''}", + ) + + BACKEND_CORS_ORIGINS: List[AnyHttpUrl] = [] + UPDATE_ALEMBIC: bool = True + + @validator("BACKEND_CORS_ORIGINS", pre=True) + def assemble_cors_origins(cls, v: Union[str, List[str]]) -> Union[List[str], str]: + if isinstance(v, str) and not v.startswith("["): + return [i.strip() for i in v.split(",")] + elif isinstance(v, (list, str)): + return v + raise ValueError(v) + + +settings = Settings(_env_file=".env") diff --git a/backend/oasst_backend/crud/__init__.py b/backend/oasst_backend/crud/__init__.py new file mode 100644 index 00000000..5ee00d4a --- /dev/null +++ b/backend/oasst_backend/crud/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +__all__ = [] diff --git a/backend/app/crud/base.py b/backend/oasst_backend/crud/base.py similarity index 100% rename from backend/app/crud/base.py rename to backend/oasst_backend/crud/base.py diff --git a/backend/app/database.py b/backend/oasst_backend/database.py similarity index 81% rename from backend/app/database.py rename to backend/oasst_backend/database.py index 89b636cd..66d7a857 100644 --- a/backend/app/database.py +++ b/backend/oasst_backend/database.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from app.config import settings +from oasst_backend.config import settings from sqlmodel import create_engine if settings.DATABASE_URI is None: diff --git a/backend/oasst_backend/models/__init__.py b/backend/oasst_backend/models/__init__.py new file mode 100644 index 00000000..414ec385 --- /dev/null +++ b/backend/oasst_backend/models/__init__.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +from .api_client import ApiClient +from .person import Person +from .person_stats import PersonStats +from .post import Post +from .post_reaction import PostReaction +from .work_package import WorkPackage + +__all__ = [ + "ApiClient", + "Person", + "PersonStats", + "Post", + "PostReaction", + "WorkPackage", +] diff --git a/backend/oasst_backend/models/api_client.py b/backend/oasst_backend/models/api_client.py new file mode 100644 index 00000000..f0050a90 --- /dev/null +++ b/backend/oasst_backend/models/api_client.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +from typing import Optional +from uuid import UUID, uuid4 + +import sqlalchemy as sa +import sqlalchemy.dialects.postgresql as pg +from sqlmodel import Field, SQLModel + + +class ApiClient(SQLModel, table=True): + __tablename__ = "api_client" + + id: Optional[UUID] = Field( + sa_column=sa.Column( + pg.UUID(as_uuid=True), primary_key=True, default=uuid4, server_default=sa.text("gen_random_uuid()") + ), + ) + api_key: str = Field(max_length=512, index=True, unique=True) + description: str = Field(max_length=256) + admin_email: Optional[str] = Field(max_length=256, nullable=True) + enabled: bool = Field(default=True) diff --git a/backend/oasst_backend/models/db_payload.py b/backend/oasst_backend/models/db_payload.py new file mode 100644 index 00000000..2a4438e2 --- /dev/null +++ b/backend/oasst_backend/models/db_payload.py @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- +from typing import Literal + +from oasst_backend.models.payload_column_type import payload_type +from oasst_shared.schemas import protocol as protocol_schema +from pydantic import BaseModel + + +@payload_type +class TaskPayload(BaseModel): + type: str + + +@payload_type +class SummarizationStoryPayload(TaskPayload): + type: Literal["summarize_story"] = "summarize_story" + story: str + + +@payload_type +class RateSummaryPayload(TaskPayload): + type: Literal["rate_summary"] = "rate_summary" + full_text: str + summary: str + scale: protocol_schema.RatingScale + + +@payload_type +class InitialPromptPayload(TaskPayload): + type: Literal["initial_prompt"] = "initial_prompt" + hint: str + + +@payload_type +class UserReplyPayload(TaskPayload): + type: Literal["user_reply"] = "user_reply" + conversation: protocol_schema.Conversation + hint: str | None + + +@payload_type +class AssistantReplyPayload(TaskPayload): + type: Literal["assistant_reply"] = "assistant_reply" + conversation: protocol_schema.Conversation + + +@payload_type +class PostPayload(BaseModel): + text: str + + +@payload_type +class ReactionPayload(BaseModel): + type: str + + +@payload_type +class RatingReactionPayload(ReactionPayload): + type: Literal["post_rating"] = "post_rating" + rating: str + + +@payload_type +class RankingReactionPayload(ReactionPayload): + type: Literal["post_ranking"] = "post_ranking" + ranking: list[int] + + +@payload_type +class RankConversationRepliesPayload(TaskPayload): + conversation: protocol_schema.Conversation # the conversation so far + replies: list[str] + + +@payload_type +class RankInitialPromptsPayload(TaskPayload): + """A task to rank a set of initial prompts.""" + + type: Literal["rank_initial_prompts"] = "rank_initial_prompts" + prompts: list[str] + + +@payload_type +class RankUserRepliesPayload(RankConversationRepliesPayload): + """A task to rank a set of user replies to a conversation.""" + + type: Literal["rank_user_replies"] = "rank_user_replies" + + +@payload_type +class RankAssistantRepliesPayload(RankConversationRepliesPayload): + """A task to rank a set of assistant replies to a conversation.""" + + type: Literal["rank_assistant_replies"] = "rank_assistant_replies" diff --git a/backend/oasst_backend/models/payload_column_type.py b/backend/oasst_backend/models/payload_column_type.py new file mode 100644 index 00000000..fbda51ce --- /dev/null +++ b/backend/oasst_backend/models/payload_column_type.py @@ -0,0 +1,102 @@ +# -*- coding: utf-8 -*- +import json +from typing import Any, Generic, Type, TypeVar + +import sqlalchemy.dialects.postgresql as pg +from fastapi.encoders import jsonable_encoder +from pydantic import BaseModel, parse_obj_as, validator +from pydantic.main import ModelMetaclass +from sqlalchemy.types import TypeDecorator + +payload_type_registry = {} + + +P = TypeVar("P", bound=BaseModel) + + +def payload_type(cls: Type[P]) -> Type[P]: + payload_type_registry[cls.__name__] = cls + return cls + + +class PayloadContainer(BaseModel): + payload_type: str = "" + payload: BaseModel = None + + def __init__(self, **v): + p = v["payload"] + if isinstance(p, dict): + t = v["payload_type"] + if t not in payload_type_registry: + raise RuntimeError(f"Payload type '{t}' not registered") + cls = payload_type_registry[t] + v["payload"] = cls(**p) + super().__init__(**v) + + @validator("payload", pre=True) + def check_payload(cls, v: BaseModel, values: dict[str, Any]) -> BaseModel: + values["payload_type"] = type(v).__name__ + return v + + class Config: + orm_mode = True + + +T = TypeVar("T") + + +def payload_column_type(pydantic_type): + class PayloadJSONBType(TypeDecorator, Generic[T]): + impl = pg.JSONB() + + def __init__( + self, + json_encoder=json, + ): + self.json_encoder = json_encoder + super(PayloadJSONBType, self).__init__() + + # serialize + def bind_processor(self, dialect): + impl_processor = self.impl.bind_processor(dialect) + dumps = self.json_encoder.dumps + + def process(value: T): + if value is not None: + if isinstance(pydantic_type, ModelMetaclass): + # This allows to assign non-InDB models and if they're + # compatible, they're directly parsed into the InDB + # representation, thus hiding the implementation in the + # background. However, the InDB model will still be returned + value_to_dump = pydantic_type.from_orm(value) + else: + value_to_dump = value + + value = jsonable_encoder(value_to_dump) + + if impl_processor: + return impl_processor(value) + else: + return dumps(jsonable_encoder(value_to_dump)) + + return process + + # deserialize + def result_processor(self, dialect, coltype) -> T: + impl_processor = self.impl.result_processor(dialect, coltype) + + def process(value): + if impl_processor: + value = impl_processor(value) + if value is None: + return None + # Explicitly use the generic directly, not type(T) + full_obj = parse_obj_as(pydantic_type, value) + return full_obj + + return process + + def compare_values(self, x, y): + return x == y + + return PayloadJSONBType diff --git a/backend/oasst_backend/models/person.py b/backend/oasst_backend/models/person.py new file mode 100644 index 00000000..f01f85f0 --- /dev/null +++ b/backend/oasst_backend/models/person.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +from datetime import datetime +from typing import Optional +from uuid import UUID, uuid4 + +import sqlalchemy as sa +import sqlalchemy.dialects.postgresql as pg +from sqlmodel import Field, Index, SQLModel + + +class Person(SQLModel, table=True): + __tablename__ = "person" + __table_args__ = (Index("ix_person_username", "api_client_id", "username", "auth_method", unique=True),) + + id: Optional[UUID] = Field( + sa_column=sa.Column( + pg.UUID(as_uuid=True), primary_key=True, default=uuid4, server_default=sa.text("gen_random_uuid()") + ), + ) + username: str = Field(nullable=False, max_length=128) + auth_method: str = Field(nullable=False, max_length=128, default="local") + display_name: str = Field(nullable=False, max_length=256) + created_date: Optional[datetime] = Field( + sa_column=sa.Column(sa.DateTime(), nullable=False, server_default=sa.func.current_timestamp()) + ) + api_client_id: UUID = Field(foreign_key="api_client.id") diff --git a/backend/oasst_backend/models/person_stats.py b/backend/oasst_backend/models/person_stats.py new file mode 100644 index 00000000..d05e0047 --- /dev/null +++ b/backend/oasst_backend/models/person_stats.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +from datetime import datetime +from typing import Optional +from uuid import UUID + +import sqlalchemy as sa +import sqlalchemy.dialects.postgresql as pg +from sqlmodel import Field, SQLModel + + +class PersonStats(SQLModel, table=True): + __tablename__ = "person_stats" + + person_id: Optional[UUID] = Field( + sa_column=sa.Column(pg.UUID(as_uuid=True), sa.ForeignKey("person.id"), primary_key=True) + ) + leader_score: int = 0 + modified_date: Optional[datetime] = Field( + sa_column=sa.Column(sa.DateTime(), nullable=False, server_default=sa.func.current_timestamp()) + ) + + reactions: int = 0 # reactions sent by user + posts: int = 0 # posts sent by user + upvotes: int = 0 # received upvotes (form other users) + downvotes: int = 0 # received downvotes (from other users) + work_reward: int = 0 # reward for workpackage completions + compare_wins: int = 0 # num times user's post won compare tasks + compare_losses: int = 0 # num times users's post lost compare tasks diff --git a/backend/oasst_backend/models/post.py b/backend/oasst_backend/models/post.py new file mode 100644 index 00000000..d1569a67 --- /dev/null +++ b/backend/oasst_backend/models/post.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +from datetime import datetime +from typing import Optional +from uuid import UUID, uuid4 + +import sqlalchemy as sa +import sqlalchemy.dialects.postgresql as pg +from sqlmodel import Field, Index, SQLModel + +from .payload_column_type import PayloadContainer, payload_column_type + + +class Post(SQLModel, table=True): + __tablename__ = "post" + __table_args__ = (Index("ix_post_frontend_post_id", "api_client_id", "frontend_post_id", unique=True),) + + id: Optional[UUID] = Field( + sa_column=sa.Column( + pg.UUID(as_uuid=True), primary_key=True, default=uuid4, server_default=sa.text("gen_random_uuid()") + ), + ) + parent_id: UUID = Field(nullable=True) + thread_id: UUID = Field(nullable=False, index=True) + workpackage_id: UUID = Field(nullable=True, index=True) + person_id: UUID = Field(nullable=True, foreign_key="person.id", index=True) + role: str = Field(nullable=False, max_length=128) + api_client_id: UUID = Field(nullable=False, foreign_key="api_client.id") + frontend_post_id: str = Field(max_length=200, nullable=False) + created_date: Optional[datetime] = Field( + sa_column=sa.Column(sa.DateTime(), nullable=False, server_default=sa.func.current_timestamp()) + ) + payload_type: str = Field(nullable=False, max_length=200) + payload: PayloadContainer = Field(sa_column=sa.Column(payload_column_type(PayloadContainer), nullable=True)) diff --git a/backend/oasst_backend/models/post_reaction.py b/backend/oasst_backend/models/post_reaction.py new file mode 100644 index 00000000..fb8b0fcb --- /dev/null +++ b/backend/oasst_backend/models/post_reaction.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +from datetime import datetime +from typing import Optional +from uuid import UUID + +import sqlalchemy as sa +import sqlalchemy.dialects.postgresql as pg +from sqlmodel import Field, SQLModel + +from .payload_column_type import PayloadContainer, payload_column_type + + +class PostReaction(SQLModel, table=True): + __tablename__ = "post_reaction" + + post_id: Optional[UUID] = Field( + sa_column=sa.Column(pg.UUID(as_uuid=True), sa.ForeignKey("post.id"), nullable=False, primary_key=True) + ) + person_id: UUID = Field( + sa_column=sa.Column(pg.UUID(as_uuid=True), sa.ForeignKey("person.id"), nullable=False, primary_key=True) + ) + created_date: Optional[datetime] = Field( + sa_column=sa.Column(sa.DateTime(), nullable=False, server_default=sa.func.current_timestamp()) + ) + payload_type: str = Field(nullable=False, max_length=200) + payload: PayloadContainer = Field(sa_column=sa.Column(payload_column_type(PayloadContainer), nullable=False)) + api_client_id: UUID = Field(nullable=False, foreign_key="api_client.id") diff --git a/backend/oasst_backend/models/work_package.py b/backend/oasst_backend/models/work_package.py new file mode 100644 index 00000000..0a452a71 --- /dev/null +++ b/backend/oasst_backend/models/work_package.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +from datetime import datetime +from typing import Optional +from uuid import UUID, uuid4 + +import sqlalchemy as sa +import sqlalchemy.dialects.postgresql as pg +from sqlmodel import Field, SQLModel + +from .payload_column_type import PayloadContainer, payload_column_type + + +class WorkPackage(SQLModel, table=True): + __tablename__ = "work_package" + + id: Optional[UUID] = Field( + sa_column=sa.Column( + pg.UUID(as_uuid=True), primary_key=True, default=uuid4, server_default=sa.text("gen_random_uuid()") + ), + ) + created_date: Optional[datetime] = Field( + sa_column=sa.Column(sa.DateTime(), nullable=False, server_default=sa.func.current_timestamp()), + ) + expiry_date: Optional[datetime] = Field(sa_column=sa.Column(sa.DateTime(), nullable=True)) + person_id: UUID = Field(nullable=True, foreign_key="person.id", index=True) + payload_type: str = Field(nullable=False, max_length=200) + payload: PayloadContainer = Field(sa_column=sa.Column(payload_column_type(PayloadContainer), nullable=False)) + api_client_id: UUID = Field(nullable=False, foreign_key="api_client.id") diff --git a/backend/oasst_backend/prompt_repository.py b/backend/oasst_backend/prompt_repository.py new file mode 100644 index 00000000..b0063cdf --- /dev/null +++ b/backend/oasst_backend/prompt_repository.py @@ -0,0 +1,316 @@ +# -*- coding: utf-8 -*- +from datetime import datetime +from typing import Optional +from uuid import UUID, uuid4 + +import oasst_backend.models.db_payload as db_payload +from loguru import logger +from oasst_backend.models import ApiClient, Person, Post, PostReaction, WorkPackage +from oasst_backend.models.payload_column_type import PayloadContainer +from oasst_shared.schemas import protocol as protocol_schema +from sqlmodel import Session + + +class PromptRepository: + def __init__(self, db: Session, api_client: ApiClient, user: Optional[protocol_schema.User]): + self.db = db + self.api_client = api_client + self.person = self.lookup_person(user) + self.person_id = self.person.id if self.person else None + + def lookup_person(self, user: protocol_schema.User) -> Person: + if not user: + return None + person: Person = ( + self.db.query(Person) + .filter( + Person.api_client_id == self.api_client.id, + Person.username == user.id, + Person.auth_method == user.auth_method, + ) + .first() + ) + if person is None: + # user is unknown, create new record + person = Person( + username=user.id, + display_name=user.display_name, + api_client_id=self.api_client.id, + auth_method=user.auth_method, + ) + self.db.add(person) + self.db.commit() + self.db.refresh(person) + elif user.display_name and user.display_name != person.display_name: + # we found the user but the display name changed + person.display_name = user.display_name + self.db.add(person) + self.db.commit() + return person + + def validate_post_id(self, post_id: str) -> None: + if not isinstance(post_id, str): + raise TypeError(f"post_id must be string, not {type(post_id)}") + if not post_id: + raise ValueError("post_id must not be empty") + + def bind_frontend_post_id(self, task_id: UUID, post_id: str): + self.validate_post_id(post_id) + + # find work package + work_pack: WorkPackage = ( + self.db.query(WorkPackage) + .filter(WorkPackage.id == task_id, WorkPackage.api_client_id == self.api_client.id) + .first() + ) + if work_pack is None: + raise KeyError(f"WorkPackage for task {task_id} not found") + if work_pack.expiry_date is not None and datetime.utcnow() > work_pack.expiry_date: + raise RuntimeError("WorkPackage already expired.") + + # ToDo: check race-condition, transaction + + # check if task thread exits + thread_root = ( + self.db.query(Post) + .filter( + Post.workpackage_id == work_pack.id, + Post.frontend_post_id == post_id, + Post.parent_id is None, + Post.api_client_id == self.api_client.id, + ) + .one_or_none() + ) + if thread_root is None: + thread_id = uuid4() + thread_root = self.insert_post( + post_id=thread_id, + thread_id=thread_id, + frontend_post_id=post_id, + parent_id=None, + role="system", + workpackage_id=work_pack.id, + payload=None, + payload_type="bind", + ) + return thread_root + + def fetch_post_by_frontend_post_id(self, frontend_post_id: str, fail_if_missing: bool = True) -> Post: + self.validate_post_id(frontend_post_id) + post: Post = ( + self.db.query(Post) + .filter(Post.api_client_id == self.api_client.id, Post.frontend_post_id == frontend_post_id) + .one_or_none() + ) + if fail_if_missing and post is None: + raise KeyError(f"Post with post_id {frontend_post_id} not found.") + return post + + def fetch_workpackage_by_postid(self, post_id: str) -> WorkPackage: + self.validate_post_id(post_id) + post = self.fetch_post_by_frontend_post_id(post_id, fail_if_missing=True) + work_pack = self.db.query(WorkPackage).filter(WorkPackage.id == post.workpackage_id).one() + return work_pack + + def store_text_reply(self, reply: protocol_schema.TextReplyToPost, role: str) -> Post: + self.validate_post_id(reply.post_id) + self.validate_post_id(reply.user_post_id) + + # find post with post-id + parent_post: Post = ( + self.db.query(Post) + .filter( + Post.api_client_id == self.api_client.id, + Post.frontend_post_id == reply.post_id, + # Post.person_id == self.person_id + ) + .one_or_none() + ) + + if parent_post is None: + raise KeyError(f"Post for post_id {reply.post_id} not found.") + + # create reply post + user_post_id = uuid4() + user_post = self.insert_post( + post_id=user_post_id, + frontend_post_id=reply.user_post_id, + parent_id=parent_post.id, + thread_id=parent_post.thread_id, + workpackage_id=parent_post.workpackage_id, + role=role, + payload=db_payload.PostPayload(text=reply.text), + ) + return user_post + + def store_rating(self, rating: protocol_schema.PostRating) -> PostReaction: + post = self.fetch_post_by_frontend_post_id(rating.post_id, fail_if_missing=True) + + work_package = self.fetch_workpackage_by_postid(rating.post_id) + work_payload: db_payload.RateSummaryPayload = work_package.payload.payload + if type(work_payload) != db_payload.RateSummaryPayload: + raise ValueError( + f"work_package payload type mismatch: {type(work_payload)=} != {db_payload.RateSummaryPayload}" + ) + + if rating.rating < work_payload.scale.min or rating.rating > work_payload.scale.max: + raise ValueError(f"Invalid rating value: {rating.rating=} not in {work_payload.scale=}") + + # store reaction to post + reaction_payload = db_payload.RatingReactionPayload(rating=rating.rating) + reaction = self.insert_reaction(post.id, reaction_payload) + logger.info(f"Ranking {rating.rating} stored for work_package {work_package.id}.") + return reaction + + def store_ranking(self, ranking: protocol_schema.PostRanking) -> PostReaction: + post = self.fetch_post_by_frontend_post_id(ranking.post_id, fail_if_missing=True) + + # fetch work_package + work_package = self.fetch_workpackage_by_postid(ranking.post_id) + work_payload: db_payload.RankConversationRepliesPayload | db_payload.RankInitialPromptsPayload = ( + work_package.payload.payload + ) + + match type(work_payload): + + case db_payload.RankUserRepliesPayload | db_payload.RankAssistantRepliesPayload: + # validate ranking + num_replies = len(work_payload.replies) + if sorted(ranking.ranking) != list(range(num_replies)): + raise ValueError( + f"Invalid ranking submitted. Each reply index must appear exactly once ({num_replies=})." + ) + + # store reaction to post + reaction_payload = db_payload.RankingReactionPayload(ranking=ranking.ranking) + reaction = self.insert_reaction(post.id, reaction_payload) + + logger.info(f"Ranking {ranking.ranking} stored for work_package {work_package.id}.") + + return reaction + + case db_payload.RankInitialPromptsPayload: + # validate ranking + if sorted(ranking.ranking) != list(range(num_prompts := len(work_payload.prompts))): + raise ValueError( + f"Invalid ranking submitted. Each reply index must appear exactly once ({num_prompts=})." + ) + + # store reaction to post + reaction_payload = db_payload.RankingReactionPayload(ranking=ranking.ranking) + reaction = self.insert_reaction(post.id, reaction_payload) + + logger.info(f"Ranking {ranking.ranking} stored for work_package {work_package.id}.") + + return reaction + + case _: + raise ValueError( + f"work_package payload type mismatch: {type(work_payload)=} != {db_payload.RankConversationRepliesPayload}" + ) + + def store_task(self, task: protocol_schema.Task) -> WorkPackage: + payload: db_payload.TaskPayload + match type(task): + case protocol_schema.SummarizeStoryTask: + payload = db_payload.SummarizationStoryPayload(story=task.story) + + case protocol_schema.RateSummaryTask: + payload = db_payload.RateSummaryPayload( + full_text=task.full_text, summary=task.summary, scale=task.scale + ) + + case protocol_schema.InitialPromptTask: + payload = db_payload.InitialPromptPayload(hint=task.hint) + + case protocol_schema.UserReplyTask: + payload = db_payload.UserReplyPayload(conversation=task.conversation, hint=task.hint) + + case protocol_schema.AssistantReplyTask: + payload = db_payload.AssistantReplyPayload(type=task.type, conversation=task.conversation) + + case protocol_schema.RankInitialPromptsTask: + payload = db_payload.RankInitialPromptsPayload(tpye=task.type, prompts=task.prompts) + + case protocol_schema.RankUserRepliesTask: + payload = db_payload.RankUserRepliesPayload( + tpye=task.type, conversation=task.conversation, replies=task.replies + ) + + case protocol_schema.RankAssistantRepliesTask: + payload = db_payload.RankAssistantRepliesPayload( + tpye=task.type, conversation=task.conversation, replies=task.replies + ) + + case _: + raise ValueError(f"Invalid task type: {type(task)=}") + + wp = self.insert_work_package(payload=payload, id=task.id) + assert wp.id == task.id + return wp + + def insert_work_package(self, payload: db_payload.TaskPayload, id: UUID = None) -> WorkPackage: + c = PayloadContainer(payload=payload) + wp = WorkPackage( + id=id, + person_id=self.person_id, + payload_type=type(payload).__name__, + payload=c, + api_client_id=self.api_client.id, + ) + self.db.add(wp) + self.db.commit() + self.db.refresh(wp) + return wp + + def insert_post( + self, + *, + post_id: UUID, + frontend_post_id: str, + parent_id: UUID, + thread_id: UUID, + workpackage_id: UUID, + role: str, + payload: db_payload.PostPayload, + payload_type: str = None, + ) -> Post: + if payload_type is None: + if payload is None: + payload_type = "null" + else: + payload_type = type(payload).__name__ + + post = Post( + id=post_id, + parent_id=parent_id, + thread_id=thread_id, + workpackage_id=workpackage_id, + person_id=self.person_id, + role=role, + frontend_post_id=frontend_post_id, + api_client_id=self.api_client.id, + payload_type=payload_type, + payload=PayloadContainer(payload=payload), + ) + self.db.add(post) + self.db.commit() + self.db.refresh(post) + return post + + def insert_reaction(self, post_id: UUID, payload: db_payload.ReactionPayload) -> PostReaction: + if self.person_id is None: + raise ValueError("User required") + + container = PayloadContainer(payload=payload) + reaction = PostReaction( + post_id=post_id, + person_id=self.person_id, + payload=container, + api_client_id=self.api_client.id, + payload_type=type(payload).__name__, + ) + self.db.add(reaction) + self.db.commit() + self.db.refresh(reaction) + return reaction diff --git a/backend/scripts/create-db.sh b/backend/scripts/create-db.sh deleted file mode 100755 index 409377e6..00000000 --- a/backend/scripts/create-db.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -set -e - -psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL - CREATE DATABASE ocgpt_backend; -EOSQL diff --git a/backend/scripts/run-local.sh b/backend/scripts/run-local.sh deleted file mode 100755 index 7c6efabc..00000000 --- a/backend/scripts/run-local.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -export DATABASE_URI=postgresql://postgres:postgres@localhost:5432/postgres - -uvicorn app.main:app --reload diff --git a/bot/Makefile b/bot/Makefile deleted file mode 100644 index 87f07026..00000000 --- a/bot/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -install: - python -m pip install -U pip - python -m pip install -e . - -lint: ## [Local development] Run pylint and black - python -m pylint app - python -m black --check -l 120 app - -black: ## [Local development] Auto-format python code using black - python -m black -l 120 . - -run: - python -m bot diff --git a/bot/README.md b/bot/README.md deleted file mode 100644 index 935cfb6c..00000000 --- a/bot/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# open-chat-gpt - -This is the github repo for the open-chat-gpt project. -We are currently building a discord bot in order to make everyone contribute with great prompts and answers. -Join us! -https://discord.gg/ZUfPw6jP - -## Project description - -We are calling the community for help to collect ChatGPT-like Instruction-Fulfillment datasamples via Discord. People can post Instructions they think would make sense for ChatGPT-like systems & also provide a good reference answer for it. - -## Todo - -Figure out ouath flow for the app to work inside the open-chat-gpt testing channel here. https://discord.gg/JJSKtRhv diff --git a/bot/bot.py b/bot/bot.py deleted file mode 100644 index 2509138a..00000000 --- a/bot/bot.py +++ /dev/null @@ -1,207 +0,0 @@ -# -*- coding: utf-8 -*- - -import json -import os - -import discord -import requests -from discord import app_commands -from dotenv import load_dotenv -from loguru import logger - -bot_url = "https://discord.com/api/oauth2/authorize?client_id=1051614245940375683&permissions=8&scope=bot" - -# Load up all the important environment variables. -load_dotenv() - -# For authentication. -TOKEN = os.getenv("DISCORD_TOKEN") - -# For Backends. -API_SERVER_URL = os.getenv("API_SERVER_URL") -API_SERVER_KEY = os.getenv("API_SERVER_KEY") - -labelers_url = f"{API_SERVER_URL}/api/v1/labelers/" -prompts_url = f"{API_SERVER_URL}/api/v1/prompts/" -headers = {"X-API-Key": API_SERVER_KEY} - -# For testing only. -TEST_GUILD = os.getenv("TEST_GUILD") - - -# Initiate the client and command tree to create slash commands. -class OpenChatGPTClient(discord.Client): - def __init__(self, *, intents: discord.Intents): - super().__init__(intents=intents) - self.tree = app_commands.CommandTree(self) - - async def setup_hook(self): - if TEST_GUILD: - # When testing the bot it's handy to run in a single server (called a - # Guide in the API). This is relatively fast. - guild = discord.Object(id=TEST_GUILD) - self.tree.copy_global_to(guild=guild) - await self.tree.sync(guild=guild) - else: - # This can take up to an hour for the commands to be registered. - await self.tree.sync() - logger.debug("Ready!") - - -# List the set of intents needed for commands to operate properly. -intents = discord.Intents.default() -intents.message_content = True -client = OpenChatGPTClient(intents=intents) - - -class LikeButton(discord.ui.Button): - def __init__(self, label, channel, username, prompt): - super().__init__(label=label, style=discord.ButtonStyle.green, emoji="👍") - self.channel = channel - self.username = username - self.prompt = prompt - - async def callback(self, interaction): - # interaction holds the interaction object - # await interaction.response.defer() - await interaction.response.send_message("Thanks for your feedback. You liked this 👍 ") - - -class NeutralButton(discord.ui.Button): - def __init__(self, label, channel, username, prompt): - super().__init__(label=label, style=discord.ButtonStyle.green, emoji="😐") - self.channel = channel - self.username = username - self.prompt = prompt - - async def callback(self, interaction): - # interaction holds the interaction object - # await interaction.response.defer() - await interaction.response.send_message("Thanks for your feedback. You thought this was neutral 😐 ") - - -class DislikeButton(discord.ui.Button): - def __init__(self, label, channel, username, prompt): - super().__init__(label=label, style=discord.ButtonStyle.green, emoji="👎") - self.channel = channel - self.username = username - self.prompt = prompt - - async def callback(self, interaction): - # interaction holds the interaction object - # await interaction.response.defer() - # send the feedback to the backend # - await interaction.response.send_message("Thanks for your feedback. You disliked this 👎 ") - - -@client.tree.command() -async def register(interaction: discord.Interaction): - """Registers the user for submissions.""" - labeler = { - "discord_username": f"{interaction.user.id}", - "display_name": interaction.user.name, - "is_enabled": True, - } - response = requests.post(labelers_url, headers=headers, json=labeler) - if response.status_code == 200: - await interaction.response.send_message(f"Added you {interaction.user.name}") - else: - logger.debug(response) - await interaction.response.send_message("Failed to add you") - - -@client.tree.command() -async def list_participants(interaction: discord.Interaction): - """Reports the set of registered participants.""" - response = requests.get(labelers_url, headers=headers) - if response.status_code == 200: - names = ",".join([labeler["display_name"] for labeler in response.json()]) - await interaction.response.send_message(f"Found these users: {names}") - else: - await interaction.response.send_message("Failed to fetch participants") - - -async def send_prompt_with_response_and_button(channel, username, prompt, response): - await channel.send(f"What do you think about the following interaction: \nprompt: {prompt} \nresponse: {response}") - # await channel.send(f'Please click on the button that best describes your reaction to the response:') - - # add buttons - view = discord.ui.View() - like = LikeButton(label="Like", channel=channel, username=username, prompt=prompt) - neutral = NeutralButton(label="Neutral", channel=channel, username=username, prompt=prompt) - dislike = DislikeButton(label="Dislike", channel=channel, username=username, prompt=prompt) - - view.add_item(item=like) - view.add_item(item=neutral) - view.add_item(item=dislike) - await channel.send(view=view) - - -@client.tree.command() -async def review_prompts(interaction: discord.Interaction, number_of_prompts: int): - # get the prompt from the db - url = f"{prompts_url}?begin_id=0&limit={number_of_prompts}" - response = requests.get(url, headers=headers) - if response.status_code == 200: - prompts = response.json() - logger.debug("the responses are:", prompts) - for prompt in prompts: - await send_prompt_with_response_and_button( - interaction.channel, interaction.user.name, prompt["prompt"], prompt["response"] - ) - else: - await interaction.response.send_message("Failed to get prompts for review") - - -@client.tree.command() -async def add_prompt(interaction: discord.Interaction, prompt: str, response: str, language: str = "en"): - """Uploads a single prompt to the server.""" - prompt = { - "discord_username": f"{interaction.user.id}", - "labeler_id": 5, - "prompt": prompt, - "response": response, - "lang": language, - } - response = requests.post(prompts_url, headers=headers, json=prompt) - if response.status_code == 200: - await send_prompt_with_response_and_button( - interaction.channel, interaction.user.name, prompt["prompt"], prompt["response"] - ) - # send the prompt back with buttons for the user to click on - # await interaction.response.send_message("Added your prompt") - else: - await interaction.response.send_message("Failed to add the prompt") - - -@client.tree.command() -async def add_prompts_set(interaction: discord.Interaction, prompts: discord.Attachment): - """Uploads a batch of prompts to the server.""" - # Loading a bunch of prompts from a file can take a while. So first defer - # the response to ensure we're able to later tell the user what happened. - await interaction.response.defer(ephemeral=True) - - # Read the prompts and load them one by one. - # TODO: Upload a batch when the API supports it. - # TODO: Handle incorrect file types and parsing errors. - prompts_raw = await prompts.read() - prompts_loaded = json.loads(prompts_raw) - count = 0 - for entry in prompts_loaded: - for response in entry["responses"]: - prompt = { - "discord_username": f"{interaction.user.id}", - "labeler_id": 5, - "prompt": entry["prompt"], - "response": response, - "lang": "en", - } - response = requests.post(prompts_url, headers=headers, json=prompt) - if response.status_code != 200: - await interaction.followup.send("Failed to upload") - return - count += 1 - await interaction.followup.send(f"Loaded up {count} prompts") - - -client.run(TOKEN) diff --git a/bot/requirements.txt b/bot/requirements.txt deleted file mode 100644 index 617e7071..00000000 --- a/bot/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -discord.py==2.1.0 -python-dotenv==0.21.0 diff --git a/bot/setup.py b/bot/setup.py deleted file mode 100644 index 25df4d9a..00000000 --- a/bot/setup.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- -from setuptools import find_packages, setup - -if __name__ == "__main__": - import os - - def _read_reqs(relpath): - fullpath = os.path.join(os.path.dirname(__file__), relpath) - with open(fullpath) as f: - return [s.strip() for s in f.readlines() if (s.strip() and not s.startswith("#"))] - - REQUIREMENTS = _read_reqs("requirements.txt") - - setup( - name="open-chat-gpt", - packages=find_packages(), - version="0.0.1", - license="Apache 2.0", - description="A Discord Bot for collecting and ranking prompts to train an Open ChatGPT", - keywords=["machine learning", "natural language processing", "discord"], - install_requires=REQUIREMENTS, - classifiers=[ - "Development Status :: Alpha", - "Intended Audience :: Developers", - "Topic :: Scientific/Engineering :: Artificial Intelligence", - "License :: OSI Approved :: Apache License", - "Programming Language :: Python :: 3.6", - ], - ) diff --git a/bot/test_prompts.json b/bot/test_prompts.json deleted file mode 100644 index be892986..00000000 --- a/bot/test_prompts.json +++ /dev/null @@ -1,10 +0,0 @@ -[ - { - "prompt": "tell me the name of two dogs", - "responses": ["Charles", "bobby"] - }, - { - "prompt": "Name one type of cheese made in france", - "responses": ["Munster", "Gouda"] - } -] diff --git a/bot/.gitignore b/discord-bot/.gitignore similarity index 100% rename from bot/.gitignore rename to discord-bot/.gitignore diff --git a/discord-bot/README.md b/discord-bot/README.md new file mode 100644 index 00000000..a585b37f --- /dev/null +++ b/discord-bot/README.md @@ -0,0 +1,20 @@ +# Open-Assistant Data Collection Discord Bot + +This bot collects human feedback to create a dataset for RLHF-alignment of an assistant chat bot based on a large langugae model. You and other people can teach the bot how to respond to user requests by demonstration and by garding and ranking the bot's outputs. If you want to learn more about RLHF please refer [to OpenAI's InstructGPT blog post](https://openai.com/blog/instruction-following/). + +## Invite official bot + +To add the official Open-Assistant data collection bot to your discord server [click here](https://discord.com/api/oauth2/authorize?client_id=1054078345542910022&permissions=1634235579456&scope=bot). The bot needs access to read the contents of user text messages. + +## Bot token for development + +To test the bot on your own discord server you need to register a discord application at the [Discord Developer Portal](https://discord.com/developers/applications) and get at bot token. + +1. Follow a tutorial on how to get a bot token, for example this one: [Creating a discord bot & getting a token](https://github.com/reactiflux/discord-irc/wiki/Creating-a-discord-bot-&-getting-a-token) +2. The bot script expects the bot token to be in an environment variable called `BOT_TOKEN`. + +The simplest way to configure the token is via an `.env` file: + +``` +BOT_TOKEN=XYZABC123... +``` diff --git a/discord-bot/__main__.py b/discord-bot/__main__.py new file mode 100644 index 00000000..9e5e29c7 --- /dev/null +++ b/discord-bot/__main__.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- +from bot import OpenAssistantBot +from bot_settings import settings + +# invite bot url: https://discord.com/api/oauth2/authorize?client_id=1054078345542910022&permissions=1634235579456&scope=bot + +if __name__ == "__main__": + bot = OpenAssistantBot( + settings.BOT_TOKEN, + bot_channel_name=settings.BOT_CHANNEL_NAME, + backend_url=settings.BACKEND_URL, + api_key=settings.API_KEY, + owner_id=settings.OWNER_ID, + template_dir=settings.TEMPLATE_DIR, + debug=settings.DEBUG, + ) + bot.run() diff --git a/discord-bot/api_client.py b/discord-bot/api_client.py new file mode 100644 index 00000000..1de6bb17 --- /dev/null +++ b/discord-bot/api_client.py @@ -0,0 +1,74 @@ +# -*- coding: utf-8 -*- +import enum +from typing import Optional, Type + +import requests +from oasst_shared.schemas import protocol as protocol_schema + + +class TaskType(str, enum.Enum): + summarize_story = "summarize_story" + rate_summary = "rate_summary" + initial_prompt = "initial_prompt" + user_reply = "user_reply" + assistant_reply = "assistant_reply" + rank_initial_prompts = "rank_initial_prompts" + rank_user_replies = "rank_user_replies" + rank_assistant_replies = "rank_assistant_replies" + done = "task_done" + + +class ApiClient: + def __init__(self, backend_url: str, api_key: str): + self.backend_url = backend_url + self.api_key = api_key + + task_models_map: dict[str, Type[protocol_schema.Task]] = { + TaskType.summarize_story: protocol_schema.SummarizeStoryTask, + TaskType.rate_summary: protocol_schema.RateSummaryTask, + TaskType.initial_prompt: protocol_schema.InitialPromptTask, + TaskType.user_reply: protocol_schema.UserReplyTask, + TaskType.assistant_reply: protocol_schema.AssistantReplyTask, + TaskType.rank_initial_prompts: protocol_schema.RankInitialPromptsTask, + TaskType.rank_user_replies: protocol_schema.RankUserRepliesTask, + TaskType.rank_assistant_replies: protocol_schema.RankAssistantRepliesTask, + TaskType.done: protocol_schema.TaskDone, + } + self.task_models_map = task_models_map + + def post(self, path: str, json: dict) -> dict: + response = requests.post(f"{self.backend_url}{path}", json=json, headers={"X-API-Key": self.api_key}) + response.raise_for_status() + return response.json() + + def _parse_task(self, data: dict) -> protocol_schema.Task: + if not isinstance(data, dict): + raise ValueError("dict expected") + + task_type = data.get("type") + if task_type not in self.task_models_map: + raise RuntimeError(f"Unsupported task type: {task_type}") + + return self.task_models_map[task_type].parse_obj(data) + + def fetch_task( + self, task_type: protocol_schema.TaskRequestType, user: Optional[protocol_schema.User] = None + ) -> protocol_schema.Task: + req = protocol_schema.TaskRequest(type=task_type, user=user) + data = self.post("/api/v1/tasks/", req.dict()) + return self._parse_task(data) + + def fetch_random_task(self, user: Optional[protocol_schema.User] = None) -> protocol_schema.Task: + return self.fetch_task(protocol_schema.TaskRequestType.random, user) + + def ack_task(self, task_id: str, post_id: str) -> None: + req = protocol_schema.TaskAck(post_id=post_id) + return self.post(f"/api/v1/tasks/{task_id}/ack", req.dict()) + + def nack_task(self, task_id: str, reason: str) -> None: + req = protocol_schema.TaskNAck(reason=reason) + return self.post(f"/api/v1/tasks/{task_id}/nack", req.dict()) + + def post_interaction(self, interaction: protocol_schema.Interaction) -> protocol_schema.Task: + data = self.post("/api/v1/tasks/interaction", interaction.dict()) + return self._parse_task(data) diff --git a/discord-bot/bot.py b/discord-bot/bot.py new file mode 100644 index 00000000..a19fdfe1 --- /dev/null +++ b/discord-bot/bot.py @@ -0,0 +1,283 @@ +# -*- coding: utf-8 -*- +from __future__ import annotations + +import asyncio +from datetime import timedelta +from pathlib import Path +from typing import Optional, Union + +import discord +import task_handlers +from api_client import ApiClient, TaskType +from bot_base import BotBase +from discord import app_commands +from loguru import logger +from message_templates import MessageTemplates +from oasst_shared.schemas import protocol as protocol_schema +from utils import get_git_head_hash, utcnow + +__version__ = "0.0.3" +BOT_NAME = "Open-Assistant Junior" + + +class OpenAssistantBot(BotBase): + def __init__( + self, + bot_token: str, + bot_channel_name: str, + backend_url: str, + api_key: str, + owner_id: Optional[Union[int, str]] = None, + template_dir: str = "./templates", + debug: bool = False, + ): + super().__init__() + + self.template_dir = Path(template_dir) + self.bot_channel_name = bot_channel_name + self.templates = MessageTemplates(template_dir) + self.debug = debug + + intents = discord.Intents.default() + intents.message_content = True + + if isinstance(owner_id, str): + owner_id = int(owner_id) + self.owner_id = owner_id + + self.bot_token = bot_token + client = discord.Client(intents=intents) + self.client = client + self.loop = client.loop + + self.bot_channel: discord.TextChannel = None + self.backend = ApiClient(backend_url, api_key) + + self.tree = app_commands.CommandTree(self.client, fallback_to_global=True) + + @client.event + async def on_ready(): + self.bot_channel = self.get_text_channel_by_name(bot_channel_name) + logger.info(f"{client.user} is now running!") + + await self.delete_all_old_bot_messages() + # if self.debug: + # await self.post_boot_message() + await self.post_welcome_message() + + client.loop.create_task(self.background_timer(), name="OpenAssistantBot.background_timer()") + + @client.event + async def on_message(message: discord.Message): + # ignore own messages + if message.author != client.user: + await self.handle_message(message) + + @self.tree.command() + async def tutorial(interaction: discord.Interaction): + """Start the Open-Assistant tutorial via DMs.""" + + dm = await self.client.create_dm(discord.Object(interaction.user.id)) + await dm.send("Tutorial coming soon... :-)") + await interaction.response.send_message(f"tutorial command by {interaction.user.name}") + + @self.tree.command() + async def help(interaction: discord.Interaction): + """Sends the user a list of all available commands""" + await self.post_help(interaction.user) + await interaction.response.send_message(f"@{interaction.user.display_name}, I've sent you a PM.") + + @self.tree.command() + async def work(interaction: discord.Interaction): + """Request a new personalized task""" + + # task = self.backend.fetch_task(protocol_schema.TaskRequestType.rate_summary, user=None) + # task = self.backend.fetch_random_task(user=None) + q = task_handlers.Questionnaire() + await interaction.response.send_modal(q) + + async def post_help(self, user: discord.abc.User) -> discord.Message: + is_bot_owner = user.id == self.owner_id + return await self.post_template("help.msg", channel=user, is_bot_owner=is_bot_owner) + + async def post_boot_message(self) -> discord.Message: + return await self.post_template( + "boot.msg", bot_name=BOT_NAME, version=__version__, git_hash=get_git_head_hash(), debug=self.debug + ) + + async def post_welcome_message(self) -> discord.Message: + return await self.post_template("welcome.msg") + + async def delete_all_old_bot_messages(self) -> None: + logger.info("Deleting old threads...") + for thread in self.bot_channel.threads: + if thread.owner_id == self.client.user.id: + await thread.delete() + logger.info("Completed deleting old theards.") + + logger.info("Deleting old messages...") + look_until = utcnow() - timedelta(days=365) + async for msg in self.bot_channel.history(limit=None): + msg: discord.Message + if msg.created_at < look_until: + break + if msg.author.id == self.client.user.id: + await msg.delete() + logger.info("Completed deleting old messages.") + + async def next_task(self): + task_type = protocol_schema.TaskRequestType.random + task = self.backend.fetch_task(task_type, user=None) + + handler: task_handlers.ChannelTaskBase = None + match task.type: + case TaskType.summarize_story: + handler = task_handlers.SummarizeStoryHandler() + case TaskType.rate_summary: + handler = task_handlers.RateSummaryHandler() + case TaskType.initial_prompt: + handler = task_handlers.InitialPromptHandler() + case TaskType.user_reply: + handler = task_handlers.UserReplyHandler() + case TaskType.assistant_reply: + handler = task_handlers.AssistantReplyHandler() + case TaskType.rank_initial_prompts: + handler = task_handlers.RankInitialPromptsHandler() + case TaskType.rank_user_replies | TaskType.rank_assistant_replies: + handler = task_handlers.RankConversationsHandler() + case _: + logger.warning(f"Unsupported task type received: {task.type}") + self.backend.nack_task(task.id, "not supported") + + if handler: + try: + logger.info(f"strarting task {task.id}") + msg = await handler.start(self, task) + self.backend.ack_task(task.id, msg.id) + except Exception: + logger.exception("Starting task failed.") + self.backend.nack_task(task.id, "faled") + + async def background_timer(self): + next_remove_completed = utcnow() + timedelta(seconds=10) + next_fetch_task = utcnow() + timedelta(seconds=1) + while True: + now = utcnow() + + if self.bot_channel: + if now > next_fetch_task: + next_fetch_task = utcnow() + timedelta(seconds=60) + + try: + await self.next_task() + except Exception: + logger.exception("fetching next task failed") + + for x in self.reply_handlers.values(): + x.handler.tick(now) + + if now > next_remove_completed: + next_remove_completed = utcnow() + timedelta(seconds=10) + await self.remove_completed_handlers() + + await asyncio.sleep(1) + + async def _sync(self, command: str, message: discord.Message): + + logger.info(f"sync tree command received: {command}") + + if command == "sync.copy_global": + await self.tree.copy_global_to(guild=message.guild) + synced = await self.tree.sync(guild=message.guild) + elif command == "sync.clear_guild": + self.tree.clear_commands(guild=message.guild) + synced = await self.tree.sync(guild=message.guild) + elif command == "sync.guild": + synced = await self.tree.sync(guild=message.guild) + else: + synced = await self.tree.sync() + + logger.info(f"Synced {len(synced)} commands") + await message.reply(f"Synced {len(synced)} commands") + + async def handle_command(self, message: discord.Message, is_owner: bool): + command_text: str = message.content + command_text = command_text[1:] + match command_text: + case "help" | "?": + await self.post_help(user=message.author) + case "sync" | "sync.guild" | "sync.copy_global" | "sync.clear_guild": + if is_owner: + await self._sync(command_text, message) + case _: + await message.reply(f"unknown command: {command_text}") + + def recipient_filter(self, message: discord.Message) -> bool: + channel = message.channel + + if ( + message.channel.type == discord.ChannelType.private + or message.channel.type == discord.ChannelType.private_thread + ): + return True + + if ( + message.channel.type == discord.ChannelType.text + or message.channel.type == discord.ChannelType.public_thread + ): + while channel: + if self.bot_channel and channel.id == self.bot_channel.id: + return True + channel = channel.parent + + return False + + async def handle_message(self, message: discord.Message): + if not self.recipient_filter(message): + return + + user_id = message.author.id + user_display_name = message.author.name + + logger.debug( + f"{message.type} {message.channel.type} from ({user_display_name}) {user_id}: {message.content} ({type(message.content)})" + ) + + command_prefix = "!" + if message.type == discord.MessageType.default and message.content.startswith(command_prefix): + is_owner = self.owner_id and user_id == self.owner_id + await self.handle_command(message, is_owner) + + if isinstance(message.channel, discord.Thread): + handler = self.reply_handlers.get(message.channel.id) + if handler and not handler.handler.completed: + handler.handler.on_reply(message) + + if message.reference: + handler = self.reply_handlers.get(message.reference.message_id) + if handler and not handler.handler.completed: + handler.handler.on_reply(message) + + async def remove_completed_handlers(self): + completed = [k for k, v in self.reply_handlers.items() if v.handler is None or v.handler.completed] + if len(completed) == 0: + return + + for c in completed: + handler = self.reply_handlers[c] + del self.reply_handlers[c] + try: + await handler.handler.finalize() + except Exception: + logger.exception("handler finalize failed") + + logger.info(f"removed {len(completed)} completed handlers (remaining: {len(self.reply_handlers)})") + + def get_text_channel_by_name(self, channel_name) -> discord.TextChannel: + for channel in self.client.get_all_channels(): + if channel.type == discord.ChannelType.text and channel.name == channel_name: + return channel + + def run(self): + """Run bot loop blocking.""" + self.client.run(self.bot_token) diff --git a/discord-bot/bot_base.py b/discord-bot/bot_base.py new file mode 100644 index 00000000..76eca22d --- /dev/null +++ b/discord-bot/bot_base.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +from __future__ import annotations + +import asyncio +from abc import ABC +from dataclasses import dataclass +from typing import Any + +import discord +from api_client import ApiClient +from channel_handlers import ChannelHandlerBase +from loguru import logger +from message_templates import MessageTemplates + + +@dataclass +class ReplyHandlerInfo: + msg_id: int + handler_task: asyncio.Task + handler: ChannelHandlerBase + + +class BotBase(ABC): + bot_channel_name: str + debug: bool + backend: ApiClient + client: discord.Client + loop: asyncio.BaseEventLoop + owner_id: int + bot_channel: discord.TextChannel + templates: MessageTemplates + reply_handlers: dict[int, ReplyHandlerInfo] + + def __init__(self): + self.reply_handlers = {} # handlers by msg_id + + def ensure_bot_channel(self) -> None: + if self.bot_channel is None: + raise RuntimeError(f"bot channel '{self.bot_channel_name}' not found") + + async def post( + self, content: str, *, view: discord.ui.View = None, channel: discord.abc.Messageable = None + ) -> discord.Message: + if channel is None: + self.ensure_bot_channel() + channel = self.bot_channel + return await channel.send(content=content, view=view) + + async def post_template( + self, name: str, *, view: discord.ui.View = None, channel: discord.abc.Messageable = None, **kwargs: Any + ) -> discord.Message: + logger.debug(f"rendering {name}") + text = self.templates.render(name, **kwargs) + return await self.post(text, view=view, channel=channel) + + def register_reply_handler(self, msg_id: int, handler: ChannelHandlerBase): + if msg_id in self.reply_handlers: + raise RuntimeError(f"Handler already registered for msg_id: {msg_id}") + task = asyncio.create_task(coro=handler.handler_loop(), name=f"reply_handler(msg_id={msg_id})") + task.add_done_callback(lambda t: handler.on_completed()) + self.reply_handlers[msg_id] = ReplyHandlerInfo(msg_id=msg_id, handler_task=task, handler=handler) diff --git a/discord-bot/bot_settings.py b/discord-bot/bot_settings.py new file mode 100644 index 00000000..c976d7cd --- /dev/null +++ b/discord-bot/bot_settings.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +from pydantic import AnyHttpUrl, BaseSettings + + +class BotSettings(BaseSettings): + BACKEND_URL: AnyHttpUrl = "http://localhost:8080" + API_KEY: str = "any_key" + BOT_TOKEN: str + BOT_CHANNEL_NAME: str = "bot" + OWNER_ID: int = None + TEMPLATE_DIR: str = "./templates" + DEBUG: bool = True + + +settings = BotSettings(_env_file=".env") diff --git a/discord-bot/channel_handlers.py b/discord-bot/channel_handlers.py new file mode 100644 index 00000000..75f03c0e --- /dev/null +++ b/discord-bot/channel_handlers.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- +import asyncio +from abc import ABC, abstractmethod +from datetime import datetime + +import discord +from loguru import logger + + +class ChannelExpiredException(Exception): + pass + + +class ChannelHandlerBase(ABC): + queue: asyncio.Queue + completed: bool = False + expiry_date: datetime + expired: bool = False + + def __init__(self, *, expiry_date: datetime = None): + self.expiry_date = expiry_date + self.queue = asyncio.Queue() + + async def read(self) -> discord.Message: + """Call this method to read the next message from the user in the handler method.""" + if self.expired: + raise ChannelExpiredException() + + msg = await self.queue.get() + if msg is None: + if self.expired: + raise ChannelExpiredException() + else: + raise RuntimeError("Unexpected None message read") + return msg + + def on_reply(self, message: discord.Message) -> None: + self.queue.put_nowait(message) + + def on_expire(self) -> None: + logger.info("ChannelHandler: on_expire") + self.expired = True + self.queue.put_nowait(None) + + def on_completed(self) -> None: + logger.info("ChannelHandler: on_completed") + self.completed = True + + def tick(self, now: datetime): + if now > self.expiry_date and not self.expired: + self.on_expire() + + @abstractmethod + async def handler_loop(self): + ... + + async def finalize(self): + pass + + +class AutoDestructThreadHandler(ChannelHandlerBase): + first_message: discord.Message = None + thread: discord.Thread = None + + def __init__(self, *, expiry_date: datetime = None): + super().__init__(expiry_date=expiry_date) + + async def read(self) -> discord.Message: + try: + return await super().read() + except ChannelExpiredException: + await self.cleanup() + raise + + async def cleanup(self): + logger.debug("AutoDestructThreadHandler.cleanup") + if self.thread: + logger.debug(f"deleting thread: {self.thread.name}") + await self.thread.delete() + self.thread = None + if self.first_message: + logger.debug(f"deleting first_message: {self.first_message.content}") + await self.first_message.delete() + self.first_message = None + + async def finalize(self): + await self.cleanup() + return await super().finalize() diff --git a/discord-bot/message_templates.py b/discord-bot/message_templates.py new file mode 100644 index 00000000..df3ef1ac --- /dev/null +++ b/discord-bot/message_templates.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +import jinja2 +from loguru import logger + + +class MessageTemplates: + def __init__(self, template_dir="./templates"): + self.env = jinja2.Environment( + loader=jinja2.FileSystemLoader(template_dir), + autoescape=jinja2.select_autoescape(disabled_extensions=("msg",), default=False, default_for_string=False), + ) + + def render(self, template_name, **kwargs): + template = self.env.get_template(template_name) + txt = template.render(kwargs) + logger.debug(txt) + + return txt diff --git a/discord-bot/requirements.txt b/discord-bot/requirements.txt new file mode 100644 index 00000000..927ebcf2 --- /dev/null +++ b/discord-bot/requirements.txt @@ -0,0 +1,7 @@ +discord.py==2.1.0 +Jinja2==3.1.2 +pydantic==1.9.1 +python-dotenv==0.21.0 +pytz==2022.7 +requests==2.28.1 +schedule==1.1.0 diff --git a/discord-bot/task_handlers.py b/discord-bot/task_handlers.py new file mode 100644 index 00000000..1434d17c --- /dev/null +++ b/discord-bot/task_handlers.py @@ -0,0 +1,267 @@ +# -*- coding: utf-8 -*- +from __future__ import annotations + +from abc import abstractmethod +from datetime import timedelta + +import discord +from api_client import ApiClient +from bot_base import BotBase +from channel_handlers import AutoDestructThreadHandler, ChannelExpiredException +from loguru import logger +from oasst_shared.schemas import protocol as protocol_schema +from utils import DiscordTimestampStyle, discord_timestamp, utcnow + + +class Questionnaire(discord.ui.Modal, title="Questionnaire Response"): + name = discord.ui.TextInput(label="Name") + answer = discord.ui.TextInput(label="Answer", style=discord.TextStyle.paragraph) + + async def on_submit(self, interaction: discord.Interaction): + await interaction.response.send_message(f"Thanks for your response, {self.name}!", ephemeral=True) + + +class ChannelTaskBase(AutoDestructThreadHandler): + thread_name: str = "Replies" + expires_after: timedelta = timedelta(minutes=5) + backend: ApiClient + + async def start(self, bot: BotBase, task: protocol_schema.Task) -> discord.Message: + try: + self.bot = bot + self.task = task + self.backend = bot.backend + self.expiry_date = utcnow() + self.expires_after if self.expires_after else None + msg = await self.send_first_message() + self.first_message = msg + self.thread = await bot.bot_channel.create_thread(message=discord.Object(msg.id), name=self.thread_name) + await self.on_thread_created(self.thread) + except Exception: + logger.exception("start task failed") + await self.cleanup() # try to cleanup messag or thread + raise + + bot.register_reply_handler(msg_id=msg.id, handler=self) + return msg + + async def on_thread_created(self, thread: discord.Thread) -> None: + pass + + @abstractmethod + async def send_first_message(self) -> discord.message: + ... + + def to_api_user(self, user: discord.User) -> protocol_schema.User: + return protocol_schema.User(auth_method="discord", id=user.id, display_name=user.display_name) + + async def post_teaser_msg(self, template_name: str): + expiry_time = discord_timestamp(self.expiry_date, DiscordTimestampStyle.long_time) + expiry_relative = discord_timestamp(self.expiry_date, DiscordTimestampStyle.relative_time) + return await self.bot.post_template( + template_name, task=self.task, expiry_time=expiry_time, expiry_relative=expiry_relative + ) + + async def post_interaction(self, interaction: protocol_schema.Interaction) -> protocol_schema.Task: + api_response = await self.backend.post_interaction(interaction) + if api_response.type != "task_done": + # multi-step tasks are not supported yet + logger.error(f"multi-step tasks are not supported yet (got response type: {api_response.type})") + raise RuntimeError("Unexpected response from backend received") + return api_response + + def post_text_reply_to_post(self, user_msg: discord.Message) -> protocol_schema.Task: + return self.backend.post_interaction( + protocol_schema.TextReplyToPost( + post_id=str(self.first_message.id), + user_post_id=str(user_msg.id), + user=self.to_api_user(user_msg.author), + text=user_msg.content, + ) + ) + + async def handle_text_reply_to_post(self, user_msg: discord.Message) -> protocol_schema.Task: + try: + self.post_text_reply_to_post(user_msg) + await user_msg.add_reaction("✅") + except ChannelExpiredException: + raise + except Exception as e: + logger.exception("Error in handle_text_reply_to_post()") + await user_msg.add_reaction("❌") + await user_msg.reply(f"❌ Error communicating with backend: {e}") + + def post_ranking(self, user_msg: discord.Message, ranking: list[int]) -> protocol_schema.Task: + return self.backend.post_interaction( + protocol_schema.PostRanking( + post_id=str(self.first_message.id), + user_post_id=str(user_msg.id), + user=self.to_api_user(user_msg.author), + ranking=ranking, + ) + ) + + async def handle_ranking(self, user_msg: discord.Message) -> protocol_schema.Task: + try: + ranking_str = user_msg.content + ranking = [int(x) - 1 for x in ranking_str.split(",")] + self.post_ranking(user_msg, ranking=ranking) + await user_msg.add_reaction("✅") + except ChannelExpiredException: + raise + except Exception as e: + logger.exception("Error in handle_ranking()") + await user_msg.add_reaction("❌") + await user_msg.reply(f"❌ Error communicating with backend: {e}") + + +class SummarizeStoryHandler(ChannelTaskBase): + task: protocol_schema.SummarizeStoryTask + thread_name: str = "Summaries" + + async def send_first_message(self) -> discord.message: + return await self.post_teaser_msg("teaser_summarize_story.msg") + + async def on_thread_created(self, thread: discord.Thread) -> None: + await self.bot.post_template("task_summarize_story.msg", channel=thread, task=self.task) + + async def handler_loop(self): + while True: + msg = await self.read() + await self.handle_text_reply_to_post(msg) + + +class InitialPromptHandler(ChannelTaskBase): + task: protocol_schema.InitialPromptTask + thread_name: str = "Prompts" + + async def send_first_message(self) -> discord.message: + return await self.post_teaser_msg("teaser_initial_prompt.msg") + + async def on_thread_created(self, thread: discord.Thread) -> None: + await self.bot.post_template("task_initial_prompt.msg", channel=thread, task=self.task) + + async def handler_loop(self): + while True: + msg = await self.read() + await self.handle_text_reply_to_post(msg) + + +class UserReplyHandler(ChannelTaskBase): + task: protocol_schema.UserReplyTask + thread_name: str = "User replies" + + async def send_first_message(self) -> discord.message: + return await self.post_teaser_msg("teaser_user_reply.msg") + + async def on_thread_created(self, thread: discord.Thread) -> None: + await self.bot.post_template("task_user_reply.msg", channel=thread, task=self.task) + + async def handler_loop(self): + while True: + msg = await self.read() + await self.handle_text_reply_to_post(msg) + + +class AssistantReplyHandler(ChannelTaskBase): + task: protocol_schema.AssistantReplyTask + thread_name: str = "Assistant replies" + + async def send_first_message(self) -> discord.message: + return await self.post_teaser_msg("teaser_assistant_reply.msg") + + async def on_thread_created(self, thread: discord.Thread) -> None: + await self.bot.post_template("task_assistant_reply.msg", channel=thread, task=self.task) + + async def handler_loop(self): + while True: + msg = await self.read() + await self.handle_text_reply_to_post(msg) + + +class RankInitialPromptsHandler(ChannelTaskBase): + task: protocol_schema.RankInitialPromptsTask + thread_name: str = "User Responses" + + async def send_first_message(self) -> discord.message: + return await self.post_teaser_msg("teaser_rank_initial_prompts.msg") + + async def on_thread_created(self, thread: discord.Thread) -> None: + await self.bot.post_template("task_rank_initial_prompts.msg", channel=thread, task=self.task) + + async def handler_loop(self): + while True: + msg = await self.read() + await self.handle_ranking(msg) + + +class RankConversationsHandler(ChannelTaskBase): + task: protocol_schema.RankConversationRepliesTask + thread_name: str = "Rankings" + + async def send_first_message(self) -> discord.message: + return await self.post_teaser_msg("teaser_rank_conversation_replies.msg") + + async def on_thread_created(self, thread: discord.Thread) -> None: + await self.bot.post_template("task_rank_conversation_replies.msg", channel=thread, task=self.task) + + async def handler_loop(self): + while True: + msg = await self.read() + await self.handle_ranking(msg) + + +class RatingButton(discord.ui.Button): + def __init__(self, label, value, response_handler): + super().__init__(label=label, style=discord.ButtonStyle.green) + self.value = value + self.response_handler = response_handler + + async def callback(self, interaction): + await self.response_handler(self.value, interaction) + + +def generate_rating_view(lo: int, hi: int, response_handler) -> discord.ui.View: + view = discord.ui.View() + for i in range(lo, hi + 1): + view.add_item(RatingButton(str(i), i, response_handler)) + return view + + +class RateSummaryHandler(ChannelTaskBase): + task: protocol_schema.RateSummaryTask + thread_name: str = "Ratings" + + async def _rating_response_handler(self, score, interaction: discord.Interaction): + logger.info("rating_response_handler", score) + if self.thread: + try: + self.backend.post_interaction( + protocol_schema.PostRating( + post_id=str(self.first_message.id), + user_post_id=str(interaction.id), + user=self.to_api_user(interaction.user), + rating=score, + ) + ) + await interaction.response.send_message( + f"Thanks {interaction.user.display_name}, got your feedback: {score}!" + ) + except ChannelExpiredException: + raise + except Exception as e: + logger.exception("Error in _rating_response_handler()") + interaction.response.send_message(f"❌ Error communicating with backend: {e}") + + async def send_first_message(self) -> discord.message: + return await self.post_teaser_msg("teaser_rate_summary.msg") + + async def on_thread_created(self, thread: discord.Thread) -> None: + view = generate_rating_view(self.task.scale.min, self.task.scale.max, self._rating_response_handler) + return await self.bot.post_template("task_rate_summary.msg", view=view, channel=thread, task=self.task) + + async def handler_loop(self): + while True: + msg = await self.read() + logger.info(f"on_rate_summary_reply: {msg.content}") + await msg.add_reaction("❌") + await msg.reply("❌ Text intput not supported.") diff --git a/discord-bot/templates/boot.msg b/discord-bot/templates/boot.msg new file mode 100644 index 00000000..a3629715 --- /dev/null +++ b/discord-bot/templates/boot.msg @@ -0,0 +1,13 @@ +``` +________ __ +\_____ \ _____ ______ _______/ |_ + / | \\__ \ / ___// ___/\ __\ +/ | \/ __ \_\___ \ \___ \ | | +\_______ (____ /____ >____ > |__| + \/ \/ \/ \/ + +{{bot_name}} {{version}} +git hash: {{git_hash}} +debug_mode: {{debug}} +``` +https://github.com/LAION-AI/Open-Assistant diff --git a/discord-bot/templates/help.msg b/discord-bot/templates/help.msg new file mode 100644 index 00000000..3fbfb50d --- /dev/null +++ b/discord-bot/templates/help.msg @@ -0,0 +1,15 @@ +**Open-Assistant Bot Help** + +Available slash-commands: + +`/work` Requests a new personalized human feedback task +`/help` Show this message + +{% if is_bot_owner %} +Commands for bot owners: + +`!sync` +`!sync.guild` +`!sync.copy_global` +`!sync.clear_guild` +{% endif %} diff --git a/discord-bot/templates/task_assistant_reply.msg b/discord-bot/templates/task_assistant_reply.msg new file mode 100644 index 00000000..b7b8abef --- /dev/null +++ b/discord-bot/templates/task_assistant_reply.msg @@ -0,0 +1,12 @@ +Act as the assistant and reply to the user. +Here is the conversation so far: +{% for message in task.conversation.messages %} +{% if message.is_assistant %} +:robot: Assistant: +{{ message.text }} +{% else %} +:person_red_hair: User: +**{{ message.text }}**" +{% endif %} +{% endfor %} +:robot: Assistant: { human, pls help me! ... } diff --git a/discord-bot/templates/task_initial_prompt.msg b/discord-bot/templates/task_initial_prompt.msg new file mode 100644 index 00000000..fae963c2 --- /dev/null +++ b/discord-bot/templates/task_initial_prompt.msg @@ -0,0 +1,4 @@ +Please provide an initial prompt to the assistant. +{% if task.hint is not none %} +Hint: {{task.hint}} +{% endif %} diff --git a/discord-bot/templates/task_rank_conversation_replies.msg b/discord-bot/templates/task_rank_conversation_replies.msg new file mode 100644 index 00000000..c2864e9f --- /dev/null +++ b/discord-bot/templates/task_rank_conversation_replies.msg @@ -0,0 +1,13 @@ +Here is the conversation so far: +{% for message in task.conversation.messages %}{% if message.is_assistant %} +:robot: Assistant: +{{ message.text }} +{% else %} +:person_red_hair: User: +**{{ message.text }}**" +{% endif %}{% endfor %} +Rank the following replies: +{% for reply in task.replies %} +{{loop.index}}: {{reply}}{% endfor %} + +:scroll: Reply with the numbers of best to worst prompts separated by commas (example: "4,1,3,2"). diff --git a/discord-bot/templates/task_rank_initial_prompts.msg b/discord-bot/templates/task_rank_initial_prompts.msg new file mode 100644 index 00000000..3f84f24e --- /dev/null +++ b/discord-bot/templates/task_rank_initial_prompts.msg @@ -0,0 +1,5 @@ +Rank the following prompts: +{% for prompt in task.prompts %} +{{loop.index}}: {{prompt}}{% endfor %} + +:scroll: Reply with the numbers of best to worst prompts separated by commas (example: "4,1,3,2"). diff --git a/discord-bot/templates/task_rate_summary.msg b/discord-bot/templates/task_rate_summary.msg new file mode 100644 index 00000000..31007c40 --- /dev/null +++ b/discord-bot/templates/task_rate_summary.msg @@ -0,0 +1,7 @@ +Rate the following summary: +{{task.summary}} + +Full text: +{{task.full_text}} + +Rating scale: {{task.scale.min}} - {{task.scale.max}} diff --git a/discord-bot/templates/task_summarize_story.msg b/discord-bot/templates/task_summarize_story.msg new file mode 100644 index 00000000..24753841 --- /dev/null +++ b/discord-bot/templates/task_summarize_story.msg @@ -0,0 +1,2 @@ +Summarize to the following story: +{{task.story}} diff --git a/discord-bot/templates/task_user_reply.msg b/discord-bot/templates/task_user_reply.msg new file mode 100644 index 00000000..7c0a047b --- /dev/null +++ b/discord-bot/templates/task_user_reply.msg @@ -0,0 +1,12 @@ +Please provide a reply to the assistant. +Here is the conversation so far: +{% for message in task.conversation.messages %}{% if message.is_assistant %} +:robot: Assistant: +{{ message.text }} +{% else %} +:person_red_hair: User: +**{{ message.text }}**" +{% endif %}{% endfor %} +{% if task.hint %} +Hint: {{ task.hint }} +{% endif %} diff --git a/discord-bot/templates/teaser_assistant_reply.msg b/discord-bot/templates/teaser_assistant_reply.msg new file mode 100644 index 00000000..f86baa3c --- /dev/null +++ b/discord-bot/templates/teaser_assistant_reply.msg @@ -0,0 +1,3 @@ +:robot: **Challenge: Assistant Reply** + +:point_down: Work on it here (:fire: Thread will self-destruct at {{ expiry_time }}, {{ expiry_relative }}). diff --git a/discord-bot/templates/teaser_initial_prompt.msg b/discord-bot/templates/teaser_initial_prompt.msg new file mode 100644 index 00000000..7aad81b4 --- /dev/null +++ b/discord-bot/templates/teaser_initial_prompt.msg @@ -0,0 +1,3 @@ +:microphone2: **Challenge: Initial Prompt** + +:point_down: Work on it here (:fire: Thread will self-destruct at {{ expiry_time }}, {{ expiry_relative }}). diff --git a/discord-bot/templates/teaser_rank_conversation_replies.msg b/discord-bot/templates/teaser_rank_conversation_replies.msg new file mode 100644 index 00000000..366d86e5 --- /dev/null +++ b/discord-bot/templates/teaser_rank_conversation_replies.msg @@ -0,0 +1,3 @@ +:bar_chart: **Challenge: Rank Replies** + +:point_down: Work on it here (:fire: Thread will self-destruct at {{ expiry_time }}, {{ expiry_relative }}). diff --git a/discord-bot/templates/teaser_rank_initial_prompts.msg b/discord-bot/templates/teaser_rank_initial_prompts.msg new file mode 100644 index 00000000..09f04ffa --- /dev/null +++ b/discord-bot/templates/teaser_rank_initial_prompts.msg @@ -0,0 +1,3 @@ +:bar_chart: **Challenge: Rank Initial Prompts** + +:point_down: Work on it here (:fire: Thread will self-destruct at {{ expiry_time }}, {{ expiry_relative }}). diff --git a/discord-bot/templates/teaser_rate_summary.msg b/discord-bot/templates/teaser_rate_summary.msg new file mode 100644 index 00000000..284aae26 --- /dev/null +++ b/discord-bot/templates/teaser_rate_summary.msg @@ -0,0 +1,3 @@ +:ballot_box: **Challenge: Rate Summary** + +:point_down: Work on it here (:fire: Thread will self-destruct at {{ expiry_time }}, {{ expiry_relative }}). diff --git a/discord-bot/templates/teaser_summarize_story.msg b/discord-bot/templates/teaser_summarize_story.msg new file mode 100644 index 00000000..52d46462 --- /dev/null +++ b/discord-bot/templates/teaser_summarize_story.msg @@ -0,0 +1,3 @@ +:books: **Challenge: Summarize Story** + +:point_down: Work on it here (:fire: Thread will self-destruct at {{ expiry_time }}, {{ expiry_relative }}). diff --git a/discord-bot/templates/teaser_user_reply.msg b/discord-bot/templates/teaser_user_reply.msg new file mode 100644 index 00000000..31827252 --- /dev/null +++ b/discord-bot/templates/teaser_user_reply.msg @@ -0,0 +1,3 @@ +:person_red_hair: **Challenge: User Reply** + +:point_down: Work on it here (:fire: Thread will self-destruct at {{ expiry_time }}, {{ expiry_relative }}). diff --git a/discord-bot/templates/welcome.msg b/discord-bot/templates/welcome.msg new file mode 100644 index 00000000..553f7925 --- /dev/null +++ b/discord-bot/templates/welcome.msg @@ -0,0 +1,6 @@ +Hi there, + +I am the **Open-Assistant Junior Bot** 🤖. I would love to get your feedback 🤗! +Currently I am still learning from human demonstrations how to reply to instructions. When I am grown up I want to become a fully functional AI Assistant language model that is fully open-sourced and assists millions of humans all over the world. + +Type `/tutorial` to start the tutorial or `/help` to see a list of all my commands. diff --git a/discord-bot/utils.py b/discord-bot/utils.py new file mode 100644 index 00000000..968e4498 --- /dev/null +++ b/discord-bot/utils.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +import enum +import subprocess +from datetime import datetime + +import pytz + + +def get_git_head_hash(): + # get current git hash + x = subprocess.run(["git", "rev-parse", "HEAD"], stdout=subprocess.PIPE, universal_newlines=True) + if x.returncode == 0: + return x.stdout.replace("\n", "") + return None + + +def utcnow() -> datetime: + return datetime.now(pytz.UTC) + + +class DiscordTimestampStyle(str, enum.Enum): + """ + Timestamp Styles + + t 16:20 Short Time + T 16:20:30 Long Time + d 20/04/2021 Short Date + D 20 April 2021 Long Date + f * 20 April 2021 16:20 Short Date/Time + F Tuesday, 20 April 2021 16:20 Long Date/Time + R 2 months ago Relative Time + + See https://discord.com/developers/docs/reference#message-formatting-timestamp-styles + """ + + default = "" + short_time = "t" + long_time = "T" + short_date = "d" + long_date = "D" + short_date_time = "f" + long_date_time = "F" + relative_time = "R" + + +def discord_timestamp(d: datetime, style: DiscordTimestampStyle = DiscordTimestampStyle.default): + parts = ["") + return "".join(parts) diff --git a/docker/Dockerfile.backend b/docker/Dockerfile.backend new file mode 100644 index 00000000..d9458ae0 --- /dev/null +++ b/docker/Dockerfile.backend @@ -0,0 +1,15 @@ +FROM tiangolo/uvicorn-gunicorn-fastapi:python3.10 + +COPY ./backend/requirements.txt /app/requirements.txt + +RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt + +ENV PORT 8080 + +COPY ./oasst-shared /oasst-shared +RUN pip install -e /oasst-shared + +COPY ./backend/alembic /app/alembic +COPY ./backend/alembic.ini /app/alembic.ini +COPY ./backend/main.py /app/main.py +COPY ./backend/oasst_backend /app/oasst_backend diff --git a/docker/Dockerfile.discord-bot b/docker/Dockerfile.discord-bot new file mode 100644 index 00000000..13ae308a --- /dev/null +++ b/docker/Dockerfile.discord-bot @@ -0,0 +1,7 @@ +FROM python:3.10-slim-bullseye +RUN mkdir /app +COPY ./discord-bot/requirements.txt /requirements.txt +RUN pip install -r requirements.txt +WORKDIR /app +COPY ./discord-bot /app +CMD ["python", "bot.py"] diff --git a/docker/Dockerfile.website b/docker/Dockerfile.website new file mode 100644 index 00000000..afb18baf --- /dev/null +++ b/docker/Dockerfile.website @@ -0,0 +1,62 @@ +# Install dependencies only when needed +FROM node:16.19 AS deps +# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed. +# RUN apk add --no-cache libc6-compat +WORKDIR /app + +# Install dependencies based on the preferred package manager +COPY ./website/package.json ./website/package-lock.json ./ +RUN \ + if [ -f package-lock.json ]; then npm ci; \ + else echo "Lockfile not found." && exit 1; \ + fi + +# Rebuild the source code only when needed +FROM node:16.19 AS builder +WORKDIR /app +COPY --from=deps /app/node_modules ./node_modules +COPY ./website/ . + +# Next.js collects completely anonymous telemetry data about general usage. +# Learn more here: https://nextjs.org/telemetry +# Uncomment the following line in case you want to disable telemetry during the build. +# ENV NEXT_TELEMETRY_DISABLED 1 + +# RUN yarn build +RUN npx prisma generate +RUN npm run build + +# Production image, copy all the files and run next +FROM node:16.19 AS runner +WORKDIR /app + +ENV NODE_ENV production +# Uncomment the following line in case you want to disable telemetry during runtime. +# ENV NEXT_TELEMETRY_DISABLED 1 + +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs + +COPY --from=builder /app/public ./public + +# Copy over the prisma schema so we can to `npx prisma db push` and ensure the +# database exists on startup. +COPY --chown=nextjs:nodejs ./website/prisma/schema.prisma ./ +# Copy over a startup script that'll run `npx prisma db push` before starting +# the webserver. This ensures the webserver can actually check user accounts. +# This is a prisma variant of the postgres solution suggested in +# https://docs.docker.com/compose/startup-order/ +COPY --chown=nextjs:nodejs ./website/wait-for-postgres.sh ./ + +# Automatically leverage output traces to reduce image size +# https://nextjs.org/docs/advanced-features/output-file-tracing +COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ +COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static + +USER nextjs + +EXPOSE 3000 + +ENV PORT 3000 + +CMD ["node", "server.js"] diff --git a/oasst-shared/README.md b/oasst-shared/README.md new file mode 100644 index 00000000..28761ced --- /dev/null +++ b/oasst-shared/README.md @@ -0,0 +1,3 @@ +# Shared Python code for Open Assisstant + +Run `pip install -e .` to install the package in editable mode. diff --git a/backend/app/tests/__init__.py b/oasst-shared/oasst_shared/__init__.py similarity index 100% rename from backend/app/tests/__init__.py rename to oasst-shared/oasst_shared/__init__.py diff --git a/oasst-shared/oasst_shared/schemas/__init__.py b/oasst-shared/oasst_shared/schemas/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/oasst-shared/oasst_shared/schemas/protocol.py b/oasst-shared/oasst_shared/schemas/protocol.py new file mode 100644 index 00000000..d5f508b6 --- /dev/null +++ b/oasst-shared/oasst_shared/schemas/protocol.py @@ -0,0 +1,206 @@ +# -*- coding: utf-8 -*- +import enum +from typing import Literal, Optional, Union +from uuid import UUID, uuid4 + +import pydantic +from pydantic import BaseModel + + +class TaskRequestType(str, enum.Enum): + random = "random" + summarize_story = "summarize_story" + rate_summary = "rate_summary" + initial_prompt = "initial_prompt" + user_reply = "user_reply" + assistant_reply = "assistant_reply" + rank_initial_prompts = "rank_initial_prompts" + rank_user_replies = "rank_user_replies" + rank_assistant_replies = "rank_assistant_replies" + + +class User(BaseModel): + id: str + display_name: str + auth_method: Literal["discord", "local"] + + +class ConversationMessage(BaseModel): + """Represents a message in a conversation between the user and the assistant.""" + + text: str + is_assistant: bool + + +class Conversation(BaseModel): + """Represents a conversation between the user and the assistant.""" + + messages: list[ConversationMessage] = [] + + +class TaskRequest(BaseModel): + """The frontend asks the backend for a task.""" + + type: TaskRequestType = TaskRequestType.random + user: Optional[User] = None + + +class TaskAck(BaseModel): + """The frontend acknowledges that it has received a task and created a post.""" + + post_id: str + + +class TaskNAck(BaseModel): + """The frontend acknowledges that it has received a task but cannot create a post.""" + + reason: str + + +class Task(BaseModel): + """A task is a unit of work that the backend gives to the frontend.""" + + id: UUID = pydantic.Field(default_factory=uuid4) + type: str + + +class SummarizeStoryTask(Task): + """A task to summarize a story.""" + + type: Literal["summarize_story"] = "summarize_story" + story: str + + +class RatingScale(BaseModel): + min: int + max: int + + +class AbstractRatingTask(Task): + """A task to rate something.""" + + scale: RatingScale = RatingScale(min=1, max=5) + + +class RateSummaryTask(AbstractRatingTask): + """A task to rate a summary.""" + + type: Literal["rate_summary"] = "rate_summary" + full_text: str + summary: str + + +class WithHintMixin(BaseModel): + hint: str | None = None # provide a hint to the user to spark their imagination + + +class InitialPromptTask(Task, WithHintMixin): + """A task to prompt the user to submit an initial prompt to the assistant.""" + + type: Literal["initial_prompt"] = "initial_prompt" + + +class ReplyToConversationTask(Task): + """A task to prompt the user to submit a reply to a conversation.""" + + type: Literal["reply_to_conversation"] = "reply_to_conversation" + conversation: Conversation # the conversation so far + + +class UserReplyTask(ReplyToConversationTask, WithHintMixin): + """A task to prompt the user to submit a reply to the assistant.""" + + type: Literal["user_reply"] = "user_reply" + + +class AssistantReplyTask(ReplyToConversationTask): + """A task to prompt the user to act as the assistant.""" + + type: Literal["assistant_reply"] = "assistant_reply" + + +class RankInitialPromptsTask(Task): + """A task to rank a set of initial prompts.""" + + type: Literal["rank_initial_prompts"] = "rank_initial_prompts" + prompts: list[str] + + +class RankConversationRepliesTask(Task): + """A task to rank a set of replies to a conversation.""" + + type: Literal["rank_conversation_replies"] = "rank_conversation_replies" + conversation: Conversation # the conversation so far + replies: list[str] + + +class RankUserRepliesTask(RankConversationRepliesTask): + """A task to rank a set of user replies to a conversation.""" + + type: Literal["rank_user_replies"] = "rank_user_replies" + + +class RankAssistantRepliesTask(RankConversationRepliesTask): + """A task to rank a set of assistant replies to a conversation.""" + + type: Literal["rank_assistant_replies"] = "rank_assistant_replies" + + +class TaskDone(Task): + """Signals to the frontend that the task is done.""" + + type: Literal["task_done"] = "task_done" + + +AnyTask = Union[ + TaskDone, + SummarizeStoryTask, + RateSummaryTask, + InitialPromptTask, + ReplyToConversationTask, + UserReplyTask, + AssistantReplyTask, + RankInitialPromptsTask, + RankConversationRepliesTask, + RankUserRepliesTask, + RankAssistantRepliesTask, +] + + +class Interaction(BaseModel): + """An interaction is a user-generated action in the frontend.""" + + type: str + user: User + + +class TextReplyToPost(Interaction): + """A user has replied to a post with text.""" + + type: Literal["text_reply_to_post"] = "text_reply_to_post" + post_id: str + user_post_id: str + text: str + + +class PostRating(Interaction): + """A user has rated a post.""" + + type: Literal["post_rating"] = "post_rating" + post_id: str + rating: int + + +class PostRanking(Interaction): + """A user has given a ranking for a post.""" + + type: Literal["post_ranking"] = "post_ranking" + post_id: str + ranking: list[int] + + +AnyInteraction = Union[ + TextReplyToPost, + PostRating, + PostRanking, +] diff --git a/oasst-shared/setup.py b/oasst-shared/setup.py new file mode 100644 index 00000000..ebaf4217 --- /dev/null +++ b/oasst-shared/setup.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# setup.py for the shared python modules + +from distutils.core import setup + +from setuptools import find_namespace_packages + +setup( + name="oasst-shared", + version="1.0", + packages=find_namespace_packages(), + author="OASST Team", + install_requires=[ + "pydantic==1.9.1", + ], +) diff --git a/scripts/backend-development/README.md b/scripts/backend-development/README.md new file mode 100644 index 00000000..3f7e6509 --- /dev/null +++ b/scripts/backend-development/README.md @@ -0,0 +1,6 @@ +# Backend Development Setup + +Run `docker compose up` to start a database. The default settings are already configured to connect to the database at `localhost:5432`. + +Make sure you have all requirements installed. You can do this by running `pip install -r requirements.txt` inside the `backend` folder and `pip install -e .` inside the `oasst-shared` folder. +Then, run the backend using the `run-local.sh` script. This will start the backend server at `http://localhost:8080`. diff --git a/backend/scripts/docker-compose.yaml b/scripts/backend-development/docker-compose.yaml similarity index 67% rename from backend/scripts/docker-compose.yaml rename to scripts/backend-development/docker-compose.yaml index 2b92d6b0..65a65e73 100644 --- a/backend/scripts/docker-compose.yaml +++ b/scripts/backend-development/docker-compose.yaml @@ -9,6 +9,11 @@ services: environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres + healthcheck: + test: ["CMD", "pg_isready", "-U", "postgres"] + interval: 2s + timeout: 2s + retries: 10 adminer: image: adminer diff --git a/scripts/backend-development/run-local.sh b/scripts/backend-development/run-local.sh new file mode 100755 index 00000000..e9df6ca2 --- /dev/null +++ b/scripts/backend-development/run-local.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +parent_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P ) + +# switch to backend directory +pushd "$parent_path/../../backend" + +export ALLOW_ANY_API_KEY=True + +uvicorn main:app --reload --port 8080 --host 0.0.0.0 + +popd diff --git a/scripts/endtoend-demo/README.md b/scripts/endtoend-demo/README.md new file mode 100644 index 00000000..2d738453 --- /dev/null +++ b/scripts/endtoend-demo/README.md @@ -0,0 +1,14 @@ +# End to End Demo + +This sets up an entire stack needed to run Open Assistant, including the +website, backend, and associated dependent services. + +To start the service, do the following: + +```sh +docker compose up --build +``` + +Then, navigate to `http://localhost:3000` and interact with the website. When +logging in, navigate to `http://localhost:1080` to get the magic email login +link. diff --git a/scripts/endtoend-demo/docker-compose.yaml b/scripts/endtoend-demo/docker-compose.yaml new file mode 100644 index 00000000..5e9ad9ac --- /dev/null +++ b/scripts/endtoend-demo/docker-compose.yaml @@ -0,0 +1,56 @@ +version: "3.7" + +services: + # This DB is for the FastAPI Backend. + db: + extends: + file: ../frontend-development/docker-compose.yaml + service: db + + # This DB is for Web Authentication and data caching. + webdb: + extends: + file: ../frontend-development/docker-compose.yaml + service: webdb + + # This lets you manually inspect the web and backend databases. + adminer: + extends: + file: ../frontend-development/docker-compose.yaml + service: adminer + + # This fakes an SMTP email server used by website authentication. + # User registration emails can be found by going to localhost:1080 and + # opening the emails listed. + maildev: + extends: + file: ../frontend-development/docker-compose.yaml + service: maildev + + # The oassist backend service. + backend: + extends: + file: ../frontend-development/docker-compose.yaml + service: backend + + # The oassist web service. + web: + build: + dockerfile: docker/Dockerfile.website + context: ../../ + image: oasst-web + environment: + - DATABASE_URL=postgres://postgres:postgres@webdb/ocgpt_website + - FASTAPI_URL=http://backend:8080 + - FASTAPI_KEY=1234 + - NEXTAUTH_SECRET=O/M2uIbGj+lDD2oyNa8ax4jEOJqCPJzO53UbWShmq98= + - EMAIL_SERVER_HOST=maildev + - EMAIL_SERVER_PORT=1025 + - EMAIL_FROM=info@example.com + - NEXTAUTH_URL=http://localhost:3000 + depends_on: + webdb: + condition: service_healthy + ports: + - "3000:3000" + command: bash wait-for-postgres.sh node server.js diff --git a/scripts/frontend-development/README.md b/scripts/frontend-development/README.md new file mode 100644 index 00000000..e13e37c0 --- /dev/null +++ b/scripts/frontend-development/README.md @@ -0,0 +1,5 @@ +# Frontend Development Setup + +Run `docker compose up --build` to start a database and the backend server. + +Then, point your frontend at `http://localhost:8080` to start developing. During development, any API key will be accepted. diff --git a/scripts/frontend-development/docker-compose.yaml b/scripts/frontend-development/docker-compose.yaml new file mode 100644 index 00000000..4e08ae29 --- /dev/null +++ b/scripts/frontend-development/docker-compose.yaml @@ -0,0 +1,57 @@ +version: "3.7" + +services: + # This DB is for the FastAPI Backend. + db: + extends: + file: ../backend-development/docker-compose.yaml + service: db + + # This DB is for Web Authentication and data caching. + webdb: + image: postgres + restart: always + ports: + - 5433:5432 + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + healthcheck: + test: ["CMD", "pg_isready", "-U", "postgres"] + interval: 2s + timeout: 2s + retries: 10 + + # This lets you manually inspect the web and backend databases. + adminer: + extends: + file: ../backend-development/docker-compose.yaml + service: adminer + + backend: + build: + dockerfile: docker/Dockerfile.backend + context: ../.. + image: oasst-backend + environment: + - POSTGRES_HOST=db + - ALLOW_ANY_API_KEY=True + - MAX_WORKERS=1 + depends_on: + db: + condition: service_healthy + ports: + - "8080:8080" + + # This fakes an SMTP email server used by website authentication. + # User registration emails can be found by going to localhost:1080 and + # opening the emails listed. + maildev: + image: maildev/maildev + restart: always + environment: + - MAILDEV_WEB_PORT=1080 + - MAILDEV_SMTP_PORT=1025 + ports: + - "1080:1080" + - "1025:1025" diff --git a/scripts/frontend-development/run-bot-local.sh b/scripts/frontend-development/run-bot-local.sh new file mode 100755 index 00000000..7308c541 --- /dev/null +++ b/scripts/frontend-development/run-bot-local.sh @@ -0,0 +1,9 @@ +#!/bin/bash +parent_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P ) + +# switch to bot directory +pushd "$parent_path/../../bot" + +python3 __main__.py + +popd diff --git a/backend/postprocessing/infogain_selector.py b/scripts/postprocessing/infogain_selector.py similarity index 100% rename from backend/postprocessing/infogain_selector.py rename to scripts/postprocessing/infogain_selector.py diff --git a/backend/postprocessing/rankings.py b/scripts/postprocessing/rankings.py similarity index 100% rename from backend/postprocessing/rankings.py rename to scripts/postprocessing/rankings.py diff --git a/text-frontend/__main__.py b/text-frontend/__main__.py new file mode 100644 index 00000000..ee34799d --- /dev/null +++ b/text-frontend/__main__.py @@ -0,0 +1,214 @@ +# -*- coding: utf-8 -*- +"""Simple REPL frontend.""" + +import random + +import requests +import typer + +app = typer.Typer() + + +# debug constants +USER = {"id": "1234", "display_name": "John Doe", "auth_method": "local"} + + +def _random_post_id(): + return str(random.randint(1000, 9999)) + + +def _render_message(message: dict) -> str: + """Render a message to the user.""" + if message["is_assistant"]: + return f"Assistant: {message['text']}" + return f"User: {message['text']}" + + +@app.command() +def main(backend_url: str = "http://127.0.0.1:8080", api_key: str = "DUMMY_KEY"): + """Simple REPL frontend.""" + + def _post(path: str, json: dict) -> dict: + response = requests.post(f"{backend_url}{path}", json=json, headers={"X-API-Key": api_key}) + response.raise_for_status() + return response.json() + + typer.echo("Requesting work...") + tasks = [_post("/api/v1/tasks/", {"type": "random"})] + while tasks: + task = tasks.pop(0) + match (task["type"]): + case "summarize_story": + typer.echo("Summarize the following story:") + typer.echo(task["story"]) + + # acknowledge task + post_id = _random_post_id() + _post(f"/api/v1/tasks/{task['id']}/ack", {"post_id": post_id}) + + summary = typer.prompt("Enter your summary") + + user_post_id = _random_post_id() + + # send interaction + new_task = _post( + "/api/v1/tasks/interaction", + { + "type": "text_reply_to_post", + "post_id": post_id, + "user_post_id": user_post_id, + "text": summary, + "user": USER, + }, + ) + tasks.append(new_task) + case "rate_summary": + typer.echo("Rate the following summary:") + typer.echo(task["summary"]) + typer.echo("Full text:") + typer.echo(task["full_text"]) + typer.echo(f"Rating scale: {task['scale']['min']} - {task['scale']['max']}") + + # acknowledge task + post_id = _random_post_id() + _post(f"/api/v1/tasks/{task['id']}/ack", {"post_id": post_id}) + + rating = typer.prompt("Enter your rating", type=int) + # send interaction + new_task = _post( + "/api/v1/tasks/interaction", + { + "type": "post_rating", + "post_id": post_id, + "rating": rating, + "user": USER, + }, + ) + tasks.append(new_task) + case "initial_prompt": + typer.echo("Please provide an initial prompt to the assistant.") + if task["hint"]: + typer.echo(f"Hint: {task['hint']}") + # acknowledge task + post_id = _random_post_id() + _post(f"/api/v1/tasks/{task['id']}/ack", {"post_id": post_id}) + prompt = typer.prompt("Enter your prompt") + user_post_id = _random_post_id() + # send interaction + new_task = _post( + "/api/v1/tasks/interaction", + { + "type": "text_reply_to_post", + "post_id": post_id, + "user_post_id": user_post_id, + "text": prompt, + "user": USER, + }, + ) + tasks.append(new_task) + + case "user_reply": + typer.echo("Please provide a reply to the assistant.") + typer.echo("Here is the conversation so far:") + for message in task["conversation"]["messages"]: + typer.echo(_render_message(message)) + if task["hint"]: + typer.echo(f"Hint: {task['hint']}") + # acknowledge task + post_id = _random_post_id() + _post(f"/api/v1/tasks/{task['id']}/ack", {"post_id": post_id}) + reply = typer.prompt("Enter your reply") + user_post_id = _random_post_id() + # send interaction + new_task = _post( + "/api/v1/tasks/interaction", + { + "type": "text_reply_to_post", + "post_id": post_id, + "user_post_id": user_post_id, + "text": reply, + "user": USER, + }, + ) + tasks.append(new_task) + + case "assistant_reply": + typer.echo("Act as the assistant and reply to the user.") + typer.echo("Here is the conversation so far:") + for message in task["conversation"]["messages"]: + typer.echo(_render_message(message)) + # acknowledge task + post_id = _random_post_id() + _post(f"/api/v1/tasks/{task['id']}/ack", {"post_id": post_id}) + reply = typer.prompt("Enter your reply") + user_post_id = _random_post_id() + # send interaction + new_task = _post( + "/api/v1/tasks/interaction", + { + "type": "text_reply_to_post", + "post_id": post_id, + "user_post_id": user_post_id, + "text": reply, + "user": USER, + }, + ) + tasks.append(new_task) + + case "rank_initial_prompts": + typer.echo("Rank the following prompts:") + for idx, prompt in enumerate(task["prompts"], start=1): + typer.echo(f"{idx}: {prompt}") + # acknowledge task + post_id = _random_post_id() + _post(f"/api/v1/tasks/{task['id']}/ack", {"post_id": post_id}) + + ranking_str = typer.prompt("Enter the prompt numbers in order of preference, separated by commas") + ranking = [int(x) - 1 for x in ranking_str.split(",")] + + # send ranking + new_task = _post( + "/api/v1/tasks/interaction", + { + "type": "post_ranking", + "post_id": post_id, + "ranking": ranking, + "user": USER, + }, + ) + tasks.append(new_task) + + case "rank_user_replies" | "rank_assistant_replies": + typer.echo("Here is the conversation so far:") + for message in task["conversation"]["messages"]: + typer.echo(_render_message(message)) + typer.echo("Rank the following replies:") + for idx, reply in enumerate(task["replies"], start=1): + typer.echo(f"{idx}: {reply}") + # acknowledge task + post_id = _random_post_id() + _post(f"/api/v1/tasks/{task['id']}/ack", {"post_id": post_id}) + + ranking_str = typer.prompt("Enter the reply numbers in order of preference, separated by commas") + ranking = [int(x) - 1 for x in ranking_str.split(",")] + + # send ranking + new_task = _post( + "/api/v1/tasks/interaction", + { + "type": "post_ranking", + "post_id": post_id, + "ranking": ranking, + "user": USER, + }, + ) + tasks.append(new_task) + + case "task_done": + typer.echo("Task done!") + case _: + typer.echo(f"Unknown task type {task['type']}") + + +if __name__ == "__main__": + app() diff --git a/text-frontend/requirements.txt b/text-frontend/requirements.txt new file mode 100644 index 00000000..3904ecb5 --- /dev/null +++ b/text-frontend/requirements.txt @@ -0,0 +1,2 @@ +requests==2.28.1 +typer==0.7.0 diff --git a/website/.env b/website/.env new file mode 100644 index 00000000..a95df390 --- /dev/null +++ b/website/.env @@ -0,0 +1,14 @@ +# The database created by running the jobs in /scripts/frontend-development/docker-compose.yaml +DATABASE_URL=postgres://postgres:postgres@localhost:5433/ocgpt_website + +# The FastAPI backend found by running the jobs in /scripts/frontend-development/docker-compose.yaml +FASTAPI_URL=http://localhost:8080 +FASTAPI_KEY=1234 + +# A dev Auth Secret. Can be exposed if we never use this publically. +NEXTAUTH_SECRET=O/M2uIbGj+lDD2oyNa8ax4jEOJqCPJzO53UbWShmq98= + +# The SMTP host and port found by running the jobs in /scripts/frontend-development/docker-compose.yaml +EMAIL_SERVER_HOST=localhost +EMAIL_SERVER_PORT=1025 +EMAIL_FROM=info@example.com diff --git a/website/.gitignore b/website/.gitignore index c87c9b39..265e0054 100644 --- a/website/.gitignore +++ b/website/.gitignore @@ -34,3 +34,6 @@ yarn-error.log* # typescript *.tsbuildinfo next-env.d.ts + +# Vim files +*.swp diff --git a/website/README.md b/website/README.md index d88f6bed..7d57ceaa 100644 --- a/website/README.md +++ b/website/README.md @@ -1,31 +1,109 @@ -This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). +# Open-Assistant NextJS Website -## Required Environment Variables +## Purpose -This requires: +This provides a comprehensive webapp interface for LAION's Open Assistant +project. Initially it will support: -- `NEXT_PUBLIC_SUPABASE_URL`: A supabase Authorization URL -- `NEXT_PUBLIC_SUPABASE_ANON_KEY`: A public supabase key for Authorization +1. User registration using either Discord or Email. +1. Adding responses to incomplete Open Assistant tasks. +1. Rating or Ranking responses to Open Assistant tasks. +1. Viewing an activity leaderboard. +1. Tracking community wide updates. -These can both be optained from the Supabase project settings page. +This interface compliments the Discord bot and will give access to the same +underlying tasks. -## Getting Started +## Contributing -First, run the development server: +### Major Dependencies -```bash -npm run dev -# or -yarn dev -``` +This website is built using: -Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. +1. [npm](https://www.npmjs.com/): The node package manager for building. +1. [React](https://reactjs.org/): The core frontend framework. +1. [Next.js](https://nextjs.org/): A React scaffolding framework to streamline + development. +1. [Prisma](https://www.prisma.io/): An ORM to interact with a web specific + [Postgres](https://www.postgresql.org/) database. +1. [NextAuth.js](https://next-auth.js.org/): A user authentication framework + to ensure we handle accounts with best practices. +1. [TailwindCSS](https://tailwindcss.com/): A general purpose framework for + styling any component. +1. [Chakra-UI](https://chakra-ui.com/): A wide collection of pre-built UI + components that generally look pretty good. -You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file. +### Set up your environment -[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`. +To contribute to the website, make sure you have the following setup and +installed: -The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages. +1. [NVM](https://github.com/nvm-sh/nvm): The Node Version Manager makes it + easy to ensure you have the right NodeJS version installed. Once installed, + run `nvm use 16` to use Node 16.x. The website is known to be stable with + NodeJS version 16.x. This will install both Node and NPM. +1. [Docker](https://www.docker.com/): We use docker to simplify running + dependent services. + +### Getting everything up and running + +If you're doing active development we suggest the following workflow: + +1. In one tab, navigate to + `${OPEN_ASSISTANT_ROOT}/scripts/frontend-development`. +1. Run `docker compose up --build`. You can optionally include `-d` to detach and + later track the logs if desired. +1. In another tab navigate to `${OPEN_ASSISTANT_ROOT/website`. +1. Run `npm install` +1. Run `npx prisma db push` (This is also needed when you restart the docker + stack from scratch). +1. Run `npm run dev`. Now the website is up and running locally at + `http://localhost:3000`. +1. To create an account, login via the user using email authentication and + navigate to `http://localhost:1080`. Check the email listed and click the + log in link. You're now logged in and authenticated. + +## Code Layout + +### React Code + +All react code is under `src/` with a few sub directories: + +1. `pages/`: All pages a user could navigate too and API URLs which are under `pages/api/`. +1. `components/`: All re-usable React components. If something gets used + twice we should create a component and put it here. +1. `lib/`: A generic place to store library files that are used anywhere. + This doesn't have much structure yet. + +NOTE: `styles/` can be ignored for now. + +### Database + +All database configurations are stored in `prisma/schema.prisma`. + +### Static Content + +All static images, fonts, svgs, etc are stored in `public/`. + +### Styles + +We're not really using CSS styles. `styles/` can be ignored. + +## Best Practices + +When writing code for the website, we have a few best practices: + +1. When importing packages import external dependencies first then local + dependencies. Order them alphabetically according to the package name. +1. When trying to implement something new, check if + [Chakra-UI](https://chakra-ui.com/) has components that are close enough to + your need. For example Sliders, Radio Buttons, Progress indicators, etc. They + have a lot and we can save time by re-using what they have and tweaking the + style as needed. +1. Format everything with [Prettier](https://prettier.io/). This is done by + default with pre-submits. We currently don't have any custom settings. +1. Define functional React components (with types for all properties when + feasible). ## Learn More @@ -33,11 +111,3 @@ To learn more about Next.js, take a look at the following resources: - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. - -You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! - -## Deploy on Vercel - -The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. - -Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. diff --git a/website/jsconfig.json b/website/jsconfig.json new file mode 100644 index 00000000..2c8ee2bb --- /dev/null +++ b/website/jsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@/*": ["src/*"] + } + } +} diff --git a/website/next.config.js b/website/next.config.js index 91ef62f0..1cbdb0e0 100644 --- a/website/next.config.js +++ b/website/next.config.js @@ -1,6 +1,10 @@ /** @type {import('next').NextConfig} */ const nextConfig = { + output: "standalone", reactStrictMode: true, + experimental: { + scrollRestoration: true, + }, }; module.exports = nextConfig; diff --git a/website/package-lock.json b/website/package-lock.json index 5623182e..45063104 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -8,15 +8,415 @@ "name": "website", "version": "0.1.0", "dependencies": { - "@supabase/auth-helpers-nextjs": "^0.5.2", - "@supabase/auth-helpers-react": "^0.3.1", - "@supabase/auth-ui-react": "^0.2.6", - "@supabase/supabase-js": "^2.1.4", + "@chakra-ui/react": "^2.4.4", + "@emotion/react": "^11.10.5", + "@emotion/styled": "^11.10.5", + "@headlessui/react": "^1.7.7", + "@heroicons/react": "^2.0.13", + "@next-auth/prisma-adapter": "^1.0.5", + "@next/font": "^13.1.0", + "@prisma/client": "^4.7.1", + "@tailwindcss/forms": "^0.5.3", + "autoprefixer": "^10.4.13", + "axios": "^1.2.1", + "clsx": "^1.2.1", "eslint": "8.29.0", "eslint-config-next": "13.0.6", + "focus-visible": "^5.2.0", + "framer-motion": "^6.5.1", "next": "13.0.6", + "next-auth": "^4.18.6", + "nodemailer": "^6.8.0", + "postcss-focus-visible": "^7.1.0", "react": "18.2.0", - "react-dom": "18.2.0" + "react-dom": "18.2.0", + "react-icons": "^4.7.1", + "swr": "^2.0.0", + "tailwindcss": "^3.2.4", + "use-debounce": "^9.0.2" + }, + "devDependencies": { + "@types/node": "18.11.17", + "@types/react": "18.0.26", + "prettier": "2.8.1", + "prisma": "^4.7.1" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "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==", + "dependencies": { + "@babel/highlight": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.5.tgz", + "integrity": "sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==", + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.5.tgz", + "integrity": "sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==", + "peer": true, + "dependencies": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.5", + "@babel/helper-compilation-targets": "^7.20.0", + "@babel/helper-module-transforms": "^7.20.2", + "@babel/helpers": "^7.20.5", + "@babel/parser": "^7.20.5", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/json5": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz", + "integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==", + "peer": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "peer": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.5.tgz", + "integrity": "sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==", + "peer": true, + "dependencies": { + "@babel/types": "^7.20.5", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "peer": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", + "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", + "peer": true, + "dependencies": { + "@babel/compat-data": "^7.20.0", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "peer": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "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==", + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "peer": true, + "dependencies": { + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.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==", + "peer": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, + "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==", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", + "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", + "peer": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.1", + "@babel/types": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "peer": true, + "dependencies": { + "@babel/types": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "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==", + "peer": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, + "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==", + "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==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.6.tgz", + "integrity": "sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==", + "peer": true, + "dependencies": { + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz", + "integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==", + "peer": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", + "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/runtime": { @@ -42,15 +442,1333 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/template": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.5.tgz", + "integrity": "sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.5", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.20.5", + "@babel/types": "^7.20.5", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/types": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.5.tgz", + "integrity": "sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==", + "dependencies": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@chakra-ui/accordion": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@chakra-ui/accordion/-/accordion-2.1.4.tgz", + "integrity": "sha512-PQFW6kr+Bdru0DjKA8akC4BAz1VAJisLgo4TsJwjPO2gTS0zr99C+3bBs9uoDnjSJAf18/Q5zdXv11adA8n2XA==", + "dependencies": { + "@chakra-ui/descendant": "3.0.11", + "@chakra-ui/icon": "3.0.13", + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/react-use-controllable-state": "2.0.6", + "@chakra-ui/react-use-merge-refs": "2.0.5", + "@chakra-ui/transition": "2.0.12" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "framer-motion": ">=4.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/alert": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@chakra-ui/alert/-/alert-2.0.13.tgz", + "integrity": "sha512-7LqPv6EUBte4XM/Q2qBFIT5o4BC0dSlni9BHOH2BgAc5B1NF+pBAMDTUH7JNBiN7RHTV7EHAIWDziiX/NK28+Q==", + "dependencies": { + "@chakra-ui/icon": "3.0.13", + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/spinner": "2.0.11" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/anatomy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@chakra-ui/anatomy/-/anatomy-2.1.0.tgz", + "integrity": "sha512-E3jMPGqKuGTbt7mKtc8g/MOOenw2c4wqRC1vOypyFgmC8wsewdY+DJJNENF3atXAK7p5VMBKQfZ7ipNlHnDAwA==" + }, + "node_modules/@chakra-ui/avatar": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@chakra-ui/avatar/-/avatar-2.2.1.tgz", + "integrity": "sha512-sgiogfLM8vas8QJTt7AJI4XxNXYdViCWj+xYJwyOwUN93dWKImqqx3O2ihCXoXTIqQWg1rcEgoJ5CxCg6rQaQQ==", + "dependencies": { + "@chakra-ui/image": "2.0.12", + "@chakra-ui/react-children-utils": "2.0.4", + "@chakra-ui/react-context": "2.0.5" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/breadcrumb": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@chakra-ui/breadcrumb/-/breadcrumb-2.1.1.tgz", + "integrity": "sha512-OSa+F9qJ1xmF0zVxC1GU46OWbbhGf0kurHioSB729d+tRw/OMzmqrrfCJ7KVUUN8NEnTZXT5FIgokMvHGEt+Hg==", + "dependencies": { + "@chakra-ui/react-children-utils": "2.0.4", + "@chakra-ui/react-context": "2.0.5" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/breakpoint-utils": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/breakpoint-utils/-/breakpoint-utils-2.0.5.tgz", + "integrity": "sha512-8uhrckMwoR/powlAhxiFZPM0s8vn0B2yEyEaRcwpy5NmRAJSTEotC2WkSyQl/Cjysx9scredumB5g+fBX7IqGQ==" + }, + "node_modules/@chakra-ui/button": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@chakra-ui/button/-/button-2.0.13.tgz", + "integrity": "sha512-T9W/zHpHZVcbx/BMg0JIXCgRycut/eYoTYee/E+eBxyPCH45n308AsYU2bZ8TgZxUwbYNRgMp4qRL/KHUQDv5g==", + "dependencies": { + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/react-use-merge-refs": "2.0.5", + "@chakra-ui/spinner": "2.0.11" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/card": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/card/-/card-2.1.3.tgz", + "integrity": "sha512-8ET6ZOo6HtJutetqHJVOz+VpZvrWMGFAELfHsCuA/7orp7QZyUyXqfA79cZqZXCd3C4zn2G8H0bkiQFvzxQgOw==", + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/checkbox": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/checkbox/-/checkbox-2.2.5.tgz", + "integrity": "sha512-7fNH+Q2nB2uMSnYAPtYxnuwZ1MOJqblZHa/ScfZ/fjiPDyEae1m068ZP/l9yJ5zlawYMTkp83m/JVcu5QFYurA==", + "dependencies": { + "@chakra-ui/form-control": "2.0.13", + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/react-types": "2.0.5", + "@chakra-ui/react-use-callback-ref": "2.0.5", + "@chakra-ui/react-use-controllable-state": "2.0.6", + "@chakra-ui/react-use-merge-refs": "2.0.5", + "@chakra-ui/react-use-safe-layout-effect": "2.0.3", + "@chakra-ui/react-use-update-effect": "2.0.5", + "@chakra-ui/visually-hidden": "2.0.13", + "@zag-js/focus-visible": "0.1.0" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/clickable": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@chakra-ui/clickable/-/clickable-2.0.11.tgz", + "integrity": "sha512-5Y2dl5cxNgOxHbjxyxsL6Vdze4wUUvwsMCCW3kXwgz2OUI2y5UsBZNcvhNJx3RchJEd0fylMKiKoKmnZMHN2aw==", + "dependencies": { + "@chakra-ui/react-use-merge-refs": "2.0.5" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/close-button": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@chakra-ui/close-button/-/close-button-2.0.13.tgz", + "integrity": "sha512-ZI/3p84FPlW0xoDCZYqsnIvR6bTc2d/TlhwyTHsDDxq9ZOWp9c2JicVn6WTdWGdshk8itnZZdG50IcnizGnimA==", + "dependencies": { + "@chakra-ui/icon": "3.0.13" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/color-mode": { + "version": "2.1.10", + "resolved": "https://registry.npmjs.org/@chakra-ui/color-mode/-/color-mode-2.1.10.tgz", + "integrity": "sha512-aUPouOUPn7IPm1v00/9AIkRuNrkCwJlbjVL1kJzLzxijYjbHvEHPxntITt+JWjtXPT8xdOq6mexLYCOGA67JwQ==", + "dependencies": { + "@chakra-ui/react-use-safe-layout-effect": "2.0.3" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/control-box": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@chakra-ui/control-box/-/control-box-2.0.11.tgz", + "integrity": "sha512-UJb4vqq+/FPuwTCuaPeHa2lwtk6u7eFvLuwDCST2e/sBWGJC1R+1/Il5pHccnWs09FWxyZ9v/Oxkg/CG3jZR4Q==", + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/counter": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@chakra-ui/counter/-/counter-2.0.11.tgz", + "integrity": "sha512-1YRt/jom+m3iWw9J9trcM6rAHDvD4lwThiO9raxUK7BRsYUhnPZvsMpcXU1Moax218C4rRpbI9KfPLaig0m1xQ==", + "dependencies": { + "@chakra-ui/number-utils": "2.0.5", + "@chakra-ui/react-use-callback-ref": "2.0.5" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/css-reset": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@chakra-ui/css-reset/-/css-reset-2.0.10.tgz", + "integrity": "sha512-FwHOfw2P4ckbpSahDZef2KoxcvHPUg09jlicWdp24/MjdsOO5PAB/apm2UBvQflY4WAJyOqYaOdnXFlR6nF4cQ==", + "peerDependencies": { + "@emotion/react": ">=10.0.35", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/descendant": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@chakra-ui/descendant/-/descendant-3.0.11.tgz", + "integrity": "sha512-sNLI6NS6uUgrvYS6Imhoc1YlI6bck6pfxMBJcnXVSfdIjD6XjCmeY2YgzrtDS+o+J8bB3YJeIAG/vsVy5USE5Q==", + "dependencies": { + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/react-use-merge-refs": "2.0.5" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/dom-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@chakra-ui/dom-utils/-/dom-utils-2.0.4.tgz", + "integrity": "sha512-P936+WKinz5fgHzfwiUQjE/t7NC8bU89Tceim4tbn8CIm/9b+CsHX64eNw4vyJqRwt78TXQK7aGBIbS18R0q5Q==" + }, + "node_modules/@chakra-ui/editable": { + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/@chakra-ui/editable/-/editable-2.0.16.tgz", + "integrity": "sha512-kIFPufzIlViNv7qi2PxxWWBvjLb+3IP5hUGmqOA9qcYz5TAdqblQqDClm0iajlIDNUFWnS4h056o8jKsQ42a5A==", + "dependencies": { + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/react-types": "2.0.5", + "@chakra-ui/react-use-callback-ref": "2.0.5", + "@chakra-ui/react-use-controllable-state": "2.0.6", + "@chakra-ui/react-use-focus-on-pointer-down": "2.0.4", + "@chakra-ui/react-use-merge-refs": "2.0.5", + "@chakra-ui/react-use-safe-layout-effect": "2.0.3", + "@chakra-ui/react-use-update-effect": "2.0.5", + "@chakra-ui/shared-utils": "2.0.3" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/event-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@chakra-ui/event-utils/-/event-utils-2.0.6.tgz", + "integrity": "sha512-ZIoqUbgJ5TcCbZRchMv4n7rOl1JL04doMebED88LO5mux36iVP9er/nnOY4Oke1bANKKURMrQf5VTT9hoYeA7A==" + }, + "node_modules/@chakra-ui/focus-lock": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@chakra-ui/focus-lock/-/focus-lock-2.0.13.tgz", + "integrity": "sha512-AVSJt+3Ukia/m9TCZZgyWvTY7pw88jArivWVJ2gySGYYIs6z/FJMnlwbCVldV2afS0g3cYaii7aARb/WrlG34Q==", + "dependencies": { + "@chakra-ui/dom-utils": "2.0.4", + "react-focus-lock": "^2.9.1" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/form-control": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@chakra-ui/form-control/-/form-control-2.0.13.tgz", + "integrity": "sha512-J964JlgrxP+LP3kYmLk1ttbl73u6ghT+JQDjEjkEUc8lSS9Iv4u9XkRDQHuz2t2y0KHjQdH12PUfUfBqcITbYw==", + "dependencies": { + "@chakra-ui/icon": "3.0.13", + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/react-types": "2.0.5", + "@chakra-ui/react-use-merge-refs": "2.0.5" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/hooks": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@chakra-ui/hooks/-/hooks-2.1.2.tgz", + "integrity": "sha512-/vDBOqqnho9q++lay0ZcvnH8VuE0wT2OkZj+qDwFwjiHAtGPVxHCSpu9KC8BIHME5TlWjyO6riVyUCb2e2ip6w==", + "dependencies": { + "@chakra-ui/react-utils": "2.0.9", + "@chakra-ui/utils": "2.0.12", + "compute-scroll-into-view": "1.0.14", + "copy-to-clipboard": "3.3.1" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/icon": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/@chakra-ui/icon/-/icon-3.0.13.tgz", + "integrity": "sha512-RaDLC4psd8qyInY2RX4AlYRfpLBNw3VsMih17BFf8EESVhBXNJcYy7Q9eMV/K4NvZfZT42vuVqGVNFmkG89lBQ==", + "dependencies": { + "@chakra-ui/shared-utils": "2.0.3" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/image": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@chakra-ui/image/-/image-2.0.12.tgz", + "integrity": "sha512-uclFhs0+wq2qujGu8Wk4eEWITA3iZZQTitGiFSEkO9Ws5VUH+Gqtn3mUilH0orubrI5srJsXAmjVTuVwge1KJQ==", + "dependencies": { + "@chakra-ui/react-use-safe-layout-effect": "2.0.3" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/input": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@chakra-ui/input/-/input-2.0.14.tgz", + "integrity": "sha512-CkSrUJeKWogOSt2pUf2vVv5s0bUVcAi4/XGj1JVCCfyIX6a6h1m8R69MShTPxPiQ0Mdebq5ATrW/aZQQXZzRGQ==", + "dependencies": { + "@chakra-ui/form-control": "2.0.13", + "@chakra-ui/object-utils": "2.0.5", + "@chakra-ui/react-children-utils": "2.0.4", + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/shared-utils": "2.0.3" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/layout": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/@chakra-ui/layout/-/layout-2.1.11.tgz", + "integrity": "sha512-UP19V8EeI/DEODbWrZlqC0sg248bpFaWpMiM/+g9Bsxs9aof3yexpMD/7gb0yrfbIrkdvSBrcQeqxXGzbfoopw==", + "dependencies": { + "@chakra-ui/breakpoint-utils": "2.0.5", + "@chakra-ui/icon": "3.0.13", + "@chakra-ui/object-utils": "2.0.5", + "@chakra-ui/react-children-utils": "2.0.4", + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/shared-utils": "2.0.3" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/lazy-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/lazy-utils/-/lazy-utils-2.0.3.tgz", + "integrity": "sha512-SQ5I5rJrcHpVUcEftHLOh8UyeY+06R8Gv3k2RjcpvM6mb2Gktlz/4xl2GcUh3LWydgGQDW/7Rse5rQhKWgzmcg==" + }, + "node_modules/@chakra-ui/live-region": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@chakra-ui/live-region/-/live-region-2.0.11.tgz", + "integrity": "sha512-ltObaKQekP75GCCbN+vt1/mGABSCaRdQELmotHTBc5AioA3iyCDHH69ev+frzEwLvKFqo+RomAdAAgqBIMJ02Q==", + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/media-query": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@chakra-ui/media-query/-/media-query-3.2.8.tgz", + "integrity": "sha512-djmEg/eJ5Qrjn7SArTqjsvlwF6mNeMuiawrTwnU+0EKq9Pq/wVSb7VaIhxdQYJLA/DbRhE/KPMogw1LNVKa4Rw==", + "dependencies": { + "@chakra-ui/breakpoint-utils": "2.0.5", + "@chakra-ui/react-env": "2.0.11" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/menu": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/menu/-/menu-2.1.5.tgz", + "integrity": "sha512-2UusrQtxHcqcO9n/0YobNN3RJC8yAZU6oJbRPuvsQ9IL89scEWCTIxXEYrnIjeh/5zikcSEDGo9zM9Udg/XcsA==", + "dependencies": { + "@chakra-ui/clickable": "2.0.11", + "@chakra-ui/descendant": "3.0.11", + "@chakra-ui/lazy-utils": "2.0.3", + "@chakra-ui/popper": "3.0.10", + "@chakra-ui/react-children-utils": "2.0.4", + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/react-use-animation-state": "2.0.6", + "@chakra-ui/react-use-controllable-state": "2.0.6", + "@chakra-ui/react-use-disclosure": "2.0.6", + "@chakra-ui/react-use-focus-effect": "2.0.7", + "@chakra-ui/react-use-merge-refs": "2.0.5", + "@chakra-ui/react-use-outside-click": "2.0.5", + "@chakra-ui/react-use-update-effect": "2.0.5", + "@chakra-ui/transition": "2.0.12" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "framer-motion": ">=4.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/modal": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/modal/-/modal-2.2.5.tgz", + "integrity": "sha512-QIoN89bT5wnR71wxZFHt7vsS65yF9WCfIwDtFk8ifxJORPi/UkLMwBpjTV2Jfsxd22W6Oo2VOpRR0a5WFeK+jA==", + "dependencies": { + "@chakra-ui/close-button": "2.0.13", + "@chakra-ui/focus-lock": "2.0.13", + "@chakra-ui/portal": "2.0.12", + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/react-types": "2.0.5", + "@chakra-ui/react-use-merge-refs": "2.0.5", + "@chakra-ui/transition": "2.0.12", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "^2.5.4" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "framer-motion": ">=4.0.0", + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/@chakra-ui/number-input": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@chakra-ui/number-input/-/number-input-2.0.14.tgz", + "integrity": "sha512-IARUAbP4pn1gP5fY2dK4wtbR3ONjzHgTjH4Zj3ErZvdu/yTURLaZmlb6UGHwgqjWLyioactZ/+n4Njj5CRjs8w==", + "dependencies": { + "@chakra-ui/counter": "2.0.11", + "@chakra-ui/form-control": "2.0.13", + "@chakra-ui/icon": "3.0.13", + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/react-types": "2.0.5", + "@chakra-ui/react-use-callback-ref": "2.0.5", + "@chakra-ui/react-use-event-listener": "2.0.5", + "@chakra-ui/react-use-interval": "2.0.3", + "@chakra-ui/react-use-merge-refs": "2.0.5", + "@chakra-ui/react-use-safe-layout-effect": "2.0.3", + "@chakra-ui/react-use-update-effect": "2.0.5" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/number-utils": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/number-utils/-/number-utils-2.0.5.tgz", + "integrity": "sha512-Thhohnlqze0i5HBJO9xkfOPq1rv3ji/hNPf2xh1fh4hxrNzdm3HCkz0c6lyRQwGuVoeltEHysYZLH/uWLFTCSQ==" + }, + "node_modules/@chakra-ui/object-utils": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/object-utils/-/object-utils-2.0.5.tgz", + "integrity": "sha512-/rIMoYI3c2uLtFIrnTFOPRAI8StUuu335WszqKM0KAW1lwG9H6uSbxqlpZT1Pxi/VQqZKfheGiMQOx5lfTmM/A==" + }, + "node_modules/@chakra-ui/pin-input": { + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/@chakra-ui/pin-input/-/pin-input-2.0.16.tgz", + "integrity": "sha512-51cioNYpBSgi9/jq6CrzoDvo8fpMwFXu3SaFRbKO47s9Dz/OAW0MpjyabTfSpwOv0xKZE+ayrYGJopCzZSWXPg==", + "dependencies": { + "@chakra-ui/descendant": "3.0.11", + "@chakra-ui/react-children-utils": "2.0.4", + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/react-use-controllable-state": "2.0.6", + "@chakra-ui/react-use-merge-refs": "2.0.5" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/popover": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@chakra-ui/popover/-/popover-2.1.4.tgz", + "integrity": "sha512-NXVtyMxYzDKzzQph/+GFRSM3tEj3gNvlCX/xGRsCOt9I446zJ1InCd/boXQKAc813coEN9McSOjNWgo+NCBD+Q==", + "dependencies": { + "@chakra-ui/close-button": "2.0.13", + "@chakra-ui/lazy-utils": "2.0.3", + "@chakra-ui/popper": "3.0.10", + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/react-types": "2.0.5", + "@chakra-ui/react-use-animation-state": "2.0.6", + "@chakra-ui/react-use-disclosure": "2.0.6", + "@chakra-ui/react-use-focus-effect": "2.0.7", + "@chakra-ui/react-use-focus-on-pointer-down": "2.0.4", + "@chakra-ui/react-use-merge-refs": "2.0.5" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "framer-motion": ">=4.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/popper": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@chakra-ui/popper/-/popper-3.0.10.tgz", + "integrity": "sha512-6LacbBGX0piHWY/DYxOGCTTFAoRGRHpGIRzTgfNy8jxw4f+rukaVudd4Pc2fwjCTdobJKM8nGNYIYNv9/Dmq9Q==", + "dependencies": { + "@chakra-ui/react-types": "2.0.5", + "@chakra-ui/react-use-merge-refs": "2.0.5", + "@popperjs/core": "^2.9.3" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/portal": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@chakra-ui/portal/-/portal-2.0.12.tgz", + "integrity": "sha512-8D/1fFUdbJtzyGL5sCBIb4oyTnPG2v6rx/L/qbG43FcXDrongmzLj0+tJ//PbJr+5hxjXAWFUjpPvyx10pTN6Q==", + "dependencies": { + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/react-use-safe-layout-effect": "2.0.3" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/@chakra-ui/progress": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@chakra-ui/progress/-/progress-2.1.2.tgz", + "integrity": "sha512-ofhMWTqCxnm1NiP/zH4SV7EvOLogfX15MSMTNfGqZv6t8eSSeTn6oRRzsTSllJfSqDey7oZNCRbP7vDhvx9HtQ==", + "dependencies": { + "@chakra-ui/react-context": "2.0.5" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/provider": { + "version": "2.0.26", + "resolved": "https://registry.npmjs.org/@chakra-ui/provider/-/provider-2.0.26.tgz", + "integrity": "sha512-ln5c3zSFvN1WrkPkX/KOWp+CPg6y8opASlZvWvM+1lTpNX82FkXyPiQYjaemGGbKuooqdRMylseWBStoFwjxOw==", + "dependencies": { + "@chakra-ui/css-reset": "2.0.10", + "@chakra-ui/portal": "2.0.12", + "@chakra-ui/react-env": "2.0.11", + "@chakra-ui/system": "2.3.5", + "@chakra-ui/utils": "2.0.12" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0", + "@emotion/styled": "^11.0.0", + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/@chakra-ui/radio": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@chakra-ui/radio/-/radio-2.0.14.tgz", + "integrity": "sha512-e/hY1g92Xdu5d5A27NFfa1+ccE2q/A5H7sc/M7p0fId6KO33Dst25Hy+HThtqnYN0Y3Om58fiXEKo5SsdtvSfA==", + "dependencies": { + "@chakra-ui/form-control": "2.0.13", + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/react-types": "2.0.5", + "@chakra-ui/react-use-merge-refs": "2.0.5", + "@zag-js/focus-visible": "0.1.0" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@chakra-ui/react/-/react-2.4.4.tgz", + "integrity": "sha512-mA0Js3qpRBTmhPuBlBw85OG9ot7uh7+4IjsASmkzbpJVB1Kz9Z+7RBOpjHfK/03zEsRp+XYrb1ps0DYl8ih5bQ==", + "dependencies": { + "@chakra-ui/accordion": "2.1.4", + "@chakra-ui/alert": "2.0.13", + "@chakra-ui/avatar": "2.2.1", + "@chakra-ui/breadcrumb": "2.1.1", + "@chakra-ui/button": "2.0.13", + "@chakra-ui/card": "2.1.3", + "@chakra-ui/checkbox": "2.2.5", + "@chakra-ui/close-button": "2.0.13", + "@chakra-ui/control-box": "2.0.11", + "@chakra-ui/counter": "2.0.11", + "@chakra-ui/css-reset": "2.0.10", + "@chakra-ui/editable": "2.0.16", + "@chakra-ui/form-control": "2.0.13", + "@chakra-ui/hooks": "2.1.2", + "@chakra-ui/icon": "3.0.13", + "@chakra-ui/image": "2.0.12", + "@chakra-ui/input": "2.0.14", + "@chakra-ui/layout": "2.1.11", + "@chakra-ui/live-region": "2.0.11", + "@chakra-ui/media-query": "3.2.8", + "@chakra-ui/menu": "2.1.5", + "@chakra-ui/modal": "2.2.5", + "@chakra-ui/number-input": "2.0.14", + "@chakra-ui/pin-input": "2.0.16", + "@chakra-ui/popover": "2.1.4", + "@chakra-ui/popper": "3.0.10", + "@chakra-ui/portal": "2.0.12", + "@chakra-ui/progress": "2.1.2", + "@chakra-ui/provider": "2.0.26", + "@chakra-ui/radio": "2.0.14", + "@chakra-ui/react-env": "2.0.11", + "@chakra-ui/select": "2.0.14", + "@chakra-ui/skeleton": "2.0.20", + "@chakra-ui/slider": "2.0.16", + "@chakra-ui/spinner": "2.0.11", + "@chakra-ui/stat": "2.0.13", + "@chakra-ui/styled-system": "2.5.0", + "@chakra-ui/switch": "2.0.17", + "@chakra-ui/system": "2.3.5", + "@chakra-ui/table": "2.0.13", + "@chakra-ui/tabs": "2.1.5", + "@chakra-ui/tag": "2.0.13", + "@chakra-ui/textarea": "2.0.14", + "@chakra-ui/theme": "2.2.2", + "@chakra-ui/theme-utils": "2.0.6", + "@chakra-ui/toast": "4.0.6", + "@chakra-ui/tooltip": "2.2.3", + "@chakra-ui/transition": "2.0.12", + "@chakra-ui/utils": "2.0.12", + "@chakra-ui/visually-hidden": "2.0.13" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0", + "@emotion/styled": "^11.0.0", + "framer-motion": ">=4.0.0", + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/@chakra-ui/react-children-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-children-utils/-/react-children-utils-2.0.4.tgz", + "integrity": "sha512-qsKUEfK/AhDbMexWo5JhmdlkxLg5WEw2dFh4XorvU1/dTYsRfP6cjFfO8zE+X3F0ZFNsgKz6rbN5oU349GLEFw==", + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-context": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-context/-/react-context-2.0.5.tgz", + "integrity": "sha512-WYS0VBl5Q3/kNShQ26BP+Q0OGMeTQWco3hSiJWvO2wYLY7N1BLq6dKs8vyKHZfpwKh2YL2bQeAObi+vSkXp6tQ==", + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-env": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-env/-/react-env-2.0.11.tgz", + "integrity": "sha512-rPwUHReSWh7rbCw0HePa8Pvc+Q82fUFvVjHTIbXKnE6d+01cCE7j4f1NLeRD9pStKPI6sIZm9xTGvOCzl8F8iw==", + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-types": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-types/-/react-types-2.0.5.tgz", + "integrity": "sha512-GApp+R/VjS1UV5ms5irrij5LOIgUM0dqSVHagyEFEz88LRKkqMD9RuO577ZsVd4Gn0ULsacVJCUA0HtNUBJNzA==", + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-animation-state": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-animation-state/-/react-use-animation-state-2.0.6.tgz", + "integrity": "sha512-M2kUzZkSBgDpfvnffh3kTsMIM3Dvn+CTMqy9zfY97NL4P3LAWL1MuFtKdlKfQ8hs/QpwS/ew8CTmCtaywn4sKg==", + "dependencies": { + "@chakra-ui/dom-utils": "2.0.4", + "@chakra-ui/react-use-event-listener": "2.0.5" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-callback-ref": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-callback-ref/-/react-use-callback-ref-2.0.5.tgz", + "integrity": "sha512-vKnXleD2PzB0nGabY35fRtklMid4z7cecbMG0fkasNNsgWmrQcXJOuEKUUVCynL6FBU6gBnpKFi5Aqj6x+K4tw==", + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-controllable-state": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-controllable-state/-/react-use-controllable-state-2.0.6.tgz", + "integrity": "sha512-7WuKrhQkpSRoiI5PKBvuIsO46IIP0wsRQgXtStSaIXv+FIvIJl9cxQXTbmZ5q1Ds641QdAUKx4+6v0K/zoZEHg==", + "dependencies": { + "@chakra-ui/react-use-callback-ref": "2.0.5" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-disclosure": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-disclosure/-/react-use-disclosure-2.0.6.tgz", + "integrity": "sha512-4UPePL+OcCY37KZ585iLjg8i6J0sjpLm7iZG3PUwmb97oKHVHq6DpmWIM0VfSjcT6AbSqyGcd5BXZQBgwt8HWQ==", + "dependencies": { + "@chakra-ui/react-use-callback-ref": "2.0.5" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-event-listener": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-event-listener/-/react-use-event-listener-2.0.5.tgz", + "integrity": "sha512-etLBphMigxy/cm7Yg22y29gQ8u/K3PniR5ADZX7WVX61Cgsa8ciCqjTE9sTtlJQWAQySbWxt9+mjlT5zaf+6Zw==", + "dependencies": { + "@chakra-ui/react-use-callback-ref": "2.0.5" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-focus-effect": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-focus-effect/-/react-use-focus-effect-2.0.7.tgz", + "integrity": "sha512-wI8OUNwfbkusajLac8QtjfSyNmsNu1D5pANmnSHIntHhui6Jwv75Pxx7RgmBEnfBEpleBndhR9E75iCjPLhZ/A==", + "dependencies": { + "@chakra-ui/dom-utils": "2.0.4", + "@chakra-ui/react-use-event-listener": "2.0.5", + "@chakra-ui/react-use-safe-layout-effect": "2.0.3", + "@chakra-ui/react-use-update-effect": "2.0.5" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-focus-on-pointer-down": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-focus-on-pointer-down/-/react-use-focus-on-pointer-down-2.0.4.tgz", + "integrity": "sha512-L3YKouIi77QbXH9mSLGEFzJbJDhyrPlcRcuu+TSC7mYaK9E+3Ap+RVSAVxj+CfQz7hCWpikPecKDuspIPWlyuA==", + "dependencies": { + "@chakra-ui/react-use-event-listener": "2.0.5" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-interval": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-interval/-/react-use-interval-2.0.3.tgz", + "integrity": "sha512-Orbij5c5QkL4NuFyU4mfY/nyRckNBgoGe9ic8574VVNJIXfassevZk0WB+lvqBn5XZeLf2Tj+OGJrg4j4H9wzw==", + "dependencies": { + "@chakra-ui/react-use-callback-ref": "2.0.5" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-latest-ref": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-latest-ref/-/react-use-latest-ref-2.0.3.tgz", + "integrity": "sha512-exNSQD4rPclDSmNwtcChUCJ4NuC2UJ4amyNGBqwSjyaK5jNHk2kkM7rZ6I0I8ul+26lvrXlSuhyv6c2PFwbFQQ==", + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-merge-refs": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-merge-refs/-/react-use-merge-refs-2.0.5.tgz", + "integrity": "sha512-uc+MozBZ8asaUpO8SWcK6D4svRPACN63jv5uosUkXJR+05jQJkUofkfQbf2HeGVbrWCr0XZsftLIm4Mt/QMoVw==", + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-outside-click": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-outside-click/-/react-use-outside-click-2.0.5.tgz", + "integrity": "sha512-WmtXUeVaMtxP9aUGGG+GQaDeUn/Bvf8TI3EU5mE1+TtqLHxyA9wtvQurynrogvpilLaBADwn/JeBeqs2wHpvqA==", + "dependencies": { + "@chakra-ui/react-use-callback-ref": "2.0.5" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-pan-event": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-pan-event/-/react-use-pan-event-2.0.6.tgz", + "integrity": "sha512-Vtgl3c+Mj4hdehFRFIgruQVXctwnG1590Ein1FiU8sVnlqO6bpug6Z+B14xBa+F+X0aK+DxnhkJFyWI93Pks2g==", + "dependencies": { + "@chakra-ui/event-utils": "2.0.6", + "@chakra-ui/react-use-latest-ref": "2.0.3", + "framesync": "5.3.0" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-previous": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-previous/-/react-use-previous-2.0.3.tgz", + "integrity": "sha512-A2ODOa0rm2HM4aqXfxxI0zPLcn5Q7iBEjRyfIQhb+EH+d2OFuj3L2slVoIpp6e/km3Xzv2d+u/WbjgTzdQ3d0w==", + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-safe-layout-effect": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-safe-layout-effect/-/react-use-safe-layout-effect-2.0.3.tgz", + "integrity": "sha512-dlTvQURzmdfyBbNdydgO4Wy2/HV8aJN8LszTtyb5vRZsyaslDM/ftcxo8E8QjHwRLD/V1Epb/A8731QfimfVaQ==", + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-size": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-size/-/react-use-size-2.0.5.tgz", + "integrity": "sha512-4arAApdiXk5uv5ZeFKltEUCs5h3yD9dp6gTIaXbAdq+/ENK3jMWTwlqzNbJtCyhwoOFrblLSdBrssBMIsNQfZQ==", + "dependencies": { + "@zag-js/element-size": "0.1.0" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-timeout": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-timeout/-/react-use-timeout-2.0.3.tgz", + "integrity": "sha512-rBBUkZSQq3nJQ8fuMkgZNY2Sgg4vKiKNp05GxAwlT7TitOfVZyoTriqQpqz296bWlmkICTZxlqCWfE5fWpsTsg==", + "dependencies": { + "@chakra-ui/react-use-callback-ref": "2.0.5" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-use-update-effect": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-update-effect/-/react-use-update-effect-2.0.5.tgz", + "integrity": "sha512-y9tCMr1yuDl8ATYdh64Gv8kge5xE1DMykqPDZw++OoBsTaWr3rx40wblA8NIWuSyJe5ErtKP2OeglvJkYhryJQ==", + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/react-utils": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-utils/-/react-utils-2.0.9.tgz", + "integrity": "sha512-nlwPBVlQmcl1PiLzZWyrT3FSnt3vKSkBMzQ0EF4SJWA/nOIqTvmffb5DCzCqPzgQaE/Da1Xgus+JufFGM8GLCQ==", + "dependencies": { + "@chakra-ui/utils": "2.0.12" + }, + "peerDependencies": { + "react": ">=18" + } + }, + "node_modules/@chakra-ui/select": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@chakra-ui/select/-/select-2.0.14.tgz", + "integrity": "sha512-fvVGxAtLaIXGOMicrzSa6imMw5h26S1ar3xyNmXgR40dbpTPHmtQJkbHBf9FwwQXgSgKWgBzsztw5iDHCpPVzA==", + "dependencies": { + "@chakra-ui/form-control": "2.0.13" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/shared-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/shared-utils/-/shared-utils-2.0.3.tgz", + "integrity": "sha512-pCU+SUGdXzjAuUiUT8mriekL3tJVfNdwSTIaNeip7k/SWDzivrKGMwAFBxd3XVTDevtVusndkO4GJuQ3yILzDg==" + }, + "node_modules/@chakra-ui/skeleton": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/@chakra-ui/skeleton/-/skeleton-2.0.20.tgz", + "integrity": "sha512-PEjjAHT/X8XEHTzXlN0kL883m1Z4Yo4A/ztv4VOvBTnXhHl2wFrrwucxj8TS3eWoCJ65dY9b0ZySP9ARTUe1ng==", + "dependencies": { + "@chakra-ui/media-query": "3.2.8", + "@chakra-ui/react-use-previous": "2.0.3" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/slider": { + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/@chakra-ui/slider/-/slider-2.0.16.tgz", + "integrity": "sha512-0nEu9+OAPv4yzMrTH6SkNNMiXbLRe7lXYv1gWbpDGOsNgpGDFYmA7qpzsiiJEJoynqcJZqmDPArqWWPNYeY6Sw==", + "dependencies": { + "@chakra-ui/number-utils": "2.0.5", + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/react-types": "2.0.5", + "@chakra-ui/react-use-callback-ref": "2.0.5", + "@chakra-ui/react-use-controllable-state": "2.0.6", + "@chakra-ui/react-use-latest-ref": "2.0.3", + "@chakra-ui/react-use-merge-refs": "2.0.5", + "@chakra-ui/react-use-pan-event": "2.0.6", + "@chakra-ui/react-use-size": "2.0.5", + "@chakra-ui/react-use-update-effect": "2.0.5" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/spinner": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@chakra-ui/spinner/-/spinner-2.0.11.tgz", + "integrity": "sha512-piO2ghWdJzQy/+89mDza7xLhPnW7pA+ADNbgCb1vmriInWedS41IBKe+pSPz4IidjCbFu7xwKE0AerFIbrocCA==", + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/stat": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@chakra-ui/stat/-/stat-2.0.13.tgz", + "integrity": "sha512-6XeuE/7w0BjyCHSxMbsf6/rNOOs8BSit1NS7g7+Jd/40Pc/SKlNWLd3kxXPid4eT3RwyNIdMPtm30OActr9nqQ==", + "dependencies": { + "@chakra-ui/icon": "3.0.13", + "@chakra-ui/react-context": "2.0.5" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/styled-system": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@chakra-ui/styled-system/-/styled-system-2.5.0.tgz", + "integrity": "sha512-xbvD9MTSXqsPbunCCxfebqslokU53zUefPDQJhgXNKKeMq0NGEgNdGOFXC8oFDP1S/I1GgohKcrSbrSXXLw8yg==", + "dependencies": { + "csstype": "^3.0.11", + "lodash.mergewith": "4.6.2" + } + }, + "node_modules/@chakra-ui/switch": { + "version": "2.0.17", + "resolved": "https://registry.npmjs.org/@chakra-ui/switch/-/switch-2.0.17.tgz", + "integrity": "sha512-BQabfC6qYi5xBJvEFPzKq0yl6fTtTNNEHTid5r7h0PWcCnAiHwQJTpQRpxp+AjK569LMLtTXReTZvNBrzEwOrA==", + "dependencies": { + "@chakra-ui/checkbox": "2.2.5" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "framer-motion": ">=4.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/system": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/system/-/system-2.3.5.tgz", + "integrity": "sha512-x7S7pNKQtFk7/qsn3aHlbZfhcacvaGXBKlnQvHKrbmDVxgLCjGExdi/8Vs7rSYzIyXHx3lItpwd2qHsqqcNvaQ==", + "dependencies": { + "@chakra-ui/color-mode": "2.1.10", + "@chakra-ui/react-utils": "2.0.9", + "@chakra-ui/styled-system": "2.5.0", + "@chakra-ui/theme-utils": "2.0.6", + "@chakra-ui/utils": "2.0.12", + "react-fast-compare": "3.2.0" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0", + "@emotion/styled": "^11.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/table": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@chakra-ui/table/-/table-2.0.13.tgz", + "integrity": "sha512-miQUBJ07L7RzVoFAD6C9I9gaaABeivFRjbr9hf3vyTCsUTV/HDIBHROr6V1sIcQS3asU5nrgbDzRm90mvFOTiw==", + "dependencies": { + "@chakra-ui/react-context": "2.0.5" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/tabs": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/tabs/-/tabs-2.1.5.tgz", + "integrity": "sha512-XmnKDclAJe0FoW4tdC8AlnZpPN5fcj92l4r2sqiL9WyYVEM71hDxZueETIph/GTtfMelG7Z8e5vBHP4rh1RT5g==", + "dependencies": { + "@chakra-ui/clickable": "2.0.11", + "@chakra-ui/descendant": "3.0.11", + "@chakra-ui/lazy-utils": "2.0.3", + "@chakra-ui/react-children-utils": "2.0.4", + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/react-use-controllable-state": "2.0.6", + "@chakra-ui/react-use-merge-refs": "2.0.5", + "@chakra-ui/react-use-safe-layout-effect": "2.0.3" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/tag": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@chakra-ui/tag/-/tag-2.0.13.tgz", + "integrity": "sha512-W1urf+tvGMt6J3cc31HudybYSl+B5jYUP5DJxzXM9p+n3JrvXWAo4D6LmpLBHY5zT2mNne14JF1rVeRcG4Rtdg==", + "dependencies": { + "@chakra-ui/icon": "3.0.13", + "@chakra-ui/react-context": "2.0.5" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/textarea": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@chakra-ui/textarea/-/textarea-2.0.14.tgz", + "integrity": "sha512-r8hF1rCi+GseLtY/IGeVWXFN0Uve2b820UQumRj4qxj7PsPqw1hFg7Cecbbb9zwF38K/m+D3IdwFeJzI1MtgRA==", + "dependencies": { + "@chakra-ui/form-control": "2.0.13" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/theme": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@chakra-ui/theme/-/theme-2.2.2.tgz", + "integrity": "sha512-7DlOQiXmnaqYyqXwqmfFSCWGkUonuqmNC5mmUCwxI435KgHNCaE2bIm6DI7N2NcIcuVcfc8Vn0UqrDoGU3zJBg==", + "dependencies": { + "@chakra-ui/anatomy": "2.1.0", + "@chakra-ui/theme-tools": "2.0.14" + }, + "peerDependencies": { + "@chakra-ui/styled-system": ">=2.0.0" + } + }, + "node_modules/@chakra-ui/theme-tools": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@chakra-ui/theme-tools/-/theme-tools-2.0.14.tgz", + "integrity": "sha512-lVcDmq5pyU0QbsIFKjt/iVUFDap7di2QHvPvGChA1YSjtg1PtuUi+BxEXWzp3Nfgw/N4rMvlBs+S0ynJypdwbg==", + "dependencies": { + "@chakra-ui/anatomy": "2.1.0", + "color2k": "^2.0.0" + }, + "peerDependencies": { + "@chakra-ui/styled-system": ">=2.0.0" + } + }, + "node_modules/@chakra-ui/theme-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@chakra-ui/theme-utils/-/theme-utils-2.0.6.tgz", + "integrity": "sha512-kUm3jaz3sQ/bhBEZ6RWPs1xptQNdSWh/krv9p92rvSkEfjCBDHM5dx7dYk/8KamyUZ6DmK+M31dPyOdOROkBFQ==", + "dependencies": { + "@chakra-ui/styled-system": "2.5.0", + "@chakra-ui/theme": "2.2.2", + "lodash.mergewith": "4.6.2" + } + }, + "node_modules/@chakra-ui/toast": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@chakra-ui/toast/-/toast-4.0.6.tgz", + "integrity": "sha512-LatqPM7Vhj22qCyOYXDuhretohp5lJWcXpI9QwpDjd/CEeChy4kYeIJbaLBMzl2WTfIZ+rfHRBhFTpp33aGyqA==", + "dependencies": { + "@chakra-ui/alert": "2.0.13", + "@chakra-ui/close-button": "2.0.13", + "@chakra-ui/portal": "2.0.12", + "@chakra-ui/react-use-timeout": "2.0.3", + "@chakra-ui/react-use-update-effect": "2.0.5", + "@chakra-ui/styled-system": "2.5.0", + "@chakra-ui/theme": "2.2.2" + }, + "peerDependencies": { + "@chakra-ui/system": "2.3.5", + "framer-motion": ">=4.0.0", + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/@chakra-ui/tooltip": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/tooltip/-/tooltip-2.2.3.tgz", + "integrity": "sha512-yOne9ofFYfW2XHsbCEPWgLUTnHKm5z21f/cPjwEqtmvCS7aTCOLFiwz2ckRS8yJbIAy+mw0UG6jQsblYKgXj4A==", + "dependencies": { + "@chakra-ui/popper": "3.0.10", + "@chakra-ui/portal": "2.0.12", + "@chakra-ui/react-types": "2.0.5", + "@chakra-ui/react-use-disclosure": "2.0.6", + "@chakra-ui/react-use-event-listener": "2.0.5", + "@chakra-ui/react-use-merge-refs": "2.0.5" + }, + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "framer-motion": ">=4.0.0", + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/@chakra-ui/transition": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@chakra-ui/transition/-/transition-2.0.12.tgz", + "integrity": "sha512-ff6eU+m08ccYfCkk0hKfY/XlmGxCrfbBgsKgV4mirZ4SKUL1GVye8CYuHwWQlBJo+8s0yIpsTNxAuX4n/cW9/w==", + "peerDependencies": { + "framer-motion": ">=4.0.0", + "react": ">=18" + } + }, + "node_modules/@chakra-ui/utils": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@chakra-ui/utils/-/utils-2.0.12.tgz", + "integrity": "sha512-1Z1MgsrfMQhNejSdrPJk8v5J4gCefHo+1wBmPPHTz5bGEbAAbZ13aXAfXy8w0eFy0Nvnawn0EHW7Oynp/MdH+Q==", + "dependencies": { + "@types/lodash.mergewith": "4.6.6", + "css-box-model": "1.2.1", + "framesync": "5.3.0", + "lodash.mergewith": "4.6.2" + } + }, + "node_modules/@chakra-ui/visually-hidden": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@chakra-ui/visually-hidden/-/visually-hidden-2.0.13.tgz", + "integrity": "sha512-sDEeeEjLfID333EC46NdCbhK2HyMXlpl5HzcJjuwWIpyVz4E1gKQ9hlwpq6grijvmzeSywQ5D3tTwUrvZck4KQ==", + "peerDependencies": { + "@chakra-ui/system": ">=2.0.0", + "react": ">=18" + } + }, + "node_modules/@emotion/babel-plugin": { + "version": "11.10.5", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.5.tgz", + "integrity": "sha512-xE7/hyLHJac7D2Ve9dKroBBZqBT7WuPQmWcq7HSGb84sUuP4mlOWoB8dvVfD9yk5DHkU1m6RW7xSoDtnQHNQeA==", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/plugin-syntax-jsx": "^7.17.12", + "@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" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@emotion/babel-plugin/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/cache": { + "version": "11.10.5", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.5.tgz", + "integrity": "sha512-dGYHWyzTdmK+f2+EnIGBpkz1lKc4Zbj2KHd4cX3Wi8/OWr5pKslNjc3yABKH4adRGCvSX4VDC0i04mrrq0aiRA==", + "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" + } + }, + "node_modules/@emotion/cache/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/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": "0.8.8", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", + "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", + "optional": true, + "dependencies": { + "@emotion/memoize": "0.7.4" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", + "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", + "optional": true + }, + "node_modules/@emotion/react": { + "version": "11.10.5", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.10.5.tgz", + "integrity": "sha512-TZs6235tCJ/7iF6/rvTaOH4oxQg2gMAcdHemjwLKIjKz4rRuYe1HJ2TQJKnAcRAfOUDdU8XoDadCe1rl72iv8A==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.10.5", + "@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": { + "@babel/core": "^7.0.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "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==", + "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" + } + }, + "node_modules/@emotion/serialize/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/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.5", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.10.5.tgz", + "integrity": "sha512-8EP6dD7dMkdku2foLoruPCNkRevzdcBaY6q0l0OsbyJK+x8D9HWjX27ARiSIKNF634hY9Zdoedh8bJCiva8yZw==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.10.5", + "@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" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/styled/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/@emotion/styled/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/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/@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/@eslint/eslintrc": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", - "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.0.tgz", + "integrity": "sha512-7yfvXy6MWLgWSFsLhz5yH3iQ52St8cdUY6FoGieKkRDVxuxmrNuUetIuu6cmjNWwniUHiWXjxCr5tTXDrbYS5A==", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^9.4.0", - "globals": "^13.15.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -64,10 +1782,33 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@headlessui/react": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.7.7.tgz", + "integrity": "sha512-BqDOd/tB9u2tA0T3Z0fn18ktw+KbVwMnkxxsGPIH2hzssrQhKB5n/6StZOyvLYP/FsYtvuXfi9I0YowKPv2c1w==", + "dependencies": { + "client-only": "^0.0.1" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": "^16 || ^17 || ^18", + "react-dom": "^16 || ^17 || ^18" + } + }, + "node_modules/@heroicons/react": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.0.13.tgz", + "integrity": "sha512-iSN5XwmagrnirWlYEWNPdCDj9aRYVD/lnK3JlsC9/+fqGF80k8C7rl+1HCvBX0dBoagKqOFBs6fMhJJ1hOg1EQ==", + "peerDependencies": { + "react": ">= 16" + } + }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.7", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", - "integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==", + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", "debug": "^4.1.1", @@ -94,6 +1835,120 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "peer": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "peer": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "peer": true, + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "node_modules/@motionone/animation": { + "version": "10.15.1", + "resolved": "https://registry.npmjs.org/@motionone/animation/-/animation-10.15.1.tgz", + "integrity": "sha512-mZcJxLjHor+bhcPuIFErMDNyrdb2vJur8lSfMCsuCB4UyV8ILZLvK+t+pg56erv8ud9xQGK/1OGPt10agPrCyQ==", + "dependencies": { + "@motionone/easing": "^10.15.1", + "@motionone/types": "^10.15.1", + "@motionone/utils": "^10.15.1", + "tslib": "^2.3.1" + } + }, + "node_modules/@motionone/dom": { + "version": "10.12.0", + "resolved": "https://registry.npmjs.org/@motionone/dom/-/dom-10.12.0.tgz", + "integrity": "sha512-UdPTtLMAktHiqV0atOczNYyDd/d8Cf5fFsd1tua03PqTwwCe/6lwhLSQ8a7TbnQ5SN0gm44N1slBfj+ORIhrqw==", + "dependencies": { + "@motionone/animation": "^10.12.0", + "@motionone/generators": "^10.12.0", + "@motionone/types": "^10.12.0", + "@motionone/utils": "^10.12.0", + "hey-listen": "^1.0.8", + "tslib": "^2.3.1" + } + }, + "node_modules/@motionone/easing": { + "version": "10.15.1", + "resolved": "https://registry.npmjs.org/@motionone/easing/-/easing-10.15.1.tgz", + "integrity": "sha512-6hIHBSV+ZVehf9dcKZLT7p5PEKHGhDwky2k8RKkmOvUoYP3S+dXsKupyZpqx5apjd9f+php4vXk4LuS+ADsrWw==", + "dependencies": { + "@motionone/utils": "^10.15.1", + "tslib": "^2.3.1" + } + }, + "node_modules/@motionone/generators": { + "version": "10.15.1", + "resolved": "https://registry.npmjs.org/@motionone/generators/-/generators-10.15.1.tgz", + "integrity": "sha512-67HLsvHJbw6cIbLA/o+gsm7h+6D4Sn7AUrB/GPxvujse1cGZ38F5H7DzoH7PhX+sjvtDnt2IhFYF2Zp1QTMKWQ==", + "dependencies": { + "@motionone/types": "^10.15.1", + "@motionone/utils": "^10.15.1", + "tslib": "^2.3.1" + } + }, + "node_modules/@motionone/types": { + "version": "10.15.1", + "resolved": "https://registry.npmjs.org/@motionone/types/-/types-10.15.1.tgz", + "integrity": "sha512-iIUd/EgUsRZGrvW0jqdst8st7zKTzS9EsKkP+6c6n4MPZoQHwiHuVtTQLD6Kp0bsBLhNzKIBlHXponn/SDT4hA==" + }, + "node_modules/@motionone/utils": { + "version": "10.15.1", + "resolved": "https://registry.npmjs.org/@motionone/utils/-/utils-10.15.1.tgz", + "integrity": "sha512-p0YncgU+iklvYr/Dq4NobTRdAPv9PveRDUXabPEeOjBLSO/1FNB2phNTZxOxpi1/GZwYpAoECEa0Wam+nsmhSw==", + "dependencies": { + "@motionone/types": "^10.15.1", + "hey-listen": "^1.0.8", + "tslib": "^2.3.1" + } + }, + "node_modules/@next-auth/prisma-adapter": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@next-auth/prisma-adapter/-/prisma-adapter-1.0.5.tgz", + "integrity": "sha512-VqMS11IxPXrPGXw6Oul6jcyS/n8GLOWzRMrPr3EMdtD6eOalM6zz05j08PcNiis8QzkfuYnCv49OvufTuaEwYQ==", + "peerDependencies": { + "@prisma/client": ">=2.26.0 || >=3", + "next-auth": "^4" + } + }, "node_modules/@next/env": { "version": "13.0.6", "resolved": "https://registry.npmjs.org/@next/env/-/env-13.0.6.tgz", @@ -107,6 +1962,11 @@ "glob": "7.1.7" } }, + "node_modules/@next/font": { + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/@next/font/-/font-13.1.0.tgz", + "integrity": "sha512-9+c2eWoeLftcGAul1fiXD8lL4o4/0beQrz2/0h0B0VV5AWrqCCfj/204quUxdp541ab+NCWVX/m49qjbqFMaFA==" + }, "node_modules/@next/swc-android-arm-eabi": { "version": "13.0.6", "resolved": "https://registry.npmjs.org/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-13.0.6.tgz", @@ -334,6 +2194,14 @@ "node": ">= 8" } }, + "node_modules/@panva/hkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@panva/hkdf/-/hkdf-1.0.2.tgz", + "integrity": "sha512-MSAs9t3Go7GUkMhpKC44T58DJ5KGk2vBo+h1cqQeqlMfdGkxaVB78ZWpv9gYi/g2fa4sopag9gJsNvS8XGgWJA==", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "node_modules/@pkgr/utils": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.3.1.tgz", @@ -353,122 +2221,52 @@ "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==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@prisma/client": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-4.7.1.tgz", + "integrity": "sha512-/GbnOwIPtjiveZNUzGXOdp7RxTEkHL4DZP3vBaFNadfr6Sf0RshU5EULFzVaSi9i9PIK9PYd+1Rn7z2B2npb9w==", + "hasInstallScript": true, + "dependencies": { + "@prisma/engines-version": "4.7.1-1.272861e07ab64f234d3ffc4094e32bd61775599c" + }, + "engines": { + "node": ">=14.17" + }, + "peerDependencies": { + "prisma": "*" + }, + "peerDependenciesMeta": { + "prisma": { + "optional": true + } + } + }, + "node_modules/@prisma/engines": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-4.7.1.tgz", + "integrity": "sha512-zWabHosTdLpXXlMefHmnouhXMoTB1+SCbUU3t4FCmdrtIOZcarPKU3Alto7gm/pZ9vHlGOXHCfVZ1G7OIrSbog==", + "devOptional": true, + "hasInstallScript": true + }, + "node_modules/@prisma/engines-version": { + "version": "4.7.1-1.272861e07ab64f234d3ffc4094e32bd61775599c", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-4.7.1-1.272861e07ab64f234d3ffc4094e32bd61775599c.tgz", + "integrity": "sha512-Bd4LZ+WAnUHOq31e9X/ihi5zPlr4SzTRwUZZYxvWOxlerIZ7HJlVa9zXpuKTKLpI9O1l8Ec4OYCKsivWCs5a3Q==" + }, "node_modules/@rushstack/eslint-patch": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz", "integrity": "sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==" }, - "node_modules/@stitches/core": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@stitches/core/-/core-1.2.8.tgz", - "integrity": "sha512-Gfkvwk9o9kE9r9XNBmJRfV8zONvXThnm1tcuojL04Uy5uRyqg93DC83lDebl0rocZCfKSjUv+fWYtMQmEDJldg==" - }, - "node_modules/@stitches/react": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@stitches/react/-/react-1.2.8.tgz", - "integrity": "sha512-9g9dWI4gsSVe8bNLlb+lMkBYsnIKCZTmvqvDG+Avnn69XfmHZKiaMrx7cgTaddq7aTPPmXiTsbFcUy0xgI4+wA==", - "peerDependencies": { - "react": ">= 16.3.0" - } - }, - "node_modules/@supabase/auth-helpers-nextjs": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@supabase/auth-helpers-nextjs/-/auth-helpers-nextjs-0.5.2.tgz", - "integrity": "sha512-B+sQFVEImAYOJKyyNX1DWqTF2qVf9SocOM1GD4eGHon6ulvLOo2a8V+v1jZAuLOBF6yzVIYnZucuYKZCiNP/Eg==", - "dependencies": { - "@supabase/auth-helpers-shared": "0.2.3" - }, - "peerDependencies": { - "@supabase/supabase-js": "^2.0.4" - } - }, - "node_modules/@supabase/auth-helpers-react": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@supabase/auth-helpers-react/-/auth-helpers-react-0.3.1.tgz", - "integrity": "sha512-g3SFv08Dz9FapNif/ZY1b7qKGlMJDyTLSayHBz3kb3FuYxg7aLWgQtydDhm5AGbc0XtvpIBuhGTIOVevwpdosA==", - "peerDependencies": { - "@supabase/supabase-js": "^2.0.4" - } - }, - "node_modules/@supabase/auth-helpers-shared": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@supabase/auth-helpers-shared/-/auth-helpers-shared-0.2.3.tgz", - "integrity": "sha512-Xwnd2UQ/VTjTKIuVg1Xl/ryrElbSccOJhC11jbVPHOs7Y6yxzy9APxQs//jj4IpbDH4uOEDCdpMIJ0tzRxj9DQ==", - "peerDependencies": { - "@supabase/supabase-js": "^2.0.4" - } - }, - "node_modules/@supabase/auth-ui-react": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/@supabase/auth-ui-react/-/auth-ui-react-0.2.6.tgz", - "integrity": "sha512-N2qxgsjxPQZPdDotVumzruj4RHaKNFb9ZRecttMeGOvrYFbMWRQVpWT/rYkTPsRW2phKiGXQlMwha6YxUE+t6Q==", - "dependencies": { - "@stitches/core": "^1.2.8", - "@stitches/react": "^1.2.8", - "prop-types": "^15.7.2" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" - }, - "peerDependencies": { - "react": "^16.13.1 || ^17.0.1 || ^18.0.0", - "react-dom": "^16.13.1 || ^17.0.1 || ^18.0.0" - } - }, - "node_modules/@supabase/functions-js": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.0.0.tgz", - "integrity": "sha512-ozb7bds2yvf5k7NM2ZzUkxvsx4S4i2eRKFSJetdTADV91T65g4gCzEs9L3LUXSrghcGIkUaon03VPzOrFredqg==", - "dependencies": { - "cross-fetch": "^3.1.5" - } - }, - "node_modules/@supabase/gotrue-js": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@supabase/gotrue-js/-/gotrue-js-2.5.0.tgz", - "integrity": "sha512-Aw5/WL0+JVjQjX2ZOQvOzoquMg1IMa4l1cA0eHVseAjujgUPpztjdhDwy3xP/c7OQsF+RK0ARxjsmIm2iaILlg==", - "dependencies": { - "cross-fetch": "^3.1.5" - } - }, - "node_modules/@supabase/postgrest-js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-1.1.0.tgz", - "integrity": "sha512-qkY8TqIu5sJuae8gjeDPjEqPrefzcTraW9PNSVJQHq4TEv98ZmwaXGwBGz0bVL63bqrGA5hqREbQHkANUTXrvA==", - "dependencies": { - "cross-fetch": "^3.1.5" - } - }, - "node_modules/@supabase/realtime-js": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.1.0.tgz", - "integrity": "sha512-iplLCofTeYjnx9FIOsIwHLhMp0+7UVyiA4/sCeq40VdOgN9eTIhjEno9Tgh4dJARi4aaXoKfRX1DTxgZaOpPAw==", - "dependencies": { - "@types/phoenix": "^1.5.4", - "websocket": "^1.0.34" - } - }, - "node_modules/@supabase/storage-js": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.1.0.tgz", - "integrity": "sha512-bRMLWCbkkx84WDAtHAAMN7FAWuayrGZtTHj/WMUK6PsAWuonovvEa5s34a5iux61qJSn+ls3tFkyQgqxunl5ww==", - "dependencies": { - "cross-fetch": "^3.1.5" - } - }, - "node_modules/@supabase/supabase-js": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.1.4.tgz", - "integrity": "sha512-i+BAiE472hMIIz6/nM5Pt/6riljjQYJrReyd0LsYsNtis4vcey7SuMX7sYiG9kMo4ivPlB1odYSOJnRbNyqRbQ==", - "dependencies": { - "@supabase/functions-js": "^2.0.0", - "@supabase/gotrue-js": "^2.5.0", - "@supabase/postgrest-js": "^1.1.0", - "@supabase/realtime-js": "^2.1.0", - "@supabase/storage-js": "^2.0.0", - "cross-fetch": "^3.1.5" - } - }, "node_modules/@swc/helpers": { "version": "0.4.14", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.14.tgz", @@ -477,15 +2275,68 @@ "tslib": "^2.4.0" } }, + "node_modules/@tailwindcss/forms": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.3.tgz", + "integrity": "sha512-y5mb86JUoiUgBjY/o6FJSFZSEttfb3Q5gllE4xoKjAAD+vBrnIhE4dViwUuow3va8mpH4s9jyUbUbrRGoRdc2Q==", + "dependencies": { + "mini-svg-data-uri": "^1.2.3" + }, + "peerDependencies": { + "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1" + } + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" }, - "node_modules/@types/phoenix": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.5.4.tgz", - "integrity": "sha512-L5eZmzw89eXBKkiqVBcJfU1QGx9y+wurRIEgt0cuLH0hwNtVUxtx+6cu0R2STwWj468sjXyBYPYDtGclUd1kjQ==" + "node_modules/@types/lodash": { + "version": "4.14.191", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz", + "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==" + }, + "node_modules/@types/lodash.mergewith": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/@types/lodash.mergewith/-/lodash.mergewith-4.6.6.tgz", + "integrity": "sha512-RY/8IaVENjG19rxTZu9Nukqh0W2UrYgmBj5sdns4hWRZaV8PqR7wIKHFKzvOTjo4zVRV7sVI+yFhAJql12Kfqg==", + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/node": { + "version": "18.11.17", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.17.tgz", + "integrity": "sha512-HJSUJmni4BeDHhfzn6nF0sVmd1SMezP7/4F0Lq+aXzmp2xm9O7WXrUtHW/CHlYVtZUbByEvWidHqRtcJXGF2Ng==", + "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", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" + }, + "node_modules/@types/prop-types": { + "version": "15.7.5", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", + "devOptional": true + }, + "node_modules/@types/react": { + "version": "18.0.26", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.26.tgz", + "integrity": "sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug==", + "devOptional": true, + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/scheduler": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", + "devOptional": true }, "node_modules/@typescript-eslint/parser": { "version": "5.46.1", @@ -583,6 +2434,16 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@zag-js/element-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@zag-js/element-size/-/element-size-0.1.0.tgz", + "integrity": "sha512-QF8wp0+V8++z+FHXiIw93+zudtubYszOtYbNgK39fg3pi+nCZtuSm4L1jC5QZMatNZ83MfOzyNCfgUubapagJQ==" + }, + "node_modules/@zag-js/focus-visible": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@zag-js/focus-visible/-/focus-visible-0.1.0.tgz", + "integrity": "sha512-PeaBcTmdZWcFf7n1aM+oiOdZc+sy14qi0emPIeUuGMTjbP0xLGrZu43kdpHnWSXy7/r4Ubp/vlg50MCV8+9Isg==" + }, "node_modules/acorn": { "version": "8.8.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", @@ -602,6 +2463,35 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/acorn-node": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", + "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", + "dependencies": { + "acorn": "^7.0.0", + "acorn-walk": "^7.0.0", + "xtend": "^4.0.2" + } + }, + "node_modules/acorn-node/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -639,11 +2529,48 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + }, "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==" }, + "node_modules/aria-hidden": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.2.tgz", + "integrity": "sha512-6y/ogyDTk/7YAe91T3E2PR1ALVKyM2QbTio5HwM+N1Q6CMlCKhvClyIjkckBswa0f2xJhjsfzIGa1yVSe1UMVA==", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.9.0 || ^17.0.0 || ^18.0.0", + "react": "^16.9.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/aria-query": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", @@ -733,24 +2660,93 @@ "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==" }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/autoprefixer": { + "version": "10.4.13", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.13.tgz", + "integrity": "sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + } + ], + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-lite": "^1.0.30001426", + "fraction.js": "^4.2.0", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, "node_modules/axe-core": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.6.0.tgz", - "integrity": "sha512-L3ZNbXPTxMrl0+qTXAzn9FBRvk5XdO56K8CvcCKtlxv44Aw2w2NCclGuvCWxHPw1Riiq3ncP/sxFYj2nUqdoTw==", + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.6.1.tgz", + "integrity": "sha512-lCZN5XRuOnpG4bpMq8v0khrWtUOn+i8lZSb6wHZH56ZfbIEv6XwJV84AAueh9/zi7qPVJ/E4yz6fmsiyOmXR4w==", "engines": { "node": ">=4" } }, + "node_modules/axios": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.2.1.tgz", + "integrity": "sha512-I88cFiGu9ryt/tfVEi4kX2SITsvDddTajXTOFmt2uK1ZVA8LytjtdeyefdQWEf5PU8w+4SSJDoYnggflB5tW4A==", + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/axobject-query": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==" }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "engines": { + "node": ">=8" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -771,16 +2767,31 @@ "node": ">=8" } }, - "node_modules/bufferutil": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.7.tgz", - "integrity": "sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw==", - "hasInstallScript": true, + "node_modules/browserslist": { + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], "dependencies": { - "node-gyp-build": "^4.3.0" + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.9" + }, + "bin": { + "browserslist": "cli.js" }, "engines": { - "node": ">=6.14.2" + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, "node_modules/call-bind": { @@ -803,6 +2814,14 @@ "node": ">=6" } }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "engines": { + "node": ">= 6" + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001439", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001439.tgz", @@ -833,11 +2852,56 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/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==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" }, + "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": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -854,11 +2918,53 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "node_modules/color2k": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/color2k/-/color2k-2.0.0.tgz", + "integrity": "sha512-DWX9eXOC4fbJNiuvdH4QSHvvfLWyFo9TuFp7V9OzdsbPAdrWAuYc8qvFP2bIQ/LKh4LrAVnJ6vhiQYPvAHdtTg==" + }, + "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==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/compute-scroll-into-view": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.14.tgz", + "integrity": "sha512-mKDjINe3tc6hGelUMNDzuhorIUZ7kS7BwyY0r2wQd2HOH2tRuJykiC06iSEX8y1TuhNzvz4GcJnK16mM2J1NMQ==" + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, + "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/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/copy-to-clipboard": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz", + "integrity": "sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==", + "dependencies": { + "toggle-selection": "^1.0.6" + } + }, "node_modules/core-js-pure": { "version": "3.26.1", "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.26.1.tgz", @@ -869,12 +2975,19 @@ "url": "https://opencollective.com/core-js" } }, - "node_modules/cross-fetch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", - "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "dependencies": { - "node-fetch": "2.6.7" + "@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/cross-spawn": { @@ -890,15 +3003,30 @@ "node": ">= 8" } }, - "node_modules/d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "node_modules/css-box-model": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz", + "integrity": "sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==", "dependencies": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" + "tiny-invariant": "^1.0.6" } }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "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/damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -948,6 +3076,48 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/defined": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz", + "integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" + }, + "node_modules/detective": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz", + "integrity": "sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==", + "dependencies": { + "acorn-node": "^1.8.2", + "defined": "^1.0.0", + "minimist": "^1.2.6" + }, + "bin": { + "detective": "bin/detective.js" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -959,6 +3129,11 @@ "node": ">=8" } }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" + }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -970,6 +3145,11 @@ "node": ">=6.0.0" } }, + "node_modules/electron-to-chromium": { + "version": "1.4.284", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", + "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==" + }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -987,6 +3167,14 @@ "node": ">=10.13.0" } }, + "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/es-abstract": { "version": "1.20.5", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.5.tgz", @@ -1049,37 +3237,12 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es5-ext": { - "version": "0.10.62", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", - "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", - "hasInstallScript": true, - "dependencies": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "next-tick": "^1.1.0" - }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "engines": { - "node": ">=0.10" - } - }, - "node_modules/es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", - "dependencies": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "node_modules/es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "dependencies": { - "d": "^1.0.1", - "ext": "^1.1.2" + "node": ">=6" } }, "node_modules/escape-string-regexp": { @@ -1524,19 +3687,6 @@ "node": ">=0.10.0" } }, - "node_modules/ext": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", - "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", - "dependencies": { - "type": "^2.7.2" - } - }, - "node_modules/ext/node_modules/type": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", - "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -1608,6 +3758,11 @@ "node": ">=8" } }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -1640,6 +3795,102 @@ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==" }, + "node_modules/focus-lock": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-0.11.4.tgz", + "integrity": "sha512-LzZWJcOBIcHslQ46N3SUu/760iLPSrUtp8omM4gh9du438V2CQdks8TcOu1yvmu2C68nVOBnl1WFiKGPbQ8L6g==", + "dependencies": { + "tslib": "^2.0.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/focus-visible": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/focus-visible/-/focus-visible-5.2.0.tgz", + "integrity": "sha512-Rwix9pBtC1Nuy5wysTmKy+UjbDJpIfg8eHjw0rjZ1mX4GNLz1Bmd16uDpI3Gk1i70Fgcs8Csg2lPm8HULFg9DQ==" + }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fraction.js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", + "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://www.patreon.com/infusion" + } + }, + "node_modules/framer-motion": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-6.5.1.tgz", + "integrity": "sha512-o1BGqqposwi7cgDrtg0dNONhkmPsUFDaLcKXigzuTFC5x58mE8iyTazxSudFzmT6MEyJKfjjU8ItoMe3W+3fiw==", + "dependencies": { + "@motionone/dom": "10.12.0", + "framesync": "6.0.1", + "hey-listen": "^1.0.8", + "popmotion": "11.0.3", + "style-value-types": "5.0.0", + "tslib": "^2.1.0" + }, + "optionalDependencies": { + "@emotion/is-prop-valid": "^0.8.2" + }, + "peerDependencies": { + "react": ">=16.8 || ^17.0.0 || ^18.0.0", + "react-dom": ">=16.8 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/framer-motion/node_modules/framesync": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/framesync/-/framesync-6.0.1.tgz", + "integrity": "sha512-fUY88kXvGiIItgNC7wcTOl0SNRCVXMKSWW2Yzfmn7EKNc+MpCzcz9DhdHcdjbrtN3c6R4H5dTY2jiCpPdysEjA==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/framesync": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/framesync/-/framesync-5.3.0.tgz", + "integrity": "sha512-oc5m68HDO/tuK2blj7ZcdEBRx3p1PjrgHazL8GYEpvULhrtGIFbQArN6cQS2QhW8mitffaB+VYzMjDqBxxQeoA==", + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -1688,6 +3939,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/get-intrinsic": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", @@ -1701,6 +3961,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "engines": { + "node": ">=6" + } + }, "node_modules/get-symbol-description": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", @@ -1881,6 +4149,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hey-listen": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/hey-listen/-/hey-listen-1.0.8.tgz", + "integrity": "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==" + }, + "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", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, "node_modules/ignore": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.1.tgz", @@ -1927,11 +4208,11 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.4.tgz", + "integrity": "sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ==", "dependencies": { - "get-intrinsic": "^1.1.0", + "get-intrinsic": "^1.1.3", "has": "^1.0.3", "side-channel": "^1.0.4" }, @@ -1939,6 +4220,19 @@ "node": ">= 0.4" } }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "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-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -1950,6 +4244,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-boolean-object": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", @@ -2129,11 +4434,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" - }, "node_modules/is-weakref": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", @@ -2161,6 +4461,14 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, + "node_modules/jose": { + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.11.1.tgz", + "integrity": "sha512-YRv4Tk/Wlug8qicwqFNFVEZSdbROCHRAC6qu/i0dyNKr5JQdoa2pIGoS04lLO/jXQX7Z9omoNewYIVIxqZBd9Q==", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "node_modules/js-sdsl": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", @@ -2186,6 +4494,23 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "peer": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -2225,9 +4550,9 @@ "integrity": "sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==" }, "node_modules/language-tags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.6.tgz", - "integrity": "sha512-HNkaCgM8wZgE/BZACeotAAgpL9FUjEnhgF0FVQMIgH//zqTPreLYMb3rWYkYAqPoF75Jwuycp1da7uz66cfFQg==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.7.tgz", + "integrity": "sha512-bSytju1/657hFjgUzPAPqszxH62ouE8nQFoFaVlIQfne4wO/wXC9A4+m8jYve7YBBvi59eq0SUpcshvG8h5Usw==", "dependencies": { "language-subtag-registry": "^0.3.20" } @@ -2244,6 +4569,19 @@ "node": ">= 0.8.0" } }, + "node_modules/lilconfig": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz", + "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==", + "engines": { + "node": ">=10" + } + }, + "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": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -2263,6 +4601,11 @@ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, + "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==" + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -2305,6 +4648,33 @@ "node": ">=8.6" } }, + "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==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mini-svg-data-uri": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", + "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==", + "bin": { + "mini-svg-data-uri": "cli.js" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -2396,40 +4766,70 @@ } } }, - "node_modules/next-tick": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" - }, - "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "node_modules/next-auth": { + "version": "4.18.6", + "resolved": "https://registry.npmjs.org/next-auth/-/next-auth-4.18.6.tgz", + "integrity": "sha512-0TQwbq5X9Jyd1wUVYUoyvHJh4JWXeW9UOcMEl245Er/Y5vsSbyGJHt8M7xjRMzk9mORVMYehoMdERgyiq/jCgA==", "dependencies": { - "whatwg-url": "^5.0.0" + "@babel/runtime": "^7.16.3", + "@panva/hkdf": "^1.0.1", + "cookie": "^0.5.0", + "jose": "^4.9.3", + "oauth": "^0.9.15", + "openid-client": "^5.1.0", + "preact": "^10.6.3", + "preact-render-to-string": "^5.1.19", + "uuid": "^8.3.2" }, "engines": { - "node": "4.x || >=6.0.0" + "node": "^12.19.0 || ^14.15.0 || ^16.13.0 || ^18.12.0" }, "peerDependencies": { - "encoding": "^0.1.0" + "next": "^12.2.5 || ^13", + "nodemailer": "^6.6.5", + "react": "^17.0.2 || ^18", + "react-dom": "^17.0.2 || ^18" }, "peerDependenciesMeta": { - "encoding": { + "nodemailer": { "optional": true } } }, - "node_modules/node-gyp-build": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.5.0.tgz", - "integrity": "sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==", - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" + "node_modules/node-releases": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", + "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==" + }, + "node_modules/nodemailer": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.8.0.tgz", + "integrity": "sha512-EjYvSmHzekz6VNkNd12aUqAco+bOkRe3Of5jVhltqKhEsjw/y0PYPJfp83+s9Wzh1dspYAkUW/YNQ350NATbSQ==", + "engines": { + "node": ">=6.0.0" } }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/oauth": { + "version": "0.9.15", + "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", + "integrity": "sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==" + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -2438,6 +4838,14 @@ "node": ">=0.10.0" } }, + "node_modules/object-hash": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", + "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", + "engines": { + "node": ">= 6" + } + }, "node_modules/object-inspect": { "version": "1.12.2", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", @@ -2528,6 +4936,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/oidc-token-hash": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.0.1.tgz", + "integrity": "sha512-EvoOtz6FIEBzE+9q253HsLCVRiK/0doEJ2HCvvqMQb3dHZrP3WlJKYtJ55CRTw4jmYomzH4wkPuCj/I3ZvpKxQ==", + "engines": { + "node": "^10.13.0 || >=12.0.0" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -2552,6 +4968,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/openid-client": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.3.1.tgz", + "integrity": "sha512-RLfehQiHch9N6tRWNx68cicf3b1WR0x74bJWHRc25uYIbSRwjxYcTFaRnzbbpls5jroLAaB/bFIodTgA5LJMvw==", + "dependencies": { + "jose": "^4.10.0", + "lru-cache": "^6.0.0", + "object-hash": "^2.0.1", + "oidc-token-hash": "^5.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "node_modules/optionator": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", @@ -2607,6 +5037,23 @@ "node": ">=6" } }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -2660,6 +5107,33 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/popmotion": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/popmotion/-/popmotion-11.0.3.tgz", + "integrity": "sha512-Y55FLdj3UxkR7Vl3s7Qr4e9m0onSnP8W7d/xQLsoJM40vs6UKHFdygs6SWryasTZYqugMjm3BepCF4CWXDiHgA==", + "dependencies": { + "framesync": "6.0.1", + "hey-listen": "^1.0.8", + "style-value-types": "5.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/popmotion/node_modules/framesync": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/framesync/-/framesync-6.0.1.tgz", + "integrity": "sha512-fUY88kXvGiIItgNC7wcTOl0SNRCVXMKSWW2Yzfmn7EKNc+MpCzcz9DhdHcdjbrtN3c6R4H5dTY2jiCpPdysEjA==", + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/postcss": { "version": "8.4.14", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", @@ -2683,6 +5157,141 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/postcss-focus-visible": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-7.1.0.tgz", + "integrity": "sha512-OGxO+eCXVkF94us4uOVLHDPaoJuV8HQhaqmVPo2DtECdjqzWNkmwhFRSRRDT5Sg04JQsAECzgIhpyX0JRTgwlQ==", + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2" + } + }, + "node_modules/postcss-import": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-14.1.0.tgz", + "integrity": "sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.0.tgz", + "integrity": "sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.3.3" + } + }, + "node_modules/postcss-load-config": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", + "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", + "dependencies": { + "lilconfig": "^2.0.5", + "yaml": "^1.10.2" + }, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-nested": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.0.tgz", + "integrity": "sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==", + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", + "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + }, + "node_modules/preact": { + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.11.3.tgz", + "integrity": "sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, + "node_modules/preact-render-to-string": { + "version": "5.2.6", + "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.6.tgz", + "integrity": "sha512-JyhErpYOvBV1hEPwIxc/fHWXPfnEGdRKxc8gFdAZ7XV4tlzyzG847XAyEZqoDnynP88akM4eaHcSOzNcLWFguw==", + "dependencies": { + "pretty-format": "^3.8.0" + }, + "peerDependencies": { + "preact": ">=10" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -2691,6 +5300,43 @@ "node": ">= 0.8.0" } }, + "node_modules/prettier": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.1.tgz", + "integrity": "sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/pretty-format": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz", + "integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==" + }, + "node_modules/prisma": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-4.7.1.tgz", + "integrity": "sha512-CCQP+m+1qZOGIZlvnL6T3ZwaU0LAleIHYFPN9tFSzjs/KL6vH9rlYbGOkTuG9Q1s6Ki5D0LJlYlW18Z9EBUpGg==", + "devOptional": true, + "hasInstallScript": true, + "dependencies": { + "@prisma/engines": "4.7.1" + }, + "bin": { + "prisma": "build/index.js", + "prisma2": "build/index.js" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -2701,6 +5347,11 @@ "react-is": "^16.13.1" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -2728,6 +5379,17 @@ } ] }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/react": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", @@ -2739,6 +5401,17 @@ "node": ">=0.10.0" } }, + "node_modules/react-clientside-effect": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/react-clientside-effect/-/react-clientside-effect-1.2.6.tgz", + "integrity": "sha512-XGGGRQAKY+q25Lz9a/4EPqom7WRjz3z9R2k4jhVKA/puQFH/5Nt27vFZYql4m4NVNdUvX8PS3O7r/Zzm7cjUlg==", + "dependencies": { + "@babel/runtime": "^7.12.13" + }, + "peerDependencies": { + "react": "^15.3.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -2751,11 +5424,132 @@ "react": "^18.2.0" } }, + "node_modules/react-fast-compare": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", + "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" + }, + "node_modules/react-focus-lock": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.9.2.tgz", + "integrity": "sha512-5JfrsOKyA5Zn3h958mk7bAcfphr24jPoMoznJ8vaJF6fUrPQ8zrtEd3ILLOK8P5jvGxdMd96OxWNjDzATfR2qw==", + "dependencies": { + "@babel/runtime": "^7.0.0", + "focus-lock": "^0.11.2", + "prop-types": "^15.6.2", + "react-clientside-effect": "^1.2.6", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-icons": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.7.1.tgz", + "integrity": "sha512-yHd3oKGMgm7zxo3EA7H2n7vxSoiGmHk5t6Ou4bXsfcgWyhfDKMpyKfhHR6Bjnn63c+YXBLBPUql9H4wPJM6sXw==", + "peerDependencies": { + "react": "*" + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/react-remove-scroll": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz", + "integrity": "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==", + "dependencies": { + "react-remove-scroll-bar": "^2.3.3", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.4.tgz", + "integrity": "sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==", + "dependencies": { + "react-style-singleton": "^2.2.1", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-style-singleton": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", + "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==", + "dependencies": { + "get-nonce": "^1.0.0", + "invariant": "^2.2.4", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/regenerator-runtime": { "version": "0.13.11", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", @@ -2932,6 +5726,14 @@ "node": ">=8" } }, + "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/source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", @@ -3014,6 +5816,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/style-value-types": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/style-value-types/-/style-value-types-5.0.0.tgz", + "integrity": "sha512-08yq36Ikn4kx4YU6RD7jWEv27v4V+PUsOGa4n/as8Et3CuODMJQ00ENeAVXAeydX4Z2j1XHZF1K2sX4mGl18fA==", + "dependencies": { + "hey-listen": "^1.0.8", + "tslib": "^2.1.0" + } + }, "node_modules/styled-jsx": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.0.tgz", @@ -3036,6 +5847,11 @@ } } }, + "node_modules/stylis": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz", + "integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA==" + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -3058,6 +5874,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/swr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/swr/-/swr-2.0.0.tgz", + "integrity": "sha512-IhUx5yPkX+Fut3h0SqZycnaNLXLXsb2ECFq0Y29cxnK7d8r7auY2JWNbCW3IX+EqXUg3rwNJFlhrw5Ye/b6k7w==", + "dependencies": { + "use-sync-external-store": "^1.2.0" + }, + "engines": { + "pnpm": "7" + }, + "peerDependencies": { + "react": "^16.11.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/synckit": { "version": "0.8.4", "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.4.tgz", @@ -3073,6 +5903,77 @@ "url": "https://opencollective.com/unts" } }, + "node_modules/tailwindcss": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.4.tgz", + "integrity": "sha512-AhwtHCKMtR71JgeYDaswmZXhPcW9iuI9Sp2LvZPo9upDZ7231ZJ7eA9RaURbhpXGVlrjX4cFNlB4ieTetEb7hQ==", + "dependencies": { + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "color-name": "^1.1.4", + "detective": "^5.2.1", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.2.12", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "lilconfig": "^2.0.6", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.18", + "postcss-import": "^14.1.0", + "postcss-js": "^4.0.0", + "postcss-load-config": "^3.1.4", + "postcss-nested": "6.0.0", + "postcss-selector-parser": "^6.0.10", + "postcss-value-parser": "^4.2.0", + "quick-lru": "^5.1.1", + "resolve": "^1.22.1" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=12.13.0" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, + "node_modules/tailwindcss/node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/tailwindcss/node_modules/postcss": { + "version": "8.4.20", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.20.tgz", + "integrity": "sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + } + ], + "dependencies": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -3095,6 +5996,19 @@ "globrex": "^0.1.2" } }, + "node_modules/tiny-invariant": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", + "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==" + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "engines": { + "node": ">=4" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -3106,10 +6020,10 @@ "node": ">=8.0" } }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + "node_modules/toggle-selection": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", + "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" }, "node_modules/tsconfig-paths": { "version": "3.14.1", @@ -3146,11 +6060,6 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, - "node_modules/type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -3173,14 +6082,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, "node_modules/typescript": { "version": "4.9.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", @@ -3208,6 +6109,31 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist-lint": "cli.js" + }, + "peerDependencies": { + "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", @@ -3216,59 +6142,77 @@ "punycode": "^2.1.0" } }, - "node_modules/utf-8-validate": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", - "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", - "hasInstallScript": true, + "node_modules/use-callback-ref": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.0.tgz", + "integrity": "sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==", "dependencies": { - "node-gyp-build": "^4.3.0" + "tslib": "^2.0.0" }, "engines": { - "node": ">=6.14.2" + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + "node_modules/use-debounce": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/use-debounce/-/use-debounce-9.0.2.tgz", + "integrity": "sha512-QLyB0sxt9F5AisGDrUybCRJSLE60bTQR0yXc+IebNGUu1GCXwii1zsZl82mPGdWqDVQy7+1FKMLHQUixxf5Nbw==", + "engines": { + "node": ">= 10.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0" + } }, - "node_modules/websocket": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz", - "integrity": "sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==", + "node_modules/use-sidecar": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", + "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", "dependencies": { - "bufferutil": "^4.0.1", - "debug": "^2.2.0", - "es5-ext": "^0.10.50", - "typedarray-to-buffer": "^3.1.5", - "utf-8-validate": "^5.0.2", - "yaeti": "^0.0.6" + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" }, "engines": { - "node": ">=4.0.0" + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.9.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/websocket/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, - "node_modules/websocket/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "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==" }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" + "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==", + "bin": { + "uuid": "dist/bin/uuid" } }, "node_modules/which": { @@ -3313,12 +6257,12 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, - "node_modules/yaeti": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", - "integrity": "sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==", + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "engines": { - "node": ">=0.10.32" + "node": ">=0.4" } }, "node_modules/yallist": { @@ -3326,6 +6270,14 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -3339,6 +6291,285 @@ } }, "dependencies": { + "@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "peer": true, + "requires": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@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==", + "requires": { + "@babel/highlight": "^7.18.6" + } + }, + "@babel/compat-data": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.5.tgz", + "integrity": "sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==", + "peer": true + }, + "@babel/core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.5.tgz", + "integrity": "sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==", + "peer": true, + "requires": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.5", + "@babel/helper-compilation-targets": "^7.20.0", + "@babel/helper-module-transforms": "^7.20.2", + "@babel/helpers": "^7.20.5", + "@babel/parser": "^7.20.5", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.1", + "semver": "^6.3.0" + }, + "dependencies": { + "json5": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz", + "integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==", + "peer": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "peer": true + } + } + }, + "@babel/generator": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.5.tgz", + "integrity": "sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==", + "peer": true, + "requires": { + "@babel/types": "^7.20.5", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + }, + "dependencies": { + "@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "peer": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + } + } + }, + "@babel/helper-compilation-targets": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", + "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", + "peer": true, + "requires": { + "@babel/compat-data": "^7.20.0", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "peer": true + } + } + }, + "@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==", + "peer": true + }, + "@babel/helper-function-name": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "peer": true, + "requires": { + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" + } + }, + "@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==", + "peer": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@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==", + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-module-transforms": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", + "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", + "peer": true, + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.1", + "@babel/types": "^7.20.2" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==" + }, + "@babel/helper-simple-access": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "peer": true, + "requires": { + "@babel/types": "^7.20.2" + } + }, + "@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==", + "peer": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@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==" + }, + "@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==" + }, + "@babel/helper-validator-option": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "peer": true + }, + "@babel/helpers": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.6.tgz", + "integrity": "sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==", + "peer": true, + "requires": { + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5" + } + }, + "@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "requires": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "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==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/parser": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz", + "integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==", + "peer": true + }, + "@babel/plugin-syntax-jsx": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", + "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, "@babel/runtime": { "version": "7.20.6", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.6.tgz", @@ -3356,15 +6587,1038 @@ "regenerator-runtime": "^0.13.11" } }, + "@babel/template": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "peer": true, + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" + } + }, + "@babel/traverse": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.5.tgz", + "integrity": "sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==", + "peer": true, + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.5", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.20.5", + "@babel/types": "^7.20.5", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "dependencies": { + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "peer": true + } + } + }, + "@babel/types": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.5.tgz", + "integrity": "sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + }, + "@chakra-ui/accordion": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@chakra-ui/accordion/-/accordion-2.1.4.tgz", + "integrity": "sha512-PQFW6kr+Bdru0DjKA8akC4BAz1VAJisLgo4TsJwjPO2gTS0zr99C+3bBs9uoDnjSJAf18/Q5zdXv11adA8n2XA==", + "requires": { + "@chakra-ui/descendant": "3.0.11", + "@chakra-ui/icon": "3.0.13", + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/react-use-controllable-state": "2.0.6", + "@chakra-ui/react-use-merge-refs": "2.0.5", + "@chakra-ui/transition": "2.0.12" + } + }, + "@chakra-ui/alert": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@chakra-ui/alert/-/alert-2.0.13.tgz", + "integrity": "sha512-7LqPv6EUBte4XM/Q2qBFIT5o4BC0dSlni9BHOH2BgAc5B1NF+pBAMDTUH7JNBiN7RHTV7EHAIWDziiX/NK28+Q==", + "requires": { + "@chakra-ui/icon": "3.0.13", + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/spinner": "2.0.11" + } + }, + "@chakra-ui/anatomy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@chakra-ui/anatomy/-/anatomy-2.1.0.tgz", + "integrity": "sha512-E3jMPGqKuGTbt7mKtc8g/MOOenw2c4wqRC1vOypyFgmC8wsewdY+DJJNENF3atXAK7p5VMBKQfZ7ipNlHnDAwA==" + }, + "@chakra-ui/avatar": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@chakra-ui/avatar/-/avatar-2.2.1.tgz", + "integrity": "sha512-sgiogfLM8vas8QJTt7AJI4XxNXYdViCWj+xYJwyOwUN93dWKImqqx3O2ihCXoXTIqQWg1rcEgoJ5CxCg6rQaQQ==", + "requires": { + "@chakra-ui/image": "2.0.12", + "@chakra-ui/react-children-utils": "2.0.4", + "@chakra-ui/react-context": "2.0.5" + } + }, + "@chakra-ui/breadcrumb": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@chakra-ui/breadcrumb/-/breadcrumb-2.1.1.tgz", + "integrity": "sha512-OSa+F9qJ1xmF0zVxC1GU46OWbbhGf0kurHioSB729d+tRw/OMzmqrrfCJ7KVUUN8NEnTZXT5FIgokMvHGEt+Hg==", + "requires": { + "@chakra-ui/react-children-utils": "2.0.4", + "@chakra-ui/react-context": "2.0.5" + } + }, + "@chakra-ui/breakpoint-utils": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/breakpoint-utils/-/breakpoint-utils-2.0.5.tgz", + "integrity": "sha512-8uhrckMwoR/powlAhxiFZPM0s8vn0B2yEyEaRcwpy5NmRAJSTEotC2WkSyQl/Cjysx9scredumB5g+fBX7IqGQ==" + }, + "@chakra-ui/button": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@chakra-ui/button/-/button-2.0.13.tgz", + "integrity": "sha512-T9W/zHpHZVcbx/BMg0JIXCgRycut/eYoTYee/E+eBxyPCH45n308AsYU2bZ8TgZxUwbYNRgMp4qRL/KHUQDv5g==", + "requires": { + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/react-use-merge-refs": "2.0.5", + "@chakra-ui/spinner": "2.0.11" + } + }, + "@chakra-ui/card": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/card/-/card-2.1.3.tgz", + "integrity": "sha512-8ET6ZOo6HtJutetqHJVOz+VpZvrWMGFAELfHsCuA/7orp7QZyUyXqfA79cZqZXCd3C4zn2G8H0bkiQFvzxQgOw==", + "requires": {} + }, + "@chakra-ui/checkbox": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/checkbox/-/checkbox-2.2.5.tgz", + "integrity": "sha512-7fNH+Q2nB2uMSnYAPtYxnuwZ1MOJqblZHa/ScfZ/fjiPDyEae1m068ZP/l9yJ5zlawYMTkp83m/JVcu5QFYurA==", + "requires": { + "@chakra-ui/form-control": "2.0.13", + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/react-types": "2.0.5", + "@chakra-ui/react-use-callback-ref": "2.0.5", + "@chakra-ui/react-use-controllable-state": "2.0.6", + "@chakra-ui/react-use-merge-refs": "2.0.5", + "@chakra-ui/react-use-safe-layout-effect": "2.0.3", + "@chakra-ui/react-use-update-effect": "2.0.5", + "@chakra-ui/visually-hidden": "2.0.13", + "@zag-js/focus-visible": "0.1.0" + } + }, + "@chakra-ui/clickable": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@chakra-ui/clickable/-/clickable-2.0.11.tgz", + "integrity": "sha512-5Y2dl5cxNgOxHbjxyxsL6Vdze4wUUvwsMCCW3kXwgz2OUI2y5UsBZNcvhNJx3RchJEd0fylMKiKoKmnZMHN2aw==", + "requires": { + "@chakra-ui/react-use-merge-refs": "2.0.5" + } + }, + "@chakra-ui/close-button": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@chakra-ui/close-button/-/close-button-2.0.13.tgz", + "integrity": "sha512-ZI/3p84FPlW0xoDCZYqsnIvR6bTc2d/TlhwyTHsDDxq9ZOWp9c2JicVn6WTdWGdshk8itnZZdG50IcnizGnimA==", + "requires": { + "@chakra-ui/icon": "3.0.13" + } + }, + "@chakra-ui/color-mode": { + "version": "2.1.10", + "resolved": "https://registry.npmjs.org/@chakra-ui/color-mode/-/color-mode-2.1.10.tgz", + "integrity": "sha512-aUPouOUPn7IPm1v00/9AIkRuNrkCwJlbjVL1kJzLzxijYjbHvEHPxntITt+JWjtXPT8xdOq6mexLYCOGA67JwQ==", + "requires": { + "@chakra-ui/react-use-safe-layout-effect": "2.0.3" + } + }, + "@chakra-ui/control-box": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@chakra-ui/control-box/-/control-box-2.0.11.tgz", + "integrity": "sha512-UJb4vqq+/FPuwTCuaPeHa2lwtk6u7eFvLuwDCST2e/sBWGJC1R+1/Il5pHccnWs09FWxyZ9v/Oxkg/CG3jZR4Q==", + "requires": {} + }, + "@chakra-ui/counter": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@chakra-ui/counter/-/counter-2.0.11.tgz", + "integrity": "sha512-1YRt/jom+m3iWw9J9trcM6rAHDvD4lwThiO9raxUK7BRsYUhnPZvsMpcXU1Moax218C4rRpbI9KfPLaig0m1xQ==", + "requires": { + "@chakra-ui/number-utils": "2.0.5", + "@chakra-ui/react-use-callback-ref": "2.0.5" + } + }, + "@chakra-ui/css-reset": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@chakra-ui/css-reset/-/css-reset-2.0.10.tgz", + "integrity": "sha512-FwHOfw2P4ckbpSahDZef2KoxcvHPUg09jlicWdp24/MjdsOO5PAB/apm2UBvQflY4WAJyOqYaOdnXFlR6nF4cQ==", + "requires": {} + }, + "@chakra-ui/descendant": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@chakra-ui/descendant/-/descendant-3.0.11.tgz", + "integrity": "sha512-sNLI6NS6uUgrvYS6Imhoc1YlI6bck6pfxMBJcnXVSfdIjD6XjCmeY2YgzrtDS+o+J8bB3YJeIAG/vsVy5USE5Q==", + "requires": { + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/react-use-merge-refs": "2.0.5" + } + }, + "@chakra-ui/dom-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@chakra-ui/dom-utils/-/dom-utils-2.0.4.tgz", + "integrity": "sha512-P936+WKinz5fgHzfwiUQjE/t7NC8bU89Tceim4tbn8CIm/9b+CsHX64eNw4vyJqRwt78TXQK7aGBIbS18R0q5Q==" + }, + "@chakra-ui/editable": { + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/@chakra-ui/editable/-/editable-2.0.16.tgz", + "integrity": "sha512-kIFPufzIlViNv7qi2PxxWWBvjLb+3IP5hUGmqOA9qcYz5TAdqblQqDClm0iajlIDNUFWnS4h056o8jKsQ42a5A==", + "requires": { + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/react-types": "2.0.5", + "@chakra-ui/react-use-callback-ref": "2.0.5", + "@chakra-ui/react-use-controllable-state": "2.0.6", + "@chakra-ui/react-use-focus-on-pointer-down": "2.0.4", + "@chakra-ui/react-use-merge-refs": "2.0.5", + "@chakra-ui/react-use-safe-layout-effect": "2.0.3", + "@chakra-ui/react-use-update-effect": "2.0.5", + "@chakra-ui/shared-utils": "2.0.3" + } + }, + "@chakra-ui/event-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@chakra-ui/event-utils/-/event-utils-2.0.6.tgz", + "integrity": "sha512-ZIoqUbgJ5TcCbZRchMv4n7rOl1JL04doMebED88LO5mux36iVP9er/nnOY4Oke1bANKKURMrQf5VTT9hoYeA7A==" + }, + "@chakra-ui/focus-lock": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@chakra-ui/focus-lock/-/focus-lock-2.0.13.tgz", + "integrity": "sha512-AVSJt+3Ukia/m9TCZZgyWvTY7pw88jArivWVJ2gySGYYIs6z/FJMnlwbCVldV2afS0g3cYaii7aARb/WrlG34Q==", + "requires": { + "@chakra-ui/dom-utils": "2.0.4", + "react-focus-lock": "^2.9.1" + } + }, + "@chakra-ui/form-control": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@chakra-ui/form-control/-/form-control-2.0.13.tgz", + "integrity": "sha512-J964JlgrxP+LP3kYmLk1ttbl73u6ghT+JQDjEjkEUc8lSS9Iv4u9XkRDQHuz2t2y0KHjQdH12PUfUfBqcITbYw==", + "requires": { + "@chakra-ui/icon": "3.0.13", + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/react-types": "2.0.5", + "@chakra-ui/react-use-merge-refs": "2.0.5" + } + }, + "@chakra-ui/hooks": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@chakra-ui/hooks/-/hooks-2.1.2.tgz", + "integrity": "sha512-/vDBOqqnho9q++lay0ZcvnH8VuE0wT2OkZj+qDwFwjiHAtGPVxHCSpu9KC8BIHME5TlWjyO6riVyUCb2e2ip6w==", + "requires": { + "@chakra-ui/react-utils": "2.0.9", + "@chakra-ui/utils": "2.0.12", + "compute-scroll-into-view": "1.0.14", + "copy-to-clipboard": "3.3.1" + } + }, + "@chakra-ui/icon": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/@chakra-ui/icon/-/icon-3.0.13.tgz", + "integrity": "sha512-RaDLC4psd8qyInY2RX4AlYRfpLBNw3VsMih17BFf8EESVhBXNJcYy7Q9eMV/K4NvZfZT42vuVqGVNFmkG89lBQ==", + "requires": { + "@chakra-ui/shared-utils": "2.0.3" + } + }, + "@chakra-ui/image": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@chakra-ui/image/-/image-2.0.12.tgz", + "integrity": "sha512-uclFhs0+wq2qujGu8Wk4eEWITA3iZZQTitGiFSEkO9Ws5VUH+Gqtn3mUilH0orubrI5srJsXAmjVTuVwge1KJQ==", + "requires": { + "@chakra-ui/react-use-safe-layout-effect": "2.0.3" + } + }, + "@chakra-ui/input": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@chakra-ui/input/-/input-2.0.14.tgz", + "integrity": "sha512-CkSrUJeKWogOSt2pUf2vVv5s0bUVcAi4/XGj1JVCCfyIX6a6h1m8R69MShTPxPiQ0Mdebq5ATrW/aZQQXZzRGQ==", + "requires": { + "@chakra-ui/form-control": "2.0.13", + "@chakra-ui/object-utils": "2.0.5", + "@chakra-ui/react-children-utils": "2.0.4", + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/shared-utils": "2.0.3" + } + }, + "@chakra-ui/layout": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/@chakra-ui/layout/-/layout-2.1.11.tgz", + "integrity": "sha512-UP19V8EeI/DEODbWrZlqC0sg248bpFaWpMiM/+g9Bsxs9aof3yexpMD/7gb0yrfbIrkdvSBrcQeqxXGzbfoopw==", + "requires": { + "@chakra-ui/breakpoint-utils": "2.0.5", + "@chakra-ui/icon": "3.0.13", + "@chakra-ui/object-utils": "2.0.5", + "@chakra-ui/react-children-utils": "2.0.4", + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/shared-utils": "2.0.3" + } + }, + "@chakra-ui/lazy-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/lazy-utils/-/lazy-utils-2.0.3.tgz", + "integrity": "sha512-SQ5I5rJrcHpVUcEftHLOh8UyeY+06R8Gv3k2RjcpvM6mb2Gktlz/4xl2GcUh3LWydgGQDW/7Rse5rQhKWgzmcg==" + }, + "@chakra-ui/live-region": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@chakra-ui/live-region/-/live-region-2.0.11.tgz", + "integrity": "sha512-ltObaKQekP75GCCbN+vt1/mGABSCaRdQELmotHTBc5AioA3iyCDHH69ev+frzEwLvKFqo+RomAdAAgqBIMJ02Q==", + "requires": {} + }, + "@chakra-ui/media-query": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@chakra-ui/media-query/-/media-query-3.2.8.tgz", + "integrity": "sha512-djmEg/eJ5Qrjn7SArTqjsvlwF6mNeMuiawrTwnU+0EKq9Pq/wVSb7VaIhxdQYJLA/DbRhE/KPMogw1LNVKa4Rw==", + "requires": { + "@chakra-ui/breakpoint-utils": "2.0.5", + "@chakra-ui/react-env": "2.0.11" + } + }, + "@chakra-ui/menu": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/menu/-/menu-2.1.5.tgz", + "integrity": "sha512-2UusrQtxHcqcO9n/0YobNN3RJC8yAZU6oJbRPuvsQ9IL89scEWCTIxXEYrnIjeh/5zikcSEDGo9zM9Udg/XcsA==", + "requires": { + "@chakra-ui/clickable": "2.0.11", + "@chakra-ui/descendant": "3.0.11", + "@chakra-ui/lazy-utils": "2.0.3", + "@chakra-ui/popper": "3.0.10", + "@chakra-ui/react-children-utils": "2.0.4", + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/react-use-animation-state": "2.0.6", + "@chakra-ui/react-use-controllable-state": "2.0.6", + "@chakra-ui/react-use-disclosure": "2.0.6", + "@chakra-ui/react-use-focus-effect": "2.0.7", + "@chakra-ui/react-use-merge-refs": "2.0.5", + "@chakra-ui/react-use-outside-click": "2.0.5", + "@chakra-ui/react-use-update-effect": "2.0.5", + "@chakra-ui/transition": "2.0.12" + } + }, + "@chakra-ui/modal": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/modal/-/modal-2.2.5.tgz", + "integrity": "sha512-QIoN89bT5wnR71wxZFHt7vsS65yF9WCfIwDtFk8ifxJORPi/UkLMwBpjTV2Jfsxd22W6Oo2VOpRR0a5WFeK+jA==", + "requires": { + "@chakra-ui/close-button": "2.0.13", + "@chakra-ui/focus-lock": "2.0.13", + "@chakra-ui/portal": "2.0.12", + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/react-types": "2.0.5", + "@chakra-ui/react-use-merge-refs": "2.0.5", + "@chakra-ui/transition": "2.0.12", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "^2.5.4" + } + }, + "@chakra-ui/number-input": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@chakra-ui/number-input/-/number-input-2.0.14.tgz", + "integrity": "sha512-IARUAbP4pn1gP5fY2dK4wtbR3ONjzHgTjH4Zj3ErZvdu/yTURLaZmlb6UGHwgqjWLyioactZ/+n4Njj5CRjs8w==", + "requires": { + "@chakra-ui/counter": "2.0.11", + "@chakra-ui/form-control": "2.0.13", + "@chakra-ui/icon": "3.0.13", + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/react-types": "2.0.5", + "@chakra-ui/react-use-callback-ref": "2.0.5", + "@chakra-ui/react-use-event-listener": "2.0.5", + "@chakra-ui/react-use-interval": "2.0.3", + "@chakra-ui/react-use-merge-refs": "2.0.5", + "@chakra-ui/react-use-safe-layout-effect": "2.0.3", + "@chakra-ui/react-use-update-effect": "2.0.5" + } + }, + "@chakra-ui/number-utils": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/number-utils/-/number-utils-2.0.5.tgz", + "integrity": "sha512-Thhohnlqze0i5HBJO9xkfOPq1rv3ji/hNPf2xh1fh4hxrNzdm3HCkz0c6lyRQwGuVoeltEHysYZLH/uWLFTCSQ==" + }, + "@chakra-ui/object-utils": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/object-utils/-/object-utils-2.0.5.tgz", + "integrity": "sha512-/rIMoYI3c2uLtFIrnTFOPRAI8StUuu335WszqKM0KAW1lwG9H6uSbxqlpZT1Pxi/VQqZKfheGiMQOx5lfTmM/A==" + }, + "@chakra-ui/pin-input": { + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/@chakra-ui/pin-input/-/pin-input-2.0.16.tgz", + "integrity": "sha512-51cioNYpBSgi9/jq6CrzoDvo8fpMwFXu3SaFRbKO47s9Dz/OAW0MpjyabTfSpwOv0xKZE+ayrYGJopCzZSWXPg==", + "requires": { + "@chakra-ui/descendant": "3.0.11", + "@chakra-ui/react-children-utils": "2.0.4", + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/react-use-controllable-state": "2.0.6", + "@chakra-ui/react-use-merge-refs": "2.0.5" + } + }, + "@chakra-ui/popover": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@chakra-ui/popover/-/popover-2.1.4.tgz", + "integrity": "sha512-NXVtyMxYzDKzzQph/+GFRSM3tEj3gNvlCX/xGRsCOt9I446zJ1InCd/boXQKAc813coEN9McSOjNWgo+NCBD+Q==", + "requires": { + "@chakra-ui/close-button": "2.0.13", + "@chakra-ui/lazy-utils": "2.0.3", + "@chakra-ui/popper": "3.0.10", + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/react-types": "2.0.5", + "@chakra-ui/react-use-animation-state": "2.0.6", + "@chakra-ui/react-use-disclosure": "2.0.6", + "@chakra-ui/react-use-focus-effect": "2.0.7", + "@chakra-ui/react-use-focus-on-pointer-down": "2.0.4", + "@chakra-ui/react-use-merge-refs": "2.0.5" + } + }, + "@chakra-ui/popper": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@chakra-ui/popper/-/popper-3.0.10.tgz", + "integrity": "sha512-6LacbBGX0piHWY/DYxOGCTTFAoRGRHpGIRzTgfNy8jxw4f+rukaVudd4Pc2fwjCTdobJKM8nGNYIYNv9/Dmq9Q==", + "requires": { + "@chakra-ui/react-types": "2.0.5", + "@chakra-ui/react-use-merge-refs": "2.0.5", + "@popperjs/core": "^2.9.3" + } + }, + "@chakra-ui/portal": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@chakra-ui/portal/-/portal-2.0.12.tgz", + "integrity": "sha512-8D/1fFUdbJtzyGL5sCBIb4oyTnPG2v6rx/L/qbG43FcXDrongmzLj0+tJ//PbJr+5hxjXAWFUjpPvyx10pTN6Q==", + "requires": { + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/react-use-safe-layout-effect": "2.0.3" + } + }, + "@chakra-ui/progress": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@chakra-ui/progress/-/progress-2.1.2.tgz", + "integrity": "sha512-ofhMWTqCxnm1NiP/zH4SV7EvOLogfX15MSMTNfGqZv6t8eSSeTn6oRRzsTSllJfSqDey7oZNCRbP7vDhvx9HtQ==", + "requires": { + "@chakra-ui/react-context": "2.0.5" + } + }, + "@chakra-ui/provider": { + "version": "2.0.26", + "resolved": "https://registry.npmjs.org/@chakra-ui/provider/-/provider-2.0.26.tgz", + "integrity": "sha512-ln5c3zSFvN1WrkPkX/KOWp+CPg6y8opASlZvWvM+1lTpNX82FkXyPiQYjaemGGbKuooqdRMylseWBStoFwjxOw==", + "requires": { + "@chakra-ui/css-reset": "2.0.10", + "@chakra-ui/portal": "2.0.12", + "@chakra-ui/react-env": "2.0.11", + "@chakra-ui/system": "2.3.5", + "@chakra-ui/utils": "2.0.12" + } + }, + "@chakra-ui/radio": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@chakra-ui/radio/-/radio-2.0.14.tgz", + "integrity": "sha512-e/hY1g92Xdu5d5A27NFfa1+ccE2q/A5H7sc/M7p0fId6KO33Dst25Hy+HThtqnYN0Y3Om58fiXEKo5SsdtvSfA==", + "requires": { + "@chakra-ui/form-control": "2.0.13", + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/react-types": "2.0.5", + "@chakra-ui/react-use-merge-refs": "2.0.5", + "@zag-js/focus-visible": "0.1.0" + } + }, + "@chakra-ui/react": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@chakra-ui/react/-/react-2.4.4.tgz", + "integrity": "sha512-mA0Js3qpRBTmhPuBlBw85OG9ot7uh7+4IjsASmkzbpJVB1Kz9Z+7RBOpjHfK/03zEsRp+XYrb1ps0DYl8ih5bQ==", + "requires": { + "@chakra-ui/accordion": "2.1.4", + "@chakra-ui/alert": "2.0.13", + "@chakra-ui/avatar": "2.2.1", + "@chakra-ui/breadcrumb": "2.1.1", + "@chakra-ui/button": "2.0.13", + "@chakra-ui/card": "2.1.3", + "@chakra-ui/checkbox": "2.2.5", + "@chakra-ui/close-button": "2.0.13", + "@chakra-ui/control-box": "2.0.11", + "@chakra-ui/counter": "2.0.11", + "@chakra-ui/css-reset": "2.0.10", + "@chakra-ui/editable": "2.0.16", + "@chakra-ui/form-control": "2.0.13", + "@chakra-ui/hooks": "2.1.2", + "@chakra-ui/icon": "3.0.13", + "@chakra-ui/image": "2.0.12", + "@chakra-ui/input": "2.0.14", + "@chakra-ui/layout": "2.1.11", + "@chakra-ui/live-region": "2.0.11", + "@chakra-ui/media-query": "3.2.8", + "@chakra-ui/menu": "2.1.5", + "@chakra-ui/modal": "2.2.5", + "@chakra-ui/number-input": "2.0.14", + "@chakra-ui/pin-input": "2.0.16", + "@chakra-ui/popover": "2.1.4", + "@chakra-ui/popper": "3.0.10", + "@chakra-ui/portal": "2.0.12", + "@chakra-ui/progress": "2.1.2", + "@chakra-ui/provider": "2.0.26", + "@chakra-ui/radio": "2.0.14", + "@chakra-ui/react-env": "2.0.11", + "@chakra-ui/select": "2.0.14", + "@chakra-ui/skeleton": "2.0.20", + "@chakra-ui/slider": "2.0.16", + "@chakra-ui/spinner": "2.0.11", + "@chakra-ui/stat": "2.0.13", + "@chakra-ui/styled-system": "2.5.0", + "@chakra-ui/switch": "2.0.17", + "@chakra-ui/system": "2.3.5", + "@chakra-ui/table": "2.0.13", + "@chakra-ui/tabs": "2.1.5", + "@chakra-ui/tag": "2.0.13", + "@chakra-ui/textarea": "2.0.14", + "@chakra-ui/theme": "2.2.2", + "@chakra-ui/theme-utils": "2.0.6", + "@chakra-ui/toast": "4.0.6", + "@chakra-ui/tooltip": "2.2.3", + "@chakra-ui/transition": "2.0.12", + "@chakra-ui/utils": "2.0.12", + "@chakra-ui/visually-hidden": "2.0.13" + } + }, + "@chakra-ui/react-children-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-children-utils/-/react-children-utils-2.0.4.tgz", + "integrity": "sha512-qsKUEfK/AhDbMexWo5JhmdlkxLg5WEw2dFh4XorvU1/dTYsRfP6cjFfO8zE+X3F0ZFNsgKz6rbN5oU349GLEFw==", + "requires": {} + }, + "@chakra-ui/react-context": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-context/-/react-context-2.0.5.tgz", + "integrity": "sha512-WYS0VBl5Q3/kNShQ26BP+Q0OGMeTQWco3hSiJWvO2wYLY7N1BLq6dKs8vyKHZfpwKh2YL2bQeAObi+vSkXp6tQ==", + "requires": {} + }, + "@chakra-ui/react-env": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-env/-/react-env-2.0.11.tgz", + "integrity": "sha512-rPwUHReSWh7rbCw0HePa8Pvc+Q82fUFvVjHTIbXKnE6d+01cCE7j4f1NLeRD9pStKPI6sIZm9xTGvOCzl8F8iw==", + "requires": {} + }, + "@chakra-ui/react-types": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-types/-/react-types-2.0.5.tgz", + "integrity": "sha512-GApp+R/VjS1UV5ms5irrij5LOIgUM0dqSVHagyEFEz88LRKkqMD9RuO577ZsVd4Gn0ULsacVJCUA0HtNUBJNzA==", + "requires": {} + }, + "@chakra-ui/react-use-animation-state": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-animation-state/-/react-use-animation-state-2.0.6.tgz", + "integrity": "sha512-M2kUzZkSBgDpfvnffh3kTsMIM3Dvn+CTMqy9zfY97NL4P3LAWL1MuFtKdlKfQ8hs/QpwS/ew8CTmCtaywn4sKg==", + "requires": { + "@chakra-ui/dom-utils": "2.0.4", + "@chakra-ui/react-use-event-listener": "2.0.5" + } + }, + "@chakra-ui/react-use-callback-ref": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-callback-ref/-/react-use-callback-ref-2.0.5.tgz", + "integrity": "sha512-vKnXleD2PzB0nGabY35fRtklMid4z7cecbMG0fkasNNsgWmrQcXJOuEKUUVCynL6FBU6gBnpKFi5Aqj6x+K4tw==", + "requires": {} + }, + "@chakra-ui/react-use-controllable-state": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-controllable-state/-/react-use-controllable-state-2.0.6.tgz", + "integrity": "sha512-7WuKrhQkpSRoiI5PKBvuIsO46IIP0wsRQgXtStSaIXv+FIvIJl9cxQXTbmZ5q1Ds641QdAUKx4+6v0K/zoZEHg==", + "requires": { + "@chakra-ui/react-use-callback-ref": "2.0.5" + } + }, + "@chakra-ui/react-use-disclosure": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-disclosure/-/react-use-disclosure-2.0.6.tgz", + "integrity": "sha512-4UPePL+OcCY37KZ585iLjg8i6J0sjpLm7iZG3PUwmb97oKHVHq6DpmWIM0VfSjcT6AbSqyGcd5BXZQBgwt8HWQ==", + "requires": { + "@chakra-ui/react-use-callback-ref": "2.0.5" + } + }, + "@chakra-ui/react-use-event-listener": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-event-listener/-/react-use-event-listener-2.0.5.tgz", + "integrity": "sha512-etLBphMigxy/cm7Yg22y29gQ8u/K3PniR5ADZX7WVX61Cgsa8ciCqjTE9sTtlJQWAQySbWxt9+mjlT5zaf+6Zw==", + "requires": { + "@chakra-ui/react-use-callback-ref": "2.0.5" + } + }, + "@chakra-ui/react-use-focus-effect": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-focus-effect/-/react-use-focus-effect-2.0.7.tgz", + "integrity": "sha512-wI8OUNwfbkusajLac8QtjfSyNmsNu1D5pANmnSHIntHhui6Jwv75Pxx7RgmBEnfBEpleBndhR9E75iCjPLhZ/A==", + "requires": { + "@chakra-ui/dom-utils": "2.0.4", + "@chakra-ui/react-use-event-listener": "2.0.5", + "@chakra-ui/react-use-safe-layout-effect": "2.0.3", + "@chakra-ui/react-use-update-effect": "2.0.5" + } + }, + "@chakra-ui/react-use-focus-on-pointer-down": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-focus-on-pointer-down/-/react-use-focus-on-pointer-down-2.0.4.tgz", + "integrity": "sha512-L3YKouIi77QbXH9mSLGEFzJbJDhyrPlcRcuu+TSC7mYaK9E+3Ap+RVSAVxj+CfQz7hCWpikPecKDuspIPWlyuA==", + "requires": { + "@chakra-ui/react-use-event-listener": "2.0.5" + } + }, + "@chakra-ui/react-use-interval": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-interval/-/react-use-interval-2.0.3.tgz", + "integrity": "sha512-Orbij5c5QkL4NuFyU4mfY/nyRckNBgoGe9ic8574VVNJIXfassevZk0WB+lvqBn5XZeLf2Tj+OGJrg4j4H9wzw==", + "requires": { + "@chakra-ui/react-use-callback-ref": "2.0.5" + } + }, + "@chakra-ui/react-use-latest-ref": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-latest-ref/-/react-use-latest-ref-2.0.3.tgz", + "integrity": "sha512-exNSQD4rPclDSmNwtcChUCJ4NuC2UJ4amyNGBqwSjyaK5jNHk2kkM7rZ6I0I8ul+26lvrXlSuhyv6c2PFwbFQQ==", + "requires": {} + }, + "@chakra-ui/react-use-merge-refs": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-merge-refs/-/react-use-merge-refs-2.0.5.tgz", + "integrity": "sha512-uc+MozBZ8asaUpO8SWcK6D4svRPACN63jv5uosUkXJR+05jQJkUofkfQbf2HeGVbrWCr0XZsftLIm4Mt/QMoVw==", + "requires": {} + }, + "@chakra-ui/react-use-outside-click": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-outside-click/-/react-use-outside-click-2.0.5.tgz", + "integrity": "sha512-WmtXUeVaMtxP9aUGGG+GQaDeUn/Bvf8TI3EU5mE1+TtqLHxyA9wtvQurynrogvpilLaBADwn/JeBeqs2wHpvqA==", + "requires": { + "@chakra-ui/react-use-callback-ref": "2.0.5" + } + }, + "@chakra-ui/react-use-pan-event": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-pan-event/-/react-use-pan-event-2.0.6.tgz", + "integrity": "sha512-Vtgl3c+Mj4hdehFRFIgruQVXctwnG1590Ein1FiU8sVnlqO6bpug6Z+B14xBa+F+X0aK+DxnhkJFyWI93Pks2g==", + "requires": { + "@chakra-ui/event-utils": "2.0.6", + "@chakra-ui/react-use-latest-ref": "2.0.3", + "framesync": "5.3.0" + } + }, + "@chakra-ui/react-use-previous": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-previous/-/react-use-previous-2.0.3.tgz", + "integrity": "sha512-A2ODOa0rm2HM4aqXfxxI0zPLcn5Q7iBEjRyfIQhb+EH+d2OFuj3L2slVoIpp6e/km3Xzv2d+u/WbjgTzdQ3d0w==", + "requires": {} + }, + "@chakra-ui/react-use-safe-layout-effect": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-safe-layout-effect/-/react-use-safe-layout-effect-2.0.3.tgz", + "integrity": "sha512-dlTvQURzmdfyBbNdydgO4Wy2/HV8aJN8LszTtyb5vRZsyaslDM/ftcxo8E8QjHwRLD/V1Epb/A8731QfimfVaQ==", + "requires": {} + }, + "@chakra-ui/react-use-size": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-size/-/react-use-size-2.0.5.tgz", + "integrity": "sha512-4arAApdiXk5uv5ZeFKltEUCs5h3yD9dp6gTIaXbAdq+/ENK3jMWTwlqzNbJtCyhwoOFrblLSdBrssBMIsNQfZQ==", + "requires": { + "@zag-js/element-size": "0.1.0" + } + }, + "@chakra-ui/react-use-timeout": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-timeout/-/react-use-timeout-2.0.3.tgz", + "integrity": "sha512-rBBUkZSQq3nJQ8fuMkgZNY2Sgg4vKiKNp05GxAwlT7TitOfVZyoTriqQpqz296bWlmkICTZxlqCWfE5fWpsTsg==", + "requires": { + "@chakra-ui/react-use-callback-ref": "2.0.5" + } + }, + "@chakra-ui/react-use-update-effect": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-use-update-effect/-/react-use-update-effect-2.0.5.tgz", + "integrity": "sha512-y9tCMr1yuDl8ATYdh64Gv8kge5xE1DMykqPDZw++OoBsTaWr3rx40wblA8NIWuSyJe5ErtKP2OeglvJkYhryJQ==", + "requires": {} + }, + "@chakra-ui/react-utils": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/@chakra-ui/react-utils/-/react-utils-2.0.9.tgz", + "integrity": "sha512-nlwPBVlQmcl1PiLzZWyrT3FSnt3vKSkBMzQ0EF4SJWA/nOIqTvmffb5DCzCqPzgQaE/Da1Xgus+JufFGM8GLCQ==", + "requires": { + "@chakra-ui/utils": "2.0.12" + } + }, + "@chakra-ui/select": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@chakra-ui/select/-/select-2.0.14.tgz", + "integrity": "sha512-fvVGxAtLaIXGOMicrzSa6imMw5h26S1ar3xyNmXgR40dbpTPHmtQJkbHBf9FwwQXgSgKWgBzsztw5iDHCpPVzA==", + "requires": { + "@chakra-ui/form-control": "2.0.13" + } + }, + "@chakra-ui/shared-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/shared-utils/-/shared-utils-2.0.3.tgz", + "integrity": "sha512-pCU+SUGdXzjAuUiUT8mriekL3tJVfNdwSTIaNeip7k/SWDzivrKGMwAFBxd3XVTDevtVusndkO4GJuQ3yILzDg==" + }, + "@chakra-ui/skeleton": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/@chakra-ui/skeleton/-/skeleton-2.0.20.tgz", + "integrity": "sha512-PEjjAHT/X8XEHTzXlN0kL883m1Z4Yo4A/ztv4VOvBTnXhHl2wFrrwucxj8TS3eWoCJ65dY9b0ZySP9ARTUe1ng==", + "requires": { + "@chakra-ui/media-query": "3.2.8", + "@chakra-ui/react-use-previous": "2.0.3" + } + }, + "@chakra-ui/slider": { + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/@chakra-ui/slider/-/slider-2.0.16.tgz", + "integrity": "sha512-0nEu9+OAPv4yzMrTH6SkNNMiXbLRe7lXYv1gWbpDGOsNgpGDFYmA7qpzsiiJEJoynqcJZqmDPArqWWPNYeY6Sw==", + "requires": { + "@chakra-ui/number-utils": "2.0.5", + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/react-types": "2.0.5", + "@chakra-ui/react-use-callback-ref": "2.0.5", + "@chakra-ui/react-use-controllable-state": "2.0.6", + "@chakra-ui/react-use-latest-ref": "2.0.3", + "@chakra-ui/react-use-merge-refs": "2.0.5", + "@chakra-ui/react-use-pan-event": "2.0.6", + "@chakra-ui/react-use-size": "2.0.5", + "@chakra-ui/react-use-update-effect": "2.0.5" + } + }, + "@chakra-ui/spinner": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@chakra-ui/spinner/-/spinner-2.0.11.tgz", + "integrity": "sha512-piO2ghWdJzQy/+89mDza7xLhPnW7pA+ADNbgCb1vmriInWedS41IBKe+pSPz4IidjCbFu7xwKE0AerFIbrocCA==", + "requires": {} + }, + "@chakra-ui/stat": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@chakra-ui/stat/-/stat-2.0.13.tgz", + "integrity": "sha512-6XeuE/7w0BjyCHSxMbsf6/rNOOs8BSit1NS7g7+Jd/40Pc/SKlNWLd3kxXPid4eT3RwyNIdMPtm30OActr9nqQ==", + "requires": { + "@chakra-ui/icon": "3.0.13", + "@chakra-ui/react-context": "2.0.5" + } + }, + "@chakra-ui/styled-system": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@chakra-ui/styled-system/-/styled-system-2.5.0.tgz", + "integrity": "sha512-xbvD9MTSXqsPbunCCxfebqslokU53zUefPDQJhgXNKKeMq0NGEgNdGOFXC8oFDP1S/I1GgohKcrSbrSXXLw8yg==", + "requires": { + "csstype": "^3.0.11", + "lodash.mergewith": "4.6.2" + } + }, + "@chakra-ui/switch": { + "version": "2.0.17", + "resolved": "https://registry.npmjs.org/@chakra-ui/switch/-/switch-2.0.17.tgz", + "integrity": "sha512-BQabfC6qYi5xBJvEFPzKq0yl6fTtTNNEHTid5r7h0PWcCnAiHwQJTpQRpxp+AjK569LMLtTXReTZvNBrzEwOrA==", + "requires": { + "@chakra-ui/checkbox": "2.2.5" + } + }, + "@chakra-ui/system": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/system/-/system-2.3.5.tgz", + "integrity": "sha512-x7S7pNKQtFk7/qsn3aHlbZfhcacvaGXBKlnQvHKrbmDVxgLCjGExdi/8Vs7rSYzIyXHx3lItpwd2qHsqqcNvaQ==", + "requires": { + "@chakra-ui/color-mode": "2.1.10", + "@chakra-ui/react-utils": "2.0.9", + "@chakra-ui/styled-system": "2.5.0", + "@chakra-ui/theme-utils": "2.0.6", + "@chakra-ui/utils": "2.0.12", + "react-fast-compare": "3.2.0" + } + }, + "@chakra-ui/table": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@chakra-ui/table/-/table-2.0.13.tgz", + "integrity": "sha512-miQUBJ07L7RzVoFAD6C9I9gaaABeivFRjbr9hf3vyTCsUTV/HDIBHROr6V1sIcQS3asU5nrgbDzRm90mvFOTiw==", + "requires": { + "@chakra-ui/react-context": "2.0.5" + } + }, + "@chakra-ui/tabs": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@chakra-ui/tabs/-/tabs-2.1.5.tgz", + "integrity": "sha512-XmnKDclAJe0FoW4tdC8AlnZpPN5fcj92l4r2sqiL9WyYVEM71hDxZueETIph/GTtfMelG7Z8e5vBHP4rh1RT5g==", + "requires": { + "@chakra-ui/clickable": "2.0.11", + "@chakra-ui/descendant": "3.0.11", + "@chakra-ui/lazy-utils": "2.0.3", + "@chakra-ui/react-children-utils": "2.0.4", + "@chakra-ui/react-context": "2.0.5", + "@chakra-ui/react-use-controllable-state": "2.0.6", + "@chakra-ui/react-use-merge-refs": "2.0.5", + "@chakra-ui/react-use-safe-layout-effect": "2.0.3" + } + }, + "@chakra-ui/tag": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@chakra-ui/tag/-/tag-2.0.13.tgz", + "integrity": "sha512-W1urf+tvGMt6J3cc31HudybYSl+B5jYUP5DJxzXM9p+n3JrvXWAo4D6LmpLBHY5zT2mNne14JF1rVeRcG4Rtdg==", + "requires": { + "@chakra-ui/icon": "3.0.13", + "@chakra-ui/react-context": "2.0.5" + } + }, + "@chakra-ui/textarea": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@chakra-ui/textarea/-/textarea-2.0.14.tgz", + "integrity": "sha512-r8hF1rCi+GseLtY/IGeVWXFN0Uve2b820UQumRj4qxj7PsPqw1hFg7Cecbbb9zwF38K/m+D3IdwFeJzI1MtgRA==", + "requires": { + "@chakra-ui/form-control": "2.0.13" + } + }, + "@chakra-ui/theme": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@chakra-ui/theme/-/theme-2.2.2.tgz", + "integrity": "sha512-7DlOQiXmnaqYyqXwqmfFSCWGkUonuqmNC5mmUCwxI435KgHNCaE2bIm6DI7N2NcIcuVcfc8Vn0UqrDoGU3zJBg==", + "requires": { + "@chakra-ui/anatomy": "2.1.0", + "@chakra-ui/theme-tools": "2.0.14" + } + }, + "@chakra-ui/theme-tools": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@chakra-ui/theme-tools/-/theme-tools-2.0.14.tgz", + "integrity": "sha512-lVcDmq5pyU0QbsIFKjt/iVUFDap7di2QHvPvGChA1YSjtg1PtuUi+BxEXWzp3Nfgw/N4rMvlBs+S0ynJypdwbg==", + "requires": { + "@chakra-ui/anatomy": "2.1.0", + "color2k": "^2.0.0" + } + }, + "@chakra-ui/theme-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@chakra-ui/theme-utils/-/theme-utils-2.0.6.tgz", + "integrity": "sha512-kUm3jaz3sQ/bhBEZ6RWPs1xptQNdSWh/krv9p92rvSkEfjCBDHM5dx7dYk/8KamyUZ6DmK+M31dPyOdOROkBFQ==", + "requires": { + "@chakra-ui/styled-system": "2.5.0", + "@chakra-ui/theme": "2.2.2", + "lodash.mergewith": "4.6.2" + } + }, + "@chakra-ui/toast": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@chakra-ui/toast/-/toast-4.0.6.tgz", + "integrity": "sha512-LatqPM7Vhj22qCyOYXDuhretohp5lJWcXpI9QwpDjd/CEeChy4kYeIJbaLBMzl2WTfIZ+rfHRBhFTpp33aGyqA==", + "requires": { + "@chakra-ui/alert": "2.0.13", + "@chakra-ui/close-button": "2.0.13", + "@chakra-ui/portal": "2.0.12", + "@chakra-ui/react-use-timeout": "2.0.3", + "@chakra-ui/react-use-update-effect": "2.0.5", + "@chakra-ui/styled-system": "2.5.0", + "@chakra-ui/theme": "2.2.2" + } + }, + "@chakra-ui/tooltip": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@chakra-ui/tooltip/-/tooltip-2.2.3.tgz", + "integrity": "sha512-yOne9ofFYfW2XHsbCEPWgLUTnHKm5z21f/cPjwEqtmvCS7aTCOLFiwz2ckRS8yJbIAy+mw0UG6jQsblYKgXj4A==", + "requires": { + "@chakra-ui/popper": "3.0.10", + "@chakra-ui/portal": "2.0.12", + "@chakra-ui/react-types": "2.0.5", + "@chakra-ui/react-use-disclosure": "2.0.6", + "@chakra-ui/react-use-event-listener": "2.0.5", + "@chakra-ui/react-use-merge-refs": "2.0.5" + } + }, + "@chakra-ui/transition": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@chakra-ui/transition/-/transition-2.0.12.tgz", + "integrity": "sha512-ff6eU+m08ccYfCkk0hKfY/XlmGxCrfbBgsKgV4mirZ4SKUL1GVye8CYuHwWQlBJo+8s0yIpsTNxAuX4n/cW9/w==", + "requires": {} + }, + "@chakra-ui/utils": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@chakra-ui/utils/-/utils-2.0.12.tgz", + "integrity": "sha512-1Z1MgsrfMQhNejSdrPJk8v5J4gCefHo+1wBmPPHTz5bGEbAAbZ13aXAfXy8w0eFy0Nvnawn0EHW7Oynp/MdH+Q==", + "requires": { + "@types/lodash.mergewith": "4.6.6", + "css-box-model": "1.2.1", + "framesync": "5.3.0", + "lodash.mergewith": "4.6.2" + } + }, + "@chakra-ui/visually-hidden": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@chakra-ui/visually-hidden/-/visually-hidden-2.0.13.tgz", + "integrity": "sha512-sDEeeEjLfID333EC46NdCbhK2HyMXlpl5HzcJjuwWIpyVz4E1gKQ9hlwpq6grijvmzeSywQ5D3tTwUrvZck4KQ==", + "requires": {} + }, + "@emotion/babel-plugin": { + "version": "11.10.5", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.5.tgz", + "integrity": "sha512-xE7/hyLHJac7D2Ve9dKroBBZqBT7WuPQmWcq7HSGb84sUuP4mlOWoB8dvVfD9yk5DHkU1m6RW7xSoDtnQHNQeA==", + "requires": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/plugin-syntax-jsx": "^7.17.12", + "@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" + }, + "dependencies": { + "@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==" + } + } + }, + "@emotion/cache": { + "version": "11.10.5", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.5.tgz", + "integrity": "sha512-dGYHWyzTdmK+f2+EnIGBpkz1lKc4Zbj2KHd4cX3Wi8/OWr5pKslNjc3yABKH4adRGCvSX4VDC0i04mrrq0aiRA==", + "requires": { + "@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" + }, + "dependencies": { + "@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==" + } + } + }, + "@emotion/hash": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.0.tgz", + "integrity": "sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ==" + }, + "@emotion/is-prop-valid": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", + "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", + "optional": true, + "requires": { + "@emotion/memoize": "0.7.4" + } + }, + "@emotion/memoize": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", + "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", + "optional": true + }, + "@emotion/react": { + "version": "11.10.5", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.10.5.tgz", + "integrity": "sha512-TZs6235tCJ/7iF6/rvTaOH4oxQg2gMAcdHemjwLKIjKz4rRuYe1HJ2TQJKnAcRAfOUDdU8XoDadCe1rl72iv8A==", + "requires": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.10.5", + "@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" + } + }, + "@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==", + "requires": { + "@emotion/hash": "^0.9.0", + "@emotion/memoize": "^0.8.0", + "@emotion/unitless": "^0.8.0", + "@emotion/utils": "^1.2.0", + "csstype": "^3.0.2" + }, + "dependencies": { + "@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==" + } + } + }, + "@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==" + }, + "@emotion/styled": { + "version": "11.10.5", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.10.5.tgz", + "integrity": "sha512-8EP6dD7dMkdku2foLoruPCNkRevzdcBaY6q0l0OsbyJK+x8D9HWjX27ARiSIKNF634hY9Zdoedh8bJCiva8yZw==", + "requires": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.10.5", + "@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" + }, + "dependencies": { + "@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==", + "requires": { + "@emotion/memoize": "^0.8.0" + } + }, + "@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==" + } + } + }, + "@emotion/unitless": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz", + "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==" + }, + "@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==", + "requires": {} + }, + "@emotion/utils": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz", + "integrity": "sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw==" + }, + "@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==" + }, "@eslint/eslintrc": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", - "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.0.tgz", + "integrity": "sha512-7yfvXy6MWLgWSFsLhz5yH3iQ52St8cdUY6FoGieKkRDVxuxmrNuUetIuu6cmjNWwniUHiWXjxCr5tTXDrbYS5A==", "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^9.4.0", - "globals": "^13.15.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -3372,10 +7626,24 @@ "strip-json-comments": "^3.1.1" } }, + "@headlessui/react": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.7.7.tgz", + "integrity": "sha512-BqDOd/tB9u2tA0T3Z0fn18ktw+KbVwMnkxxsGPIH2hzssrQhKB5n/6StZOyvLYP/FsYtvuXfi9I0YowKPv2c1w==", + "requires": { + "client-only": "^0.0.1" + } + }, + "@heroicons/react": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.0.13.tgz", + "integrity": "sha512-iSN5XwmagrnirWlYEWNPdCDj9aRYVD/lnK3JlsC9/+fqGF80k8C7rl+1HCvBX0dBoagKqOFBs6fMhJJ1hOg1EQ==", + "requires": {} + }, "@humanwhocodes/config-array": { - "version": "0.11.7", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", - "integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==", + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", "requires": { "@humanwhocodes/object-schema": "^1.2.1", "debug": "^4.1.1", @@ -3392,6 +7660,108 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" }, + "@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "peer": true, + "requires": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "peer": true + }, + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "peer": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "peer": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "peer": true, + "requires": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "@motionone/animation": { + "version": "10.15.1", + "resolved": "https://registry.npmjs.org/@motionone/animation/-/animation-10.15.1.tgz", + "integrity": "sha512-mZcJxLjHor+bhcPuIFErMDNyrdb2vJur8lSfMCsuCB4UyV8ILZLvK+t+pg56erv8ud9xQGK/1OGPt10agPrCyQ==", + "requires": { + "@motionone/easing": "^10.15.1", + "@motionone/types": "^10.15.1", + "@motionone/utils": "^10.15.1", + "tslib": "^2.3.1" + } + }, + "@motionone/dom": { + "version": "10.12.0", + "resolved": "https://registry.npmjs.org/@motionone/dom/-/dom-10.12.0.tgz", + "integrity": "sha512-UdPTtLMAktHiqV0atOczNYyDd/d8Cf5fFsd1tua03PqTwwCe/6lwhLSQ8a7TbnQ5SN0gm44N1slBfj+ORIhrqw==", + "requires": { + "@motionone/animation": "^10.12.0", + "@motionone/generators": "^10.12.0", + "@motionone/types": "^10.12.0", + "@motionone/utils": "^10.12.0", + "hey-listen": "^1.0.8", + "tslib": "^2.3.1" + } + }, + "@motionone/easing": { + "version": "10.15.1", + "resolved": "https://registry.npmjs.org/@motionone/easing/-/easing-10.15.1.tgz", + "integrity": "sha512-6hIHBSV+ZVehf9dcKZLT7p5PEKHGhDwky2k8RKkmOvUoYP3S+dXsKupyZpqx5apjd9f+php4vXk4LuS+ADsrWw==", + "requires": { + "@motionone/utils": "^10.15.1", + "tslib": "^2.3.1" + } + }, + "@motionone/generators": { + "version": "10.15.1", + "resolved": "https://registry.npmjs.org/@motionone/generators/-/generators-10.15.1.tgz", + "integrity": "sha512-67HLsvHJbw6cIbLA/o+gsm7h+6D4Sn7AUrB/GPxvujse1cGZ38F5H7DzoH7PhX+sjvtDnt2IhFYF2Zp1QTMKWQ==", + "requires": { + "@motionone/types": "^10.15.1", + "@motionone/utils": "^10.15.1", + "tslib": "^2.3.1" + } + }, + "@motionone/types": { + "version": "10.15.1", + "resolved": "https://registry.npmjs.org/@motionone/types/-/types-10.15.1.tgz", + "integrity": "sha512-iIUd/EgUsRZGrvW0jqdst8st7zKTzS9EsKkP+6c6n4MPZoQHwiHuVtTQLD6Kp0bsBLhNzKIBlHXponn/SDT4hA==" + }, + "@motionone/utils": { + "version": "10.15.1", + "resolved": "https://registry.npmjs.org/@motionone/utils/-/utils-10.15.1.tgz", + "integrity": "sha512-p0YncgU+iklvYr/Dq4NobTRdAPv9PveRDUXabPEeOjBLSO/1FNB2phNTZxOxpi1/GZwYpAoECEa0Wam+nsmhSw==", + "requires": { + "@motionone/types": "^10.15.1", + "hey-listen": "^1.0.8", + "tslib": "^2.3.1" + } + }, + "@next-auth/prisma-adapter": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@next-auth/prisma-adapter/-/prisma-adapter-1.0.5.tgz", + "integrity": "sha512-VqMS11IxPXrPGXw6Oul6jcyS/n8GLOWzRMrPr3EMdtD6eOalM6zz05j08PcNiis8QzkfuYnCv49OvufTuaEwYQ==", + "requires": {} + }, "@next/env": { "version": "13.0.6", "resolved": "https://registry.npmjs.org/@next/env/-/env-13.0.6.tgz", @@ -3405,6 +7775,11 @@ "glob": "7.1.7" } }, + "@next/font": { + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/@next/font/-/font-13.1.0.tgz", + "integrity": "sha512-9+c2eWoeLftcGAul1fiXD8lL4o4/0beQrz2/0h0B0VV5AWrqCCfj/204quUxdp541ab+NCWVX/m49qjbqFMaFA==" + }, "@next/swc-android-arm-eabi": { "version": "13.0.6", "resolved": "https://registry.npmjs.org/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-13.0.6.tgz", @@ -3506,6 +7881,11 @@ "fastq": "^1.6.0" } }, + "@panva/hkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@panva/hkdf/-/hkdf-1.0.2.tgz", + "integrity": "sha512-MSAs9t3Go7GUkMhpKC44T58DJ5KGk2vBo+h1cqQeqlMfdGkxaVB78ZWpv9gYi/g2fa4sopag9gJsNvS8XGgWJA==" + }, "@pkgr/utils": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.3.1.tgz", @@ -3519,107 +7899,35 @@ "tslib": "^2.4.0" } }, + "@popperjs/core": { + "version": "2.11.6", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz", + "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==" + }, + "@prisma/client": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-4.7.1.tgz", + "integrity": "sha512-/GbnOwIPtjiveZNUzGXOdp7RxTEkHL4DZP3vBaFNadfr6Sf0RshU5EULFzVaSi9i9PIK9PYd+1Rn7z2B2npb9w==", + "requires": { + "@prisma/engines-version": "4.7.1-1.272861e07ab64f234d3ffc4094e32bd61775599c" + } + }, + "@prisma/engines": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-4.7.1.tgz", + "integrity": "sha512-zWabHosTdLpXXlMefHmnouhXMoTB1+SCbUU3t4FCmdrtIOZcarPKU3Alto7gm/pZ9vHlGOXHCfVZ1G7OIrSbog==", + "devOptional": true + }, + "@prisma/engines-version": { + "version": "4.7.1-1.272861e07ab64f234d3ffc4094e32bd61775599c", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-4.7.1-1.272861e07ab64f234d3ffc4094e32bd61775599c.tgz", + "integrity": "sha512-Bd4LZ+WAnUHOq31e9X/ihi5zPlr4SzTRwUZZYxvWOxlerIZ7HJlVa9zXpuKTKLpI9O1l8Ec4OYCKsivWCs5a3Q==" + }, "@rushstack/eslint-patch": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz", "integrity": "sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==" }, - "@stitches/core": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@stitches/core/-/core-1.2.8.tgz", - "integrity": "sha512-Gfkvwk9o9kE9r9XNBmJRfV8zONvXThnm1tcuojL04Uy5uRyqg93DC83lDebl0rocZCfKSjUv+fWYtMQmEDJldg==" - }, - "@stitches/react": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@stitches/react/-/react-1.2.8.tgz", - "integrity": "sha512-9g9dWI4gsSVe8bNLlb+lMkBYsnIKCZTmvqvDG+Avnn69XfmHZKiaMrx7cgTaddq7aTPPmXiTsbFcUy0xgI4+wA==", - "requires": {} - }, - "@supabase/auth-helpers-nextjs": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@supabase/auth-helpers-nextjs/-/auth-helpers-nextjs-0.5.2.tgz", - "integrity": "sha512-B+sQFVEImAYOJKyyNX1DWqTF2qVf9SocOM1GD4eGHon6ulvLOo2a8V+v1jZAuLOBF6yzVIYnZucuYKZCiNP/Eg==", - "requires": { - "@supabase/auth-helpers-shared": "0.2.3" - } - }, - "@supabase/auth-helpers-react": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@supabase/auth-helpers-react/-/auth-helpers-react-0.3.1.tgz", - "integrity": "sha512-g3SFv08Dz9FapNif/ZY1b7qKGlMJDyTLSayHBz3kb3FuYxg7aLWgQtydDhm5AGbc0XtvpIBuhGTIOVevwpdosA==", - "requires": {} - }, - "@supabase/auth-helpers-shared": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@supabase/auth-helpers-shared/-/auth-helpers-shared-0.2.3.tgz", - "integrity": "sha512-Xwnd2UQ/VTjTKIuVg1Xl/ryrElbSccOJhC11jbVPHOs7Y6yxzy9APxQs//jj4IpbDH4uOEDCdpMIJ0tzRxj9DQ==", - "requires": {} - }, - "@supabase/auth-ui-react": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/@supabase/auth-ui-react/-/auth-ui-react-0.2.6.tgz", - "integrity": "sha512-N2qxgsjxPQZPdDotVumzruj4RHaKNFb9ZRecttMeGOvrYFbMWRQVpWT/rYkTPsRW2phKiGXQlMwha6YxUE+t6Q==", - "requires": { - "@stitches/core": "^1.2.8", - "@stitches/react": "^1.2.8", - "fsevents": "^2.3.2", - "prop-types": "^15.7.2" - } - }, - "@supabase/functions-js": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.0.0.tgz", - "integrity": "sha512-ozb7bds2yvf5k7NM2ZzUkxvsx4S4i2eRKFSJetdTADV91T65g4gCzEs9L3LUXSrghcGIkUaon03VPzOrFredqg==", - "requires": { - "cross-fetch": "^3.1.5" - } - }, - "@supabase/gotrue-js": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@supabase/gotrue-js/-/gotrue-js-2.5.0.tgz", - "integrity": "sha512-Aw5/WL0+JVjQjX2ZOQvOzoquMg1IMa4l1cA0eHVseAjujgUPpztjdhDwy3xP/c7OQsF+RK0ARxjsmIm2iaILlg==", - "requires": { - "cross-fetch": "^3.1.5" - } - }, - "@supabase/postgrest-js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-1.1.0.tgz", - "integrity": "sha512-qkY8TqIu5sJuae8gjeDPjEqPrefzcTraW9PNSVJQHq4TEv98ZmwaXGwBGz0bVL63bqrGA5hqREbQHkANUTXrvA==", - "requires": { - "cross-fetch": "^3.1.5" - } - }, - "@supabase/realtime-js": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.1.0.tgz", - "integrity": "sha512-iplLCofTeYjnx9FIOsIwHLhMp0+7UVyiA4/sCeq40VdOgN9eTIhjEno9Tgh4dJARi4aaXoKfRX1DTxgZaOpPAw==", - "requires": { - "@types/phoenix": "^1.5.4", - "websocket": "^1.0.34" - } - }, - "@supabase/storage-js": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.1.0.tgz", - "integrity": "sha512-bRMLWCbkkx84WDAtHAAMN7FAWuayrGZtTHj/WMUK6PsAWuonovvEa5s34a5iux61qJSn+ls3tFkyQgqxunl5ww==", - "requires": { - "cross-fetch": "^3.1.5" - } - }, - "@supabase/supabase-js": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.1.4.tgz", - "integrity": "sha512-i+BAiE472hMIIz6/nM5Pt/6riljjQYJrReyd0LsYsNtis4vcey7SuMX7sYiG9kMo4ivPlB1odYSOJnRbNyqRbQ==", - "requires": { - "@supabase/functions-js": "^2.0.0", - "@supabase/gotrue-js": "^2.5.0", - "@supabase/postgrest-js": "^1.1.0", - "@supabase/realtime-js": "^2.1.0", - "@supabase/storage-js": "^2.0.0", - "cross-fetch": "^3.1.5" - } - }, "@swc/helpers": { "version": "0.4.14", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.14.tgz", @@ -3628,15 +7936,65 @@ "tslib": "^2.4.0" } }, + "@tailwindcss/forms": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.3.tgz", + "integrity": "sha512-y5mb86JUoiUgBjY/o6FJSFZSEttfb3Q5gllE4xoKjAAD+vBrnIhE4dViwUuow3va8mpH4s9jyUbUbrRGoRdc2Q==", + "requires": { + "mini-svg-data-uri": "^1.2.3" + } + }, "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" }, - "@types/phoenix": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.5.4.tgz", - "integrity": "sha512-L5eZmzw89eXBKkiqVBcJfU1QGx9y+wurRIEgt0cuLH0hwNtVUxtx+6cu0R2STwWj468sjXyBYPYDtGclUd1kjQ==" + "@types/lodash": { + "version": "4.14.191", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz", + "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==" + }, + "@types/lodash.mergewith": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/@types/lodash.mergewith/-/lodash.mergewith-4.6.6.tgz", + "integrity": "sha512-RY/8IaVENjG19rxTZu9Nukqh0W2UrYgmBj5sdns4hWRZaV8PqR7wIKHFKzvOTjo4zVRV7sVI+yFhAJql12Kfqg==", + "requires": { + "@types/lodash": "*" + } + }, + "@types/node": { + "version": "18.11.17", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.17.tgz", + "integrity": "sha512-HJSUJmni4BeDHhfzn6nF0sVmd1SMezP7/4F0Lq+aXzmp2xm9O7WXrUtHW/CHlYVtZUbByEvWidHqRtcJXGF2Ng==", + "dev": true + }, + "@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" + }, + "@types/prop-types": { + "version": "15.7.5", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", + "devOptional": true + }, + "@types/react": { + "version": "18.0.26", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.26.tgz", + "integrity": "sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug==", + "devOptional": true, + "requires": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "@types/scheduler": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", + "devOptional": true }, "@typescript-eslint/parser": { "version": "5.46.1", @@ -3686,6 +8044,16 @@ "eslint-visitor-keys": "^3.3.0" } }, + "@zag-js/element-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@zag-js/element-size/-/element-size-0.1.0.tgz", + "integrity": "sha512-QF8wp0+V8++z+FHXiIw93+zudtubYszOtYbNgK39fg3pi+nCZtuSm4L1jC5QZMatNZ83MfOzyNCfgUubapagJQ==" + }, + "@zag-js/focus-visible": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@zag-js/focus-visible/-/focus-visible-0.1.0.tgz", + "integrity": "sha512-PeaBcTmdZWcFf7n1aM+oiOdZc+sy14qi0emPIeUuGMTjbP0xLGrZu43kdpHnWSXy7/r4Ubp/vlg50MCV8+9Isg==" + }, "acorn": { "version": "8.8.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", @@ -3697,6 +8065,28 @@ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "requires": {} }, + "acorn-node": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", + "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", + "requires": { + "acorn": "^7.0.0", + "acorn-walk": "^7.0.0", + "xtend": "^4.0.2" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" + } + } + }, + "acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==" + }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -3721,11 +8111,33 @@ "color-convert": "^2.0.1" } }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, + "aria-hidden": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.2.tgz", + "integrity": "sha512-6y/ogyDTk/7YAe91T3E2PR1ALVKyM2QbTio5HwM+N1Q6CMlCKhvClyIjkckBswa0f2xJhjsfzIGa1yVSe1UMVA==", + "requires": { + "tslib": "^2.0.0" + } + }, "aria-query": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", @@ -3791,21 +8203,64 @@ "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==" }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "autoprefixer": { + "version": "10.4.13", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.13.tgz", + "integrity": "sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==", + "requires": { + "browserslist": "^4.21.4", + "caniuse-lite": "^1.0.30001426", + "fraction.js": "^4.2.0", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + } + }, "axe-core": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.6.0.tgz", - "integrity": "sha512-L3ZNbXPTxMrl0+qTXAzn9FBRvk5XdO56K8CvcCKtlxv44Aw2w2NCclGuvCWxHPw1Riiq3ncP/sxFYj2nUqdoTw==" + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.6.1.tgz", + "integrity": "sha512-lCZN5XRuOnpG4bpMq8v0khrWtUOn+i8lZSb6wHZH56ZfbIEv6XwJV84AAueh9/zi7qPVJ/E4yz6fmsiyOmXR4w==" + }, + "axios": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.2.1.tgz", + "integrity": "sha512-I88cFiGu9ryt/tfVEi4kX2SITsvDddTajXTOFmt2uK1ZVA8LytjtdeyefdQWEf5PU8w+4SSJDoYnggflB5tW4A==", + "requires": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } }, "axobject-query": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==" }, + "babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "requires": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + } + }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -3823,12 +8278,15 @@ "fill-range": "^7.0.1" } }, - "bufferutil": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.7.tgz", - "integrity": "sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw==", + "browserslist": { + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", "requires": { - "node-gyp-build": "^4.3.0" + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.9" } }, "call-bind": { @@ -3845,6 +8303,11 @@ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" }, + "camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==" + }, "caniuse-lite": { "version": "1.0.30001439", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001439.tgz", @@ -3859,11 +8322,41 @@ "supports-color": "^7.1.0" } }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, "client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" }, + "clsx": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==" + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -3877,22 +8370,62 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "color2k": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/color2k/-/color2k-2.0.0.tgz", + "integrity": "sha512-DWX9eXOC4fbJNiuvdH4QSHvvfLWyFo9TuFp7V9OzdsbPAdrWAuYc8qvFP2bIQ/LKh4LrAVnJ6vhiQYPvAHdtTg==" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "compute-scroll-into-view": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.14.tgz", + "integrity": "sha512-mKDjINe3tc6hGelUMNDzuhorIUZ7kS7BwyY0r2wQd2HOH2tRuJykiC06iSEX8y1TuhNzvz4GcJnK16mM2J1NMQ==" + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, + "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==" + }, + "cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" + }, + "copy-to-clipboard": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz", + "integrity": "sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==", + "requires": { + "toggle-selection": "^1.0.6" + } + }, "core-js-pure": { "version": "3.26.1", "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.26.1.tgz", "integrity": "sha512-VVXcDpp/xJ21KdULRq/lXdLzQAtX7+37LzpyfFM973il0tWSsDEoyzG38G14AjTpK9VTfiNM9jnFauq/CpaWGQ==" }, - "cross-fetch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", - "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "requires": { - "node-fetch": "2.6.7" + "@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" } }, "cross-spawn": { @@ -3905,15 +8438,24 @@ "which": "^2.0.1" } }, - "d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "css-box-model": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz", + "integrity": "sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==", "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" + "tiny-invariant": "^1.0.6" } }, + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" + }, + "csstype": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", + "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" + }, "damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -3946,6 +8488,36 @@ "object-keys": "^1.1.1" } }, + "defined": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz", + "integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==" + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, + "detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" + }, + "detective": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz", + "integrity": "sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==", + "requires": { + "acorn-node": "^1.8.2", + "defined": "^1.0.0", + "minimist": "^1.2.6" + } + }, + "didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" + }, "dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -3954,6 +8526,11 @@ "path-type": "^4.0.0" } }, + "dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" + }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -3962,6 +8539,11 @@ "esutils": "^2.0.2" } }, + "electron-to-chromium": { + "version": "1.4.284", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", + "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==" + }, "emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -3976,6 +8558,14 @@ "tapable": "^2.2.0" } }, + "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==", + "requires": { + "is-arrayish": "^0.2.1" + } + }, "es-abstract": { "version": "1.20.5", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.5.tgz", @@ -4026,34 +8616,10 @@ "is-symbol": "^1.0.2" } }, - "es5-ext": { - "version": "0.10.62", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", - "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", - "requires": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "next-tick": "^1.1.0" - } - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "requires": { - "d": "^1.0.1", - "ext": "^1.1.2" - } + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" }, "escape-string-regexp": { "version": "4.0.0", @@ -4380,21 +8946,6 @@ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" }, - "ext": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", - "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", - "requires": { - "type": "^2.7.2" - }, - "dependencies": { - "type": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", - "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" - } - } - }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -4456,6 +9007,11 @@ "to-regex-range": "^5.0.1" } }, + "find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, "find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -4479,6 +9035,71 @@ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==" }, + "focus-lock": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-0.11.4.tgz", + "integrity": "sha512-LzZWJcOBIcHslQ46N3SUu/760iLPSrUtp8omM4gh9du438V2CQdks8TcOu1yvmu2C68nVOBnl1WFiKGPbQ8L6g==", + "requires": { + "tslib": "^2.0.3" + } + }, + "focus-visible": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/focus-visible/-/focus-visible-5.2.0.tgz", + "integrity": "sha512-Rwix9pBtC1Nuy5wysTmKy+UjbDJpIfg8eHjw0rjZ1mX4GNLz1Bmd16uDpI3Gk1i70Fgcs8Csg2lPm8HULFg9DQ==" + }, + "follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" + }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "fraction.js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", + "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==" + }, + "framer-motion": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-6.5.1.tgz", + "integrity": "sha512-o1BGqqposwi7cgDrtg0dNONhkmPsUFDaLcKXigzuTFC5x58mE8iyTazxSudFzmT6MEyJKfjjU8ItoMe3W+3fiw==", + "requires": { + "@emotion/is-prop-valid": "^0.8.2", + "@motionone/dom": "10.12.0", + "framesync": "6.0.1", + "hey-listen": "^1.0.8", + "popmotion": "11.0.3", + "style-value-types": "5.0.0", + "tslib": "^2.1.0" + }, + "dependencies": { + "framesync": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/framesync/-/framesync-6.0.1.tgz", + "integrity": "sha512-fUY88kXvGiIItgNC7wcTOl0SNRCVXMKSWW2Yzfmn7EKNc+MpCzcz9DhdHcdjbrtN3c6R4H5dTY2jiCpPdysEjA==", + "requires": { + "tslib": "^2.1.0" + } + } + } + }, + "framesync": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/framesync/-/framesync-5.3.0.tgz", + "integrity": "sha512-oc5m68HDO/tuK2blj7ZcdEBRx3p1PjrgHazL8GYEpvULhrtGIFbQArN6cQS2QhW8mitffaB+VYzMjDqBxxQeoA==", + "requires": { + "tslib": "^2.1.0" + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -4511,6 +9132,12 @@ "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==" }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "peer": true + }, "get-intrinsic": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", @@ -4521,6 +9148,11 @@ "has-symbols": "^1.0.3" } }, + "get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==" + }, "get-symbol-description": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", @@ -4644,6 +9276,19 @@ "has-symbols": "^1.0.2" } }, + "hey-listen": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/hey-listen/-/hey-listen-1.0.8.tgz", + "integrity": "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==" + }, + "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", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + } + }, "ignore": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.1.tgz", @@ -4678,15 +9323,28 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.4.tgz", + "integrity": "sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ==", "requires": { - "get-intrinsic": "^1.1.0", + "get-intrinsic": "^1.1.3", "has": "^1.0.3", "side-channel": "^1.0.4" } }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "requires": { + "loose-envify": "^1.0.0" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, "is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -4695,6 +9353,14 @@ "has-bigints": "^1.0.1" } }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "requires": { + "binary-extensions": "^2.0.0" + } + }, "is-boolean-object": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", @@ -4799,11 +9465,6 @@ "has-symbols": "^1.0.2" } }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" - }, "is-weakref": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", @@ -4825,6 +9486,11 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, + "jose": { + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.11.1.tgz", + "integrity": "sha512-YRv4Tk/Wlug8qicwqFNFVEZSdbROCHRAC6qu/i0dyNKr5JQdoa2pIGoS04lLO/jXQX7Z9omoNewYIVIxqZBd9Q==" + }, "js-sdsl": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", @@ -4843,6 +9509,17 @@ "argparse": "^2.0.1" } }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "peer": true + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -4876,9 +9553,9 @@ "integrity": "sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==" }, "language-tags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.6.tgz", - "integrity": "sha512-HNkaCgM8wZgE/BZACeotAAgpL9FUjEnhgF0FVQMIgH//zqTPreLYMb3rWYkYAqPoF75Jwuycp1da7uz66cfFQg==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.7.tgz", + "integrity": "sha512-bSytju1/657hFjgUzPAPqszxH62ouE8nQFoFaVlIQfne4wO/wXC9A4+m8jYve7YBBvi59eq0SUpcshvG8h5Usw==", "requires": { "language-subtag-registry": "^0.3.20" } @@ -4892,6 +9569,16 @@ "type-check": "~0.4.0" } }, + "lilconfig": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz", + "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==" + }, + "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==" + }, "locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -4905,6 +9592,11 @@ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, + "lodash.mergewith": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==" + }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -4935,6 +9627,24 @@ "picomatch": "^2.3.1" } }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "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==", + "requires": { + "mime-db": "1.52.0" + } + }, + "mini-svg-data-uri": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", + "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==" + }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -4988,29 +9698,57 @@ "styled-jsx": "5.1.0" } }, - "next-tick": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" - }, - "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "next-auth": { + "version": "4.18.6", + "resolved": "https://registry.npmjs.org/next-auth/-/next-auth-4.18.6.tgz", + "integrity": "sha512-0TQwbq5X9Jyd1wUVYUoyvHJh4JWXeW9UOcMEl245Er/Y5vsSbyGJHt8M7xjRMzk9mORVMYehoMdERgyiq/jCgA==", "requires": { - "whatwg-url": "^5.0.0" + "@babel/runtime": "^7.16.3", + "@panva/hkdf": "^1.0.1", + "cookie": "^0.5.0", + "jose": "^4.9.3", + "oauth": "^0.9.15", + "openid-client": "^5.1.0", + "preact": "^10.6.3", + "preact-render-to-string": "^5.1.19", + "uuid": "^8.3.2" } }, - "node-gyp-build": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.5.0.tgz", - "integrity": "sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==" + "node-releases": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", + "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==" + }, + "nodemailer": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.8.0.tgz", + "integrity": "sha512-EjYvSmHzekz6VNkNd12aUqAco+bOkRe3Of5jVhltqKhEsjw/y0PYPJfp83+s9Wzh1dspYAkUW/YNQ350NATbSQ==" + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==" + }, + "oauth": { + "version": "0.9.15", + "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", + "integrity": "sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==" }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" }, + "object-hash": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", + "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==" + }, "object-inspect": { "version": "1.12.2", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", @@ -5071,6 +9809,11 @@ "es-abstract": "^1.20.4" } }, + "oidc-token-hash": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.0.1.tgz", + "integrity": "sha512-EvoOtz6FIEBzE+9q253HsLCVRiK/0doEJ2HCvvqMQb3dHZrP3WlJKYtJ55CRTw4jmYomzH4wkPuCj/I3ZvpKxQ==" + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -5089,6 +9832,17 @@ "is-wsl": "^2.2.0" } }, + "openid-client": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.3.1.tgz", + "integrity": "sha512-RLfehQiHch9N6tRWNx68cicf3b1WR0x74bJWHRc25uYIbSRwjxYcTFaRnzbbpls5jroLAaB/bFIodTgA5LJMvw==", + "requires": { + "jose": "^4.10.0", + "lru-cache": "^6.0.0", + "object-hash": "^2.0.1", + "oidc-token-hash": "^5.0.1" + } + }, "optionator": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", @@ -5126,6 +9880,17 @@ "callsites": "^3.0.0" } }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -5161,6 +9926,32 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==" + }, + "popmotion": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/popmotion/-/popmotion-11.0.3.tgz", + "integrity": "sha512-Y55FLdj3UxkR7Vl3s7Qr4e9m0onSnP8W7d/xQLsoJM40vs6UKHFdygs6SWryasTZYqugMjm3BepCF4CWXDiHgA==", + "requires": { + "framesync": "6.0.1", + "hey-listen": "^1.0.8", + "style-value-types": "5.0.0", + "tslib": "^2.1.0" + }, + "dependencies": { + "framesync": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/framesync/-/framesync-6.0.1.tgz", + "integrity": "sha512-fUY88kXvGiIItgNC7wcTOl0SNRCVXMKSWW2Yzfmn7EKNc+MpCzcz9DhdHcdjbrtN3c6R4H5dTY2jiCpPdysEjA==", + "requires": { + "tslib": "^2.1.0" + } + } + } + }, "postcss": { "version": "8.4.14", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", @@ -5171,11 +9962,101 @@ "source-map-js": "^1.0.2" } }, + "postcss-focus-visible": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-7.1.0.tgz", + "integrity": "sha512-OGxO+eCXVkF94us4uOVLHDPaoJuV8HQhaqmVPo2DtECdjqzWNkmwhFRSRRDT5Sg04JQsAECzgIhpyX0JRTgwlQ==", + "requires": { + "postcss-selector-parser": "^6.0.10" + } + }, + "postcss-import": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-14.1.0.tgz", + "integrity": "sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==", + "requires": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + } + }, + "postcss-js": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.0.tgz", + "integrity": "sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==", + "requires": { + "camelcase-css": "^2.0.1" + } + }, + "postcss-load-config": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", + "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", + "requires": { + "lilconfig": "^2.0.5", + "yaml": "^1.10.2" + } + }, + "postcss-nested": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.0.tgz", + "integrity": "sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==", + "requires": { + "postcss-selector-parser": "^6.0.10" + } + }, + "postcss-selector-parser": { + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", + "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + }, + "postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + }, + "preact": { + "version": "10.11.3", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.11.3.tgz", + "integrity": "sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg==" + }, + "preact-render-to-string": { + "version": "5.2.6", + "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.6.tgz", + "integrity": "sha512-JyhErpYOvBV1hEPwIxc/fHWXPfnEGdRKxc8gFdAZ7XV4tlzyzG847XAyEZqoDnynP88akM4eaHcSOzNcLWFguw==", + "requires": { + "pretty-format": "^3.8.0" + } + }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" }, + "prettier": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.1.tgz", + "integrity": "sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==", + "dev": true + }, + "pretty-format": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz", + "integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==" + }, + "prisma": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-4.7.1.tgz", + "integrity": "sha512-CCQP+m+1qZOGIZlvnL6T3ZwaU0LAleIHYFPN9tFSzjs/KL6vH9rlYbGOkTuG9Q1s6Ki5D0LJlYlW18Z9EBUpGg==", + "devOptional": true, + "requires": { + "@prisma/engines": "4.7.1" + } + }, "prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -5186,6 +10067,11 @@ "react-is": "^16.13.1" } }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -5196,6 +10082,11 @@ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" }, + "quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==" + }, "react": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", @@ -5204,6 +10095,14 @@ "loose-envify": "^1.1.0" } }, + "react-clientside-effect": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/react-clientside-effect/-/react-clientside-effect-1.2.6.tgz", + "integrity": "sha512-XGGGRQAKY+q25Lz9a/4EPqom7WRjz3z9R2k4jhVKA/puQFH/5Nt27vFZYql4m4NVNdUvX8PS3O7r/Zzm7cjUlg==", + "requires": { + "@babel/runtime": "^7.12.13" + } + }, "react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -5213,11 +10112,82 @@ "scheduler": "^0.23.0" } }, + "react-fast-compare": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", + "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" + }, + "react-focus-lock": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.9.2.tgz", + "integrity": "sha512-5JfrsOKyA5Zn3h958mk7bAcfphr24jPoMoznJ8vaJF6fUrPQ8zrtEd3ILLOK8P5jvGxdMd96OxWNjDzATfR2qw==", + "requires": { + "@babel/runtime": "^7.0.0", + "focus-lock": "^0.11.2", + "prop-types": "^15.6.2", + "react-clientside-effect": "^1.2.6", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" + } + }, + "react-icons": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.7.1.tgz", + "integrity": "sha512-yHd3oKGMgm7zxo3EA7H2n7vxSoiGmHk5t6Ou4bXsfcgWyhfDKMpyKfhHR6Bjnn63c+YXBLBPUql9H4wPJM6sXw==", + "requires": {} + }, "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "react-remove-scroll": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz", + "integrity": "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==", + "requires": { + "react-remove-scroll-bar": "^2.3.3", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" + } + }, + "react-remove-scroll-bar": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.4.tgz", + "integrity": "sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==", + "requires": { + "react-style-singleton": "^2.2.1", + "tslib": "^2.0.0" + } + }, + "react-style-singleton": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", + "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==", + "requires": { + "get-nonce": "^1.0.0", + "invariant": "^2.2.4", + "tslib": "^2.0.0" + } + }, + "read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "requires": { + "pify": "^2.3.0" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "requires": { + "picomatch": "^2.2.1" + } + }, "regenerator-runtime": { "version": "0.13.11", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", @@ -5328,6 +10298,11 @@ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==" + }, "source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", @@ -5386,6 +10361,15 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" }, + "style-value-types": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/style-value-types/-/style-value-types-5.0.0.tgz", + "integrity": "sha512-08yq36Ikn4kx4YU6RD7jWEv27v4V+PUsOGa4n/as8Et3CuODMJQ00ENeAVXAeydX4Z2j1XHZF1K2sX4mGl18fA==", + "requires": { + "hey-listen": "^1.0.8", + "tslib": "^2.1.0" + } + }, "styled-jsx": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.0.tgz", @@ -5394,6 +10378,11 @@ "client-only": "0.0.1" } }, + "stylis": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz", + "integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA==" + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -5407,6 +10396,14 @@ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" }, + "swr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/swr/-/swr-2.0.0.tgz", + "integrity": "sha512-IhUx5yPkX+Fut3h0SqZycnaNLXLXsb2ECFq0Y29cxnK7d8r7auY2JWNbCW3IX+EqXUg3rwNJFlhrw5Ye/b6k7w==", + "requires": { + "use-sync-external-store": "^1.2.0" + } + }, "synckit": { "version": "0.8.4", "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.4.tgz", @@ -5416,6 +10413,53 @@ "tslib": "^2.4.0" } }, + "tailwindcss": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.4.tgz", + "integrity": "sha512-AhwtHCKMtR71JgeYDaswmZXhPcW9iuI9Sp2LvZPo9upDZ7231ZJ7eA9RaURbhpXGVlrjX4cFNlB4ieTetEb7hQ==", + "requires": { + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "color-name": "^1.1.4", + "detective": "^5.2.1", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.2.12", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "lilconfig": "^2.0.6", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.18", + "postcss-import": "^14.1.0", + "postcss-js": "^4.0.0", + "postcss-load-config": "^3.1.4", + "postcss-nested": "6.0.0", + "postcss-selector-parser": "^6.0.10", + "postcss-value-parser": "^4.2.0", + "quick-lru": "^5.1.1", + "resolve": "^1.22.1" + }, + "dependencies": { + "object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==" + }, + "postcss": { + "version": "8.4.20", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.20.tgz", + "integrity": "sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==", + "requires": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + } + } + } + }, "tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -5435,6 +10479,16 @@ "globrex": "^0.1.2" } }, + "tiny-invariant": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", + "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==" + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" + }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -5443,10 +10497,10 @@ "is-number": "^7.0.0" } }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" + "toggle-selection": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", + "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" }, "tsconfig-paths": { "version": "3.14.1", @@ -5479,11 +10533,6 @@ } } }, - "type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" - }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -5497,14 +10546,6 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "requires": { - "is-typedarray": "^1.0.0" - } - }, "typescript": { "version": "4.9.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", @@ -5522,6 +10563,15 @@ "which-boxed-primitive": "^1.0.2" } }, + "update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -5530,55 +10580,44 @@ "punycode": "^2.1.0" } }, - "utf-8-validate": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", - "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", + "use-callback-ref": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.0.tgz", + "integrity": "sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==", "requires": { - "node-gyp-build": "^4.3.0" + "tslib": "^2.0.0" } }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" + "use-debounce": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/use-debounce/-/use-debounce-9.0.2.tgz", + "integrity": "sha512-QLyB0sxt9F5AisGDrUybCRJSLE60bTQR0yXc+IebNGUu1GCXwii1zsZl82mPGdWqDVQy7+1FKMLHQUixxf5Nbw==", + "requires": {} }, - "websocket": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz", - "integrity": "sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==", + "use-sidecar": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", + "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", "requires": { - "bufferutil": "^4.0.1", - "debug": "^2.2.0", - "es5-ext": "^0.10.50", - "typedarray-to-buffer": "^3.1.5", - "utf-8-validate": "^5.0.2", - "yaeti": "^0.0.6" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - } + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" } }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } + "use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "requires": {} + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, "which": { "version": "2.0.2", @@ -5610,16 +10649,21 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, - "yaeti": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", - "integrity": "sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==" + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" + }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/website/package.json b/website/package.json index 03af2bfa..bfec87c7 100644 --- a/website/package.json +++ b/website/package.json @@ -1,6 +1,6 @@ { "name": "website", - "homepage": "http://projects.laion.ai.github.io/Open-Chat-GPT", + "homepage": "http://projects.laion.ai.github.io/Open-Assistant", "version": "0.1.0", "private": true, "scripts": { @@ -10,14 +10,37 @@ "lint": "next lint" }, "dependencies": { - "@supabase/auth-helpers-nextjs": "^0.5.2", - "@supabase/auth-helpers-react": "^0.3.1", - "@supabase/auth-ui-react": "^0.2.6", - "@supabase/supabase-js": "^2.1.4", + "@chakra-ui/react": "^2.4.4", + "@emotion/react": "^11.10.5", + "@emotion/styled": "^11.10.5", + "@headlessui/react": "^1.7.7", + "@heroicons/react": "^2.0.13", + "@next-auth/prisma-adapter": "^1.0.5", + "@next/font": "^13.1.0", + "@prisma/client": "^4.7.1", + "@tailwindcss/forms": "^0.5.3", + "autoprefixer": "^10.4.13", + "axios": "^1.2.1", + "clsx": "^1.2.1", "eslint": "8.29.0", "eslint-config-next": "13.0.6", + "focus-visible": "^5.2.0", + "framer-motion": "^6.5.1", "next": "13.0.6", + "next-auth": "^4.18.6", + "nodemailer": "^6.8.0", + "postcss-focus-visible": "^7.1.0", "react": "18.2.0", - "react-dom": "18.2.0" + "react-dom": "18.2.0", + "react-icons": "^4.7.1", + "swr": "^2.0.0", + "tailwindcss": "^3.2.4", + "use-debounce": "^9.0.2" + }, + "devDependencies": { + "@types/node": "18.11.17", + "@types/react": "18.0.26", + "prettier": "2.8.1", + "prisma": "^4.7.1" } } diff --git a/website/pages/_app.js b/website/pages/_app.js deleted file mode 100644 index 0bf2e144..00000000 --- a/website/pages/_app.js +++ /dev/null @@ -1,20 +0,0 @@ -import { createBrowserSupabaseClient } from "@supabase/auth-helpers-nextjs"; -import { SessionContextProvider } from "@supabase/auth-helpers-react"; - -import { useState } from "react"; - -import "../styles/globals.css"; - -function MyApp({ Component, pageProps }) { - const [supabase] = useState(() => createBrowserSupabaseClient()); - return ( - - - - ); -} - -export default MyApp; diff --git a/website/pages/api/hello.js b/website/pages/api/hello.js deleted file mode 100644 index aee21e9a..00000000 --- a/website/pages/api/hello.js +++ /dev/null @@ -1,5 +0,0 @@ -// Next.js API route support: https://nextjs.org/docs/api-routes/introduction - -export default function handler(req, res) { - res.status(200).json({ name: "John Doe" }); -} diff --git a/website/pages/index.js b/website/pages/index.js deleted file mode 100644 index eb83ff6e..00000000 --- a/website/pages/index.js +++ /dev/null @@ -1,71 +0,0 @@ -import { Auth, ThemeSupa } from "@supabase/auth-ui-react"; -import { useSession, useSupabaseClient } from "@supabase/auth-helpers-react"; - -import { useState } from "react"; -import Head from "next/head"; -import Image from "next/image"; - -import styles from "../styles/Home.module.css"; - -export default function Home() { - const session = useSession(); - const supabase = useSupabaseClient(); - - const signinWithDiscord = async () => { - const { data, error } = await supabase.auth.signInWithOAuth({ - provider: "discord", - }); - }; - - if (!session) { - return ( -
-
- {/* logo */} -

Open Chat Gpt

-

- Open chat gpt is a project meant to give everyone access to a great - chat based large language model. -

- - -

- We believe that by doing this we will create a revolution in - innovation in language. In the same way that stable-diffusion helped - the world make art and images in new ways we hope open chat gpt can - help improve the world by improving language itself. -

- -

How can you help?

-

- All open source projects begins with people like you. Open source is - the belief that if we collaborate we can together gift our knowledge - and technology to the world for the benefit of humanity. -

- -

I am in! Now what?

-

We live and collaborate the work in the LAION discord. Join us!

- - Join us on Discord - -
-
- ); - } - return ( -
-
- {/* logo */} - -

Open Chat Gpt

- -

You are logged in

-
-
- ); -} diff --git a/website/postcss.config.js b/website/postcss.config.js new file mode 100644 index 00000000..12a703d9 --- /dev/null +++ b/website/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; diff --git a/website/prisma/migrations/20221215064332_initialized/migration.sql b/website/prisma/migrations/20221215064332_initialized/migration.sql new file mode 100644 index 00000000..7ae4196d --- /dev/null +++ b/website/prisma/migrations/20221215064332_initialized/migration.sql @@ -0,0 +1,66 @@ +-- CreateTable +CREATE TABLE "Account" ( + "id" TEXT NOT NULL, + "userId" TEXT NOT NULL, + "type" TEXT NOT NULL, + "provider" TEXT NOT NULL, + "providerAccountId" TEXT NOT NULL, + "refresh_token" TEXT, + "access_token" TEXT, + "expires_at" INTEGER, + "token_type" TEXT, + "scope" TEXT, + "id_token" TEXT, + "session_state" TEXT, + + CONSTRAINT "Account_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Session" ( + "id" TEXT NOT NULL, + "sessionToken" TEXT NOT NULL, + "userId" TEXT NOT NULL, + "expires" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "Session_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "User" ( + "id" TEXT NOT NULL, + "name" TEXT, + "email" TEXT, + "emailVerified" TIMESTAMP(3), + "image" TEXT, + + CONSTRAINT "User_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "VerificationToken" ( + "identifier" TEXT NOT NULL, + "token" TEXT NOT NULL, + "expires" TIMESTAMP(3) NOT NULL +); + +-- CreateIndex +CREATE UNIQUE INDEX "Account_provider_providerAccountId_key" ON "Account"("provider", "providerAccountId"); + +-- CreateIndex +CREATE UNIQUE INDEX "Session_sessionToken_key" ON "Session"("sessionToken"); + +-- CreateIndex +CREATE UNIQUE INDEX "User_email_key" ON "User"("email"); + +-- CreateIndex +CREATE UNIQUE INDEX "VerificationToken_token_key" ON "VerificationToken"("token"); + +-- CreateIndex +CREATE UNIQUE INDEX "VerificationToken_identifier_token_key" ON "VerificationToken"("identifier", "token"); + +-- AddForeignKey +ALTER TABLE "Account" ADD CONSTRAINT "Account_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Session" ADD CONSTRAINT "Session_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/website/prisma/migrations/20221215101838_record_labeler_id/migration.sql b/website/prisma/migrations/20221215101838_record_labeler_id/migration.sql new file mode 100644 index 00000000..acbdbf8d --- /dev/null +++ b/website/prisma/migrations/20221215101838_record_labeler_id/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "User" ADD COLUMN "labelerId" INTEGER; diff --git a/website/prisma/migrations/migration_lock.toml b/website/prisma/migrations/migration_lock.toml new file mode 100644 index 00000000..99e4f200 --- /dev/null +++ b/website/prisma/migrations/migration_lock.toml @@ -0,0 +1,3 @@ +# Please do not edit this file manually +# It should be added in your version-control system (i.e. Git) +provider = "postgresql" diff --git a/website/prisma/schema.prisma b/website/prisma/schema.prisma new file mode 100644 index 00000000..9a9678c9 --- /dev/null +++ b/website/prisma/schema.prisma @@ -0,0 +1,75 @@ +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} + +generator client { + provider = "prisma-client-js" +} + +model Account { + id String @id @default(cuid()) + userId String + type String + provider String + providerAccountId String + refresh_token String? @db.Text + access_token String? @db.Text + expires_at Int? + token_type String? + scope String? + id_token String? @db.Text + session_state String? + + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + + @@unique([provider, providerAccountId]) +} + +model Session { + id String @id @default(cuid()) + sessionToken String @unique + userId String + expires DateTime + user User @relation(fields: [userId], references: [id], onDelete: Cascade) +} + +model User { + id String @id @default(cuid()) + name String? + email String? @unique + emailVerified DateTime? + image String? + + accounts Account[] + sessions Session[] + + tasks RegisteredTask[] +} + +model VerificationToken { + identifier String + token String @unique + expires DateTime + + @@unique([identifier, token]) +} + +model RegisteredTask { + id String @id @default(uuid()) + task Json + + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + userId String + + interaction TaskInteraction[] +} + +model TaskInteraction { + id String @id @default(uuid()) + + content Json + + task RegisteredTask @relation(fields: [taskId], references: [id], onDelete: Cascade) + taskId String +} diff --git a/website/public/favicon.ico b/website/public/favicon.ico deleted file mode 100644 index 718d6fea..00000000 Binary files a/website/public/favicon.ico and /dev/null differ diff --git a/website/public/fonts/Inter-italic.var.woff2 b/website/public/fonts/Inter-italic.var.woff2 new file mode 100644 index 00000000..b826d5af Binary files /dev/null and b/website/public/fonts/Inter-italic.var.woff2 differ diff --git a/website/public/fonts/Inter-roman.var.woff2 b/website/public/fonts/Inter-roman.var.woff2 new file mode 100644 index 00000000..6a256a06 Binary files /dev/null and b/website/public/fonts/Inter-roman.var.woff2 differ diff --git a/website/public/fonts/lexend.txt b/website/public/fonts/lexend.txt new file mode 100644 index 00000000..ef5fbbc7 --- /dev/null +++ b/website/public/fonts/lexend.txt @@ -0,0 +1,93 @@ +Copyright 2018 The Lexend Project Authors (https://github.com/googlefonts/lexend), with Reserved Font Name “RevReading Lexend”. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +https://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/website/public/fonts/lexend.woff2 b/website/public/fonts/lexend.woff2 new file mode 100644 index 00000000..00384e46 Binary files /dev/null and b/website/public/fonts/lexend.woff2 differ diff --git a/website/public/images/logos/favicon.png b/website/public/images/logos/favicon.png new file mode 100644 index 00000000..9f21cbc9 Binary files /dev/null and b/website/public/images/logos/favicon.png differ diff --git a/website/public/images/logos/logo.png b/website/public/images/logos/logo.png new file mode 100644 index 00000000..34cdf878 Binary files /dev/null and b/website/public/images/logos/logo.png differ diff --git a/website/public/images/logos/logo.svg b/website/public/images/logos/logo.svg new file mode 100644 index 00000000..8cc9a708 --- /dev/null +++ b/website/public/images/logos/logo.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/website/public/images/logos/logo_mono.png b/website/public/images/logos/logo_mono.png new file mode 100644 index 00000000..2b7cd775 Binary files /dev/null and b/website/public/images/logos/logo_mono.png differ diff --git a/website/public/images/logos/logo_mono.svg b/website/public/images/logos/logo_mono.svg new file mode 100644 index 00000000..ef272256 --- /dev/null +++ b/website/public/images/logos/logo_mono.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/website/public/images/temp-avatars/av1.jpg b/website/public/images/temp-avatars/av1.jpg new file mode 100644 index 00000000..0c76c2b7 Binary files /dev/null and b/website/public/images/temp-avatars/av1.jpg differ diff --git a/website/public/images/temp-avatars/av2.jpg b/website/public/images/temp-avatars/av2.jpg new file mode 100644 index 00000000..9eb06f60 Binary files /dev/null and b/website/public/images/temp-avatars/av2.jpg differ diff --git a/website/public/images/temp-avatars/av3.jpg b/website/public/images/temp-avatars/av3.jpg new file mode 100644 index 00000000..402d485f Binary files /dev/null and b/website/public/images/temp-avatars/av3.jpg differ diff --git a/website/public/images/temp-avatars/av4.jpg b/website/public/images/temp-avatars/av4.jpg new file mode 100644 index 00000000..286997af Binary files /dev/null and b/website/public/images/temp-avatars/av4.jpg differ diff --git a/website/public/images/temp-avatars/av5.jpg b/website/public/images/temp-avatars/av5.jpg new file mode 100644 index 00000000..c017c767 Binary files /dev/null and b/website/public/images/temp-avatars/av5.jpg differ diff --git a/website/public/index.html b/website/public/index.html deleted file mode 100644 index bc6ba7d3..00000000 --- a/website/public/index.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - Open Chat GPT - - - -
- - - diff --git a/website/public/vercel.svg b/website/public/vercel.svg deleted file mode 100644 index 7daff190..00000000 --- a/website/public/vercel.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - diff --git a/website/src/.prettierignore b/website/src/.prettierignore new file mode 100644 index 00000000..e69de29b diff --git a/website/src/.prettierrc.json b/website/src/.prettierrc.json new file mode 100644 index 00000000..3665c446 --- /dev/null +++ b/website/src/.prettierrc.json @@ -0,0 +1,12 @@ +{ + "tabWidth": 2, + "printWidth": 120, + "overrides": [ + { + "files": "*.css", + "options": { + "tabWidth": 4 + } + } + ] +} diff --git a/website/src/App.js b/website/src/App.js deleted file mode 100644 index f6282e63..00000000 --- a/website/src/App.js +++ /dev/null @@ -1,43 +0,0 @@ -import logo from "./logo.svg"; -import "./App.css"; - -function App() { - return ( -
-
- {/* logo */} -

Open Chat Gpt

-

- Open chat gpt is a project meant to give everyone access to a great - chat based large language model. -

-

- We believe that by doing this we will create a revolution in - innovation in language. In the same way that stable-diffusion helped - the world make art and images in new ways we hope open chat gpt can - help improve the world by improving language itself. -

- -

How can you help?

-

- All open source projects begins with people like you. Open source is - the belief that if we collaborate we can together gift our knowledge - and technology to the world for the benefit of humanity. -

- -

I'm in! Now what?

-

We live and collaborate the work in the LAION discord. Join us!

- - Join us on Discord - -
-
- ); -} - -export default App; diff --git a/website/src/App.test.js b/website/src/App.test.js deleted file mode 100644 index 9382b9ad..00000000 --- a/website/src/App.test.js +++ /dev/null @@ -1,8 +0,0 @@ -import { render, screen } from "@testing-library/react"; -import App from "./App"; - -test("renders learn react link", () => { - render(); - const linkElement = screen.getByText(/learn react/i); - expect(linkElement).toBeInTheDocument(); -}); diff --git a/website/src/components/AuthLayout.tsx b/website/src/components/AuthLayout.tsx new file mode 100644 index 00000000..04110253 --- /dev/null +++ b/website/src/components/AuthLayout.tsx @@ -0,0 +1,17 @@ +import Link from "next/link"; +import Image from "next/image"; + +export function AuthLayout({ children }) { + return ( +
+
+ + Open Assistant Logo Open Assistant + +
+ {children} +
+
+
+ ); +} diff --git a/website/src/components/Avatar.tsx b/website/src/components/Avatar.tsx new file mode 100644 index 00000000..26bdec0b --- /dev/null +++ b/website/src/components/Avatar.tsx @@ -0,0 +1,96 @@ +import React from "react"; +import { signOut, useSession } from "next-auth/react"; +import Image from "next/image"; +import { Popover } from "@headlessui/react"; +import { AnimatePresence, motion } from "framer-motion"; +import { FaCog, FaSignOutAlt, FaGithub } from "react-icons/fa"; + +export function Avatar() { + const { data: session } = useSession(); + + if (!session) { + return <>; + } + if (session && session.user) { + const email = session.user.email; + const accountOptions = [ + { + name: "Account Settings", + href: "#", + desc: "Account Settings", + icon: FaCog, + //For future use + }, + ]; + return ( + + {({ open }) => ( + <> + +
+ Profile Picture +

{email}

+ {/* Will be changed to username once it is implemented */} +
+
+ + {open && ( + <> + +
+ {accountOptions.map((item) => ( + +
+
+
+

{item.name}

+
+
+ ))} + signOut()} + > +
+ +
+
+

Sign Out

+
+
+
+
+ + )} +
+ + )} +
+ ); + } +} + +export default Avatar; diff --git a/website/src/components/CallToAction.tsx b/website/src/components/CallToAction.tsx new file mode 100644 index 00000000..2fd91c79 --- /dev/null +++ b/website/src/components/CallToAction.tsx @@ -0,0 +1,63 @@ +import { CircleBackground } from "./CircleBackground"; +import { Container } from "./Container"; + +export function CallToAction() { + return ( +
+
+ +
+ +
+

Join Us

+

+ All open source projects begin with people like you. Open source is the belief that if we collaborate we can + together gift our knowledge and technology to the world for the benefit of humanity. Are you in? Find us + here: +

+ +
+
+
+ ); +} diff --git a/website/src/components/CircleBackground.tsx b/website/src/components/CircleBackground.tsx new file mode 100644 index 00000000..b5873c33 --- /dev/null +++ b/website/src/components/CircleBackground.tsx @@ -0,0 +1,22 @@ +import { useId } from "react"; + +export function CircleBackground({ color, width = 558, height = 558, ...props }) { + let id = useId(); + + return ( + + ); +} diff --git a/website/src/components/Container.tsx b/website/src/components/Container.tsx new file mode 100644 index 00000000..f65ed282 --- /dev/null +++ b/website/src/components/Container.tsx @@ -0,0 +1,5 @@ +import clsx from "clsx"; + +export function Container({ className, ...props }) { + return
; +} diff --git a/website/src/components/Faq.tsx b/website/src/components/Faq.tsx new file mode 100644 index 00000000..d7c2eae9 --- /dev/null +++ b/website/src/components/Faq.tsx @@ -0,0 +1,68 @@ +import Link from "next/link"; + +import { Container } from "./Container"; + +const faqs = [ + [ + { + question: "How far along is this project?", + answer: + "We are in the early stages of development, working from established research in applying RLHF to large language models.", + }, + ], + [ + { + question: "Who is behind Open Assistant?", + answer: + "Open Assistant is a project organized by LAION and individuals around the world interested in bringing this technology to everyone.", + }, + ], + [ + // { + // question: 'Where can I learn more?', + // answer: + // 'Please feel free to reach out to us on Discord. We are happy to answer any questions you may have.', + // }, + ], +]; + +export function Faq() { + return ( +
+ +
+

+ Frequently Asked Questions +

+ {/*

+ If you have anything else you want to ask,{' '} + + reach out to us + + . +

*/} +
+
    + {faqs.map((column, columnIndex) => ( +
  • +
      + {column.map((faq, faqIndex) => ( +
    • +

      {faq.question}

      +

      {faq.answer}

      +
    • + ))} +
    +
  • + ))} +
+
+
+ ); +} diff --git a/website/src/components/Fields.tsx b/website/src/components/Fields.tsx new file mode 100644 index 00000000..2233318e --- /dev/null +++ b/website/src/components/Fields.tsx @@ -0,0 +1,30 @@ +import clsx from "clsx"; + +const formClasses = + "block w-full appearance-none rounded-lg border border-gray-200 bg-white py-[calc(theme(spacing.2)-1px)] px-[calc(theme(spacing.3)-1px)] text-gray-900 placeholder:text-gray-400 focus:border-cyan-500 focus:outline-none focus:ring-cyan-500 sm:text-sm"; + +function Label({ id, children }) { + return ( + + ); +} + +export function TextField({ id, label, type = "text", className, ...props }) { + return ( +
+ {label && } + +
+ ); +} + +export function SelectField({ id, label, className, ...props }) { + return ( +
+ {label && } + + + {option} + + + ); +}; + +const RatingRadioGroup = (props) => { + const { min, max, onChange, ...rest } = props; + const { value, getRadioProps, getRootProps } = useRadioGroup({ + defaultValue: min, + onChange: onChange, + }); + const options = Array.from(new Array(1 + max - min), (x, i) => i + min); + + return ( + + {options.map((option) => ( + + ))} + + ); +}; + +export default RatingRadioGroup; diff --git a/website/src/index.css b/website/src/index.css deleted file mode 100644 index 4a1df4db..00000000 --- a/website/src/index.css +++ /dev/null @@ -1,13 +0,0 @@ -body { - margin: 0; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", - "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", - sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -code { - font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", - monospace; -} diff --git a/website/src/index.js b/website/src/index.js deleted file mode 100644 index 770ee7d6..00000000 --- a/website/src/index.js +++ /dev/null @@ -1,17 +0,0 @@ -import React from "react"; -import ReactDOM from "react-dom/client"; -import "./index.css"; -import App from "./App"; -import reportWebVitals from "./reportWebVitals"; - -const root = ReactDOM.createRoot(document.getElementById("root")); -root.render( - - - -); - -// If you want to start measuring performance in your app, pass a function -// to log results (for example: reportWebVitals(console.log)) -// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals -reportWebVitals(); diff --git a/website/src/lib/fetcher.ts b/website/src/lib/fetcher.ts new file mode 100644 index 00000000..3daa92a1 --- /dev/null +++ b/website/src/lib/fetcher.ts @@ -0,0 +1,8 @@ +import axios from "axios"; + +/** + * A minimal Axios based fetcher. + */ +const fetcher = (url) => axios.get(url).then((res) => res.data); + +export default fetcher; diff --git a/website/src/lib/poster.ts b/website/src/lib/poster.ts new file mode 100644 index 00000000..9d961806 --- /dev/null +++ b/website/src/lib/poster.ts @@ -0,0 +1,8 @@ +const poster = (url, { arg }) => { + return fetch(url, { + method: "POST", + body: JSON.stringify(arg), + }); +}; + +export default poster; diff --git a/website/src/lib/prismadb.ts b/website/src/lib/prismadb.ts new file mode 100644 index 00000000..32fb23d0 --- /dev/null +++ b/website/src/lib/prismadb.ts @@ -0,0 +1,12 @@ +import { PrismaClient } from "@prisma/client"; + +declare global { + var prisma; +} + +const client = globalThis.prisma || new PrismaClient(); +if (process.env.NODE_ENV !== "production") { + globalThis.prisma = client; +} + +export default client; diff --git a/website/src/middleware.ts b/website/src/middleware.ts new file mode 100644 index 00000000..b383586b --- /dev/null +++ b/website/src/middleware.ts @@ -0,0 +1,8 @@ +export { default } from "next-auth/middleware"; + +/** + * Guards all pages under `/grading` and redirects them to the sign in page. + */ +export const config = { + matcher: ["/grading/:path*"], +}; diff --git a/website/src/pages/404.tsx b/website/src/pages/404.tsx new file mode 100644 index 00000000..7af22569 --- /dev/null +++ b/website/src/pages/404.tsx @@ -0,0 +1,45 @@ +import { useSession } from "next-auth/react"; +import { Footer } from "../components/Footer"; +import { Header } from "../components/Header"; +import Head from "next/head"; +import Link from "next/link"; + +export default function Error() { + const { data: session } = useSession(); + + if (!session) { + return ( + <> + + Open Assistant + + +
+
+ {"Sorry, the page you're looking for doesn't exist."} +
+