diff --git a/aibi-embedding/README.md b/aibi-embedding/README.md new file mode 100644 index 0000000..98b7b91 --- /dev/null +++ b/aibi-embedding/README.md @@ -0,0 +1,106 @@ +# Embedded Analytics with Databricks AI/BI + +## :bulb: Demo Overview + +This demo showcases how to embed Databricks AI/BI Dashboards and Genie into your application, providing users with real-time insights without leaving your platform. + +For this demo, let's imagine a fictional company called Brickstore, where brick suppliers sell bricks to customers on the Brickstore web platform. Brickstore embeds AI/BI dashboards and Genie into their platform, allowing users to analyze sales data without having to leave to another site! + +:no_good: Disclaimer: Please read the following before proceeding. +1. This demo uses Databricks Apps for simplicity but can be deployed on any modern web server. +2. This application is for demonstration purposes only; consider adding security measures and error handling for production use. +3. This repo is not meant to be a "click-and-deploy" solution. Instead, use the code in this repo as reference as you build your own embedded analytics application. + +## :star2: AI/BI Embedding + +AI/BI features two complementary capabilities: Dashboards and Genie. Dashboards provide a low-code experience to help analysts quickly build highly interactive data visualizations for their business teams using natural language, and Genie allows business users to converse with their data to ask questions and self-serve their own analytics. Both of these capabilites can be embedded into external applications. + +### 1. Dashboard Embedding + +![Example](images/dashboard_embedding_example.png) +With dashboard embedding, you are able to seamlessly embed a dashboard into your application as you can see in the example above. There are two different ways you can embed dashbaords with AI/BI. + +**Option 1: iframe embedding (a.k.a Copy Embed Code)** + +- Generally Available! +- This is the simplest way to embed an AI/BI dashboard (see [here](https://docs.databricks.com/en/dashboards/embed.html#embed-a-dashboard) for instructions). +- Best-suited for internal use cases + - Users are already Databricks users in your account + - Low-code/No-code approach, but comes with limitations (ex: users need to sign-in to Databricks to see dashboard) +- Not showcased in this demo + +**Option 2: Token-Based Embedding (a.k.a App-Delegated Authentication Embedding)** + +- Private Preview as of March 2025 (reach out to your Databricks Account Team) +- Best-suited for external use cases + - Users are not Databricks users in your account (i.e. your end-customers) + - More complex, requires backend and frontend implementation via code + - Allows passing parameters for Row-Level Security (RLS). +- For sample code, refer to: + - **app.py** + - backend/**dashboard_embedding.py** + - frontend/src/pages/**Analytics.js** + +#### Dashboard Embedding Architecture Diagram +![Architecture](images/dashboard_embedding_architecture.gif) + +### 2. Genie Embedding +![Example](images/genie_embedding_example.png) +Before Genie Conversational APIs became available, you could only interact with Genie through the Databricks UI. Now, you are able to use Genie Conversational APIs to build your own version of Genie in your own application as you can see above. + +**Genie Conversational APIs** + +- Public Preview as of March 2025 +- Surfaces AI/BI Genie through a REST endpoint +- For sample code, refer to: + - **app.py** + - backend/**genie_embedding.py** + - frontend/src/pages/**Genie.js** + - frontend/src/components/**ChatMessage.js** + +#### API Flow +![Architecture](images/genie_api_flow.gif) + +#### Genie Embedding Architecture Diagram +![Architecture](images/genie_api_architecture.gif) + +## :rocket: Learn More + +- AI/BI + - [Databricks AI/BI Product Page](https://www.databricks.com/product/ai-bi) +- Dashboard Embedding + - [iframe Embedding Documentation](https://docs.databricks.com/aws/en/dashboards/embed) + +- Genie Conversational APIs + - [Genie API Documentation](https://docs.databricks.com/api/workspace/genie) + - [Genie API Blog](https://www.databricks.com/blog/genie-conversation-apis-public-preview) + + +## :closed_lock_with_key: License + +© 2025 Databricks, Inc. All rights reserved. The source in this project is provided subject to the Databricks License [https://databricks.com/db-license-source]. All included or referenced third party libraries are subject to the licenses set forth below. + +| library | description | license | source | +|----------------------------------------|-------------------------|------------|-----------------------------------------------------| +| **Flask** | Lightweight WSGI web application framework | BSD 3-Clause | https://github.com/pallets/flask | +| **Flask-SQLAlchemy** | Extension for Flask that adds support for SQLAlchemy | MIT | https://github.com/pallets/flask-sqlalchemy | +| **requests** | Library for making HTTP requests | Apache 2.0 | https://github.com/psf/requests | +| **pandas** | Library for data manipulation and analysis | BSD 3-Clause | https://github.com/pandas-dev/pandas | +| **Flask-JWT-Extended** | Extension for handling JSON Web Tokens in Flask | MIT | https://github.com/vimalloc/flask-jwt-extended | +| **Flask-CORS** | Extension for handling Cross-Origin Resource Sharing in Flask | MIT | https://github.com/corydolphin/flask-cors | +| **python-dotenv** | Library for loading environment variables from .env files | MIT | https://github.com/theskumar/python-dotenv | +| **axios** | Promise based HTTP client for the browser and node.js | MIT | https://github.com/axios/axios | +| **@emotion/react** | Library for building robust, customizable, and performant UI components with React | MIT | https://github.com/emotion-js/emotion | +| **@emotion/styled** | Library for building robust, customizable, and performant UI components with React | MIT | https://github.com/emotion-js/emotion | +| **@fontsource/roboto** | Font package for Roboto | Apache-2.0 | https://github.com/fontsource/fontsource | +| **@mui/icons-material** | Material Design icons for React | MIT | https://github.com/mui-org/material-ui | +| **@mui/material** | Material Design components for React | MIT | https://github.com/mui-org/material-ui | +| **react** | JavaScript library for building user interfaces | MIT | https://github.com/facebook/react | +| **react-dom** | React package for working with the DOM | MIT | https://github.com/facebook/react | +| **react-router-dom** | DOM bindings for React Router | MIT | https://github.com/remix-run/react-router | +| **react-scripts** | Scripts and configuration used by Create React App | MIT | https://github.com/facebook/create-react-app | +| **cra-template** | Template for Create React App | MIT | https://github.com/facebook/create-react-app | +| **@databricks/aibi-client** | Databricks AI & BI Client | MIT | https://github.com/databricks/aibi-client | +--- + +Databricks support doesn't cover this content. For questions or bugs, please open a github issue and the team will help on a best effort basis. diff --git a/aibi-embedding/app.py b/aibi-embedding/app.py new file mode 100644 index 0000000..e1f4df2 --- /dev/null +++ b/aibi-embedding/app.py @@ -0,0 +1,128 @@ +import pandas as pd +from flask import Flask, jsonify, send_from_directory, session, request, redirect, url_for +from flask_jwt_extended import JWTManager, create_access_token, jwt_required, get_jwt_identity, get_jwt +from flask_sqlalchemy import SQLAlchemy +from flask_cors import CORS +import logging +import secrets +from backend.models import db, User +from backend.dashboard_embedding import get_dashboard_embedding_oauth_token +from backend.genie_embedding import get_databricks_oauth_token, get_genie_space_id, new_genie_conversation, continue_genie_conversation +from dotenv import load_dotenv +import os + +log = logging.getLogger('werkzeug') +log.setLevel(logging.ERROR) + +app = Flask(__name__, static_folder='frontend/build', static_url_path='/') +CORS(app, resources={r"/api/*": {"origins": ["https://aibi-embedding-demo-984752964297111.11.azure.databricksapps.com", "http://localhost:3000"]}}) + +# Configuration +app.config['SECRET_KEY'] = secrets.token_hex(32) +app.config["JWT_SECRET_KEY"] = secrets.token_hex(32) +app.config['JWT_TOKEN_LOCATION'] = ['headers'] + +# Dummy Database for storing user information +app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db.sqlite' + +# JWT Initialization +jwt = JWTManager(app) + +# Pull Environment Variables +load_dotenv() +databricks_host = os.environ['DATABRICKS_HOST'] +databricks_client_id = os.environ['DATABRICKS_CLIENT_ID'] +databricks_client_secret = os.environ['DATABRICKS_CLIENT_SECRET'] + +db.init_app(app) +with app.app_context(): + db.create_all() + +@app.route('/') +@app.route('/login') +@app.route('/home') +@app.route('/genie') +@app.route('/analytics') +def serve(): + return send_from_directory(app.static_folder, 'index.html') + +# This is the endpoint the front-end will hit to verify login information +@app.route('/api/login', methods=['POST']) +def login(): + data = request.get_json() + email = data['email'] + password = data['password'] + print('Received data:', email , password) + + user = User.query.filter_by(email=email).first() + + if user and user.password==password: + access_token = create_access_token(identity=user.id) + databricks_token = get_databricks_oauth_token() + return jsonify({'message': 'Login Success', 'databricks_token':databricks_token,'first_name': user.first_name, 'last_name': user.last_name,'email': email, 'access_token': access_token,'company': user.company}) + else: + return jsonify({'message': 'Login Failed'}), 401 + +@app.route('/api/data', methods=['GET']) +def get_data(): + return jsonify({"message": "Hello from Flask!"}) + + +@app.route('/api/dashboard/config', methods=['POST']) +def dashboard_config(): + return jsonify({ + "instance_url": "https://" + os.environ['DATABRICKS_HOST'], + "workspace_id": os.environ['DATABRICKS_WORKSPACE_ID'], + "dashboard_id": os.environ['DATABRICKS_DASHBOARD_ID'] + }) + +# This is the endpoint the front-end will hit to embed the dashboard +@app.route('/api/dashboard/get_token', methods=['POST']) +def dashboard_get_token(): + # Unwrap the payload sent from the front-end. This includes the user's question as well as additional information about the user + data = request.get_json() + + # Inputs sent from the front-end + external_data = data['external_data'] + external_viewer_id = data['external_viewer_id'] + dashboard_name = data['dashboard_name'] + + # Call the continue_genie_conversation from 'backend/dashboard_embedding.py' + response = get_dashboard_embedding_oauth_token(external_data = external_data, external_viewer_id = external_viewer_id, dashboard_name = dashboard_name) + return response + +# This is the endpoint the front-end will hit to start a new conversation +@app.route('/api/genie/start_conversation', methods=['POST']) +def genie_start_conversation(): + # Unwrap the payload sent from the front-end. This includes the user's question as well as additional information about the user + data = request.get_json() + + # Inputs sent from the front-end + initial_message = data['question'] + databricks_token = data['databricks_token'] + user_company = data['user_company'] + databricks_genie_space_id = get_genie_space_id(user_company) + + # Call the new_genie_conversation from 'backend/genie_embedding.py' + response = new_genie_conversation(space_id = databricks_genie_space_id, content=initial_message, token = databricks_token, databricks_host = databricks_host) + return response + +# This is the endpoint the front-end will hit to continue an existing conversation +@app.route('/api/genie/continue_conversation', methods=['POST']) +def genie_continue_conversation(): + # Unwrap the payload sent from the front-end. This includes the user's question as well as additional information about the user + data = request.get_json() + + # Inputs sent from the front-end + followup_message = data['question'] + conversation_id = data['conversation_id'] + databricks_token = data['databricks_token'] + user_company = data['user_company'] + databricks_genie_space_id = get_genie_space_id(user_company) + + # Call the continue_genie_conversation from 'backend/genie_embedding.py' + response = continue_genie_conversation(space_id = databricks_genie_space_id, content=followup_message, conversation_id = conversation_id, token = databricks_token, databricks_host = databricks_host) + return response + +if __name__ == '__main__': + app.run(debug=True) diff --git a/aibi-embedding/app.yaml b/aibi-embedding/app.yaml new file mode 100644 index 0000000..bcc4902 --- /dev/null +++ b/aibi-embedding/app.yaml @@ -0,0 +1,12 @@ +command: + - gunicorn + - app:app + - -w + - 4 +env: + - name: DATABRICKS_GENIE_SPACE_ID_APEX + value: '' + - name: DATABRICKS_GENIE_SPACE_ID_SYNERGY + value: '' + - name: DATABRICKS_DASHBOARD_ID + value: '' \ No newline at end of file diff --git a/aibi-embedding/backend/dashboard_embedding.py b/aibi-embedding/backend/dashboard_embedding.py new file mode 100644 index 0000000..e61fd76 --- /dev/null +++ b/aibi-embedding/backend/dashboard_embedding.py @@ -0,0 +1,41 @@ +import os +import requests +from dotenv import load_dotenv + +# Function to retrieve minted OAuth Token from Databricks server +def get_dashboard_embedding_oauth_token(external_data, external_viewer_id, dashboard_name): + # Pull Environment Variables from .env file + load_dotenv() + + databricks_host = os.environ['DATABRICKS_HOST'] + databricks_client_id = os.environ['DATABRICKS_CLIENT_ID'] + databricks_client_secret = os.environ['DATABRICKS_CLIENT_SECRET'] + if dashboard_name == "defects": + dashboard_id = os.environ['DATABRICKS_DASHBOARD_ID'] + + # These are additional parameters when making the OAuth request + # 1. The Oauth Scope limits the amount of access granted to an access token, ensuring scoped access + # 2. The Custom Claim will be used to filter data in the SQL statement for Row-Level Security + oauth_scopes = "dashboards.query-execution dashboards.lakeview-embedded:read sql.redash-config:read settings:read" + custom_claim = f'urn:aibi:external_data:{external_data}:{external_viewer_id}:{dashboard_id}' + + # Make M2M OAuth Request to Databricks server to get a Databricks Access Token + token_url = f"https://{databricks_host}/oidc/v1/token" + + payload = { + "grant_type": "client_credentials", + "client_id": databricks_client_id, + "client_secret": databricks_client_secret, + "scope": oauth_scopes, + "custom_claim": custom_claim + } + + response = requests.post(token_url, data=payload) + + # No need to worry about token expiration, since the dashboard embedding library will automatically reissue expired tokens + token_data = response.json() + + # Store the access token and its expiration time + access_token = token_data["access_token"] + + return access_token diff --git a/aibi-embedding/backend/genie_embedding.py b/aibi-embedding/backend/genie_embedding.py new file mode 100644 index 0000000..7d9fd97 --- /dev/null +++ b/aibi-embedding/backend/genie_embedding.py @@ -0,0 +1,289 @@ +import requests +import json +import time +import pandas as pd +from dotenv import load_dotenv +import os + + +# Function for retrieving a Databricks token which will be used to make API calls to Databricks +def get_databricks_oauth_token(): + # Pull Environment Variables from .env file + load_dotenv() + databricks_host = os.environ['DATABRICKS_HOST'] + databricks_client_id = os.environ['DATABRICKS_CLIENT_ID'] + databricks_client_secret = os.environ['DATABRICKS_CLIENT_SECRET'] + + # Make M2M OAuth Request to Databricks server to get a Databricks Access Token + token_url = f"https://{databricks_host}/oidc/v1/token" + + payload = { + "grant_type": "client_credentials", + "client_id": databricks_client_id, + "client_secret": databricks_client_secret, + "scope": "all-apis" + } + + response = requests.post(token_url, data=payload) + token_data = response.json() + + # Store the access token and its expiration time + access_token = token_data["access_token"] + expires_in = token_data['expires_in'] + expiration_time = time.time() + expires_in + + if response.status_code == 200: + return {'access_token':access_token, 'expiration_time':expiration_time} + else: + raise Exception(f"Failed to get token: {response.status_code}, {response.text}") + +# Function for checking Databricks token for expiry, and renews if necessary +def is_token_valid(token): + current_time = time.time() # Get the current time in Unix timestamp format + # If the token is not expired, return the same token + if current_time < token['expiration_time']: + return token + # If the token expired, request a new access token + else: + return get_databricks_oauth_token() + +# In this example, we have one Genie Space for each customer. +# This function checks the user's company and determines which Genie Space ID to retrieve from the environment varible. +# In production, you could use a database to store this mapping +def get_genie_space_id(user_company): + if user_company.lower() == 'apex': + return os.environ['DATABRICKS_GENIE_SPACE_ID_APEX'] + elif user_company.lower() == 'synergy': + return os.environ['DATABRICKS_GENIE_SPACE_ID_SYNERGY'] + else: + raise Exception(f"Failed to get genie space for: {user_company}") + +# Function for starting a new conversation with Genie +def new_genie_conversation(space_id, content, token, databricks_host): + # First, we check that the access token is valid + token = is_token_valid(token) + + # Then, we make an API request to the Genie space + url = f"https://{databricks_host}/api/2.0/genie/spaces/{space_id}/start-conversation" + + headers = { + "Authorization": f"Bearer {token['access_token']}", + "Content-Type": "application/json" + } + + payload = { + "content": content + } + + response = requests.post(url, headers=headers, data=json.dumps(payload)) + + # Finally, we check the response to see if the API call was succesful + # This request may fail if you don't have the right permissions, or if you don't have the right resources provisioned + if response.status_code == 200: + # If the request was successful, we call another function to now retrieve Genie's response to our question + return get_genie_message(space_id, response.json()['conversation_id'], response.json()['message_id'], token, databricks_host) + else: + raise Exception(f"API request failed at start_conversation: {response.status_code}, {response.text}") + +# Function for retrieving Genie's response to the message we sent +def get_genie_message(space_id, conversation_id, message_id, token, databricks_host): + # First, we check that the access token is valid + token = is_token_valid(token) + + # Then, we make an API request to the Genie space + url = f"https://{databricks_host}/api/2.0/genie/spaces/{space_id}/conversations/{conversation_id}/messages/{message_id}" + + headers = { + "Authorization": f"Bearer {token['access_token']}" + } + + response = requests.get(url, headers=headers) + + # Finally, we check the response to see if the API call was succesful + if response.status_code == 200: + # After verifying that the request was succesful, we need to keep polling the endpoint until Genie finishes generating its response + while True: + response = requests.get(url, headers=headers).json() + state = response['status'] + + # In this stage, Genie finished generating a response and we can now check the content that Genie generated + if state == 'COMPLETED': + print(f"Generation complete.") + # If the response only contains text, retrieve the text (In some cases, Genie's response will also contain data) + if 'text' in response['attachments'][0]: + return {'message_id': message_id, + 'conversation_id': conversation_id, + 'attachment_id': response['attachments'][0]['attachment_id'], + 'content':response['attachments'][0]['text']['content']} + # If the response also contains a query, we need to call another API endpoint to retrieve the query results + elif 'query' in response['attachments'][0]: + attachment_id = response['attachments'][0]['attachment_id'] + #query_result = get_genie_message_query_result(space_id, conversation_id, message_id, token, databricks_host) + query_result = get_genie_message_query_result_updated(space_id, conversation_id, message_id, attachment_id, token, databricks_host) + return {'message_id':message_id, + 'conversation_id':conversation_id, + 'attachment_id': response['attachments'][0]['attachment_id'], + 'description':response['attachments'][0]['query']['description'], + 'query_result':query_result} + # In this stage, Genie is still generating a response + elif state in ["SUBMITTED",'FILTERING_CONTEXT','FETCHING_METADATA','ASKING_AI','PENDING_WAREHOUSE']: + print(f"Generation in progress: {state}") + time.sleep(3) + # In this stage, the SQL query is still executing + elif state == 'EXECUTING_QUERY': + print(f"Query execution in progress: {state}") + time.sleep(3) + # In this stage, the generation failed + elif state == 'FAILED': + raise Exception(f"API request failed: {response['error']}") + else: + print(f"No query result: {state}") + return None + else: + raise Exception(f"API request failed at get_message: {response.status_code}, {response.text}") + +# Function for retrieving the query result for the SQL query that Genie executed +def get_genie_message_query_result(space_id, conversation_id, message_id, token, databricks_host): + token = is_token_valid(token) + # Construct the URL + url = f"https://{databricks_host}/api/2.0/genie/spaces/{space_id}/conversations/{conversation_id}/messages/{message_id}/query-result" + + # Set up the headers + headers = { + "Authorization": f"Bearer {token['access_token']}" + } + + # Make the GET request + response = requests.get(url, headers=headers) + + if response.status_code == 200: + while True: + response = requests.get(url, headers=headers).json()['statement_response'] + state = response['status']['state'] + if state == 'SUCCEEDED': + data = response.get('result', {}) + meta = response['manifest'] + print("Successfully retrieved query result.") + + columns = [c['name'] for c in meta['schema']['columns']] + + if data and 'data_typed_array' in data: + # Check if the values in data_typed_array are not empty + if any(value for row in data['data_typed_array'] for value in row['values']): + rows = [[c.get('str', '') for c in r['values']] for r in data['data_typed_array']] + df = pd.DataFrame(rows, columns=columns) + + # Handle duplicate column names + if df.columns.duplicated().any(): + df.columns = [ + f"{col}_{i}" if is_duplicate else col + for i, (col, is_duplicate) in enumerate(zip(df.columns, df.columns.duplicated()), 1) + ] + + else: + df = pd.DataFrame() + else: + df = pd.DataFrame() + + return df.to_json(orient='records') + elif state == 'RUNNING' or state == 'PENDING': + print(f"Waiting for query result...") + time.sleep(5) + else: + print(f"No query result: {response['state']}") + return None + else: + raise Exception(f"API request failed at get_query_results: {response.status_code}, {response.text}") + +# Function for retrieving the query result for the SQL query that Genie executed +def get_genie_message_query_result_updated(space_id, conversation_id, message_id, attachment_id, token, databricks_host): + # First, we check that the access token is valid + token = is_token_valid(token) + + # Then, we make an API request to the Genie space + url = f"https://{databricks_host}/api/2.0//genie/spaces/{space_id}/conversations/{conversation_id}/messages/{message_id}/query-result/{attachment_id}" + + headers = { + "Authorization": f"Bearer {token['access_token']}" + } + + response = requests.get(url, headers=headers) + print(response.json()) # DELETE LATER + + # Finally, we check the response to see if the API call was succesful + if response.status_code == 200: + while True: + # The payload is wrapped inside a "statement_response" key, so we are going to unwrap it and store in as a response. + #response = requests.get(url, headers=headers).json()['statement_response'] + try: + response = requests.get(url, headers=headers).json()['statement_response'] + except: + response = requests.get(url, headers=headers).json() + + # We also extract the status of the SQL query execution + state = response['status']['state'] + # In this stage, the SQL Query finished running. We now package the data into a pandas dataframe and return it to the front-end. + if state == 'SUCCEEDED': + # "Results" stores the actual data. + # Sometimes, when there is no data available, this response is empty. + data = response.get('result', {}) + rows = data.get('data_array',[]) + + # "Meta" stores metadata about the query results, including the column names. + meta = response['manifest'] + columns = [column['name'] for column in meta['schema']['columns']] + + # Sanity Check + print("Successfully retrieved query result.") + + # If empty rows are returned, create a dataframe with "No Data Available" + if rows == []: + df = pd.DataFrame([{"Message": "No data available"}]) + else: + # Package data into a Pandas Dataframe. + df = pd.DataFrame(rows, columns=columns) + + # Some joins may result in duplicate columns, which Pandas doesn't like. Handle duplicate column names here. + if df.columns.duplicated().any(): + df.columns = [ + f"{col}_{i}" if is_duplicate else col + for i, (col, is_duplicate) in enumerate(zip(df.columns, df.columns.duplicated()), 1) + ] + + return df.to_json(orient='records') + # In this stage, the query is still executing so we retry after 5 seconds. We could also implement incremental back-off here. + elif state == 'RUNNING' or state == 'PENDING': + print(f"Waiting for query result...") + time.sleep(5) + # Otherwise, raise an error + else: + print(f"Error getting Query Result: {response['state']}") + return None + else: + raise Exception(f"API request failed at get_query_results: {response.status_code}, {response.text}") + +# Function for asking a followup question to an existing conversation +def continue_genie_conversation(space_id, content, conversation_id, token, databricks_host): + # First, we check that the access token is valid + token = is_token_valid(token) + + # Then, we make an API request to the Genie space + url = f"https://{databricks_host}/api/2.0/genie/spaces/{space_id}/conversations/{conversation_id}/messages" + + headers = { + "Authorization": f"Bearer {token['access_token']}", + "Content-Type": "application/json" + } + + payload = { + "content": content + } + + response = requests.post(url, headers=headers, data=json.dumps(payload)) + + # Finally, we check the response to see if the API call was succesful + if response.status_code == 200: + # If the request was successful, we call another function to now retrieve Genie's response to our question + return get_genie_message(space_id, conversation_id, response.json()['message_id'], token, databricks_host) + else: + raise Exception(f"API request failed at create_message: {response.status_code}, {response.text}") \ No newline at end of file diff --git a/aibi-embedding/backend/models.py b/aibi-embedding/backend/models.py new file mode 100644 index 0000000..d634a15 --- /dev/null +++ b/aibi-embedding/backend/models.py @@ -0,0 +1,16 @@ +from flask_sqlalchemy import SQLAlchemy + +db = SQLAlchemy() + +# Database for storing user credentials (DEMO PURPOSES ONLY! DO NOT USE THIS AS YOUR PRODUCTION DATABASE) +class User(db.Model): + id = db.Column(db.Integer, primary_key=True) + email = db.Column(db.String(20), unique=True, nullable=False) + password = db.Column(db.String(80), nullable=False) + company = db.Column(db.String(20), nullable=False) + first_name = db.Column(db.String(50)) + last_name = db.Column(db.String(50)) + + + def __repr__(self): + return f'' \ No newline at end of file diff --git a/aibi-embedding/frontend/README.md b/aibi-embedding/frontend/README.md new file mode 100644 index 0000000..58beeac --- /dev/null +++ b/aibi-embedding/frontend/README.md @@ -0,0 +1,70 @@ +# Getting Started with Create React App + +This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). + +## Available Scripts + +In the project directory, you can run: + +### `npm start` + +Runs the app in the development mode.\ +Open [http://localhost:3000](http://localhost:3000) to view it in your browser. + +The page will reload when you make changes.\ +You may also see any lint errors in the console. + +### `npm test` + +Launches the test runner in the interactive watch mode.\ +See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. + +### `npm run build` + +Builds the app for production to the `build` folder.\ +It correctly bundles React in production mode and optimizes the build for the best performance. + +The build is minified and the filenames include the hashes.\ +Your app is ready to be deployed! + +See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. + +### `npm run eject` + +**Note: this is a one-way operation. Once you `eject`, you can't go back!** + +If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. + +Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own. + +You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it. + +## Learn More + +You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). + +To learn React, check out the [React documentation](https://reactjs.org/). + +### Code Splitting + +This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting) + +### Analyzing the Bundle Size + +This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size) + +### Making a Progressive Web App + +This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app) + +### Advanced Configuration + +This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration) + +### Deployment + +This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment) + +### `npm run build` fails to minify + +This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify) diff --git a/aibi-embedding/frontend/build/asset-manifest.json b/aibi-embedding/frontend/build/asset-manifest.json new file mode 100644 index 0000000..4ae1339 --- /dev/null +++ b/aibi-embedding/frontend/build/asset-manifest.json @@ -0,0 +1,14 @@ +{ + "files": { + "main.css": "/static/css/main.e6c13ad2.css", + "main.js": "/static/js/main.83526e3f.js", + "static/media/BrickstoreLogo.png": "/static/media/BrickstoreLogo.d77eb785de2a002326f9.png", + "index.html": "/index.html", + "main.e6c13ad2.css.map": "/static/css/main.e6c13ad2.css.map", + "main.83526e3f.js.map": "/static/js/main.83526e3f.js.map" + }, + "entrypoints": [ + "static/css/main.e6c13ad2.css", + "static/js/main.83526e3f.js" + ] +} \ No newline at end of file diff --git a/aibi-embedding/frontend/build/favicon.ico b/aibi-embedding/frontend/build/favicon.ico new file mode 100644 index 0000000..ce0c915 Binary files /dev/null and b/aibi-embedding/frontend/build/favicon.ico differ diff --git a/aibi-embedding/frontend/build/index.html b/aibi-embedding/frontend/build/index.html new file mode 100644 index 0000000..672d032 --- /dev/null +++ b/aibi-embedding/frontend/build/index.html @@ -0,0 +1 @@ +Brickstore
\ No newline at end of file diff --git a/aibi-embedding/frontend/build/logo.svg b/aibi-embedding/frontend/build/logo.svg new file mode 100644 index 0000000..9dfc1c0 --- /dev/null +++ b/aibi-embedding/frontend/build/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/aibi-embedding/frontend/build/logo192.png b/aibi-embedding/frontend/build/logo192.png new file mode 100644 index 0000000..fc44b0a Binary files /dev/null and b/aibi-embedding/frontend/build/logo192.png differ diff --git a/aibi-embedding/frontend/build/logo512.png b/aibi-embedding/frontend/build/logo512.png new file mode 100644 index 0000000..a4e47a6 Binary files /dev/null and b/aibi-embedding/frontend/build/logo512.png differ diff --git a/aibi-embedding/frontend/build/manifest.json b/aibi-embedding/frontend/build/manifest.json new file mode 100644 index 0000000..080d6c7 --- /dev/null +++ b/aibi-embedding/frontend/build/manifest.json @@ -0,0 +1,25 @@ +{ + "short_name": "React App", + "name": "Create React App Sample", + "icons": [ + { + "src": "favicon.ico", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/x-icon" + }, + { + "src": "logo192.png", + "type": "image/png", + "sizes": "192x192" + }, + { + "src": "logo512.png", + "type": "image/png", + "sizes": "512x512" + } + ], + "start_url": ".", + "display": "standalone", + "theme_color": "#000000", + "background_color": "#ffffff" +} diff --git a/aibi-embedding/frontend/build/robots.txt b/aibi-embedding/frontend/build/robots.txt new file mode 100644 index 0000000..e9e57dc --- /dev/null +++ b/aibi-embedding/frontend/build/robots.txt @@ -0,0 +1,3 @@ +# https://www.robotstxt.org/robotstxt.html +User-agent: * +Disallow: diff --git a/aibi-embedding/frontend/build/static/css/main.e6c13ad2.css b/aibi-embedding/frontend/build/static/css/main.e6c13ad2.css new file mode 100644 index 0000000..50410fa --- /dev/null +++ b/aibi-embedding/frontend/build/static/css/main.e6c13ad2.css @@ -0,0 +1,2 @@ +body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;margin:0}code{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace} +/*# sourceMappingURL=main.e6c13ad2.css.map*/ \ No newline at end of file diff --git a/aibi-embedding/frontend/build/static/css/main.e6c13ad2.css.map b/aibi-embedding/frontend/build/static/css/main.e6c13ad2.css.map new file mode 100644 index 0000000..5c4dfb9 --- /dev/null +++ b/aibi-embedding/frontend/build/static/css/main.e6c13ad2.css.map @@ -0,0 +1 @@ +{"version":3,"file":"static/css/main.e6c13ad2.css","mappings":"AAAA,KAKE,kCAAmC,CACnC,iCAAkC,CAJlC,mIAEY,CAHZ,QAMF,CAEA,KACE,uEAEF","sources":["index.css"],"sourcesContent":["body {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',\n 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',\n sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\ncode {\n font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',\n monospace;\n}\n"],"names":[],"sourceRoot":""} \ No newline at end of file diff --git a/aibi-embedding/frontend/build/static/js/main.83526e3f.js b/aibi-embedding/frontend/build/static/js/main.83526e3f.js new file mode 100644 index 0000000..254fa14 --- /dev/null +++ b/aibi-embedding/frontend/build/static/js/main.83526e3f.js @@ -0,0 +1,3 @@ +/*! For license information please see main.83526e3f.js.LICENSE.txt */ +(()=>{"use strict";var e={219:(e,t,n)=>{var r=n(763),o={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},a={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},l={};function s(e){return r.isMemo(e)?i:l[e.$$typeof]||o}l[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},l[r.Memo]=i;var c=Object.defineProperty,u=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,p=Object.getOwnPropertyDescriptor,f=Object.getPrototypeOf,h=Object.prototype;e.exports=function e(t,n,r){if("string"!==typeof n){if(h){var o=f(n);o&&o!==h&&e(t,o,r)}var i=u(n);d&&(i=i.concat(d(n)));for(var l=s(t),m=s(n),g=0;g{var n="function"===typeof Symbol&&Symbol.for,r=n?Symbol.for("react.element"):60103,o=n?Symbol.for("react.portal"):60106,a=n?Symbol.for("react.fragment"):60107,i=n?Symbol.for("react.strict_mode"):60108,l=n?Symbol.for("react.profiler"):60114,s=n?Symbol.for("react.provider"):60109,c=n?Symbol.for("react.context"):60110,u=n?Symbol.for("react.async_mode"):60111,d=n?Symbol.for("react.concurrent_mode"):60111,p=n?Symbol.for("react.forward_ref"):60112,f=n?Symbol.for("react.suspense"):60113,h=n?Symbol.for("react.suspense_list"):60120,m=n?Symbol.for("react.memo"):60115,g=n?Symbol.for("react.lazy"):60116,v=n?Symbol.for("react.block"):60121,y=n?Symbol.for("react.fundamental"):60117,b=n?Symbol.for("react.responder"):60118,x=n?Symbol.for("react.scope"):60119;function w(e){if("object"===typeof e&&null!==e){var t=e.$$typeof;switch(t){case r:switch(e=e.type){case u:case d:case a:case l:case i:case f:return e;default:switch(e=e&&e.$$typeof){case c:case p:case g:case m:case s:return e;default:return t}}case o:return t}}}function S(e){return w(e)===d}t.AsyncMode=u,t.ConcurrentMode=d,t.ContextConsumer=c,t.ContextProvider=s,t.Element=r,t.ForwardRef=p,t.Fragment=a,t.Lazy=g,t.Memo=m,t.Portal=o,t.Profiler=l,t.StrictMode=i,t.Suspense=f,t.isAsyncMode=function(e){return S(e)||w(e)===u},t.isConcurrentMode=S,t.isContextConsumer=function(e){return w(e)===c},t.isContextProvider=function(e){return w(e)===s},t.isElement=function(e){return"object"===typeof e&&null!==e&&e.$$typeof===r},t.isForwardRef=function(e){return w(e)===p},t.isFragment=function(e){return w(e)===a},t.isLazy=function(e){return w(e)===g},t.isMemo=function(e){return w(e)===m},t.isPortal=function(e){return w(e)===o},t.isProfiler=function(e){return w(e)===l},t.isStrictMode=function(e){return w(e)===i},t.isSuspense=function(e){return w(e)===f},t.isValidElementType=function(e){return"string"===typeof e||"function"===typeof e||e===a||e===d||e===l||e===i||e===f||e===h||"object"===typeof e&&null!==e&&(e.$$typeof===g||e.$$typeof===m||e.$$typeof===s||e.$$typeof===c||e.$$typeof===p||e.$$typeof===y||e.$$typeof===b||e.$$typeof===x||e.$$typeof===v)},t.typeOf=w},763:(e,t,n)=>{e.exports=n(983)},4:(e,t,n)=>{var r=n(853),o=n(43),a=n(950);function i(e){var t="https://react.dev/errors/"+e;if(1)":-1--o||s[r]!==c[o]){var u="\n"+s[r].replace(" at new "," at ");return e.displayName&&u.includes("")&&(u=u.replace("",e.displayName)),u}}while(1<=r&&0<=o);break}}}finally{N=!1,Error.prepareStackTrace=n}return(n=e?e.displayName||e.name:"")?A(n):""}function I(e){switch(e.tag){case 26:case 27:case 5:return A(e.type);case 16:return A("Lazy");case 13:return A("Suspense");case 19:return A("SuspenseList");case 0:case 15:return e=z(e.type,!1);case 11:return e=z(e.type.render,!1);case 1:return e=z(e.type,!0);default:return""}}function L(e){try{var t="";do{t+=I(e),e=e.return}while(e);return t}catch(n){return"\nError generating stack: "+n.message+"\n"+n.stack}}function B(e){var t=e,n=e;if(e.alternate)for(;t.return;)t=t.return;else{e=t;do{0!==(4098&(t=e).flags)&&(n=t.return),e=t.return}while(e)}return 3===t.tag?n:null}function F(e){if(13===e.tag){var t=e.memoizedState;if(null===t&&(null!==(e=e.alternate)&&(t=e.memoizedState)),null!==t)return t.dehydrated}return null}function _(e){if(B(e)!==e)throw Error(i(188))}function D(e){var t=e.tag;if(5===t||26===t||27===t||6===t)return e;for(e=e.child;null!==e;){if(null!==(t=D(e)))return t;e=e.sibling}return null}var W=Array.isArray,H=a.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,V={pending:!1,data:null,method:null,action:null},U=[],q=-1;function $(e){return{current:e}}function G(e){0>q||(e.current=U[q],U[q]=null,q--)}function K(e,t){q++,U[q]=e.current,e.current=t}var Q=$(null),X=$(null),Y=$(null),J=$(null);function Z(e,t){switch(K(Y,t),K(X,e),K(Q,null),e=t.nodeType){case 9:case 11:t=(t=t.documentElement)&&(t=t.namespaceURI)?Xu(t):0;break;default:if(t=(e=8===e?t.parentNode:t).tagName,e=e.namespaceURI)t=Yu(e=Xu(e),t);else switch(t){case"svg":t=1;break;case"math":t=2;break;default:t=0}}G(Q),K(Q,t)}function ee(){G(Q),G(X),G(Y)}function te(e){null!==e.memoizedState&&K(J,e);var t=Q.current,n=Yu(t,e.type);t!==n&&(K(X,e),K(Q,n))}function ne(e){X.current===e&&(G(Q),G(X)),J.current===e&&(G(J),Ld._currentValue=V)}var re=Object.prototype.hasOwnProperty,oe=r.unstable_scheduleCallback,ae=r.unstable_cancelCallback,ie=r.unstable_shouldYield,le=r.unstable_requestPaint,se=r.unstable_now,ce=r.unstable_getCurrentPriorityLevel,ue=r.unstable_ImmediatePriority,de=r.unstable_UserBlockingPriority,pe=r.unstable_NormalPriority,fe=r.unstable_LowPriority,he=r.unstable_IdlePriority,me=r.log,ge=r.unstable_setDisableYieldValue,ve=null,ye=null;function be(e){if("function"===typeof me&&ge(e),ye&&"function"===typeof ye.setStrictMode)try{ye.setStrictMode(ve,e)}catch(t){}}var xe=Math.clz32?Math.clz32:function(e){return 0===(e>>>=0)?32:31-(we(e)/Se|0)|0},we=Math.log,Se=Math.LN2;var ke=128,Ce=4194304;function Ee(e){var t=42&e;if(0!==t)return t;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return 4194176&e;case 4194304:case 8388608:case 16777216:case 33554432:return 62914560&e;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function Re(e,t){var n=e.pendingLanes;if(0===n)return 0;var r=0,o=e.suspendedLanes,a=e.pingedLanes,i=e.warmLanes;e=0!==e.finishedLanes;var l=134217727&n;return 0!==l?0!==(n=l&~o)?r=Ee(n):0!==(a&=l)?r=Ee(a):e||0!==(i=l&~i)&&(r=Ee(i)):0!==(l=n&~o)?r=Ee(l):0!==a?r=Ee(a):e||0!==(i=n&~i)&&(r=Ee(i)),0===r?0:0!==t&&t!==r&&0===(t&o)&&((o=r&-r)>=(i=t&-t)||32===o&&0!==(4194176&i))?t:r}function Pe(e,t){return 0===(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)}function Te(e,t){switch(e){case 1:case 2:case 4:case 8:return t+250;case 16:case 32:case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;default:return-1}}function je(){var e=ke;return 0===(4194176&(ke<<=1))&&(ke=128),e}function Oe(){var e=Ce;return 0===(62914560&(Ce<<=1))&&(Ce=4194304),e}function Me(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function Ae(e,t){e.pendingLanes|=t,268435456!==t&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function Ne(e,t,n){e.pendingLanes|=t,e.suspendedLanes&=~t;var r=31-xe(t);e.entangledLanes|=t,e.entanglements[r]=1073741824|e.entanglements[r]|4194218&n}function ze(e,t){var n=e.entangledLanes|=t;for(e=e.entanglements;n;){var r=31-xe(n),o=1<=Sn),En=String.fromCharCode(32),Rn=!1;function Pn(e,t){switch(e){case"keyup":return-1!==xn.indexOf(t.keyCode);case"keydown":return 229!==t.keyCode;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Tn(e){return"object"===typeof(e=e.detail)&&"data"in e?e.data:null}var jn=!1;var On={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function Mn(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return"input"===t?!!On[e.type]:"textarea"===t}function An(e,t,n,r){At?Nt?Nt.push(r):Nt=[r]:At=r,0<(t=Lu(t,"onChange")).length&&(n=new Jt("onChange","change",null,n,r),e.push({event:n,listeners:t}))}var Nn=null,zn=null;function In(e){Tu(e,0)}function Ln(e){if(pt(Qe(e)))return e}function Bn(e,t){if("change"===e)return t}var Fn=!1;if(nt){var _n;if(nt){var Dn="oninput"in document;if(!Dn){var Wn=document.createElement("div");Wn.setAttribute("oninput","return;"),Dn="function"===typeof Wn.oninput}_n=Dn}else _n=!1;Fn=_n&&(!document.documentMode||9=t)return{node:r,offset:t-e};e=n}e:{for(;r;){if(r.nextSibling){r=r.nextSibling;break e}r=r.parentNode}r=void 0}r=Xn(r)}}function Jn(e,t){return!(!e||!t)&&(e===t||(!e||3!==e.nodeType)&&(t&&3===t.nodeType?Jn(e,t.parentNode):"contains"in e?e.contains(t):!!e.compareDocumentPosition&&!!(16&e.compareDocumentPosition(t))))}function Zn(e){for(var t=ft((e=null!=e&&null!=e.ownerDocument&&null!=e.ownerDocument.defaultView?e.ownerDocument.defaultView:window).document);t instanceof e.HTMLIFrameElement;){try{var n="string"===typeof t.contentWindow.location.href}catch(r){n=!1}if(!n)break;t=ft((e=t.contentWindow).document)}return t}function er(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&("input"===t&&("text"===e.type||"search"===e.type||"tel"===e.type||"url"===e.type||"password"===e.type)||"textarea"===t||"true"===e.contentEditable)}function tr(e,t){var n=Zn(t);t=e.focusedElem;var r=e.selectionRange;if(n!==t&&t&&t.ownerDocument&&Jn(t.ownerDocument.documentElement,t)){if(null!==r&&er(t))if(e=r.start,void 0===(n=r.end)&&(n=e),"selectionStart"in t)t.selectionStart=e,t.selectionEnd=Math.min(n,t.value.length);else if((n=(e=t.ownerDocument||document)&&e.defaultView||window).getSelection){n=n.getSelection();var o=t.textContent.length,a=Math.min(r.start,o);r=void 0===r.end?a:Math.min(r.end,o),!n.extend&&a>r&&(o=r,r=a,a=o),o=Yn(t,a);var i=Yn(t,r);o&&i&&(1!==n.rangeCount||n.anchorNode!==o.node||n.anchorOffset!==o.offset||n.focusNode!==i.node||n.focusOffset!==i.offset)&&((e=e.createRange()).setStart(o.node,o.offset),n.removeAllRanges(),a>r?(n.addRange(e),n.extend(i.node,i.offset)):(e.setEnd(i.node,i.offset),n.addRange(e)))}for(e=[],n=t;n=n.parentNode;)1===n.nodeType&&e.push({element:n,left:n.scrollLeft,top:n.scrollTop});for("function"===typeof t.focus&&t.focus(),t=0;t=document.documentMode,rr=null,or=null,ar=null,ir=!1;function lr(e,t,n){var r=n.window===n?n.document:9===n.nodeType?n:n.ownerDocument;ir||null==rr||rr!==ft(r)||("selectionStart"in(r=rr)&&er(r)?r={start:r.selectionStart,end:r.selectionEnd}:r={anchorNode:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection()).anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset},ar&&Qn(ar,r)||(ar=r,0<(r=Lu(or,"onSelect")).length&&(t=new Jt("onSelect","select",null,t,n),e.push({event:t,listeners:r}),t.target=rr)))}function sr(e,t){var n={};return n[e.toLowerCase()]=t.toLowerCase(),n["Webkit"+e]="webkit"+t,n["Moz"+e]="moz"+t,n}var cr={animationend:sr("Animation","AnimationEnd"),animationiteration:sr("Animation","AnimationIteration"),animationstart:sr("Animation","AnimationStart"),transitionrun:sr("Transition","TransitionRun"),transitionstart:sr("Transition","TransitionStart"),transitioncancel:sr("Transition","TransitionCancel"),transitionend:sr("Transition","TransitionEnd")},ur={},dr={};function pr(e){if(ur[e])return ur[e];if(!cr[e])return e;var t,n=cr[e];for(t in n)if(n.hasOwnProperty(t)&&t in dr)return ur[e]=n[t];return e}nt&&(dr=document.createElement("div").style,"AnimationEvent"in window||(delete cr.animationend.animation,delete cr.animationiteration.animation,delete cr.animationstart.animation),"TransitionEvent"in window||delete cr.transitionend.transition);var fr=pr("animationend"),hr=pr("animationiteration"),mr=pr("animationstart"),gr=pr("transitionrun"),vr=pr("transitionstart"),yr=pr("transitioncancel"),br=pr("transitionend"),xr=new Map,wr="abort auxClick beforeToggle cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll scrollEnd toggle touchMove waiting wheel".split(" ");function Sr(e,t){xr.set(e,t),et(t,[e])}var kr=[],Cr=0,Er=0;function Rr(){for(var e=Cr,t=Er=Cr=0;t>=i,o-=i,Hr=1<<32-xe(t)+o|n<p?(f=d,d=null):f=d.sibling;var h=v(o,d,l[p],s);if(null===h){null===d&&(d=f);break}e&&d&&null===h.alternate&&t(o,d),i=a(h,i,p),null===u?c=h:u.sibling=h,u=h,d=f}if(p===l.length)return n(o,d),Xr&&Ur(o,p),c;if(null===d){for(;pf?(h=p,p=null):h=p.sibling;var b=v(o,p,g.value,c);if(null===b){null===p&&(p=h);break}e&&p&&null===b.alternate&&t(o,p),l=a(b,l,f),null===d?u=b:d.sibling=b,d=b,p=h}if(g.done)return n(o,p),Xr&&Ur(o,f),u;if(null===p){for(;!g.done;f++,g=s.next())null!==(g=m(o,g.value,c))&&(l=a(g,l,f),null===d?u=g:d.sibling=g,d=g);return Xr&&Ur(o,f),u}for(p=r(p);!g.done;f++,g=s.next())null!==(g=y(p,o,f,g.value,c))&&(e&&null!==g.alternate&&p.delete(null===g.key?f:g.key),l=a(g,l,f),null===d?u=g:d.sibling=g,d=g);return e&&p.forEach((function(e){return t(o,e)})),Xr&&Ur(o,f),u}(s,p,f=x.call(f),h)}if("function"===typeof f.then)return b(s,p,vo(f),h);if(f.$$typeof===g)return b(s,p,Rl(s,f),h);bo(s,f)}return"string"===typeof f&&""!==f||"number"===typeof f||"bigint"===typeof f?(f=""+f,null!==p&&6===p.tag?(n(s,p.sibling),(h=o(p,f)).return=s,s=h):(n(s,p),(h=Hs(f,s.mode,h)).return=s,s=h),l(s)):n(s,p)}return function(e,t,n,r){try{go=0;var o=b(e,t,n,r);return mo=null,o}catch(i){if(i===io)throw i;var a=Is(29,i,null,e.mode);return a.lanes=r,a.return=e,a}}}var So=wo(!0),ko=wo(!1),Co=$(null),Eo=$(0);function Ro(e,t){K(Eo,e=cc),K(Co,t),cc=e|t.baseLanes}function Po(){K(Eo,cc),K(Co,Co.current)}function To(){cc=Eo.current,G(Co),G(Eo)}var jo=$(null),Oo=null;function Mo(e){var t=e.alternate;K(Io,1&Io.current),K(jo,e),null===Oo&&(null===t||null!==Co.current||null!==t.memoizedState)&&(Oo=e)}function Ao(e){if(22===e.tag){if(K(Io,Io.current),K(jo,e),null===Oo){var t=e.alternate;null!==t&&null!==t.memoizedState&&(Oo=e)}}else No()}function No(){K(Io,Io.current),K(jo,jo.current)}function zo(e){G(jo),Oo===e&&(Oo=null),G(Io)}var Io=$(0);function Lo(e){for(var t=e;null!==t;){if(13===t.tag){var n=t.memoizedState;if(null!==n&&(null===(n=n.dehydrated)||"$?"===n.data||"$!"===n.data))return t}else if(19===t.tag&&void 0!==t.memoizedProps.revealOrder){if(0!==(128&t.flags))return t}else if(null!==t.child){t.child.return=t,t=t.child;continue}if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}return null}var Bo="undefined"!==typeof AbortController?AbortController:function(){var e=[],t=this.signal={aborted:!1,addEventListener:function(t,n){e.push(n)}};this.abort=function(){t.aborted=!0,e.forEach((function(e){return e()}))}},Fo=r.unstable_scheduleCallback,_o=r.unstable_NormalPriority,Do={$$typeof:g,Consumer:null,Provider:null,_currentValue:null,_currentValue2:null,_threadCount:0};function Wo(){return{controller:new Bo,data:new Map,refCount:0}}function Ho(e){e.refCount--,0===e.refCount&&Fo(_o,(function(){e.controller.abort()}))}var Vo=null,Uo=0,qo=0,$o=null;function Go(){if(0===--Uo&&null!==Vo){null!==$o&&($o.status="fulfilled");var e=Vo;Vo=null,qo=0,$o=null;for(var t=0;ta?a:8;var i=O.T,l={};O.T=l,wi(e,!1,t,n);try{var s=o(),c=O.S;if(null!==c&&c(l,s),null!==s&&"object"===typeof s&&"function"===typeof s.then)xi(e,t,function(e,t){var n=[],r={status:"pending",value:null,reason:null,then:function(e){n.push(e)}};return e.then((function(){r.status="fulfilled",r.value=t;for(var e=0;e title"))),$u(a,r,n),a[Fe]=e,Ye(a),r=a;break e;case"link":var l=Pd("link","href",o).get(r+(n.href||""));if(l)for(var s=0;s<\/script>",e=e.removeChild(e.firstChild);break;case"select":e="string"===typeof r.is?o.createElement("select",{is:r.is}):o.createElement("select"),r.multiple?e.multiple=!0:r.size&&(e.size=r.size);break;default:e="string"===typeof r.is?o.createElement(n,{is:r.is}):o.createElement(n)}}e[Fe]=t,e[_e]=r;e:for(o=t.child;null!==o;){if(5===o.tag||6===o.tag)e.appendChild(o.stateNode);else if(4!==o.tag&&27!==o.tag&&null!==o.child){o.child.return=o,o=o.child;continue}if(o===t)break e;for(;null===o.sibling;){if(null===o.return||o.return===t)break e;o=o.return}o.sibling.return=o.return,o=o.sibling}t.stateNode=e;e:switch($u(e,n,r),n){case"button":case"input":case"select":case"textarea":e=!!r.autoFocus;break e;case"img":e=!0;break e;default:e=!1}e&&Us(t)}}return Ks(t),t.flags&=-16777217,null;case 6:if(e&&null!=t.stateNode)e.memoizedProps!==r&&Us(t);else{if("string"!==typeof r&&null===t.stateNode)throw Error(i(166));if(e=Y.current,ro(t)){if(e=t.stateNode,n=t.memoizedProps,r=null,null!==(o=Kr))switch(o.tag){case 27:case 5:r=o.memoizedProps}e[Fe]=t,(e=!!(e.nodeValue===n||null!==r&&!0===r.suppressHydrationWarning||Hu(e.nodeValue,n)))||eo(t)}else(e=Qu(e).createTextNode(r))[Fe]=t,t.stateNode=e}return Ks(t),null;case 13:if(r=t.memoizedState,null===e||null!==e.memoizedState&&null!==e.memoizedState.dehydrated){if(o=ro(t),null!==r&&null!==r.dehydrated){if(null===e){if(!o)throw Error(i(318));if(!(o=null!==(o=t.memoizedState)?o.dehydrated:null))throw Error(i(317));o[Fe]=t}else oo(),0===(128&t.flags)&&(t.memoizedState=null),t.flags|=4;Ks(t),o=!1}else null!==Yr&&(zc(Yr),Yr=null),o=!0;if(!o)return 256&t.flags?(zo(t),t):(zo(t),null)}if(zo(t),0!==(128&t.flags))return t.lanes=n,t;if(n=null!==r,e=null!==e&&null!==e.memoizedState,n){o=null,null!==(r=t.child).alternate&&null!==r.alternate.memoizedState&&null!==r.alternate.memoizedState.cachePool&&(o=r.alternate.memoizedState.cachePool.pool);var a=null;null!==r.memoizedState&&null!==r.memoizedState.cachePool&&(a=r.memoizedState.cachePool.pool),a!==o&&(r.flags|=2048)}return n!==e&&n&&(t.child.flags|=8192),$s(t,t.updateQueue),Ks(t),null;case 4:return ee(),null===e&&Au(t.stateNode.containerInfo),Ks(t),null;case 10:return bl(t.type),Ks(t),null;case 19:if(G(Io),null===(o=t.memoizedState))return Ks(t),null;if(r=0!==(128&t.flags),null===(a=o.rendering))if(r)Gs(o,!1);else{if(0!==uc||null!==e&&0!==(128&e.flags))for(e=t.child;null!==e;){if(null!==(a=Lo(e))){for(t.flags|=128,Gs(o,!1),e=a.updateQueue,t.updateQueue=e,$s(t,e),t.subtreeFlags=0,e=n,n=t.child;null!==n;)Fs(n,e),n=n.sibling;return K(Io,1&Io.current|2),t.child}e=e.sibling}null!==o.tail&&se()>xc&&(t.flags|=128,r=!0,Gs(o,!1),t.lanes=4194304)}else{if(!r)if(null!==(e=Lo(a))){if(t.flags|=128,r=!0,e=e.updateQueue,t.updateQueue=e,$s(t,e),Gs(o,!0),null===o.tail&&"hidden"===o.tailMode&&!a.alternate&&!Xr)return Ks(t),null}else 2*se()-o.renderingStartTime>xc&&536870912!==n&&(t.flags|=128,r=!0,Gs(o,!1),t.lanes=4194304);o.isBackwards?(a.sibling=t.child,t.child=a):(null!==(e=o.last)?e.sibling=a:t.child=a,o.last=a)}return null!==o.tail?(t=o.tail,o.rendering=t,o.tail=t.sibling,o.renderingStartTime=se(),t.sibling=null,e=Io.current,K(Io,r?1&e|2:1&e),t):(Ks(t),null);case 22:case 23:return zo(t),To(),r=null!==t.memoizedState,null!==e?null!==e.memoizedState!==r&&(t.flags|=8192):r&&(t.flags|=8192),r?0!==(536870912&n)&&0===(128&t.flags)&&(Ks(t),6&t.subtreeFlags&&(t.flags|=8192)):Ks(t),null!==(n=t.updateQueue)&&$s(t,n.retryQueue),n=null,null!==e&&null!==e.memoizedState&&null!==e.memoizedState.cachePool&&(n=e.memoizedState.cachePool.pool),r=null,null!==t.memoizedState&&null!==t.memoizedState.cachePool&&(r=t.memoizedState.cachePool.pool),r!==n&&(t.flags|=2048),null!==e&&G(Qo),null;case 24:return n=null,null!==e&&(n=e.memoizedState.cache),t.memoizedState.cache!==n&&(t.flags|=2048),bl(Do),Ks(t),null;case 25:return null}throw Error(i(156,t.tag))}function Xs(e,t){switch(Gr(t),t.tag){case 1:return 65536&(e=t.flags)?(t.flags=-65537&e|128,t):null;case 3:return bl(Do),ee(),0!==(65536&(e=t.flags))&&0===(128&e)?(t.flags=-65537&e|128,t):null;case 26:case 27:case 5:return ne(t),null;case 13:if(zo(t),null!==(e=t.memoizedState)&&null!==e.dehydrated){if(null===t.alternate)throw Error(i(340));oo()}return 65536&(e=t.flags)?(t.flags=-65537&e|128,t):null;case 19:return G(Io),null;case 4:return ee(),null;case 10:return bl(t.type),null;case 22:case 23:return zo(t),To(),null!==e&&G(Qo),65536&(e=t.flags)?(t.flags=-65537&e|128,t):null;case 24:return bl(Do),null;default:return null}}function Ys(e,t){switch(Gr(t),t.tag){case 3:bl(Do),ee();break;case 26:case 27:case 5:ne(t);break;case 4:ee();break;case 13:zo(t);break;case 19:G(Io);break;case 10:bl(t.type);break;case 22:case 23:zo(t),To(),null!==e&&G(Qo);break;case 24:bl(Do)}}var Js={getCacheForType:function(e){var t=El(Do),n=t.data.get(e);return void 0===n&&(n=e(),t.data.set(e,n)),n}},Zs="function"===typeof WeakMap?WeakMap:Map,ec=0,tc=null,nc=null,rc=0,oc=0,ac=null,ic=!1,lc=!1,sc=!1,cc=0,uc=0,dc=0,pc=0,fc=0,hc=0,mc=0,gc=null,vc=null,yc=!1,bc=0,xc=1/0,wc=null,Sc=null,kc=!1,Cc=null,Ec=0,Rc=0,Pc=null,Tc=0,jc=null;function Oc(){if(0!==(2&ec)&&0!==rc)return rc&-rc;if(null!==O.T){return 0!==qo?qo:wu()}return Le()}function Mc(){0===hc&&(hc=0===(536870912&rc)||Xr?je():536870912);var e=jo.current;return null!==e&&(e.flags|=32),hc}function Ac(e,t,n){(e===tc&&2===oc||null!==e.cancelPendingCommit)&&(Dc(e,0),Bc(e,rc,hc,!1)),Ae(e,n),0!==(2&ec)&&e===tc||(e===tc&&(0===(2&ec)&&(pc|=n),4===uc&&Bc(e,rc,hc,!1)),mu(e))}function Nc(e,t,n){if(0!==(6&ec))throw Error(i(327));for(var r=!n&&0===(60&t)&&0===(t&e.expiredLanes)||Pe(e,t),o=r?function(e,t){var n=ec;ec|=2;var r=Hc(),o=Vc();tc!==e||rc!==t?(wc=null,xc=se()+500,Dc(e,t)):lc=Pe(e,t);e:for(;;)try{if(0!==oc&&null!==nc){t=nc;var a=ac;t:switch(oc){case 1:oc=0,ac=null,Xc(e,t,a,1);break;case 2:if(co(a)){oc=0,ac=null,Qc(t);break}t=function(){2===oc&&tc===e&&(oc=7),mu(e)},a.then(t,t);break e;case 3:oc=7;break e;case 4:oc=5;break e;case 7:co(a)?(oc=0,ac=null,Qc(t)):(oc=0,ac=null,Xc(e,t,a,7));break;case 5:var l=null;switch(nc.tag){case 26:l=nc.memoizedState;case 5:case 27:var s=nc;if(!l||jd(l)){oc=0,ac=null;var c=s.sibling;if(null!==c)nc=c;else{var u=s.return;null!==u?(nc=u,Yc(u)):nc=null}break t}}oc=0,ac=null,Xc(e,t,a,5);break;case 6:oc=0,ac=null,Xc(e,t,a,6);break;case 8:_c(),uc=6;break e;default:throw Error(i(462))}}Gc();break}catch(d){Wc(e,d)}return vl=gl=null,O.H=r,O.A=o,ec=n,null!==nc?0:(tc=null,rc=0,Rr(),uc)}(e,t):qc(e,t,!0),a=r;;){if(0===o){lc&&!r&&Bc(e,t,0,!1);break}if(6===o)Bc(e,t,0,!ic);else{if(n=e.current.alternate,a&&!Lc(n)){o=qc(e,t,!1),a=!1;continue}if(2===o){if(a=t,e.errorRecoveryDisabledLanes&a)var l=0;else l=0!==(l=-536870913&e.pendingLanes)?l:536870912&l?536870912:0;if(0!==l){t=l;e:{var s=e;o=gc;var c=s.current.memoizedState.isDehydrated;if(c&&(Dc(s,l).flags|=256),2!==(l=qc(s,l,!1))){if(sc&&!c){s.errorRecoveryDisabledLanes|=a,pc|=a,o=4;break e}a=vc,vc=o,null!==a&&zc(a)}o=l}if(a=!1,2!==o)continue}}if(1===o){Dc(e,0),Bc(e,t,0,!0);break}e:{switch(r=e,o){case 0:case 1:throw Error(i(345));case 4:if((4194176&t)===t){Bc(r,t,hc,!ic);break e}break;case 2:vc=null;break;case 3:case 5:break;default:throw Error(i(329))}if(r.finishedWork=n,r.finishedLanes=t,(62914560&t)===t&&10<(a=bc+300-se())){if(Bc(r,t,hc,!ic),0!==Re(r,0))break e;r.timeoutHandle=ed(Ic.bind(null,r,n,vc,wc,yc,t,hc,pc,mc,ic,2,-0,0),a)}else Ic(r,n,vc,wc,yc,t,hc,pc,mc,ic,0,-0,0)}}break}mu(e)}function zc(e){null===vc?vc=e:vc.push.apply(vc,e)}function Ic(e,t,n,r,o,a,l,s,c,u,d,p,f){var h=t.subtreeFlags;if((8192&h||16785408===(16785408&h))&&(Od={stylesheets:null,count:0,unsuspend:Md},Ts(t),null!==(t=function(){if(null===Od)throw Error(i(475));var e=Od;return e.stylesheets&&0===e.count&&zd(e,e.stylesheets),0n?32:n,O.T=null,null===Cc)var a=!1;else{n=Pc,Pc=null;var l=Cc,s=Ec;if(Cc=null,Ec=0,0!==(6&ec))throw Error(i(331));var c=ec;if(ec|=4,Ms(l.current),ks(l,l.current,s,n),ec=c,gu(0,!1),ye&&"function"===typeof ye.onPostCommitFiberRoot)try{ye.onPostCommitFiberRoot(ve,l)}catch(u){}a=!0}return a}finally{H.p=o,O.T=r,eu(e,t)}}return!1}function nu(e,t,n){t=zr(n,t),null!==(e=Al(e,t=Di(e.stateNode,t,2),2))&&(Ae(e,2),mu(e))}function ru(e,t,n){if(3===e.tag)nu(e,e,n);else for(;null!==t;){if(3===t.tag){nu(t,e,n);break}if(1===t.tag){var r=t.stateNode;if("function"===typeof t.type.getDerivedStateFromError||"function"===typeof r.componentDidCatch&&(null===Sc||!Sc.has(r))){e=zr(n,e),null!==(r=Al(t,n=Wi(2),2))&&(Hi(n,r,t,e),Ae(r,2),mu(r));break}}t=t.return}}function ou(e,t,n){var r=e.pingCache;if(null===r){r=e.pingCache=new Zs;var o=new Set;r.set(t,o)}else void 0===(o=r.get(t))&&(o=new Set,r.set(t,o));o.has(n)||(sc=!0,o.add(n),e=au.bind(null,e,t,n),t.then(e,e))}function au(e,t,n){var r=e.pingCache;null!==r&&r.delete(t),e.pingedLanes|=e.suspendedLanes&n,e.warmLanes&=~n,tc===e&&(rc&n)===n&&(4===uc||3===uc&&(62914560&rc)===rc&&300>se()-bc?0===(2&ec)&&Dc(e,0):fc|=n,mc===rc&&(mc=0)),mu(e)}function iu(e,t){0===t&&(t=Oe()),null!==(e=jr(e,t))&&(Ae(e,t),mu(e))}function lu(e){var t=e.memoizedState,n=0;null!==t&&(n=t.retryLane),iu(e,n)}function su(e,t){var n=0;switch(e.tag){case 13:var r=e.stateNode,o=e.memoizedState;null!==o&&(n=o.retryLane);break;case 19:r=e.stateNode;break;case 22:r=e.stateNode._retryCache;break;default:throw Error(i(314))}null!==r&&r.delete(t),iu(e,n)}var cu=null,uu=null,du=!1,pu=!1,fu=!1,hu=0;function mu(e){var t;e!==uu&&null===e.next&&(null===uu?cu=uu=e:uu=uu.next=e),pu=!0,du||(du=!0,t=vu,rd((function(){0!==(6&ec)?oe(ue,t):t()})))}function gu(e,t){if(!fu&&pu){fu=!0;do{for(var n=!1,r=cu;null!==r;){if(!t)if(0!==e){var o=r.pendingLanes;if(0===o)var a=0;else{var i=r.suspendedLanes,l=r.pingedLanes;a=(1<<31-xe(42|e)+1)-1,a=201326677&(a&=o&~(i&~l))?201326677&a|1:a?2|a:0}0!==a&&(n=!0,xu(r,a))}else a=rc,0===(3&(a=Re(r,r===tc?a:0)))||Pe(r,a)||(n=!0,xu(r,a));r=r.next}}while(n);fu=!1}}function vu(){pu=du=!1;var e=0;0!==hu&&(function(){var e=window.event;if(e&&"popstate"===e.type)return e!==Zu&&(Zu=e,!0);return Zu=null,!1}()&&(e=hu),hu=0);for(var t=se(),n=null,r=cu;null!==r;){var o=r.next,a=yu(r,t);0===a?(r.next=null,null===n?cu=o:n.next=o,null===o&&(uu=n)):(n=r,(0!==e||0!==(3&a))&&(pu=!0)),r=o}gu(e,!1)}function yu(e,t){for(var n=e.suspendedLanes,r=e.pingedLanes,o=e.expirationTimes,a=-62914561&e.pendingLanes;0 title"):null)}function jd(e){return"stylesheet"!==e.type||0!==(3&e.state.loading)}var Od=null;function Md(){}function Ad(){if(this.count--,0===this.count)if(this.stylesheets)zd(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}var Nd=null;function zd(e,t){e.stylesheets=null,null!==e.unsuspend&&(e.count++,Nd=new Map,t.forEach(Id,e),Nd=null,Ad.call(e))}function Id(e,t){if(!(4&t.state.loading)){var n=Nd.get(e);if(n)var r=n.get(null);else{n=new Map,Nd.set(e,n);for(var o=e.querySelectorAll("link[data-precedence],style[data-precedence]"),a=0;a{var r=n(43);function o(e){var t="https://react.dev/errors/"+e;if(1{!function e(){if("undefined"!==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"===typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(t){console.error(t)}}(),e.exports=n(4)},950:(e,t,n)=>{!function e(){if("undefined"!==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"===typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(t){console.error(t)}}(),e.exports=n(672)},358:(e,t)=>{const n=/^[\u0021-\u003A\u003C\u003E-\u007E]+$/,r=/^[\u0021-\u003A\u003C-\u007E]*$/,o=/^([.]?[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)([.][a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*$/i,a=/^[\u0020-\u003A\u003D-\u007E]*$/,i=Object.prototype.toString,l=(()=>{const e=function(){};return e.prototype=Object.create(null),e})();function s(e,t,n){do{const n=e.charCodeAt(t);if(32!==n&&9!==n)return t}while(++tn;){const n=e.charCodeAt(--t);if(32!==n&&9!==n)return t+1}return n}function u(e){if(-1===e.indexOf("%"))return e;try{return decodeURIComponent(e)}catch(t){return e}}},799:(e,t)=>{var n=Symbol.for("react.transitional.element"),r=Symbol.for("react.fragment");function o(e,t,r){var o=null;if(void 0!==r&&(o=""+r),void 0!==t.key&&(o=""+t.key),"key"in t)for(var a in r={},t)"key"!==a&&(r[a]=t[a]);else r=t;return t=r.ref,{$$typeof:n,type:e,key:o,ref:void 0!==t?t:null,props:r}}t.Fragment=r,t.jsx=o,t.jsxs=o},288:(e,t)=>{var n=Symbol.for("react.transitional.element"),r=Symbol.for("react.portal"),o=Symbol.for("react.fragment"),a=Symbol.for("react.strict_mode"),i=Symbol.for("react.profiler"),l=Symbol.for("react.consumer"),s=Symbol.for("react.context"),c=Symbol.for("react.forward_ref"),u=Symbol.for("react.suspense"),d=Symbol.for("react.memo"),p=Symbol.for("react.lazy"),f=Symbol.iterator;var h={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},m=Object.assign,g={};function v(e,t,n){this.props=e,this.context=t,this.refs=g,this.updater=n||h}function y(){}function b(e,t,n){this.props=e,this.context=t,this.refs=g,this.updater=n||h}v.prototype.isReactComponent={},v.prototype.setState=function(e,t){if("object"!==typeof e&&"function"!==typeof e&&null!=e)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,t,"setState")},v.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},y.prototype=v.prototype;var x=b.prototype=new y;x.constructor=b,m(x,v.prototype),x.isPureReactComponent=!0;var w=Array.isArray,S={H:null,A:null,T:null,S:null},k=Object.prototype.hasOwnProperty;function C(e,t,r,o,a,i){return r=i.ref,{$$typeof:n,type:e,key:t,ref:void 0!==r?r:null,props:i}}function E(e){return"object"===typeof e&&null!==e&&e.$$typeof===n}var R=/\/+/g;function P(e,t){return"object"===typeof e&&null!==e&&null!=e.key?function(e){var t={"=":"=0",":":"=2"};return"$"+e.replace(/[=:]/g,(function(e){return t[e]}))}(""+e.key):t.toString(36)}function T(){}function j(e,t,o,a,i){var l=typeof e;"undefined"!==l&&"boolean"!==l||(e=null);var s,c,u=!1;if(null===e)u=!0;else switch(l){case"bigint":case"string":case"number":u=!0;break;case"object":switch(e.$$typeof){case n:case r:u=!0;break;case p:return j((u=e._init)(e._payload),t,o,a,i)}}if(u)return i=i(e),u=""===a?"."+P(e,0):a,w(i)?(o="",null!=u&&(o=u.replace(R,"$&/")+"/"),j(i,t,o,"",(function(e){return e}))):null!=i&&(E(i)&&(s=i,c=o+(null==i.key||e&&e.key===i.key?"":(""+i.key).replace(R,"$&/")+"/")+u,i=C(s.type,c,void 0,0,0,s.props)),t.push(i)),1;u=0;var d,h=""===a?".":a+":";if(w(e))for(var m=0;m{e.exports=n(288)},579:(e,t,n)=>{e.exports=n(799)},896:(e,t)=>{function n(e,t){var n=e.length;e.push(t);e:for(;0>>1,o=e[r];if(!(0>>1;ra(s,n))ca(u,s)?(e[r]=u,e[c]=n,r=c):(e[r]=s,e[l]=n,r=l);else{if(!(ca(u,n)))break e;e[r]=u,e[c]=n,r=c}}}return t}function a(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}if(t.unstable_now=void 0,"object"===typeof performance&&"function"===typeof performance.now){var i=performance;t.unstable_now=function(){return i.now()}}else{var l=Date,s=l.now();t.unstable_now=function(){return l.now()-s}}var c=[],u=[],d=1,p=null,f=3,h=!1,m=!1,g=!1,v="function"===typeof setTimeout?setTimeout:null,y="function"===typeof clearTimeout?clearTimeout:null,b="undefined"!==typeof setImmediate?setImmediate:null;function x(e){for(var t=r(u);null!==t;){if(null===t.callback)o(u);else{if(!(t.startTime<=e))break;o(u),t.sortIndex=t.expirationTime,n(c,t)}t=r(u)}}function w(e){if(g=!1,x(e),!m)if(null!==r(c))m=!0,M();else{var t=r(u);null!==t&&A(w,t.startTime-e)}}var S,k=!1,C=-1,E=5,R=-1;function P(){return!(t.unstable_now()-Re&&P());){var i=p.callback;if("function"===typeof i){p.callback=null,f=p.priorityLevel;var l=i(p.expirationTime<=e);if(e=t.unstable_now(),"function"===typeof l){p.callback=l,x(e),n=!0;break t}p===r(c)&&o(c),x(e)}else o(c);p=r(c)}if(null!==p)n=!0;else{var s=r(u);null!==s&&A(w,s.startTime-e),n=!1}}break e}finally{p=null,f=a,h=!1}n=void 0}}finally{n?S():k=!1}}}if("function"===typeof b)S=function(){b(T)};else if("undefined"!==typeof MessageChannel){var j=new MessageChannel,O=j.port2;j.port1.onmessage=T,S=function(){O.postMessage(null)}}else S=function(){v(T,0)};function M(){k||(k=!0,S())}function A(e,n){C=v((function(){e(t.unstable_now())}),n)}t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_continueExecution=function(){m||h||(m=!0,M())},t.unstable_forceFrameRate=function(e){0>e||125i?(e.sortIndex=a,n(u,e),null===r(c)&&e===r(u)&&(g?(y(C),C=-1):g=!0,A(w,a-i))):(e.sortIndex=l,n(c,e),m||h||(m=!0,M())),e},t.unstable_shouldYield=P,t.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}},853:(e,t,n)=>{e.exports=n(896)}},t={};function n(r){var o=t[r];if(void 0!==o)return o.exports;var a=t[r]={exports:{}};return e[r](a,a.exports,n),a.exports}(()=>{var e,t=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__;n.t=function(r,o){if(1&o&&(r=this(r)),8&o)return r;if("object"===typeof r&&r){if(4&o&&r.__esModule)return r;if(16&o&&"function"===typeof r.then)return r}var a=Object.create(null);n.r(a);var i={};e=e||[null,t({}),t([]),t(t)];for(var l=2&o&&r;"object"==typeof l&&!~e.indexOf(l);l=t(l))Object.getOwnPropertyNames(l).forEach((e=>i[e]=()=>r[e]));return i.default=()=>r,n.d(a,i),a}})(),n.d=(e,t)=>{for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),n.r=e=>{"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.p="/";var r={};n.r(r),n.d(r,{hasBrowserEnv:()=>An,hasStandardBrowserEnv:()=>zn,hasStandardBrowserWebWorkerEnv:()=>In,navigator:()=>Nn,origin:()=>Ln});var o=n(43),a=n.t(o,2),i=n(391);function l(e,t){if(null==e)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.includes(r))continue;n[r]=e[r]}return n}function s(e,t){if(null==e)return{};var n,r,o=l(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r0&&void 0!==arguments[0]?arguments[0]:{})}function w(e,t){if(!1===e||null===e||"undefined"===typeof e)throw new Error(t)}function S(e,t){if(!e){"undefined"!==typeof console&&console.warn(t);try{throw new Error(t)}catch(n){}}}function k(e,t){return{usr:e.state,key:e.key,idx:t}}function C(e,t){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,r=arguments.length>3?arguments[3]:void 0;return f(f({pathname:"string"===typeof e?e:e.pathname,search:"",hash:""},"string"===typeof t?R(t):t),{},{state:n,key:t&&t.key||r||Math.random().toString(36).substring(2,10)})}function E(e){let{pathname:t="/",search:n="",hash:r=""}=e;return n&&"?"!==n&&(t+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(t+="#"===r.charAt(0)?r:"#"+r),t}function R(e){let t={};if(e){let n=e.indexOf("#");n>=0&&(t.hash=e.substring(n),e=e.substring(0,n));let r=e.indexOf("?");r>=0&&(t.search=e.substring(r),e=e.substring(0,r)),e&&(t.pathname=e)}return t}function P(e,t,n){let r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},{window:o=document.defaultView,v5Compat:a=!1}=r,i=o.history,l="POP",s=null,c=u();function u(){return(i.state||{idx:null}).idx}function d(){l="POP";let e=u(),t=null==e?null:e-c;c=e,s&&s({action:l,location:h.location,delta:t})}function p(e){let t="null"!==o.location.origin?o.location.origin:o.location.href,n="string"===typeof e?e:E(e);return n=n.replace(/ $/,"%20"),w(t,"No window.location.(origin|href) available to create URL for href: ".concat(n)),new URL(n,t)}null==c&&(c=0,i.replaceState(f(f({},i.state),{},{idx:c}),""));let h={get action(){return l},get location(){return e(o,i)},listen(e){if(s)throw new Error("A history only accepts one active listener");return o.addEventListener(b,d),s=e,()=>{o.removeEventListener(b,d),s=null}},createHref:e=>t(o,e),createURL:p,encodeLocation(e){let t=p(e);return{pathname:t.pathname,search:t.search,hash:t.hash}},push:function(e,t){l="PUSH";let r=C(h.location,e,t);n&&n(r,e),c=u()+1;let d=k(r,c),p=h.createHref(r);try{i.pushState(d,"",p)}catch(f){if(f instanceof DOMException&&"DataCloneError"===f.name)throw f;o.location.assign(p)}a&&s&&s({action:l,location:h.location,delta:1})},replace:function(e,t){l="REPLACE";let r=C(h.location,e,t);n&&n(r,e),c=u();let o=k(r,c),d=h.createHref(r);i.replaceState(o,"",d),a&&s&&s({action:l,location:h.location,delta:0})},go:e=>i.go(e)};return h}function T(e,t){return j(e,t,arguments.length>2&&void 0!==arguments[2]?arguments[2]:"/",!1)}function j(e,t,n,r){let o=V(("string"===typeof t?R(t):t).pathname||"/",n);if(null==o)return null;let a=O(e);!function(e){e.sort(((e,t)=>e.score!==t.score?t.score-e.score:function(e,t){let n=e.length===t.length&&e.slice(0,-1).every(((e,n)=>e===t[n]));return n?e[e.length-1]-t[t.length-1]:0}(e.routesMeta.map((e=>e.childrenIndex)),t.routesMeta.map((e=>e.childrenIndex)))))}(a);let i=null;for(let l=0;null==i&&l1&&void 0!==arguments[1]?arguments[1]:[],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"",o=(e,o,a)=>{let i={relativePath:void 0===a?e.path||"":a,caseSensitive:!0===e.caseSensitive,childrenIndex:o,route:e};i.relativePath.startsWith("/")&&(w(i.relativePath.startsWith(r),'Absolute route path "'.concat(i.relativePath,'" nested under path "').concat(r,'" is not valid. An absolute child route path must start with the combined path of all its parent routes.')),i.relativePath=i.relativePath.slice(r.length));let l=K([r,i.relativePath]),s=n.concat(i);e.children&&e.children.length>0&&(w(!0!==e.index,'Index routes must not have child routes. Please remove all child routes from route path "'.concat(l,'".')),O(e.children,t,s,l)),(null!=e.path||e.index)&&t.push({path:l,score:_(l,e.index),routesMeta:s})};return e.forEach(((e,t)=>{var n;if(""!==e.path&&null!==(n=e.path)&&void 0!==n&&n.includes("?"))for(let r of M(e.path))o(e,t,r);else o(e,t)})),t}function M(e){let t=e.split("/");if(0===t.length)return[];let[n,...r]=t,o=n.endsWith("?"),a=n.replace(/\?$/,"");if(0===r.length)return o?[a,""]:[a];let i=M(r.join("/")),l=[];return l.push(...i.map((e=>""===e?a:[a,e].join("/")))),o&&l.push(...i),l.map((t=>e.startsWith("/")&&""===t?"/":t))}var A=/^:[\w-]+$/,N=3,z=2,I=1,L=10,B=-2,F=e=>"*"===e;function _(e,t){let n=e.split("/"),r=n.length;return n.some(F)&&(r+=B),t&&(r+=z),n.filter((e=>!F(e))).reduce(((e,t)=>e+(A.test(t)?N:""===t?I:L)),r)}function D(e,t){let n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],{routesMeta:r}=e,o={},a="/",i=[];for(let l=0;l1&&void 0!==arguments[1]&&arguments[1],n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];S("*"===e||!e.endsWith("*")||e.endsWith("/*"),'Route path "'.concat(e,'" will be treated as if it were "').concat(e.replace(/\*$/,"/*"),'" because the `*` character must always follow a `/` in the pattern. To get rid of this warning, please change the route path to "').concat(e.replace(/\*$/,"/*"),'".'));let r=[],o="^"+e.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,((e,t,n)=>(r.push({paramName:t,isOptional:null!=n}),n?"/?([^\\/]+)?":"/([^\\/]+)")));e.endsWith("*")?(r.push({paramName:"*"}),o+="*"===e||"/*"===e?"(.*)$":"(?:\\/(.+)|\\/*)$"):n?o+="\\/*$":""!==e&&"/"!==e&&(o+="(?:(?=\\/|$))");let a=new RegExp(o,t?void 0:"i");return[a,r]}(e.path,e.caseSensitive,e.end),o=t.match(n);if(!o)return null;let a=o[0],i=a.replace(/(.)\/+$/,"$1"),l=o.slice(1);return{params:r.reduce(((e,t,n)=>{let{paramName:r,isOptional:o}=t;if("*"===r){let e=l[n]||"";i=a.slice(0,a.length-e.length).replace(/(.)\/+$/,"$1")}const s=l[n];return e[r]=o&&!s?void 0:(s||"").replace(/%2F/g,"/"),e}),{}),pathname:a,pathnameBase:i,pattern:e}}function H(e){try{return e.split("/").map((e=>decodeURIComponent(e).replace(/\//g,"%2F"))).join("/")}catch(t){return S(!1,'The URL path "'.concat(e,'" could not be decoded because it is is a malformed URL segment. This is probably due to a bad percent encoding (').concat(t,").")),e}}function V(e,t){if("/"===t)return e;if(!e.toLowerCase().startsWith(t.toLowerCase()))return null;let n=t.endsWith("/")?t.length-1:t.length,r=e.charAt(n);return r&&"/"!==r?null:e.slice(n)||"/"}function U(e,t,n,r){return"Cannot include a '".concat(e,"' character in a manually specified `to.").concat(t,"` field [").concat(JSON.stringify(r),"]. Please separate it out to the `to.").concat(n,'` field. Alternatively you may provide the full path as a string in and the router will parse it for you.')}function q(e){return e.filter(((e,t)=>0===t||e.route.path&&e.route.path.length>0))}function $(e){let t=q(e);return t.map(((e,n)=>n===t.length-1?e.pathname:e.pathnameBase))}function G(e,t,n){let r,o=arguments.length>3&&void 0!==arguments[3]&&arguments[3];"string"===typeof e?r=R(e):(r=f({},e),w(!r.pathname||!r.pathname.includes("?"),U("?","pathname","search",r)),w(!r.pathname||!r.pathname.includes("#"),U("#","pathname","hash",r)),w(!r.search||!r.search.includes("#"),U("#","search","hash",r)));let a,i=""===e||""===r.pathname,l=i?"/":r.pathname;if(null==l)a=n;else{let e=t.length-1;if(!o&&l.startsWith("..")){let t=l.split("/");for(;".."===t[0];)t.shift(),e-=1;r.pathname=t.join("/")}a=e>=0?t[e]:"/"}let s=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"/",{pathname:n,search:r="",hash:o=""}="string"===typeof e?R(e):e,a=n?n.startsWith("/")?n:function(e,t){let n=t.replace(/\/+$/,"").split("/");return e.split("/").forEach((e=>{".."===e?n.length>1&&n.pop():"."!==e&&n.push(e)})),n.length>1?n.join("/"):"/"}(n,t):t;return{pathname:a,search:X(r),hash:Y(o)}}(r,a),c=l&&"/"!==l&&l.endsWith("/"),u=(i||"."===l)&&n.endsWith("/");return s.pathname.endsWith("/")||!c&&!u||(s.pathname+="/"),s}var K=e=>e.join("/").replace(/\/\/+/g,"/"),Q=e=>e.replace(/\/+$/,"").replace(/^\/*/,"/"),X=e=>e&&"?"!==e?e.startsWith("?")?e:"?"+e:"",Y=e=>e&&"#"!==e?e.startsWith("#")?e:"#"+e:"";function J(e){return null!=e&&"number"===typeof e.status&&"string"===typeof e.statusText&&"boolean"===typeof e.internal&&"data"in e}var Z=["POST","PUT","PATCH","DELETE"],ee=(new Set(Z),["GET",...Z]);new Set(ee),Symbol("ResetLoaderData");var te=o.createContext(null);te.displayName="DataRouter";var ne=o.createContext(null);ne.displayName="DataRouterState";var re=o.createContext({isTransitioning:!1});re.displayName="ViewTransition";var oe=o.createContext(new Map);oe.displayName="Fetchers";var ae=o.createContext(null);ae.displayName="Await";var ie=o.createContext(null);ie.displayName="Navigation";var le=o.createContext(null);le.displayName="Location";var se=o.createContext({outlet:null,matches:[],isDataRoute:!1});se.displayName="Route";var ce=o.createContext(null);ce.displayName="RouteError";function ue(){return null!=o.useContext(le)}function de(){return w(ue(),"useLocation() may be used only in the context of a component."),o.useContext(le).location}var pe="You should call navigate() in a React.useEffect(), not when your component is first rendered.";function fe(e){o.useContext(ie).static||o.useLayoutEffect(e)}function he(){let{isDataRoute:e}=o.useContext(se);return e?function(){let{router:e}=Ce("useNavigate"),t=Re("useNavigate"),n=o.useRef(!1);fe((()=>{n.current=!0}));let r=o.useCallback((async function(r){let o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};S(n.current,pe),n.current&&("number"===typeof r?e.navigate(r):await e.navigate(r,f({fromRouteId:t},o)))}),[e,t]);return r}():function(){w(ue(),"useNavigate() may be used only in the context of a component.");let e=o.useContext(te),{basename:t,navigator:n}=o.useContext(ie),{matches:r}=o.useContext(se),{pathname:a}=de(),i=JSON.stringify($(r)),l=o.useRef(!1);fe((()=>{l.current=!0}));let s=o.useCallback((function(r){let o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(S(l.current,pe),!l.current)return;if("number"===typeof r)return void n.go(r);let s=G(r,JSON.parse(i),a,"path"===o.relative);null==e&&"/"!==t&&(s.pathname="/"===s.pathname?t:K([t,s.pathname])),(o.replace?n.replace:n.push)(s,o.state,o)}),[t,n,i,a,e]);return s}()}var me=o.createContext(null);function ge(e){let{relative:t}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},{matches:n}=o.useContext(se),{pathname:r}=de(),a=JSON.stringify($(n));return o.useMemo((()=>G(e,JSON.parse(a),r,"path"===t)),[e,a,r,t])}function ve(e,t,n,r){w(ue(),"useRoutes() may be used only in the context of a component.");let{navigator:a}=o.useContext(ie),{matches:i}=o.useContext(se),l=i[i.length-1],s=l?l.params:{},c=l?l.pathname:"/",u=l?l.pathnameBase:"/",d=l&&l.route;{let e=d&&d.path||"";je(c,!d||e.endsWith("*")||e.endsWith("*?"),'You rendered descendant (or called `useRoutes()`) at "'.concat(c,'" (under ) but the parent route path has no trailing "*". This means if you navigate deeper, the parent won\'t match anymore and therefore the child routes will never render.\n\nPlease change the parent to .'))}let p,h=de();if(t){var m;let e="string"===typeof t?R(t):t;w("/"===u||(null===(m=e.pathname)||void 0===m?void 0:m.startsWith(u)),'When overriding the location using `` or `useRoutes(routes, location)`, the location pathname must begin with the portion of the URL pathname that was matched by all parent routes. The current pathname base is "'.concat(u,'" but pathname "').concat(e.pathname,'" was given in the `location` prop.')),p=e}else p=h;let g=p.pathname||"/",v=g;if("/"!==u){let e=u.replace(/^\//,"").split("/");v="/"+g.replace(/^\//,"").split("/").slice(e.length).join("/")}let y=T(e,{pathname:v});S(d||null!=y,'No routes matched location "'.concat(p.pathname).concat(p.search).concat(p.hash,'" ')),S(null==y||void 0!==y[y.length-1].route.element||void 0!==y[y.length-1].route.Component||void 0!==y[y.length-1].route.lazy,'Matched leaf route at location "'.concat(p.pathname).concat(p.search).concat(p.hash,'" does not have an element or Component. This means it will render an with a null value by default resulting in an "empty" page.'));let b=Se(y&&y.map((e=>Object.assign({},e,{params:Object.assign({},s,e.params),pathname:K([u,a.encodeLocation?a.encodeLocation(e.pathname).pathname:e.pathname]),pathnameBase:"/"===e.pathnameBase?u:K([u,a.encodeLocation?a.encodeLocation(e.pathnameBase).pathname:e.pathnameBase])}))),i,n,r);return t&&b?o.createElement(le.Provider,{value:{location:f({pathname:"/",search:"",hash:"",state:null,key:"default"},p),navigationType:"POP"}},b):b}function ye(){let e=Pe(),t=J(e)?"".concat(e.status," ").concat(e.statusText):e instanceof Error?e.message:JSON.stringify(e),n=e instanceof Error?e.stack:null,r="rgba(200,200,200, 0.5)",a={padding:"0.5rem",backgroundColor:r},i={padding:"2px 4px",backgroundColor:r},l=null;return console.error("Error handled by React Router default ErrorBoundary:",e),l=o.createElement(o.Fragment,null,o.createElement("p",null,"\ud83d\udcbf Hey developer \ud83d\udc4b"),o.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",o.createElement("code",{style:i},"ErrorBoundary")," or"," ",o.createElement("code",{style:i},"errorElement")," prop on your route.")),o.createElement(o.Fragment,null,o.createElement("h2",null,"Unexpected Application Error!"),o.createElement("h3",{style:{fontStyle:"italic"}},t),n?o.createElement("pre",{style:a},n):null,l)}var be=o.createElement(ye,null),xe=class extends o.Component{constructor(e){super(e),this.state={location:e.location,revalidation:e.revalidation,error:e.error}}static getDerivedStateFromError(e){return{error:e}}static getDerivedStateFromProps(e,t){return t.location!==e.location||"idle"!==t.revalidation&&"idle"===e.revalidation?{error:e.error,location:e.location,revalidation:e.revalidation}:{error:void 0!==e.error?e.error:t.error,location:t.location,revalidation:e.revalidation||t.revalidation}}componentDidCatch(e,t){console.error("React Router caught the following error during render",e,t)}render(){return void 0!==this.state.error?o.createElement(se.Provider,{value:this.props.routeContext},o.createElement(ce.Provider,{value:this.state.error,children:this.props.component})):this.props.children}};function we(e){let{routeContext:t,match:n,children:r}=e,a=o.useContext(te);return a&&a.static&&a.staticContext&&(n.route.errorElement||n.route.ErrorBoundary)&&(a.staticContext._deepestRenderedBoundaryId=n.route.id),o.createElement(se.Provider,{value:t},r)}function Se(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;if(null==e){if(!n)return null;if(n.errors)e=n.matches;else{if(0!==t.length||n.initialized||!(n.matches.length>0))return null;e=n.matches}}let r=e,a=null===n||void 0===n?void 0:n.errors;if(null!=a){let e=r.findIndex((e=>e.route.id&&void 0!==(null===a||void 0===a?void 0:a[e.route.id])));w(e>=0,"Could not find a matching route for errors on route IDs: ".concat(Object.keys(a).join(","))),r=r.slice(0,Math.min(r.length,e+1))}let i=!1,l=-1;if(n)for(let o=0;o=0?r.slice(0,l+1):[r[0]];break}}}return r.reduceRight(((e,s,c)=>{let u,d=!1,p=null,f=null;n&&(u=a&&s.route.id?a[s.route.id]:void 0,p=s.route.errorElement||be,i&&(l<0&&0===c?(je("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),d=!0,f=null):l===c&&(d=!0,f=s.route.hydrateFallbackElement||null)));let h=t.concat(r.slice(0,c+1)),m=()=>{let t;return t=u?p:d?f:s.route.Component?o.createElement(s.route.Component,null):s.route.element?s.route.element:e,o.createElement(we,{match:s,routeContext:{outlet:e,matches:h,isDataRoute:null!=n},children:t})};return n&&(s.route.ErrorBoundary||s.route.errorElement||0===c)?o.createElement(xe,{location:n.location,revalidation:n.revalidation,component:p,error:u,children:m(),routeContext:{outlet:null,matches:h,isDataRoute:!0}}):m()}),null)}function ke(e){return"".concat(e," must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.")}function Ce(e){let t=o.useContext(te);return w(t,ke(e)),t}function Ee(e){let t=o.useContext(ne);return w(t,ke(e)),t}function Re(e){let t=function(e){let t=o.useContext(se);return w(t,ke(e)),t}(e),n=t.matches[t.matches.length-1];return w(n.route.id,"".concat(e,' can only be used on routes that contain a unique "id"')),n.route.id}function Pe(){var e;let t=o.useContext(ce),n=Ee("useRouteError"),r=Re("useRouteError");return void 0!==t?t:null===(e=n.errors)||void 0===e?void 0:e[r]}var Te={};function je(e,t,n){t||Te[e]||(Te[e]=!0,S(!1,n))}o.memo((function(e){let{routes:t,future:n,state:r}=e;return ve(t,void 0,r,n)}));function Oe(e){let{to:t,replace:n,state:r,relative:a}=e;w(ue()," may be used only in the context of a component.");let{static:i}=o.useContext(ie);S(!i," must not be used on the initial render in a . This is a no-op, but you should modify your code so the is only ever rendered in response to some user interaction or state change.");let{matches:l}=o.useContext(se),{pathname:s}=de(),c=he(),u=G(t,$(l),s,"path"===a),d=JSON.stringify(u);return o.useEffect((()=>{c(JSON.parse(d),{replace:n,state:r,relative:a})}),[c,d,a,n,r]),null}function Me(e){return function(e){let t=o.useContext(se).outlet;return t?o.createElement(me.Provider,{value:e},t):t}(e.context)}function Ae(e){w(!1,"A is only ever to be used as the child of element, never rendered directly. Please wrap your in a .")}function Ne(e){let{basename:t="/",children:n=null,location:r,navigationType:a="POP",navigator:i,static:l=!1}=e;w(!ue(),"You cannot render a inside another . You should never have more than one in your app.");let s=t.replace(/^\/*/,"/"),c=o.useMemo((()=>({basename:s,navigator:i,static:l,future:{}})),[s,i,l]);"string"===typeof r&&(r=R(r));let{pathname:u="/",search:d="",hash:p="",state:f=null,key:h="default"}=r,m=o.useMemo((()=>{let e=V(u,s);return null==e?null:{location:{pathname:e,search:d,hash:p,state:f,key:h},navigationType:a}}),[s,u,d,p,f,h,a]);return S(null!=m,' is not able to match the URL "').concat(u).concat(d).concat(p,"\" because it does not start with the basename, so the won't render anything.")),null==m?null:o.createElement(ie.Provider,{value:c},o.createElement(le.Provider,{children:n,value:m}))}function ze(e){let{children:t,location:n}=e;return ve(Ie(t),n)}o.Component;function Ie(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],n=[];return o.Children.forEach(e,((e,r)=>{if(!o.isValidElement(e))return;let a=[...t,r];if(e.type===o.Fragment)return void n.push.apply(n,Ie(e.props.children,a));w(e.type===Ae,"[".concat("string"===typeof e.type?e.type:e.type.name,"] is not a component. All component children of must be a or ")),w(!e.props.index||!e.props.children,"An index route cannot have child routes.");let i={id:e.props.id||a.join("-"),caseSensitive:e.props.caseSensitive,element:e.props.element,Component:e.props.Component,index:e.props.index,path:e.props.path,loader:e.props.loader,action:e.props.action,hydrateFallbackElement:e.props.hydrateFallbackElement,HydrateFallback:e.props.HydrateFallback,errorElement:e.props.errorElement,ErrorBoundary:e.props.ErrorBoundary,hasErrorBoundary:!0===e.props.hasErrorBoundary||null!=e.props.ErrorBoundary||null!=e.props.errorElement,shouldRevalidate:e.props.shouldRevalidate,handle:e.props.handle,lazy:e.props.lazy};e.props.children&&(i.children=Ie(e.props.children,a)),n.push(i)})),n}var Le="get",Be="application/x-www-form-urlencoded";function Fe(e){return null!=e&&"string"===typeof e.tagName}var _e=null;var De=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function We(e){return null==e||De.has(e)?e:(S(!1,'"'.concat(e,'" is not a valid `encType` for `
`/`` and will default to "').concat(Be,'"')),null)}function He(e,t){let n,r,o,a,i;if(Fe(l=e)&&"form"===l.tagName.toLowerCase()){let i=e.getAttribute("action");r=i?V(i,t):null,n=e.getAttribute("method")||Le,o=We(e.getAttribute("enctype"))||Be,a=new FormData(e)}else if(function(e){return Fe(e)&&"button"===e.tagName.toLowerCase()}(e)||function(e){return Fe(e)&&"input"===e.tagName.toLowerCase()}(e)&&("submit"===e.type||"image"===e.type)){let i=e.form;if(null==i)throw new Error('Cannot submit a