diff --git a/.github/workflows/alerts-ee.yaml b/.github/workflows/alerts-ee.yaml index 1df316c3e..ad7201b2f 100644 --- a/.github/workflows/alerts-ee.yaml +++ b/.github/workflows/alerts-ee.yaml @@ -130,7 +130,7 @@ jobs: cat /tmp/image_override.yaml # Deploy command mkdir -p /tmp/charts - mv openreplay/charts/{ingress-nginx,alerts,quickwit,connector} /tmp/charts/ + mv openreplay/charts/{ingress-nginx,alerts,quickwit,connector,assist-api} /tmp/charts/ rm -rf openreplay/charts/* mv /tmp/charts/* openreplay/charts/ helm template openreplay -n app openreplay -f vars.yaml -f /tmp/image_override.yaml --set ingress-nginx.enabled=false --set skipMigration=true --no-hooks --kube-version=$k_version | kubectl apply -f - diff --git a/.github/workflows/alerts.yaml b/.github/workflows/alerts.yaml index c5d268648..7fb6e6742 100644 --- a/.github/workflows/alerts.yaml +++ b/.github/workflows/alerts.yaml @@ -130,7 +130,7 @@ jobs: cat /tmp/image_override.yaml # Deploy command mkdir -p /tmp/charts - mv openreplay/charts/{ingress-nginx,alerts,quickwit,connector} /tmp/charts/ + mv openreplay/charts/{ingress-nginx,alerts,quickwit,connector,assist-api} /tmp/charts/ rm -rf openreplay/charts/* mv /tmp/charts/* openreplay/charts/ helm template openreplay -n app openreplay -f vars.yaml -f /tmp/image_override.yaml --set ingress-nginx.enabled=false --set skipMigration=true --no-hooks | kubectl apply -n app -f - diff --git a/.github/workflows/api-ee.yaml b/.github/workflows/api-ee.yaml index ad2250e24..f93b0d873 100644 --- a/.github/workflows/api-ee.yaml +++ b/.github/workflows/api-ee.yaml @@ -127,7 +127,7 @@ jobs: cat /tmp/image_override.yaml # Deploy command mkdir -p /tmp/charts - mv openreplay/charts/{ingress-nginx,chalice,quickwit,connector} /tmp/charts/ + mv openreplay/charts/{ingress-nginx,chalice,quickwit,connector,assist-api} /tmp/charts/ rm -rf openreplay/charts/* mv /tmp/charts/* openreplay/charts/ helm template openreplay -n app openreplay -f vars.yaml -f /tmp/image_override.yaml --set ingress-nginx.enabled=false --set skipMigration=true --no-hooks --kube-version=$k_version | kubectl apply -f - diff --git a/.github/workflows/api.yaml b/.github/workflows/api.yaml index 4dbbfadb0..537510ce4 100644 --- a/.github/workflows/api.yaml +++ b/.github/workflows/api.yaml @@ -120,7 +120,7 @@ jobs: cat /tmp/image_override.yaml # Deploy command mkdir -p /tmp/charts - mv openreplay/charts/{ingress-nginx,chalice,quickwit,connector} /tmp/charts/ + mv openreplay/charts/{ingress-nginx,chalice,quickwit,connector,assist-api} /tmp/charts/ rm -rf openreplay/charts/* mv /tmp/charts/* openreplay/charts/ helm template openreplay -n app openreplay -f vars.yaml -f /tmp/image_override.yaml --set ingress-nginx.enabled=false --set skipMigration=true --no-hooks | kubectl apply -n app -f - diff --git a/.github/workflows/assist-ee.yaml b/.github/workflows/assist-ee.yaml index 808646328..c10b22939 100644 --- a/.github/workflows/assist-ee.yaml +++ b/.github/workflows/assist-ee.yaml @@ -113,7 +113,7 @@ jobs: cat /tmp/image_override.yaml # Deploy command mkdir -p /tmp/charts - mv openreplay/charts/{ingress-nginx,assist,quickwit,connector} /tmp/charts/ + mv openreplay/charts/{ingress-nginx,assist,quickwit,connector,assist-api} /tmp/charts/ rm -rf openreplay/charts/* mv /tmp/charts/* openreplay/charts/ helm template openreplay -n app openreplay -f vars.yaml -f /tmp/image_override.yaml --set ingress-nginx.enabled=false --set skipMigration=true --no-hooks --kube-version=$k_version | kubectl apply -f - diff --git a/.github/workflows/assist-server-ee.yaml b/.github/workflows/assist-server-ee.yaml index 62f857f9d..39401f5d2 100644 --- a/.github/workflows/assist-server-ee.yaml +++ b/.github/workflows/assist-server-ee.yaml @@ -111,7 +111,7 @@ jobs: cat /tmp/image_override.yaml # Deploy command mkdir -p /tmp/charts - mv openreplay/charts/{ingress-nginx,assist-server,quickwit,connector} /tmp/charts/ + mv openreplay/charts/{ingress-nginx,assist-server,quickwit,connector,assist-api} /tmp/charts/ rm -rf openreplay/charts/* mv /tmp/charts/* openreplay/charts/ helm template openreplay -n app openreplay -f vars.yaml -f /tmp/image_override.yaml --set ingress-nginx.enabled=false --set skipMigration=true --no-hooks --kube-version=$k_version | kubectl apply -f - diff --git a/.github/workflows/assist-stats.yaml b/.github/workflows/assist-stats.yaml index f76861237..5323d13da 100644 --- a/.github/workflows/assist-stats.yaml +++ b/.github/workflows/assist-stats.yaml @@ -130,7 +130,7 @@ jobs: cat /tmp/image_override.yaml # Deploy command mkdir -p /tmp/charts - mv openreplay/charts/{ingress-nginx,assist-stats,quickwit,connector} /tmp/charts/ + mv openreplay/charts/{ingress-nginx,assist-stats,quickwit,connector,assist-api} /tmp/charts/ rm -rf openreplay/charts/* mv /tmp/charts/* openreplay/charts/ helm template openreplay -n app openreplay -f vars.yaml -f /tmp/image_override.yaml --set ingress-nginx.enabled=false --set skipMigration=true --no-hooks | kubectl apply -f - diff --git a/.github/workflows/assist.yaml b/.github/workflows/assist.yaml index 4c8a454b7..970ceb3c1 100644 --- a/.github/workflows/assist.yaml +++ b/.github/workflows/assist.yaml @@ -112,7 +112,7 @@ jobs: cat /tmp/image_override.yaml # Deploy command mkdir -p /tmp/charts - mv openreplay/charts/{ingress-nginx,assist,quickwit,connector} /tmp/charts/ + mv openreplay/charts/{ingress-nginx,assist,quickwit,connector,assist-api} /tmp/charts/ rm -rf openreplay/charts/* mv /tmp/charts/* openreplay/charts/ helm template openreplay -n app openreplay -f vars.yaml -f /tmp/image_override.yaml --set ingress-nginx.enabled=false --set skipMigration=true --no-hooks --kube-version=$k_version | kubectl apply -f - diff --git a/.github/workflows/crons-ee.yaml b/.github/workflows/crons-ee.yaml index 56bf97b2c..7c46049c5 100644 --- a/.github/workflows/crons-ee.yaml +++ b/.github/workflows/crons-ee.yaml @@ -129,7 +129,7 @@ jobs: cat /tmp/image_override.yaml # Deploy command mkdir -p /tmp/charts - mv openreplay/charts/{ingress-nginx,utilities,quickwit,connector} /tmp/charts/ + mv openreplay/charts/{ingress-nginx,utilities,quickwit,connector,assist-api} /tmp/charts/ rm -rf openreplay/charts/* mv /tmp/charts/* openreplay/charts/ helm template openreplay -n app openreplay -f vars.yaml -f /tmp/image_override.yaml --set ingress-nginx.enabled=false --set skipMigration=true --no-hooks --kube-version=$k_version | kubectl apply -f - diff --git a/.github/workflows/frontend-dev.yaml b/.github/workflows/frontend-dev.yaml index 548ed2537..446164ba6 100644 --- a/.github/workflows/frontend-dev.yaml +++ b/.github/workflows/frontend-dev.yaml @@ -76,7 +76,7 @@ jobs: cat /tmp/image_override.yaml # Deploy command mkdir -p /tmp/charts - mv openreplay/charts/{ingress-nginx,frontend,quickwit,connector} /tmp/charts/ + mv openreplay/charts/{ingress-nginx,frontend,quickwit,connector,assist-api} /tmp/charts/ rm -rf openreplay/charts/* mv /tmp/charts/* openreplay/charts/ helm template openreplay -n app openreplay -f vars.yaml -f /tmp/image_override.yaml --set ingress-nginx.enabled=false --set skipMigration=true --no-hooks | kubectl apply -n app -f - diff --git a/.github/workflows/frontend.yaml b/.github/workflows/frontend.yaml index 1dc69c580..25e68c0c8 100644 --- a/.github/workflows/frontend.yaml +++ b/.github/workflows/frontend.yaml @@ -89,7 +89,7 @@ jobs: cat /tmp/image_override.yaml # Deploy command mkdir -p /tmp/charts - mv openreplay/charts/{ingress-nginx,frontend,quickwit,connector} /tmp/charts/ + mv openreplay/charts/{ingress-nginx,frontend,quickwit,connector,assist-api} /tmp/charts/ rm -rf openreplay/charts/* mv /tmp/charts/* openreplay/charts/ helm template openreplay -n app openreplay -f vars.yaml -f /tmp/image_override.yaml --set ingress-nginx.enabled=false --set skipMigration=true --no-hooks | kubectl apply -n app -f - @@ -138,7 +138,7 @@ jobs: cat /tmp/image_override.yaml # Deploy command mkdir -p /tmp/charts - mv openreplay/charts/{ingress-nginx,frontend,quickwit,connector} /tmp/charts/ + mv openreplay/charts/{ingress-nginx,frontend,quickwit,connector,assist-api} /tmp/charts/ rm -rf openreplay/charts/* mv /tmp/charts/* openreplay/charts/ helm template openreplay -n app openreplay -f vars.yaml -f /tmp/image_override.yaml --set ingress-nginx.enabled=false --set skipMigration=true --no-hooks | kubectl apply -n app -f - diff --git a/.github/workflows/patch-build.yaml b/.github/workflows/patch-build.yaml index c6ef462c1..9825be3f9 100644 --- a/.github/workflows/patch-build.yaml +++ b/.github/workflows/patch-build.yaml @@ -20,12 +20,20 @@ jobs: DEPOT_PROJECT_ID: ${{ secrets.DEPOT_PROJECT_ID }} steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: - fetch-depth: 1 + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} - name: Rebase with main branch, to make sure the code has latest main changes + if: github.ref != 'refs/heads/main' run: | - git pull --rebase origin main + git remote -v + git config --global user.email "action@github.com" + git config --global user.name "GitHub Action" + git config --global rebase.autoStash true + git fetch origin main:main + git rebase main + git log -3 - name: Downloading yq run: | @@ -48,6 +56,8 @@ jobs: aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin ${{ secrets.RELEASE_OSS_REGISTRY }} - uses: depot/setup-action@v1 + env: + DEPOT_TOKEN: ${{ secrets.DEPOT_TOKEN }} - name: Get HEAD Commit ID run: echo "HEAD_COMMIT_ID=$(git rev-parse HEAD)" >> $GITHUB_ENV - name: Define Branch Name @@ -100,7 +110,7 @@ jobs: else cd $MSAAS_REPO_FOLDER/openreplay/$service fi - IMAGE_TAG=$version DOCKER_RUNTIME="depot" DOCKER_BUILD_ARGS="--push" ARCH=arm64 DOCKER_REPO=$DOCKER_REPO_ARM PUSH_IMAGE=0 bash build.sh >> /tmp/arm.txt + IMAGE_TAG=$version DOCKER_RUNTIME="depot" DOCKER_BUILD_ARGS="--push" ARCH=amd64 DOCKER_REPO=$DOCKER_REPO_OSS PUSH_IMAGE=0 bash $BUILD_SCRIPT_NAME >> /tmp/managed_${service}.txt 2>&1 || { echo "Build failed for $service"; cat /tmp/managed_${service}.txt; exit 1; } } # Checking for backend images ls backend/cmd >> /tmp/backend.txt diff --git a/.github/workflows/sourcemaps-reader-ee.yaml b/.github/workflows/sourcemaps-reader-ee.yaml index 459762c69..0822f4b32 100644 --- a/.github/workflows/sourcemaps-reader-ee.yaml +++ b/.github/workflows/sourcemaps-reader-ee.yaml @@ -119,7 +119,7 @@ jobs: cat /tmp/image_override.yaml # Deploy command mkdir -p /tmp/charts - mv openreplay/charts/{ingress-nginx,sourcemapreader,quickwit,connector} /tmp/charts/ + mv openreplay/charts/{ingress-nginx,sourcemapreader,quickwit,connector,assist-api} /tmp/charts/ rm -rf openreplay/charts/* mv /tmp/charts/* openreplay/charts/ helm template openreplay -n app openreplay -f vars.yaml -f /tmp/image_override.yaml --set ingress-nginx.enabled=false --set skipMigration=true --no-hooks | kubectl apply -n app -f - diff --git a/.github/workflows/sourcemaps-reader.yaml b/.github/workflows/sourcemaps-reader.yaml index a05dfaeb2..b6a8ea79b 100644 --- a/.github/workflows/sourcemaps-reader.yaml +++ b/.github/workflows/sourcemaps-reader.yaml @@ -118,7 +118,7 @@ jobs: cat /tmp/image_override.yaml # Deploy command mkdir -p /tmp/charts - mv openreplay/charts/{ingress-nginx,sourcemapreader,quickwit,connector} /tmp/charts/ + mv openreplay/charts/{ingress-nginx,sourcemapreader,quickwit,connector,assist-api} /tmp/charts/ rm -rf openreplay/charts/* mv /tmp/charts/* openreplay/charts/ helm template openreplay -n app openreplay -f vars.yaml -f /tmp/image_override.yaml --set ingress-nginx.enabled=false --set skipMigration=true --no-hooks | kubectl apply -n app -f - diff --git a/.github/workflows/workers-ee.yaml b/.github/workflows/workers-ee.yaml index 5ed1039b2..5c8951f75 100644 --- a/.github/workflows/workers-ee.yaml +++ b/.github/workflows/workers-ee.yaml @@ -148,9 +148,7 @@ jobs: set -x echo > /tmp/image_override.yaml mkdir /tmp/helmcharts - mv openreplay/charts/ingress-nginx /tmp/helmcharts/ - mv openreplay/charts/quickwit /tmp/helmcharts/ - mv openreplay/charts/connector /tmp/helmcharts/ + mv openreplay/charts/{ingress-nginx,quickwit,connector,assist-api} /tmp/helmcharts/ ## Update images for image in $(cat /tmp/images_to_build.txt); do diff --git a/.github/workflows/workers.yaml b/.github/workflows/workers.yaml index ceb4e0f43..0e1c4c341 100644 --- a/.github/workflows/workers.yaml +++ b/.github/workflows/workers.yaml @@ -141,9 +141,7 @@ jobs: set -x echo > /tmp/image_override.yaml mkdir /tmp/helmcharts - mv openreplay/charts/ingress-nginx /tmp/helmcharts/ - mv openreplay/charts/quickwit /tmp/helmcharts/ - mv openreplay/charts/connector /tmp/helmcharts/ + mv openreplay/charts/{ingress-nginx,quickwit,connector,assist-api} /tmp/helmcharts/ ## Update images for image in $(cat /tmp/images_to_build.txt); do diff --git a/api/chalicelib/core/events/events_ch.py b/api/chalicelib/core/events/events_ch.py index f1f28a9e7..384a31d3d 100644 --- a/api/chalicelib/core/events/events_ch.py +++ b/api/chalicelib/core/events/events_ch.py @@ -1,18 +1,13 @@ from chalicelib.utils import ch_client from .events_pg import * - - -def __explode_properties(rows): - for i in range(len(rows)): - rows[i] = {**rows[i], **rows[i]["$properties"]} - rows[i].pop("$properties") - return rows +from chalicelib.utils.exp_ch_helper import explode_dproperties, add_timestamp def get_customs_by_session_id(session_id, project_id): with ch_client.ClickHouseClient() as cur: rows = cur.execute(""" \ SELECT `$properties`, + properties, created_at, 'CUSTOM' AS type FROM product_analytics.events @@ -21,8 +16,10 @@ def get_customs_by_session_id(session_id, project_id): AND `$event_name`!='INCIDENT' ORDER BY created_at;""", {"project_id": project_id, "session_id": session_id}) - rows = __explode_properties(rows) - return helper.list_to_camel_case(rows) + rows = helper.list_to_camel_case(rows, ignore_keys=["properties"]) + rows = explode_dproperties(rows) + rows = add_timestamp(rows) + return rows def __merge_cells(rows, start, count, replacement): @@ -69,12 +66,13 @@ def get_by_session_id(session_id, project_id, group_clickrage=False, event_type: parameters={"project_id": project_id, "session_id": session_id, "select_events": select_events}) rows = cur.execute(query) - rows = __explode_properties(rows) + rows = explode_dproperties(rows) if group_clickrage and 'CLICK' in select_events: rows = __get_grouped_clickrage(rows=rows, session_id=session_id, project_id=project_id) rows = helper.list_to_camel_case(rows) rows = sorted(rows, key=lambda k: k["createdAt"]) + rows = add_timestamp(rows) return rows @@ -91,7 +89,7 @@ def get_incidents_by_session_id(session_id, project_id): ORDER BY created_at;""", parameters={"project_id": project_id, "session_id": session_id}) rows = cur.execute(query) - rows = __explode_properties(rows) + rows = explode_dproperties(rows) rows = helper.list_to_camel_case(rows) rows = sorted(rows, key=lambda k: k["createdAt"]) return rows diff --git a/api/chalicelib/core/events/events_pg.py b/api/chalicelib/core/events/events_pg.py index 06b524f51..d8bba29d5 100644 --- a/api/chalicelib/core/events/events_pg.py +++ b/api/chalicelib/core/events/events_pg.py @@ -131,7 +131,7 @@ def supported_types(): query=autocomplete.__generic_query( typename=schemas.EventType.GRAPHQL)), schemas.EventType.STATE_ACTION: SupportedFilter( - get=autocomplete.__generic_autocomplete(schemas.EventType.STATEACTION), + get=autocomplete.__generic_autocomplete(schemas.EventType.STATE_ACTION), query=autocomplete.__generic_query( typename=schemas.EventType.STATE_ACTION)), schemas.EventType.TAG: SupportedFilter(get=_search_tags, query=None), diff --git a/api/chalicelib/core/issue_tracking/jira_cloud.py b/api/chalicelib/core/issue_tracking/jira_cloud.py index eb86bf915..ffd0c380c 100644 --- a/api/chalicelib/core/issue_tracking/jira_cloud.py +++ b/api/chalicelib/core/issue_tracking/jira_cloud.py @@ -50,8 +50,8 @@ class JIRAIntegration(base.BaseIntegration): cur.execute( cur.mogrify( """SELECT username, token, url - FROM public.jira_cloud - WHERE user_id=%(user_id)s;""", + FROM public.jira_cloud + WHERE user_id = %(user_id)s;""", {"user_id": self._user_id}) ) data = helper.dict_to_camel_case(cur.fetchone()) @@ -95,10 +95,9 @@ class JIRAIntegration(base.BaseIntegration): def add(self, username, token, url, obfuscate=False): with pg_client.PostgresClient() as cur: cur.execute( - cur.mogrify("""\ - INSERT INTO public.jira_cloud(username, token, user_id,url) - VALUES (%(username)s, %(token)s, %(user_id)s,%(url)s) - RETURNING username, token, url;""", + cur.mogrify(""" \ + INSERT INTO public.jira_cloud(username, token, user_id, url) + VALUES (%(username)s, %(token)s, %(user_id)s, %(url)s) RETURNING username, token, url;""", {"user_id": self._user_id, "username": username, "token": token, "url": url}) ) @@ -112,9 +111,10 @@ class JIRAIntegration(base.BaseIntegration): def delete(self): with pg_client.PostgresClient() as cur: cur.execute( - cur.mogrify("""\ - DELETE FROM public.jira_cloud - WHERE user_id=%(user_id)s;""", + cur.mogrify(""" \ + DELETE + FROM public.jira_cloud + WHERE user_id = %(user_id)s;""", {"user_id": self._user_id}) ) return {"state": "success"} @@ -125,7 +125,7 @@ class JIRAIntegration(base.BaseIntegration): changes={ "username": data.username, "token": data.token if len(data.token) > 0 and data.token.find("***") == -1 \ - else self.integration.token, + else self.integration["token"], "url": str(data.url) }, obfuscate=True diff --git a/api/chalicelib/core/issues/issues_ch.py b/api/chalicelib/core/issues/issues_ch.py index b6297f598..3b0421747 100644 --- a/api/chalicelib/core/issues/issues_ch.py +++ b/api/chalicelib/core/issues/issues_ch.py @@ -1,6 +1,6 @@ from chalicelib.utils import ch_client, helper import datetime -from .issues_pg import get_all_types +from chalicelib.utils.exp_ch_helper import explode_dproperties, add_timestamp def get(project_id, issue_id): @@ -21,7 +21,7 @@ def get(project_id, issue_id): def get_by_session_id(session_id, project_id, issue_type=None): with ch_client.ClickHouseClient() as cur: query = cur.format(query=f"""\ - SELECT * + SELECT created_at, `$properties` FROM product_analytics.events WHERE session_id = %(session_id)s AND project_id= %(project_id)s @@ -29,8 +29,11 @@ def get_by_session_id(session_id, project_id, issue_type=None): {"AND issue_type = %(type)s" if issue_type is not None else ""} ORDER BY created_at;""", parameters={"session_id": session_id, "project_id": project_id, "type": issue_type}) - data = cur.execute(query) - return helper.list_to_camel_case(data) + rows = cur.execute(query) + rows = explode_dproperties(rows) + rows = helper.list_to_camel_case(rows) + rows = add_timestamp(rows) + return rows # To reduce the number of issues in the replay; diff --git a/api/chalicelib/core/metadata.py b/api/chalicelib/core/metadata.py index 1e7fcea00..85bb523d4 100644 --- a/api/chalicelib/core/metadata.py +++ b/api/chalicelib/core/metadata.py @@ -260,6 +260,5 @@ def get_for_filters(project_id): "name": k, "displayName": metas[k], "possibleTypes": ["String"], - "autoCaptured": False, - "icon": None}) + "autoCaptured": False}) return {"total": len(results), "list": results} diff --git a/api/chalicelib/core/metrics/custom_metrics.py b/api/chalicelib/core/metrics/custom_metrics.py index 1df053c73..06fe705c9 100644 --- a/api/chalicelib/core/metrics/custom_metrics.py +++ b/api/chalicelib/core/metrics/custom_metrics.py @@ -172,7 +172,8 @@ def get_sessions_by_card_id(project: schemas.ProjectContext, user_id, metric_id, results = [] for s in data.series: results.append({"seriesId": s.series_id, "seriesName": s.name, - **sessions_search.search_sessions(data=s.filter, project=project, user_id=user_id)}) + **sessions_search.search_sessions(data=s.filter, project=project, user_id=user_id, + metric_of=data.metric_of)}) return results @@ -187,7 +188,8 @@ def get_sessions(project: schemas.ProjectContext, user_id, data: schemas.CardSes s.filter = schemas.SessionsSearchPayloadSchema(**s.filter.model_dump(by_alias=True)) results.append({"seriesId": None, "seriesName": s.name, - **sessions_search.search_sessions(data=s.filter, project=project, user_id=user_id)}) + **sessions_search.search_sessions(data=s.filter, project=project, user_id=user_id, + metric_of=data.metric_of)}) return results diff --git a/api/chalicelib/core/product_analytics/autocomplete.py b/api/chalicelib/core/product_analytics/autocomplete.py index fafcc72d6..25493be77 100644 --- a/api/chalicelib/core/product_analytics/autocomplete.py +++ b/api/chalicelib/core/product_analytics/autocomplete.py @@ -28,32 +28,32 @@ def search_events(project_id: int, q: Optional[str] = None): def search_properties(project_id: int, property_name: Optional[str] = None, event_name: Optional[str] = None, q: Optional[str] = None): with ClickHouseClient() as ch_client: - select = "value" + select = "value, data_count" + grouping = "" full_args = {"project_id": project_id, "limit": 20, - "event_name": event_name, "property_name": property_name, "q": q, - "property_name_l": helper.string_to_sql_like(property_name), + "event_name": event_name, "property_name": property_name, "q_l": helper.string_to_sql_like(q)} constraints = ["project_id = %(project_id)s", - "_timestamp >= now()-INTERVAL 1 MONTH"] + "_timestamp >= now()-INTERVAL 1 MONTH", + "property_name = %(property_name)s"] if event_name: constraints += ["event_name = %(event_name)s"] - - if property_name and q: - constraints += ["property_name = %(property_name)s"] - elif property_name: - select = "DISTINCT ON(property_name) property_name AS value" - constraints += ["property_name ILIKE %(property_name_l)s"] + else: + select = "value, sum(aepg.data_count) AS data_count" + grouping = "GROUP BY 1" if q: constraints += ["value ILIKE %(q_l)s"] + query = ch_client.format( - f"""SELECT {select},data_count - FROM product_analytics.autocomplete_event_properties_grouped - WHERE {" AND ".join(constraints)} - ORDER BY data_count DESC + f"""SELECT {select} + FROM product_analytics.autocomplete_event_properties_grouped AS aepg + WHERE {" AND ".join(constraints)} + {grouping} + ORDER BY data_count DESC LIMIT %(limit)s;""", parameters=full_args) rows = ch_client.execute(query) - return {"values": helper.list_to_camel_case(rows), "_src": 2} + return {"events": helper.list_to_camel_case(rows), "_src": 2} diff --git a/api/chalicelib/core/product_analytics/events.py b/api/chalicelib/core/product_analytics/events.py index f7b4cea86..99a2914d3 100644 --- a/api/chalicelib/core/product_analytics/events.py +++ b/api/chalicelib/core/product_analytics/events.py @@ -7,14 +7,13 @@ from chalicelib.utils.ch_client import ClickHouseClient from chalicelib.utils.exp_ch_helper import get_sub_condition, get_col_cast logger = logging.getLogger(__name__) -PREDEFINED_EVENTS = { - "CLICK": "String", - "INPUT": "String", - "LOCATION": "String", - "ERROR": "String", - "PERFORMANCE": "String", - "REQUEST": "String" -} +PREDEFINED_EVENTS = [ + "CLICK", + "INPUT", + "LOCATION", + "ERROR", + "REQUEST" +] def get_events(project_id: int, page: schemas.PaginatedSchema): diff --git a/api/chalicelib/core/product_analytics/properties.py b/api/chalicelib/core/product_analytics/properties.py index c88fe1c7d..24fcc7f7e 100644 --- a/api/chalicelib/core/product_analytics/properties.py +++ b/api/chalicelib/core/product_analytics/properties.py @@ -58,6 +58,14 @@ PREDEFINED_PROPERTIES = { "message_id": "UInt64" } +EVENT_DEFAULT_PROPERTIES = { + "CLICK": "label", + "INPUT": "label", + "LOCATION": "url_path", + "ERROR": "name", + "REQUEST": "url_path" +} + def get_all_properties(project_id: int, page: schemas.PaginatedSchema): with ClickHouseClient() as ch_client: @@ -104,7 +112,7 @@ def get_all_properties(project_id: int, page: schemas.PaginatedSchema): return {"total": total, "list": properties} -def get_event_properties(project_id: int, event_name): +def get_event_properties(project_id: int, event_name: str, auto_captured: bool): with ClickHouseClient() as ch_client: r = ch_client.format( """SELECT all_properties.property_name AS name, @@ -115,9 +123,10 @@ def get_event_properties(project_id: int, event_name): WHERE event_properties.project_id = %(project_id)s AND all_properties.project_id = %(project_id)s AND event_properties.event_name = %(event_name)s + AND event_properties.auto_captured = %(auto_captured)s GROUP BY ALL ORDER BY 1;""", - parameters={"project_id": project_id, "event_name": event_name}) + parameters={"project_id": project_id, "event_name": event_name, "auto_captured": auto_captured}) properties = ch_client.execute(r) properties = helper.list_to_camel_case(properties) for i, p in enumerate(properties): @@ -127,6 +136,8 @@ def get_event_properties(project_id: int, event_name): p["dataType"] = exp_ch_helper.simplify_clickhouse_type(PREDEFINED_PROPERTIES[p["name"]]) p["_foundInPredefinedList"] = True p["possibleTypes"] = list(set(exp_ch_helper.simplify_clickhouse_types(p["possibleTypes"]))) + p["defaultProperty"] = auto_captured and event_name in EVENT_DEFAULT_PROPERTIES \ + and p["name"] == EVENT_DEFAULT_PROPERTIES[event_name] return properties diff --git a/api/chalicelib/core/sessions/sessions_ch.py b/api/chalicelib/core/sessions/sessions_ch.py index fb5457932..69e0d5111 100644 --- a/api/chalicelib/core/sessions/sessions_ch.py +++ b/api/chalicelib/core/sessions/sessions_ch.py @@ -150,7 +150,7 @@ def search2_table(data: schemas.SessionsSearchPayloadSchema, project_id: int, de for e in data.events: if e.type == schemas.EventType.LOCATION: if e.operator not in extra_conditions: - extra_conditions[e.operator] = schemas.SessionSearchEventSchema.model_validate({ + extra_conditions[e.operator] = schemas.SessionSearchEventSchema(**{ "type": e.type, "isEvent": True, "value": [], @@ -175,7 +175,7 @@ def search2_table(data: schemas.SessionsSearchPayloadSchema, project_id: int, de for e in data.events: if e.type == schemas.EventType.REQUEST_DETAILS: if e.operator not in extra_conditions: - extra_conditions[e.operator] = schemas.SessionSearchEventSchema.model_validate({ + extra_conditions[e.operator] = schemas.SessionSearchEventSchema(**{ "type": e.type, "isEvent": True, "value": [], @@ -240,8 +240,10 @@ def search2_table(data: schemas.SessionsSearchPayloadSchema, project_id: int, de main_query = f"""SELECT COUNT(DISTINCT {main_col}) OVER () AS main_count, {main_col} AS name, count(DISTINCT session_id) AS total, - COALESCE(SUM(count(DISTINCT session_id)) OVER (), 0) AS total_count - FROM (SELECT s.session_id AS session_id {extra_col} + any(total_count) as total_count + FROM (SELECT s.session_id AS session_id, + count(DISTINCT s.session_id) OVER () AS total_count + {extra_col} {query_part}) AS filtred_sessions {extra_where} GROUP BY {main_col} @@ -251,8 +253,10 @@ def search2_table(data: schemas.SessionsSearchPayloadSchema, project_id: int, de main_query = f"""SELECT COUNT(DISTINCT {main_col}) OVER () AS main_count, {main_col} AS name, count(DISTINCT user_id) AS total, - COALESCE(SUM(count(DISTINCT user_id)) OVER (), 0) AS total_count - FROM (SELECT s.user_id AS user_id {extra_col} + any(total_count) AS total_count + FROM (SELECT s.user_id AS user_id, + count(DISTINCT s.user_id) OVER () AS total_count + {extra_col} {query_part} WHERE isNotNull(user_id) AND notEmpty(user_id)) AS filtred_sessions diff --git a/api/chalicelib/core/sessions/sessions_search_ch.py b/api/chalicelib/core/sessions/sessions_search_ch.py index c0142bae4..2b03b27b1 100644 --- a/api/chalicelib/core/sessions/sessions_search_ch.py +++ b/api/chalicelib/core/sessions/sessions_search_ch.py @@ -64,8 +64,7 @@ def __parse_metadata(metadata_map): # This function executes the query and return result def search_sessions(data: schemas.SessionsSearchPayloadSchema, project: schemas.ProjectContext, user_id, errors_only=False, error_status=schemas.ErrorStatus.ALL, - count_only=False, issue=None, ids_only=False): - platform = project.platform + count_only=False, issue=None, ids_only=False, metric_of: schemas.MetricOfTable = None): if data.bookmarked: data.startTimestamp, data.endTimestamp = sessions_favorite.get_start_end_timestamp(project.project_id, user_id) if data.startTimestamp is None: @@ -75,18 +74,78 @@ def search_sessions(data: schemas.SessionsSearchPayloadSchema, project: schemas. 'sessions': [], '_src': 2 } + # ---------------------- extra filter in order to only select sessions that has been used in the card-table + extra_event = None + # extra_deduplication = [] + extra_conditions = None + if metric_of == schemas.MetricOfTable.VISITED_URL: + extra_event = f"""SELECT DISTINCT ev.session_id, + JSONExtractString(toString(ev.`$properties`), 'url_path') AS url_path + FROM {exp_ch_helper.get_main_events_table(data.startTimestamp)} AS ev + WHERE ev.created_at >= toDateTime(%(startDate)s / 1000) + AND ev.created_at <= toDateTime(%(endDate)s / 1000) + AND ev.project_id = %(project_id)s + AND ev.`$event_name` = 'LOCATION'""" + # extra_deduplication.append("url_path") + extra_conditions = {} + for e in data.events: + if e.type == schemas.EventType.LOCATION: + if e.operator not in extra_conditions: + extra_conditions[e.operator] = schemas.SessionSearchEventSchema(**{ + "type": e.type, + "isEvent": True, + "value": [], + "operator": e.operator, + "filters": e.filters + }) + for v in e.value: + if v not in extra_conditions[e.operator].value: + extra_conditions[e.operator].value.append(v) + extra_conditions = list(extra_conditions.values()) + elif metric_of == schemas.MetricOfTable.FETCH: + extra_event = f"""SELECT DISTINCT ev.session_id + FROM {exp_ch_helper.get_main_events_table(data.startTimestamp)} AS ev + WHERE ev.created_at >= toDateTime(%(startDate)s / 1000) + AND ev.created_at <= toDateTime(%(endDate)s / 1000) + AND ev.project_id = %(project_id)s + AND ev.`$event_name` = 'REQUEST'""" + + # extra_deduplication.append("url_path") + extra_conditions = {} + for e in data.events: + if e.type == schemas.EventType.REQUEST_DETAILS: + if e.operator not in extra_conditions: + extra_conditions[e.operator] = schemas.SessionSearchEventSchema(**{ + "type": e.type, + "isEvent": True, + "value": [], + "operator": e.operator, + "filters": e.filters + }) + for v in e.value: + if v not in extra_conditions[e.operator].value: + extra_conditions[e.operator].value.append(v) + extra_conditions = list(extra_conditions.values()) + + # elif metric_of == schemas.MetricOfTable.ISSUES and len(metric_value) > 0: + # data.filters.append(schemas.SessionSearchFilterSchema(value=metric_value, type=schemas.FilterType.ISSUE, + # operator=schemas.SearchEventOperator.IS)) + # ---------------------- if project.platform == "web": full_args, query_part = sessions.search_query_parts_ch(data=data, error_status=error_status, errors_only=errors_only, favorite_only=data.bookmarked, issue=issue, project_id=project.project_id, - user_id=user_id, platform=platform) + user_id=user_id, platform=project.platform, + extra_event=extra_event, + # extra_deduplication=extra_deduplication, + extra_conditions=extra_conditions) else: full_args, query_part = sessions_legacy_mobil.search_query_parts_ch(data=data, error_status=error_status, errors_only=errors_only, favorite_only=data.bookmarked, issue=issue, project_id=project.project_id, - user_id=user_id, platform=platform) + user_id=user_id, platform=project.platform) if data.sort == "startTs": data.sort = "datetime" if data.limit is not None and data.page is not None: diff --git a/api/chalicelib/core/sessions/sessions_search_pg.py b/api/chalicelib/core/sessions/sessions_search_pg.py index 9036e2686..920ea6487 100644 --- a/api/chalicelib/core/sessions/sessions_search_pg.py +++ b/api/chalicelib/core/sessions/sessions_search_pg.py @@ -40,7 +40,7 @@ COALESCE((SELECT TRUE # This function executes the query and return result def search_sessions(data: schemas.SessionsSearchPayloadSchema, project: schemas.ProjectContext, user_id, errors_only=False, error_status=schemas.ErrorStatus.ALL, - count_only=False, issue=None, ids_only=False): + count_only=False, issue=None, ids_only=False, metric_of: schemas.MetricOfTable = None): platform = project.platform if data.bookmarked: data.startTimestamp, data.endTimestamp = sessions_favorite.get_start_end_timestamp(project.project_id, user_id) diff --git a/api/chalicelib/utils/exp_ch_helper.py b/api/chalicelib/utils/exp_ch_helper.py index a0d02a524..f1231ec09 100644 --- a/api/chalicelib/utils/exp_ch_helper.py +++ b/api/chalicelib/utils/exp_ch_helper.py @@ -1,13 +1,14 @@ import logging +import math import re +import struct +from decimal import Decimal from typing import Union, Any import schemas from chalicelib.utils import sql_helper as sh +from chalicelib.utils.TimeUTC import TimeUTC from schemas import SearchEventOperator -import math -import struct -from decimal import Decimal logger = logging.getLogger(__name__) @@ -233,3 +234,16 @@ def best_clickhouse_type(value): return "Float64" raise TypeError(f"Unsupported type: {type(value).__name__}") + + +def explode_dproperties(rows): + for i in range(len(rows)): + rows[i] = {**rows[i], **rows[i]["$properties"]} + rows[i].pop("$properties") + return rows + + +def add_timestamp(rows): + for row in rows: + row["timestamp"] = TimeUTC.datetime_to_timestamp(row["createdAt"]) + return rows diff --git a/api/chalicelib/utils/helper.py b/api/chalicelib/utils/helper.py index 0c128d4a1..3d10ddcf3 100644 --- a/api/chalicelib/utils/helper.py +++ b/api/chalicelib/utils/helper.py @@ -15,11 +15,11 @@ def random_string(length=36): return "".join(random.choices(string.hexdigits, k=length)) -def list_to_camel_case(items: list[dict], flatten: bool = False) -> list[dict]: +def list_to_camel_case(items: list[dict], flatten: bool = False, ignore_keys=[]) -> list[dict]: for i in range(len(items)): if flatten: items[i] = flatten_nested_dicts(items[i]) - items[i] = dict_to_camel_case(items[i]) + items[i] = dict_to_camel_case(items[i], ignore_keys=[]) return items diff --git a/api/routers/core.py b/api/routers/core.py index 260df30f2..a79cb9245 100644 --- a/api/routers/core.py +++ b/api/routers/core.py @@ -4,8 +4,9 @@ from decouple import config from fastapi import Depends, Body, BackgroundTasks import schemas -from chalicelib.core import events, projects, metadata, reset_password, log_tools, \ +from chalicelib.core import projects, metadata, reset_password, log_tools, \ announcements, weekly_report, assist, mobile, tenants, boarding, notifications, webhook, users, saved_search, tags +from chalicelib.core.events import events from chalicelib.core.issues import issues from chalicelib.core.sourcemaps import sourcemaps from chalicelib.core.metrics import custom_metrics diff --git a/api/routers/subs/metrics.py b/api/routers/subs/metrics.py index 082ab9fdf..d53f5692f 100644 --- a/api/routers/subs/metrics.py +++ b/api/routers/subs/metrics.py @@ -220,9 +220,9 @@ def get_card_chart(projectId: int, metric_id: int, data: schemas.CardSessionsSch @app.post("/{projectId}/dashboards/{dashboardId}/cards/{metric_id}/chart", tags=["card"]) -@app.post("/{projectId}/dashboards/{dashboardId}/cards/{metric_id}", tags=["card"]) +# @app.post("/{projectId}/dashboards/{dashboardId}/cards/{metric_id}", tags=["card"]) def get_card_chart_for_dashboard(projectId: int, dashboardId: int, metric_id: int, - data: schemas.CardSessionsSchema = Body(...), + data: schemas.SavedCardSchema = Body(...), context: schemas.CurrentContext = Depends(OR_context)): data = custom_metrics.make_chart_from_card( project=context.project, user_id=context.user_id, metric_id=metric_id, data=data, for_dashboard=True diff --git a/api/routers/subs/product_analytics.py b/api/routers/subs/product_analytics.py index 6141af313..3b289cd25 100644 --- a/api/routers/subs/product_analytics.py +++ b/api/routers/subs/product_analytics.py @@ -15,6 +15,9 @@ public_app, app, app_apikey = get_routers() @app.get('/{projectId}/filters', tags=["product_analytics"]) def get_all_filters(projectId: int, filter_query: Annotated[schemas.PaginatedSchema, Query()], context: schemas.CurrentContext = Depends(OR_context)): + # TODO: fix total attribute to return the total count instead of the total number of pages + # TODO: no pagination, return everything + # TODO: remove icon return { "data": { "events": events.get_events(project_id=projectId, page=filter_query), @@ -31,11 +34,12 @@ def get_all_events(projectId: int, filter_query: Annotated[schemas.PaginatedSche @app.get('/{projectId}/properties/search', tags=["product_analytics"]) -def get_event_properties(projectId: int, event_name: str = None, +def get_event_properties(projectId: int, en: str = Query(default=None, description="event name"), + ac: bool = Query(description="auto captured"), context: schemas.CurrentContext = Depends(OR_context)): - if not event_name or len(event_name) == 0: + if not en or len(en) == 0: return {"data": []} - return {"data": properties.get_event_properties(project_id=projectId, event_name=event_name)} + return {"data": properties.get_event_properties(project_id=projectId, event_name=en, auto_captured=ac)} @app.post('/{projectId}/events/search', tags=["product_analytics"]) @@ -63,15 +67,12 @@ def autocomplete_events(projectId: int, q: Optional[str] = None, @app.get('/{projectId}/properties/autocomplete', tags=["autocomplete"]) -def autocomplete_properties(projectId: int, propertyName: Optional[str] = None, eventName: Optional[str] = None, +def autocomplete_properties(projectId: int, propertyName: str, eventName: Optional[str] = None, q: Optional[str] = None, context: schemas.CurrentContext = Depends(OR_context)): - if not propertyName and not eventName and not q: - return {"error": ["Specify eventName to get top properties", - "Specify propertyName to get top values of that property", - "Specify eventName&propertyName to get top values of that property for the selected event"]} + # Specify propertyName to get top values of that property + # Specify eventName&propertyName to get top values of that property for the selected event return {"data": autocomplete.search_properties(project_id=projectId, event_name=None if not eventName \ or len(eventName) == 0 else eventName, - property_name=None if not propertyName \ - or len(propertyName) == 0 else propertyName, + property_name=propertyName, q=None if not q or len(q) == 0 else q)} diff --git a/api/schemas/overrides.py b/api/schemas/overrides.py index 51c81365c..b543fa6b9 100644 --- a/api/schemas/overrides.py +++ b/api/schemas/overrides.py @@ -21,7 +21,9 @@ def schema_extra(schema: dict, _): class BaseModel(_BaseModel): model_config = ConfigDict(alias_generator=attribute_to_camel_case, use_enum_values=True, - json_schema_extra=schema_extra) + json_schema_extra=schema_extra, + # extra='forbid' + ) class Enum(_Enum): diff --git a/api/schemas/schemas.py b/api/schemas/schemas.py index c138f9ca5..e9a0647bc 100644 --- a/api/schemas/schemas.py +++ b/api/schemas/schemas.py @@ -1043,11 +1043,16 @@ class MetricOfPathAnalysis(str, Enum): session_count = MetricOfTimeseries.SESSION_COUNT.value -# class CardSessionsSchema(SessionsSearchPayloadSchema): class CardSessionsSchema(_TimedSchema, _PaginatedSchema): startTimestamp: int = Field(default=TimeUTC.now(-7)) endTimestamp: int = Field(default=TimeUTC.now()) density: int = Field(default=7, ge=1, le=200) + # we need metric_type&metric_of in the payload of sessions search + # because the API will retrun all sessions if the card is not identified + # example: table of requests contains only sessions that have a request, + # but drill-down doesn't take that into consideration + metric_type: MetricType = Field(...) + metric_of: Any series: List[CardSeriesSchema] = Field(default_factory=list) # events: List[SessionSearchEventSchema2] = Field(default_factory=list, doc_hidden=True) @@ -1112,6 +1117,11 @@ class CardSessionsSchema(_TimedSchema, _PaginatedSchema): return self +class SavedCardSchema(CardSessionsSchema): + metric_type: Optional[MetricType] = Field(default=None) + metric_of: Optional[Any] = Field(default=None) + + class CardConfigSchema(BaseModel): col: Optional[int] = Field(default=None) row: Optional[int] = Field(default=2) @@ -1125,8 +1135,6 @@ class __CardSchema(CardSessionsSchema): thumbnail: Optional[str] = Field(default=None) metric_format: Optional[MetricFormatType] = Field(default=None) view_type: Any - metric_type: MetricType = Field(...) - metric_of: Any metric_value: List[IssueType] = Field(default_factory=list) # This is used to save the selected session for heatmaps session_id: Optional[int] = Field(default=None) diff --git a/backend/cmd/db/main.go b/backend/cmd/db/main.go index 77ad5edd8..f468f5f4f 100644 --- a/backend/cmd/db/main.go +++ b/backend/cmd/db/main.go @@ -70,7 +70,7 @@ func main() { messages.MsgMouseClickDeprecated, messages.MsgSetPageLocation, messages.MsgSetPageLocationDeprecated, messages.MsgPageLoadTiming, messages.MsgPageRenderTiming, messages.MsgPageEvent, messages.MsgPageEventDeprecated, messages.MsgMouseThrashing, messages.MsgInputChange, - messages.MsgUnbindNodes, messages.MsgCanvasNode, messages.MsgTagTrigger, + messages.MsgUnbindNodes, messages.MsgCanvasNode, messages.MsgTagTrigger, messages.MsgIncident, // Mobile messages messages.MsgMobileSessionStart, messages.MsgMobileSessionEnd, messages.MsgMobileUserID, messages.MsgMobileUserAnonymousID, messages.MsgMobileMetadata, messages.MsgMobileEvent, messages.MsgMobileNetworkCall, diff --git a/backend/internal/db/datasaver/web.go b/backend/internal/db/datasaver/web.go index 701fe0e8d..b98cc4759 100644 --- a/backend/internal/db/datasaver/web.go +++ b/backend/internal/db/datasaver/web.go @@ -140,6 +140,11 @@ func (s *saverImpl) handleWebMessage(sessCtx context.Context, session *sessions. return err } return s.ch.InsertWebPerformanceTrackAggr(session, m) + case *messages.Incident: + if err := s.pg.InsertIncident(session, m); err != nil { + return err + } + return s.ch.InsertIncident(session, m) } return nil } diff --git a/backend/pkg/db/clickhouse/connector.go b/backend/pkg/db/clickhouse/connector.go index d09993095..de39bb2cc 100644 --- a/backend/pkg/db/clickhouse/connector.go +++ b/backend/pkg/db/clickhouse/connector.go @@ -39,6 +39,7 @@ type Connector interface { InsertIssue(session *sessions.Session, msg *messages.IssueEvent) error InsertWebInputDuration(session *sessions.Session, msg *messages.InputChange) error InsertMouseThrashing(session *sessions.Session, msg *messages.MouseThrashing) error + InsertIncident(session *sessions.Session, msg *messages.Incident) error InsertMobileSession(session *sessions.Session) error InsertMobileCustom(session *sessions.Session, msg *messages.MobileEvent) error InsertMobileClick(session *sessions.Session, msg *messages.MobileClickEvent) error @@ -106,15 +107,15 @@ func (c *connectorImpl) newBatch(name, query string) error { } var batches = map[string]string{ - "sessions": "INSERT INTO experimental.sessions (session_id, project_id, user_id, user_uuid, user_os, user_os_version, user_device, user_device_type, user_country, user_state, user_city, datetime, duration, pages_count, events_count, errors_count, issue_score, referrer, issue_types, tracker_version, user_browser, user_browser_version, metadata_1, metadata_2, metadata_3, metadata_4, metadata_5, metadata_6, metadata_7, metadata_8, metadata_9, metadata_10, platform, timezone, utm_source, utm_medium, utm_campaign) VALUES (?, ?, SUBSTR(?, 1, 8000), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, SUBSTR(?, 1, 8000), ?, ?, ?, ?, SUBSTR(?, 1, 8000), SUBSTR(?, 1, 8000), SUBSTR(?, 1, 8000), SUBSTR(?, 1, 8000), SUBSTR(?, 1, 8000), SUBSTR(?, 1, 8000), SUBSTR(?, 1, 8000), SUBSTR(?, 1, 8000), SUBSTR(?, 1, 8000), SUBSTR(?, 1, 8000), ?, ?, ?, ?, ?)", + "sessions": "INSERT INTO experimental.sessions (session_id, project_id, user_id, user_uuid, user_os, user_os_version, user_device, user_device_type, user_country, user_state, user_city, datetime, duration, pages_count, events_count, errors_count, issue_score, referrer, issue_types, tracker_version, user_browser, user_browser_version, metadata_1, metadata_2, metadata_3, metadata_4, metadata_5, metadata_6, metadata_7, metadata_8, metadata_9, metadata_10, platform, timezone, utm_source, utm_medium, utm_campaign, screen_width, screen_height) VALUES (?, ?, SUBSTR(?, 1, 8000), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, SUBSTR(?, 1, 8000), ?, ?, ?, ?, SUBSTR(?, 1, 8000), SUBSTR(?, 1, 8000), SUBSTR(?, 1, 8000), SUBSTR(?, 1, 8000), SUBSTR(?, 1, 8000), SUBSTR(?, 1, 8000), SUBSTR(?, 1, 8000), SUBSTR(?, 1, 8000), SUBSTR(?, 1, 8000), SUBSTR(?, 1, 8000), ?, ?, ?, ?, ?, ?, ?)", "autocompletes": "INSERT INTO experimental.autocomplete (project_id, type, value) VALUES (?, ?, SUBSTR(?, 1, 8000))", "pages": `INSERT INTO product_analytics.events (session_id, project_id, event_id, "$event_name", created_at, "$time", distinct_id, "$auto_captured", "$device", "$os_version", "$os", "$browser", "$referrer", "$country", "$state", "$city", "$current_url", "$properties") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, "clicks": `INSERT INTO product_analytics.events (session_id, project_id, event_id, "$event_name", created_at, "$time", distinct_id, "$auto_captured", "$device", "$os_version", "$os", "$browser", "$referrer", "$country", "$state", "$city", "$current_url", "$properties") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, "inputs": `INSERT INTO product_analytics.events (session_id, project_id, event_id, "$event_name", created_at, "$time", distinct_id, "$auto_captured", "$device", "$os_version", "$os", "$browser", "$referrer", "$country", "$state", "$city", "$current_url", "$duration_s", "$properties") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, - "errors": `INSERT INTO product_analytics.events (session_id, project_id, event_id, "$event_name", created_at, "$time", distinct_id, "$auto_captured", "$device", "$os_version", "$os", "$browser", "$referrer", "$country", "$state", "$city", "$current_url", error_id, "$properties") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, - "performance": `INSERT INTO product_analytics.events (session_id, project_id, event_id, "$event_name", created_at, "$time", distinct_id, "$auto_captured", "$device", "$os_version", "$os", "$browser", "$referrer", "$country", "$state", "$city", "$current_url", "$properties") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, + "errors": `INSERT INTO product_analytics.events (session_id, project_id, event_id, "$event_name", created_at, "$time", distinct_id, "$auto_captured", "$device", "$os_version", "$os", "$browser", "$referrer", "$country", "$state", "$city", "$current_url", error_id, "$properties") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, + "performance": `INSERT INTO product_analytics.events (session_id, project_id, event_id, "$event_name", created_at, "$time", distinct_id, "$auto_captured", "$device", "$os_version", "$os", "$browser", "$referrer", "$country", "$state", "$city", "$current_url", "$properties") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, "requests": `INSERT INTO product_analytics.events (session_id, project_id, event_id, "$event_name", created_at, "$time", distinct_id, "$auto_captured", "$device", "$os_version", "$os", "$browser", "$referrer", "$country", "$state", "$city", "$current_url", "$duration_s", "$properties") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, - "custom": `INSERT INTO product_analytics.events (session_id, project_id, event_id, "$event_name", created_at, "$time", distinct_id, "$auto_captured", "$device", "$os_version", "$os", "$browser", "$referrer", "$country", "$state", "$city", "$current_url", "$properties") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, + "custom": `INSERT INTO product_analytics.events (session_id, project_id, event_id, "$event_name", created_at, "$time", distinct_id, "$auto_captured", "$device", "$os_version", "$os", "$browser", "$referrer", "$country", "$state", "$city", "$current_url", "$properties", properties) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, "graphql": `INSERT INTO product_analytics.events (session_id, project_id, event_id, "$event_name", created_at, "$time", distinct_id, "$auto_captured", "$device", "$os_version", "$os", "$browser", "$referrer", "$country", "$state", "$city", "$current_url", "$properties") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, "issuesEvents": `INSERT INTO product_analytics.events (session_id, project_id, event_id, "$event_name", created_at, "$time", distinct_id, "$auto_captured", "$device", "$os_version", "$os", "$browser", "$referrer", "$country", "$state", "$city", "$current_url", issue_type, issue_id, "$properties") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, "issues": "INSERT INTO experimental.issues (project_id, issue_id, type, context_string) VALUES (?, ?, ?, ?)", @@ -220,6 +221,8 @@ func (c *connectorImpl) InsertWebSession(session *sessions.Session) error { session.UtmSource, session.UtmMedium, session.UtmCampaign, + session.ScreenWidth, + session.ScreenHeight, ); err != nil { c.checkError("sessions", err) return fmt.Errorf("can't append to sessions batch: %s", err) @@ -725,7 +728,6 @@ func (c *connectorImpl) InsertRequest(session *sessions.Session, msg *messages.N func (c *connectorImpl) InsertCustom(session *sessions.Session, msg *messages.CustomEvent) error { jsonString, err := json.Marshal(map[string]interface{}{ - "payload": msg.Payload, "user_device": session.UserDevice, "user_device_type": session.UserDeviceType, "page_title ": msg.PageTitle, @@ -733,6 +735,14 @@ func (c *connectorImpl) InsertCustom(session *sessions.Session, msg *messages.Cu if err != nil { return fmt.Errorf("can't marshal custom event: %s", err) } + customPayload := make(map[string]interface{}) + if err := json.Unmarshal([]byte(msg.Payload), &customPayload); err != nil { + log.Printf("can't unmarshal custom event payload into object: %s", err) + customPayload = map[string]interface{}{ + "payload": msg.Payload, + } + } + eventTime := datetime(msg.Timestamp) if err := c.batches["custom"].Append( session.SessionID, @@ -752,7 +762,8 @@ func (c *connectorImpl) InsertCustom(session *sessions.Session, msg *messages.Cu session.UserState, session.UserCity, cropString(msg.Url), - jsonString, + jsonString, // $properties + customPayload, // properties ); err != nil { c.checkError("custom", err) return fmt.Errorf("can't append to custom batch: %s", err) @@ -799,6 +810,45 @@ func (c *connectorImpl) InsertGraphQL(session *sessions.Session, msg *messages.G return nil } +func (c *connectorImpl) InsertIncident(session *sessions.Session, msg *messages.Incident) error { + jsonString, err := json.Marshal(map[string]interface{}{ + "label": msg.Label, + "start_time": msg.StartTime, + "end_time": msg.EndTime, + "user_device": session.UserDevice, + "user_device_type": session.UserDeviceType, + "page_title ": msg.PageTitle, + }) + if err != nil { + return fmt.Errorf("can't marshal custom event: %s", err) + } + eventTime := datetime(msg.Timestamp) + if err := c.batches["custom"].Append( + session.SessionID, + uint16(session.ProjectID), + getUUID(msg), + "INCIDENT", + eventTime, + eventTime.Unix(), + session.UserUUID, + true, + session.Platform, + session.UserOSVersion, + session.UserOS, + session.UserBrowser, + session.Referrer, + session.UserCountry, + session.UserState, + session.UserCity, + cropString(msg.Url), + jsonString, + ); err != nil { + c.checkError("custom", err) + return fmt.Errorf("can't append to custom batch: %s", err) + } + return nil +} + // Mobile events func (c *connectorImpl) InsertMobileSession(session *sessions.Session) error { diff --git a/backend/pkg/db/postgres/events.go b/backend/pkg/db/postgres/events.go index 8a61e8140..9782ea2d2 100644 --- a/backend/pkg/db/postgres/events.go +++ b/backend/pkg/db/postgres/events.go @@ -270,3 +270,15 @@ func (conn *Conn) InsertWebStatsPerformance(p *messages.PerformanceTrackAggr) er ) return nil } + +func (conn *Conn) InsertIncident(sess *sessions.Session, e *messages.Incident) error { + sessCtx := context.WithValue(context.Background(), "sessionID", sess.SessionID) + issueID := hashid.MobileIncidentID(sess.ProjectID, sess.SessionID, e.Timestamp) + if err := conn.bulks.Get("webIssues").Append(sess.ProjectID, issueID, "incident", e.Url); err != nil { + conn.log.Error(sessCtx, "insert incident issue err: %s", err) + } + if err := conn.bulks.Get("webIssueEvents").Append(sess.SessionID, issueID, e.Timestamp, truncSqIdx(e.MsgID()), nil); err != nil { + conn.log.Error(sessCtx, "insert incident issue event err: %s", err) + } + return nil +} diff --git a/backend/pkg/hashid/hashid.go b/backend/pkg/hashid/hashid.go index 0dca54e9f..bea70ea4e 100644 --- a/backend/pkg/hashid/hashid.go +++ b/backend/pkg/hashid/hashid.go @@ -38,3 +38,11 @@ func MouseThrashingID(projectID uint32, sessID, ts uint64) string { hash.Write([]byte(strconv.FormatUint(ts, 10))) return strconv.FormatUint(uint64(projectID), 16) + hex.EncodeToString(hash.Sum(nil)) } + +func MobileIncidentID(projectID uint32, sessID, ts uint64) string { + hash := fnv.New128a() + hash.Write([]byte("mobile_incident")) + hash.Write([]byte(strconv.FormatUint(sessID, 10))) + hash.Write([]byte(strconv.FormatUint(ts, 10))) + return strconv.FormatUint(uint64(projectID), 16) + hex.EncodeToString(hash.Sum(nil)) +} diff --git a/backend/pkg/messages/filters.go b/backend/pkg/messages/filters.go index 094586abf..9b84a4c92 100644 --- a/backend/pkg/messages/filters.go +++ b/backend/pkg/messages/filters.go @@ -11,4 +11,4 @@ func IsMobileType(id int) bool { func IsDOMType(id int) bool { return 0 == id || 4 == id || 5 == id || 6 == id || 7 == id || 8 == id || 9 == id || 10 == id || 11 == id || 12 == id || 13 == id || 14 == id || 15 == id || 16 == id || 18 == id || 19 == id || 20 == id || 34 == id || 35 == id || 37 == id || 38 == id || 49 == id || 50 == id || 51 == id || 43 == id || 52 == id || 54 == id || 55 == id || 57 == id || 58 == id || 59 == id || 60 == id || 61 == id || 67 == id || 68 == id || 69 == id || 70 == id || 71 == id || 72 == id || 73 == id || 74 == id || 75 == id || 76 == id || 77 == id || 113 == id || 114 == id || 117 == id || 118 == id || 119 == id || 122 == id || 93 == id || 96 == id || 100 == id || 101 == id || 102 == id || 103 == id || 104 == id || 105 == id || 106 == id || 111 == id -} +} \ No newline at end of file diff --git a/backend/pkg/messages/messages.go b/backend/pkg/messages/messages.go index a6503b7d9..d987feffc 100644 --- a/backend/pkg/messages/messages.go +++ b/backend/pkg/messages/messages.go @@ -2,127 +2,129 @@ package messages const ( - MsgTimestamp = 0 - MsgSessionStart = 1 - MsgSessionEndDeprecated = 3 - MsgSetPageLocationDeprecated = 4 - MsgSetViewportSize = 5 - MsgSetViewportScroll = 6 - MsgCreateDocument = 7 - MsgCreateElementNode = 8 - MsgCreateTextNode = 9 - MsgMoveNode = 10 - MsgRemoveNode = 11 - MsgSetNodeAttribute = 12 - MsgRemoveNodeAttribute = 13 - MsgSetNodeData = 14 - MsgSetCSSData = 15 - MsgSetNodeScroll = 16 - MsgSetInputTarget = 17 - MsgSetInputValue = 18 - MsgSetInputChecked = 19 - MsgMouseMove = 20 - MsgNetworkRequestDeprecated = 21 - MsgConsoleLog = 22 - MsgPageLoadTiming = 23 - MsgPageRenderTiming = 24 - MsgJSExceptionDeprecated = 25 - MsgIntegrationEvent = 26 - MsgCustomEvent = 27 - MsgUserID = 28 - MsgUserAnonymousID = 29 - MsgMetadata = 30 - MsgPageEventDeprecated = 31 - MsgInputEvent = 32 - MsgPageEvent = 33 - MsgStringDictGlobal = 34 - MsgSetNodeAttributeDictGlobal = 35 - MsgCSSInsertRule = 37 - MsgCSSDeleteRule = 38 - MsgFetch = 39 - MsgProfiler = 40 - MsgOTable = 41 - MsgStateAction = 42 - MsgReduxDeprecated = 44 - MsgVuex = 45 - MsgMobX = 46 - MsgNgRx = 47 - MsgGraphQLDeprecated = 48 - MsgPerformanceTrack = 49 - MsgStringDictDeprecated = 50 - MsgSetNodeAttributeDictDeprecated = 51 - MsgStringDict = 43 - MsgSetNodeAttributeDict = 52 - MsgResourceTimingDeprecatedDeprecated = 53 - MsgConnectionInformation = 54 - MsgSetPageVisibility = 55 - MsgPerformanceTrackAggr = 56 - MsgLoadFontFace = 57 - MsgSetNodeFocus = 58 - MsgLongTask = 59 - MsgSetNodeAttributeURLBased = 60 - MsgSetCSSDataURLBased = 61 - MsgIssueEventDeprecated = 62 - MsgTechnicalInfo = 63 - MsgCustomIssue = 64 - MsgAssetCache = 66 - MsgCSSInsertRuleURLBased = 67 - MsgMouseClick = 68 - MsgMouseClickDeprecated = 69 - MsgCreateIFrameDocument = 70 - MsgAdoptedSSReplaceURLBased = 71 - MsgAdoptedSSReplace = 72 - MsgAdoptedSSInsertRuleURLBased = 73 - MsgAdoptedSSInsertRule = 74 - MsgAdoptedSSDeleteRule = 75 - MsgAdoptedSSAddOwner = 76 - MsgAdoptedSSRemoveOwner = 77 - MsgJSException = 78 - MsgZustand = 79 - MsgBatchMeta = 80 - MsgBatchMetadata = 81 - MsgPartitionedMessage = 82 - MsgNetworkRequest = 83 - MsgWSChannel = 84 - MsgResourceTiming = 85 - MsgLongAnimationTask = 89 - MsgInputChange = 112 - MsgSelectionChange = 113 - MsgMouseThrashing = 114 - MsgUnbindNodes = 115 - MsgResourceTimingDeprecated = 116 - MsgTabChange = 117 - MsgTabData = 118 - MsgCanvasNode = 119 - MsgTagTrigger = 120 - MsgRedux = 121 - MsgSetPageLocation = 122 - MsgGraphQL = 123 - MsgWebVitals = 124 - MsgIssueEvent = 125 - MsgSessionEnd = 126 - MsgSessionSearch = 127 - MsgMobileSessionStart = 90 - MsgMobileSessionEnd = 91 - MsgMobileMetadata = 92 - MsgMobileEvent = 93 - MsgMobileUserID = 94 - MsgMobileUserAnonymousID = 95 - MsgMobileScreenChanges = 96 - MsgMobileCrash = 97 - MsgMobileViewComponentEvent = 98 - MsgMobileClickEvent = 100 - MsgMobileInputEvent = 101 - MsgMobilePerformanceEvent = 102 - MsgMobileLog = 103 - MsgMobileInternalError = 104 - MsgMobileNetworkCall = 105 - MsgMobileSwipeEvent = 106 - MsgMobileBatchMeta = 107 - MsgMobilePerformanceAggregated = 110 - MsgMobileIssueEvent = 111 + MsgTimestamp = 0 + MsgSessionStart = 1 + MsgSessionEndDeprecated = 3 + MsgSetPageLocationDeprecated = 4 + MsgSetViewportSize = 5 + MsgSetViewportScroll = 6 + MsgCreateDocument = 7 + MsgCreateElementNode = 8 + MsgCreateTextNode = 9 + MsgMoveNode = 10 + MsgRemoveNode = 11 + MsgSetNodeAttribute = 12 + MsgRemoveNodeAttribute = 13 + MsgSetNodeData = 14 + MsgSetCSSData = 15 + MsgSetNodeScroll = 16 + MsgSetInputTarget = 17 + MsgSetInputValue = 18 + MsgSetInputChecked = 19 + MsgMouseMove = 20 + MsgNetworkRequestDeprecated = 21 + MsgConsoleLog = 22 + MsgPageLoadTiming = 23 + MsgPageRenderTiming = 24 + MsgJSExceptionDeprecated = 25 + MsgIntegrationEvent = 26 + MsgCustomEvent = 27 + MsgUserID = 28 + MsgUserAnonymousID = 29 + MsgMetadata = 30 + MsgPageEventDeprecated = 31 + MsgInputEvent = 32 + MsgPageEvent = 33 + MsgStringDictGlobal = 34 + MsgSetNodeAttributeDictGlobal = 35 + MsgCSSInsertRule = 37 + MsgCSSDeleteRule = 38 + MsgFetch = 39 + MsgProfiler = 40 + MsgOTable = 41 + MsgStateAction = 42 + MsgReduxDeprecated = 44 + MsgVuex = 45 + MsgMobX = 46 + MsgNgRx = 47 + MsgGraphQLDeprecated = 48 + MsgPerformanceTrack = 49 + MsgStringDictDeprecated = 50 + MsgSetNodeAttributeDictDeprecated = 51 + MsgStringDict = 43 + MsgSetNodeAttributeDict = 52 + MsgResourceTimingDeprecatedDeprecated = 53 + MsgConnectionInformation = 54 + MsgSetPageVisibility = 55 + MsgPerformanceTrackAggr = 56 + MsgLoadFontFace = 57 + MsgSetNodeFocus = 58 + MsgLongTask = 59 + MsgSetNodeAttributeURLBased = 60 + MsgSetCSSDataURLBased = 61 + MsgIssueEventDeprecated = 62 + MsgTechnicalInfo = 63 + MsgCustomIssue = 64 + MsgAssetCache = 66 + MsgCSSInsertRuleURLBased = 67 + MsgMouseClick = 68 + MsgMouseClickDeprecated = 69 + MsgCreateIFrameDocument = 70 + MsgAdoptedSSReplaceURLBased = 71 + MsgAdoptedSSReplace = 72 + MsgAdoptedSSInsertRuleURLBased = 73 + MsgAdoptedSSInsertRule = 74 + MsgAdoptedSSDeleteRule = 75 + MsgAdoptedSSAddOwner = 76 + MsgAdoptedSSRemoveOwner = 77 + MsgJSException = 78 + MsgZustand = 79 + MsgBatchMeta = 80 + MsgBatchMetadata = 81 + MsgPartitionedMessage = 82 + MsgNetworkRequest = 83 + MsgWSChannel = 84 + MsgResourceTiming = 85 + MsgIncident = 87 + MsgLongAnimationTask = 89 + MsgInputChange = 112 + MsgSelectionChange = 113 + MsgMouseThrashing = 114 + MsgUnbindNodes = 115 + MsgResourceTimingDeprecated = 116 + MsgTabChange = 117 + MsgTabData = 118 + MsgCanvasNode = 119 + MsgTagTrigger = 120 + MsgRedux = 121 + MsgSetPageLocation = 122 + MsgGraphQL = 123 + MsgWebVitals = 124 + MsgIssueEvent = 125 + MsgSessionEnd = 126 + MsgSessionSearch = 127 + MsgMobileSessionStart = 90 + MsgMobileSessionEnd = 91 + MsgMobileMetadata = 92 + MsgMobileEvent = 93 + MsgMobileUserID = 94 + MsgMobileUserAnonymousID = 95 + MsgMobileScreenChanges = 96 + MsgMobileCrash = 97 + MsgMobileViewComponentEvent = 98 + MsgMobileClickEvent = 100 + MsgMobileInputEvent = 101 + MsgMobilePerformanceEvent = 102 + MsgMobileLog = 103 + MsgMobileInternalError = 104 + MsgMobileNetworkCall = 105 + MsgMobileSwipeEvent = 106 + MsgMobileBatchMeta = 107 + MsgMobilePerformanceAggregated = 110 + MsgMobileIssueEvent = 111 ) + type Timestamp struct { message Timestamp uint64 @@ -146,22 +148,22 @@ func (msg *Timestamp) TypeID() int { type SessionStart struct { message - Timestamp uint64 - ProjectID uint64 - TrackerVersion string - RevID string - UserUUID string - UserAgent string - UserOS string - UserOSVersion string - UserBrowser string - UserBrowserVersion string - UserDevice string - UserDeviceType string + Timestamp uint64 + ProjectID uint64 + TrackerVersion string + RevID string + UserUUID string + UserAgent string + UserOS string + UserOSVersion string + UserBrowser string + UserBrowserVersion string + UserDevice string + UserDeviceType string UserDeviceMemorySize uint64 - UserDeviceHeapSize uint64 - UserCountry string - UserID string + UserDeviceHeapSize uint64 + UserCountry string + UserID string } func (msg *SessionStart) Encode() []byte { @@ -218,8 +220,8 @@ func (msg *SessionEndDeprecated) TypeID() int { type SetPageLocationDeprecated struct { message - URL string - Referrer string + URL string + Referrer string NavigationStart uint64 } @@ -243,7 +245,7 @@ func (msg *SetPageLocationDeprecated) TypeID() int { type SetViewportSize struct { message - Width uint64 + Width uint64 Height uint64 } @@ -289,6 +291,7 @@ func (msg *SetViewportScroll) TypeID() int { type CreateDocument struct { message + } func (msg *CreateDocument) Encode() []byte { @@ -309,11 +312,11 @@ func (msg *CreateDocument) TypeID() int { type CreateElementNode struct { message - ID uint64 + ID uint64 ParentID uint64 - index uint64 - Tag string - SVG bool + index uint64 + Tag string + SVG bool } func (msg *CreateElementNode) Encode() []byte { @@ -338,9 +341,9 @@ func (msg *CreateElementNode) TypeID() int { type CreateTextNode struct { message - ID uint64 + ID uint64 ParentID uint64 - Index uint64 + Index uint64 } func (msg *CreateTextNode) Encode() []byte { @@ -363,9 +366,9 @@ func (msg *CreateTextNode) TypeID() int { type MoveNode struct { message - ID uint64 + ID uint64 ParentID uint64 - Index uint64 + Index uint64 } func (msg *MoveNode) Encode() []byte { @@ -409,8 +412,8 @@ func (msg *RemoveNode) TypeID() int { type SetNodeAttribute struct { message - ID uint64 - Name string + ID uint64 + Name string Value string } @@ -434,7 +437,7 @@ func (msg *SetNodeAttribute) TypeID() int { type RemoveNodeAttribute struct { message - ID uint64 + ID uint64 Name string } @@ -457,7 +460,7 @@ func (msg *RemoveNodeAttribute) TypeID() int { type SetNodeData struct { message - ID uint64 + ID uint64 Data string } @@ -480,7 +483,7 @@ func (msg *SetNodeData) TypeID() int { type SetCSSData struct { message - ID uint64 + ID uint64 Data string } @@ -504,8 +507,8 @@ func (msg *SetCSSData) TypeID() int { type SetNodeScroll struct { message ID uint64 - X int64 - Y int64 + X int64 + Y int64 } func (msg *SetNodeScroll) Encode() []byte { @@ -528,7 +531,7 @@ func (msg *SetNodeScroll) TypeID() int { type SetInputTarget struct { message - ID uint64 + ID uint64 Label string } @@ -551,9 +554,9 @@ func (msg *SetInputTarget) TypeID() int { type SetInputValue struct { message - ID uint64 + ID uint64 Value string - Mask int64 + Mask int64 } func (msg *SetInputValue) Encode() []byte { @@ -576,7 +579,7 @@ func (msg *SetInputValue) TypeID() int { type SetInputChecked struct { message - ID uint64 + ID uint64 Checked bool } @@ -622,14 +625,14 @@ func (msg *MouseMove) TypeID() int { type NetworkRequestDeprecated struct { message - Type string - Method string - URL string - Request string - Response string - Status uint64 + Type string + Method string + URL string + Request string + Response string + Status uint64 Timestamp uint64 - Duration uint64 + Duration uint64 } func (msg *NetworkRequestDeprecated) Encode() []byte { @@ -680,15 +683,15 @@ func (msg *ConsoleLog) TypeID() int { type PageLoadTiming struct { message - RequestStart uint64 - ResponseStart uint64 - ResponseEnd uint64 + RequestStart uint64 + ResponseStart uint64 + ResponseEnd uint64 DomContentLoadedEventStart uint64 - DomContentLoadedEventEnd uint64 - LoadEventStart uint64 - LoadEventEnd uint64 - FirstPaint uint64 - FirstContentfulPaint uint64 + DomContentLoadedEventEnd uint64 + LoadEventStart uint64 + LoadEventEnd uint64 + FirstPaint uint64 + FirstContentfulPaint uint64 } func (msg *PageLoadTiming) Encode() []byte { @@ -717,8 +720,8 @@ func (msg *PageLoadTiming) TypeID() int { type PageRenderTiming struct { message - SpeedIndex uint64 - VisuallyComplete uint64 + SpeedIndex uint64 + VisuallyComplete uint64 TimeToInteractive uint64 } @@ -742,7 +745,7 @@ func (msg *PageRenderTiming) TypeID() int { type JSExceptionDeprecated struct { message - Name string + Name string Message string Payload string } @@ -768,10 +771,10 @@ func (msg *JSExceptionDeprecated) TypeID() int { type IntegrationEvent struct { message Timestamp uint64 - Source string - Name string - Message string - Payload string + Source string + Name string + Message string + Payload string } func (msg *IntegrationEvent) Encode() []byte { @@ -796,7 +799,7 @@ func (msg *IntegrationEvent) TypeID() int { type CustomEvent struct { message - Name string + Name string Payload string } @@ -861,7 +864,7 @@ func (msg *UserAnonymousID) TypeID() int { type Metadata struct { message - Key string + Key string Value string } @@ -884,23 +887,23 @@ func (msg *Metadata) TypeID() int { type PageEventDeprecated struct { message - MessageID uint64 - Timestamp uint64 - URL string - Referrer string - Loaded bool - RequestStart uint64 - ResponseStart uint64 - ResponseEnd uint64 + MessageID uint64 + Timestamp uint64 + URL string + Referrer string + Loaded bool + RequestStart uint64 + ResponseStart uint64 + ResponseEnd uint64 DomContentLoadedEventStart uint64 - DomContentLoadedEventEnd uint64 - LoadEventStart uint64 - LoadEventEnd uint64 - FirstPaint uint64 - FirstContentfulPaint uint64 - SpeedIndex uint64 - VisuallyComplete uint64 - TimeToInteractive uint64 + DomContentLoadedEventEnd uint64 + LoadEventStart uint64 + LoadEventEnd uint64 + FirstPaint uint64 + FirstContentfulPaint uint64 + SpeedIndex uint64 + VisuallyComplete uint64 + TimeToInteractive uint64 } func (msg *PageEventDeprecated) Encode() []byte { @@ -937,11 +940,11 @@ func (msg *PageEventDeprecated) TypeID() int { type InputEvent struct { message - MessageID uint64 - Timestamp uint64 - Value string + MessageID uint64 + Timestamp uint64 + Value string ValueMasked bool - Label string + Label string } func (msg *InputEvent) Encode() []byte { @@ -966,24 +969,24 @@ func (msg *InputEvent) TypeID() int { type PageEvent struct { message - MessageID uint64 - Timestamp uint64 - URL string - Referrer string - Loaded bool - RequestStart uint64 - ResponseStart uint64 - ResponseEnd uint64 + MessageID uint64 + Timestamp uint64 + URL string + Referrer string + Loaded bool + RequestStart uint64 + ResponseStart uint64 + ResponseEnd uint64 DomContentLoadedEventStart uint64 - DomContentLoadedEventEnd uint64 - LoadEventStart uint64 - LoadEventEnd uint64 - FirstPaint uint64 - FirstContentfulPaint uint64 - SpeedIndex uint64 - VisuallyComplete uint64 - TimeToInteractive uint64 - WebVitals string + DomContentLoadedEventEnd uint64 + LoadEventStart uint64 + LoadEventEnd uint64 + FirstPaint uint64 + FirstContentfulPaint uint64 + SpeedIndex uint64 + VisuallyComplete uint64 + TimeToInteractive uint64 + WebVitals string } func (msg *PageEvent) Encode() []byte { @@ -1021,7 +1024,7 @@ func (msg *PageEvent) TypeID() int { type StringDictGlobal struct { message - Key uint64 + Key uint64 Value string } @@ -1044,8 +1047,8 @@ func (msg *StringDictGlobal) TypeID() int { type SetNodeAttributeDictGlobal struct { message - ID uint64 - Name uint64 + ID uint64 + Name uint64 Value uint64 } @@ -1069,8 +1072,8 @@ func (msg *SetNodeAttributeDictGlobal) TypeID() int { type CSSInsertRule struct { message - ID uint64 - Rule string + ID uint64 + Rule string Index uint64 } @@ -1094,7 +1097,7 @@ func (msg *CSSInsertRule) TypeID() int { type CSSDeleteRule struct { message - ID uint64 + ID uint64 Index uint64 } @@ -1117,13 +1120,13 @@ func (msg *CSSDeleteRule) TypeID() int { type Fetch struct { message - Method string - URL string - Request string - Response string - Status uint64 + Method string + URL string + Request string + Response string + Status uint64 Timestamp uint64 - Duration uint64 + Duration uint64 } func (msg *Fetch) Encode() []byte { @@ -1150,10 +1153,10 @@ func (msg *Fetch) TypeID() int { type Profiler struct { message - Name string + Name string Duration uint64 - Args string - Result string + Args string + Result string } func (msg *Profiler) Encode() []byte { @@ -1177,7 +1180,7 @@ func (msg *Profiler) TypeID() int { type OTable struct { message - Key string + Key string Value string } @@ -1221,8 +1224,8 @@ func (msg *StateAction) TypeID() int { type ReduxDeprecated struct { message - Action string - State string + Action string + State string Duration uint64 } @@ -1247,7 +1250,7 @@ func (msg *ReduxDeprecated) TypeID() int { type Vuex struct { message Mutation string - State string + State string } func (msg *Vuex) Encode() []byte { @@ -1269,7 +1272,7 @@ func (msg *Vuex) TypeID() int { type MobX struct { message - Type string + Type string Payload string } @@ -1292,8 +1295,8 @@ func (msg *MobX) TypeID() int { type NgRx struct { message - Action string - State string + Action string + State string Duration uint64 } @@ -1319,9 +1322,9 @@ type GraphQLDeprecated struct { message OperationKind string OperationName string - Variables string - Response string - Duration int64 + Variables string + Response string + Duration int64 } func (msg *GraphQLDeprecated) Encode() []byte { @@ -1346,10 +1349,10 @@ func (msg *GraphQLDeprecated) TypeID() int { type PerformanceTrack struct { message - Frames int64 - Ticks int64 + Frames int64 + Ticks int64 TotalJSHeapSize uint64 - UsedJSHeapSize uint64 + UsedJSHeapSize uint64 } func (msg *PerformanceTrack) Encode() []byte { @@ -1373,7 +1376,7 @@ func (msg *PerformanceTrack) TypeID() int { type StringDictDeprecated struct { message - Key uint64 + Key uint64 Value string } @@ -1396,8 +1399,8 @@ func (msg *StringDictDeprecated) TypeID() int { type SetNodeAttributeDictDeprecated struct { message - ID uint64 - NameKey uint64 + ID uint64 + NameKey uint64 ValueKey uint64 } @@ -1421,7 +1424,7 @@ func (msg *SetNodeAttributeDictDeprecated) TypeID() int { type StringDict struct { message - Key string + Key string Value string } @@ -1444,8 +1447,8 @@ func (msg *StringDict) TypeID() int { type SetNodeAttributeDict struct { message - ID uint64 - Name string + ID uint64 + Name string Value string } @@ -1469,14 +1472,14 @@ func (msg *SetNodeAttributeDict) TypeID() int { type ResourceTimingDeprecatedDeprecated struct { message - Timestamp uint64 - Duration uint64 - TTFB uint64 - HeaderSize uint64 + Timestamp uint64 + Duration uint64 + TTFB uint64 + HeaderSize uint64 EncodedBodySize uint64 DecodedBodySize uint64 - URL string - Initiator string + URL string + Initiator string } func (msg *ResourceTimingDeprecatedDeprecated) Encode() []byte { @@ -1505,7 +1508,7 @@ func (msg *ResourceTimingDeprecatedDeprecated) TypeID() int { type ConnectionInformation struct { message Downlink uint64 - Type string + Type string } func (msg *ConnectionInformation) Encode() []byte { @@ -1548,20 +1551,20 @@ func (msg *SetPageVisibility) TypeID() int { type PerformanceTrackAggr struct { message - TimestampStart uint64 - TimestampEnd uint64 - MinFPS uint64 - AvgFPS uint64 - MaxFPS uint64 - MinCPU uint64 - AvgCPU uint64 - MaxCPU uint64 + TimestampStart uint64 + TimestampEnd uint64 + MinFPS uint64 + AvgFPS uint64 + MaxFPS uint64 + MinCPU uint64 + AvgCPU uint64 + MaxCPU uint64 MinTotalJSHeapSize uint64 AvgTotalJSHeapSize uint64 MaxTotalJSHeapSize uint64 - MinUsedJSHeapSize uint64 - AvgUsedJSHeapSize uint64 - MaxUsedJSHeapSize uint64 + MinUsedJSHeapSize uint64 + AvgUsedJSHeapSize uint64 + MaxUsedJSHeapSize uint64 } func (msg *PerformanceTrackAggr) Encode() []byte { @@ -1595,9 +1598,9 @@ func (msg *PerformanceTrackAggr) TypeID() int { type LoadFontFace struct { message - ParentID uint64 - Family string - Source string + ParentID uint64 + Family string + Source string Descriptors string } @@ -1643,12 +1646,12 @@ func (msg *SetNodeFocus) TypeID() int { type LongTask struct { message - Timestamp uint64 - Duration uint64 - Context uint64 + Timestamp uint64 + Duration uint64 + Context uint64 ContainerType uint64 - ContainerSrc string - ContainerId string + ContainerSrc string + ContainerId string ContainerName string } @@ -1676,9 +1679,9 @@ func (msg *LongTask) TypeID() int { type SetNodeAttributeURLBased struct { message - ID uint64 - Name string - Value string + ID uint64 + Name string + Value string BaseURL string } @@ -1703,8 +1706,8 @@ func (msg *SetNodeAttributeURLBased) TypeID() int { type SetCSSDataURLBased struct { message - ID uint64 - Data string + ID uint64 + Data string BaseURL string } @@ -1728,12 +1731,12 @@ func (msg *SetCSSDataURLBased) TypeID() int { type IssueEventDeprecated struct { message - MessageID uint64 - Timestamp uint64 - Type string + MessageID uint64 + Timestamp uint64 + Type string ContextString string - Context string - Payload string + Context string + Payload string } func (msg *IssueEventDeprecated) Encode() []byte { @@ -1759,7 +1762,7 @@ func (msg *IssueEventDeprecated) TypeID() int { type TechnicalInfo struct { message - Type string + Type string Value string } @@ -1782,7 +1785,7 @@ func (msg *TechnicalInfo) TypeID() int { type CustomIssue struct { message - Name string + Name string Payload string } @@ -1826,9 +1829,9 @@ func (msg *AssetCache) TypeID() int { type CSSInsertRuleURLBased struct { message - ID uint64 - Rule string - Index uint64 + ID uint64 + Rule string + Index uint64 BaseURL string } @@ -1853,12 +1856,12 @@ func (msg *CSSInsertRuleURLBased) TypeID() int { type MouseClick struct { message - ID uint64 + ID uint64 HesitationTime uint64 - Label string - Selector string - NormalizedX uint64 - NormalizedY uint64 + Label string + Selector string + NormalizedX uint64 + NormalizedY uint64 } func (msg *MouseClick) Encode() []byte { @@ -1884,10 +1887,10 @@ func (msg *MouseClick) TypeID() int { type MouseClickDeprecated struct { message - ID uint64 + ID uint64 HesitationTime uint64 - Label string - Selector string + Label string + Selector string } func (msg *MouseClickDeprecated) Encode() []byte { @@ -1912,7 +1915,7 @@ func (msg *MouseClickDeprecated) TypeID() int { type CreateIFrameDocument struct { message FrameID uint64 - ID uint64 + ID uint64 } func (msg *CreateIFrameDocument) Encode() []byte { @@ -1935,7 +1938,7 @@ func (msg *CreateIFrameDocument) TypeID() int { type AdoptedSSReplaceURLBased struct { message SheetID uint64 - Text string + Text string BaseURL string } @@ -1960,7 +1963,7 @@ func (msg *AdoptedSSReplaceURLBased) TypeID() int { type AdoptedSSReplace struct { message SheetID uint64 - Text string + Text string } func (msg *AdoptedSSReplace) Encode() []byte { @@ -1983,8 +1986,8 @@ func (msg *AdoptedSSReplace) TypeID() int { type AdoptedSSInsertRuleURLBased struct { message SheetID uint64 - Rule string - Index uint64 + Rule string + Index uint64 BaseURL string } @@ -2010,8 +2013,8 @@ func (msg *AdoptedSSInsertRuleURLBased) TypeID() int { type AdoptedSSInsertRule struct { message SheetID uint64 - Rule string - Index uint64 + Rule string + Index uint64 } func (msg *AdoptedSSInsertRule) Encode() []byte { @@ -2035,7 +2038,7 @@ func (msg *AdoptedSSInsertRule) TypeID() int { type AdoptedSSDeleteRule struct { message SheetID uint64 - Index uint64 + Index uint64 } func (msg *AdoptedSSDeleteRule) Encode() []byte { @@ -2058,7 +2061,7 @@ func (msg *AdoptedSSDeleteRule) TypeID() int { type AdoptedSSAddOwner struct { message SheetID uint64 - ID uint64 + ID uint64 } func (msg *AdoptedSSAddOwner) Encode() []byte { @@ -2081,7 +2084,7 @@ func (msg *AdoptedSSAddOwner) TypeID() int { type AdoptedSSRemoveOwner struct { message SheetID uint64 - ID uint64 + ID uint64 } func (msg *AdoptedSSRemoveOwner) Encode() []byte { @@ -2103,9 +2106,9 @@ func (msg *AdoptedSSRemoveOwner) TypeID() int { type JSException struct { message - Name string - Message string - Payload string + Name string + Message string + Payload string Metadata string } @@ -2131,7 +2134,7 @@ func (msg *JSException) TypeID() int { type Zustand struct { message Mutation string - State string + State string } func (msg *Zustand) Encode() []byte { @@ -2153,9 +2156,9 @@ func (msg *Zustand) TypeID() int { type BatchMeta struct { message - PageNo uint64 + PageNo uint64 FirstIndex uint64 - Timestamp int64 + Timestamp int64 } func (msg *BatchMeta) Encode() []byte { @@ -2178,11 +2181,11 @@ func (msg *BatchMeta) TypeID() int { type BatchMetadata struct { message - Version uint64 - PageNo uint64 + Version uint64 + PageNo uint64 FirstIndex uint64 - Timestamp int64 - Location string + Timestamp int64 + Location string } func (msg *BatchMetadata) Encode() []byte { @@ -2207,7 +2210,7 @@ func (msg *BatchMetadata) TypeID() int { type PartitionedMessage struct { message - PartNo uint64 + PartNo uint64 PartTotal uint64 } @@ -2230,14 +2233,14 @@ func (msg *PartitionedMessage) TypeID() int { type NetworkRequest struct { message - Type string - Method string - URL string - Request string - Response string - Status uint64 - Timestamp uint64 - Duration uint64 + Type string + Method string + URL string + Request string + Response string + Status uint64 + Timestamp uint64 + Duration uint64 TransferredBodySize uint64 } @@ -2267,11 +2270,11 @@ func (msg *NetworkRequest) TypeID() int { type WSChannel struct { message - ChType string + ChType string ChannelName string - Data string - Timestamp uint64 - Dir string + Data string + Timestamp uint64 + Dir string MessageType string } @@ -2298,23 +2301,23 @@ func (msg *WSChannel) TypeID() int { type ResourceTiming struct { message - Timestamp uint64 - Duration uint64 - TTFB uint64 - HeaderSize uint64 - EncodedBodySize uint64 - DecodedBodySize uint64 - URL string - Initiator string - TransferredSize uint64 - Cached bool - Queueing uint64 - DnsLookup uint64 + Timestamp uint64 + Duration uint64 + TTFB uint64 + HeaderSize uint64 + EncodedBodySize uint64 + DecodedBodySize uint64 + URL string + Initiator string + TransferredSize uint64 + Cached bool + Queueing uint64 + DnsLookup uint64 InitialConnection uint64 - SSL uint64 - ContentDownload uint64 - Total uint64 - Stalled uint64 + SSL uint64 + ContentDownload uint64 + Total uint64 + Stalled uint64 } func (msg *ResourceTiming) Encode() []byte { @@ -2349,14 +2352,39 @@ func (msg *ResourceTiming) TypeID() int { return 85 } +type Incident struct { + message + Label string + StartTime int64 + EndTime int64 +} + +func (msg *Incident) Encode() []byte { + buf := make([]byte, 31+len(msg.Label)) + buf[0] = 87 + p := 1 + p = WriteString(msg.Label, buf, p) + p = WriteInt(msg.StartTime, buf, p) + p = WriteInt(msg.EndTime, buf, p) + return buf[:p] +} + +func (msg *Incident) Decode() Message { + return msg +} + +func (msg *Incident) TypeID() int { + return 87 +} + type LongAnimationTask struct { message - Name string - Duration int64 - BlockingDuration int64 + Name string + Duration int64 + BlockingDuration int64 FirstUIEventTimestamp int64 - StartTime int64 - Scripts string + StartTime int64 + Scripts string } func (msg *LongAnimationTask) Encode() []byte { @@ -2382,12 +2410,12 @@ func (msg *LongAnimationTask) TypeID() int { type InputChange struct { message - ID uint64 - Value string - ValueMasked bool - Label string + ID uint64 + Value string + ValueMasked bool + Label string HesitationTime int64 - InputDuration int64 + InputDuration int64 } func (msg *InputChange) Encode() []byte { @@ -2414,8 +2442,8 @@ func (msg *InputChange) TypeID() int { type SelectionChange struct { message SelectionStart uint64 - SelectionEnd uint64 - Selection string + SelectionEnd uint64 + Selection string } func (msg *SelectionChange) Encode() []byte { @@ -2480,16 +2508,16 @@ func (msg *UnbindNodes) TypeID() int { type ResourceTimingDeprecated struct { message - Timestamp uint64 - Duration uint64 - TTFB uint64 - HeaderSize uint64 + Timestamp uint64 + Duration uint64 + TTFB uint64 + HeaderSize uint64 EncodedBodySize uint64 DecodedBodySize uint64 - URL string - Initiator string + URL string + Initiator string TransferredSize uint64 - Cached bool + Cached bool } func (msg *ResourceTimingDeprecated) Encode() []byte { @@ -2561,7 +2589,7 @@ func (msg *TabData) TypeID() int { type CanvasNode struct { message - NodeId string + NodeId string Timestamp uint64 } @@ -2605,9 +2633,9 @@ func (msg *TagTrigger) TypeID() int { type Redux struct { message - Action string - State string - Duration uint64 + Action string + State string + Duration uint64 ActionTime uint64 } @@ -2632,10 +2660,10 @@ func (msg *Redux) TypeID() int { type SetPageLocation struct { message - URL string - Referrer string + URL string + Referrer string NavigationStart uint64 - DocumentTitle string + DocumentTitle string } func (msg *SetPageLocation) Encode() []byte { @@ -2661,9 +2689,9 @@ type GraphQL struct { message OperationKind string OperationName string - Variables string - Response string - Duration uint64 + Variables string + Response string + Duration uint64 } func (msg *GraphQL) Encode() []byte { @@ -2688,7 +2716,7 @@ func (msg *GraphQL) TypeID() int { type WebVitals struct { message - Name string + Name string Value string } @@ -2711,13 +2739,13 @@ func (msg *WebVitals) TypeID() int { type IssueEvent struct { message - MessageID uint64 - Timestamp uint64 - Type string + MessageID uint64 + Timestamp uint64 + Type string ContextString string - Context string - Payload string - URL string + Context string + Payload string + URL string } func (msg *IssueEvent) Encode() []byte { @@ -2744,7 +2772,7 @@ func (msg *IssueEvent) TypeID() int { type SessionEnd struct { message - Timestamp uint64 + Timestamp uint64 EncryptionKey string } @@ -2790,16 +2818,16 @@ func (msg *SessionSearch) TypeID() int { type MobileSessionStart struct { message - Timestamp uint64 - ProjectID uint64 + Timestamp uint64 + ProjectID uint64 TrackerVersion string - RevID string - UserUUID string - UserOS string - UserOSVersion string - UserDevice string + RevID string + UserUUID string + UserOS string + UserOSVersion string + UserDevice string UserDeviceType string - UserCountry string + UserCountry string } func (msg *MobileSessionStart) Encode() []byte { @@ -2851,9 +2879,9 @@ func (msg *MobileSessionEnd) TypeID() int { type MobileMetadata struct { message Timestamp uint64 - Length uint64 - Key string - Value string + Length uint64 + Key string + Value string } func (msg *MobileMetadata) Encode() []byte { @@ -2878,9 +2906,9 @@ func (msg *MobileMetadata) TypeID() int { type MobileEvent struct { message Timestamp uint64 - Length uint64 - Name string - Payload string + Length uint64 + Name string + Payload string } func (msg *MobileEvent) Encode() []byte { @@ -2905,8 +2933,8 @@ func (msg *MobileEvent) TypeID() int { type MobileUserID struct { message Timestamp uint64 - Length uint64 - ID string + Length uint64 + ID string } func (msg *MobileUserID) Encode() []byte { @@ -2930,8 +2958,8 @@ func (msg *MobileUserID) TypeID() int { type MobileUserAnonymousID struct { message Timestamp uint64 - Length uint64 - ID string + Length uint64 + ID string } func (msg *MobileUserAnonymousID) Encode() []byte { @@ -2955,11 +2983,11 @@ func (msg *MobileUserAnonymousID) TypeID() int { type MobileScreenChanges struct { message Timestamp uint64 - Length uint64 - X uint64 - Y uint64 - Width uint64 - Height uint64 + Length uint64 + X uint64 + Y uint64 + Width uint64 + Height uint64 } func (msg *MobileScreenChanges) Encode() []byte { @@ -2985,10 +3013,10 @@ func (msg *MobileScreenChanges) TypeID() int { type MobileCrash struct { message - Timestamp uint64 - Length uint64 - Name string - Reason string + Timestamp uint64 + Length uint64 + Name string + Reason string Stacktrace string } @@ -3014,11 +3042,11 @@ func (msg *MobileCrash) TypeID() int { type MobileViewComponentEvent struct { message - Timestamp uint64 - Length uint64 + Timestamp uint64 + Length uint64 ScreenName string - ViewName string - Visible bool + ViewName string + Visible bool } func (msg *MobileViewComponentEvent) Encode() []byte { @@ -3044,10 +3072,10 @@ func (msg *MobileViewComponentEvent) TypeID() int { type MobileClickEvent struct { message Timestamp uint64 - Length uint64 - Label string - X uint64 - Y uint64 + Length uint64 + Label string + X uint64 + Y uint64 } func (msg *MobileClickEvent) Encode() []byte { @@ -3072,11 +3100,11 @@ func (msg *MobileClickEvent) TypeID() int { type MobileInputEvent struct { message - Timestamp uint64 - Length uint64 - Value string + Timestamp uint64 + Length uint64 + Value string ValueMasked bool - Label string + Label string } func (msg *MobileInputEvent) Encode() []byte { @@ -3102,9 +3130,9 @@ func (msg *MobileInputEvent) TypeID() int { type MobilePerformanceEvent struct { message Timestamp uint64 - Length uint64 - Name string - Value uint64 + Length uint64 + Name string + Value uint64 } func (msg *MobilePerformanceEvent) Encode() []byte { @@ -3129,9 +3157,9 @@ func (msg *MobilePerformanceEvent) TypeID() int { type MobileLog struct { message Timestamp uint64 - Length uint64 - Severity string - Content string + Length uint64 + Severity string + Content string } func (msg *MobileLog) Encode() []byte { @@ -3156,8 +3184,8 @@ func (msg *MobileLog) TypeID() int { type MobileInternalError struct { message Timestamp uint64 - Length uint64 - Content string + Length uint64 + Content string } func (msg *MobileInternalError) Encode() []byte { @@ -3181,14 +3209,14 @@ func (msg *MobileInternalError) TypeID() int { type MobileNetworkCall struct { message Timestamp uint64 - Length uint64 - Type string - Method string - URL string - Request string - Response string - Status uint64 - Duration uint64 + Length uint64 + Type string + Method string + URL string + Request string + Response string + Status uint64 + Duration uint64 } func (msg *MobileNetworkCall) Encode() []byte { @@ -3218,10 +3246,10 @@ func (msg *MobileNetworkCall) TypeID() int { type MobileSwipeEvent struct { message Timestamp uint64 - Length uint64 - Label string - X uint64 - Y uint64 + Length uint64 + Label string + X uint64 + Y uint64 Direction string } @@ -3248,8 +3276,8 @@ func (msg *MobileSwipeEvent) TypeID() int { type MobileBatchMeta struct { message - Timestamp uint64 - Length uint64 + Timestamp uint64 + Length uint64 FirstIndex uint64 } @@ -3274,19 +3302,19 @@ func (msg *MobileBatchMeta) TypeID() int { type MobilePerformanceAggregated struct { message TimestampStart uint64 - TimestampEnd uint64 - MinFPS uint64 - AvgFPS uint64 - MaxFPS uint64 - MinCPU uint64 - AvgCPU uint64 - MaxCPU uint64 - MinMemory uint64 - AvgMemory uint64 - MaxMemory uint64 - MinBattery uint64 - AvgBattery uint64 - MaxBattery uint64 + TimestampEnd uint64 + MinFPS uint64 + AvgFPS uint64 + MaxFPS uint64 + MinCPU uint64 + AvgCPU uint64 + MaxCPU uint64 + MinMemory uint64 + AvgMemory uint64 + MaxMemory uint64 + MinBattery uint64 + AvgBattery uint64 + MaxBattery uint64 } func (msg *MobilePerformanceAggregated) Encode() []byte { @@ -3320,11 +3348,11 @@ func (msg *MobilePerformanceAggregated) TypeID() int { type MobileIssueEvent struct { message - Timestamp uint64 - Type string + Timestamp uint64 + Type string ContextString string - Context string - Payload string + Context string + Payload string } func (msg *MobileIssueEvent) Encode() []byte { @@ -3346,3 +3374,4 @@ func (msg *MobileIssueEvent) Decode() Message { func (msg *MobileIssueEvent) TypeID() int { return 111 } + diff --git a/backend/pkg/messages/read-message.go b/backend/pkg/messages/read-message.go index 3caa6af08..ef9a49586 100644 --- a/backend/pkg/messages/read-message.go +++ b/backend/pkg/messages/read-message.go @@ -6,2161 +6,2176 @@ import ( ) func DecodeTimestamp(reader BytesReader) (Message, error) { - var err error = nil - msg := &Timestamp{} - if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + var err error = nil + msg := &Timestamp{} + if msg.Timestamp, err = reader.ReadUint(); err != nil { + return nil, err + } + return msg, err } func DecodeSessionStart(reader BytesReader) (Message, error) { - var err error = nil - msg := &SessionStart{} - if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &SessionStart{} + if msg.Timestamp, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.ProjectID, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.TrackerVersion, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.RevID, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.UserUUID, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.UserAgent, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.UserOS, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.UserOSVersion, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.UserBrowser, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.UserBrowserVersion, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.UserDevice, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.UserDeviceType, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.UserDeviceMemorySize, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.UserDeviceHeapSize, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.UserCountry, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.UserID, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeSessionEndDeprecated(reader BytesReader) (Message, error) { - var err error = nil - msg := &SessionEndDeprecated{} - if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + var err error = nil + msg := &SessionEndDeprecated{} + if msg.Timestamp, err = reader.ReadUint(); err != nil { + return nil, err + } + return msg, err } func DecodeSetPageLocationDeprecated(reader BytesReader) (Message, error) { - var err error = nil - msg := &SetPageLocationDeprecated{} - if msg.URL, err = reader.ReadString(); err != nil { - return nil, err - } + var err error = nil + msg := &SetPageLocationDeprecated{} + if msg.URL, err = reader.ReadString(); err != nil { + return nil, err + } if msg.Referrer, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.NavigationStart, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeSetViewportSize(reader BytesReader) (Message, error) { - var err error = nil - msg := &SetViewportSize{} - if msg.Width, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &SetViewportSize{} + if msg.Width, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Height, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeSetViewportScroll(reader BytesReader) (Message, error) { - var err error = nil - msg := &SetViewportScroll{} - if msg.X, err = reader.ReadInt(); err != nil { - return nil, err - } + var err error = nil + msg := &SetViewportScroll{} + if msg.X, err = reader.ReadInt(); err != nil { + return nil, err + } if msg.Y, err = reader.ReadInt(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeCreateDocument(reader BytesReader) (Message, error) { - var err error = nil - msg := &CreateDocument{} - - return msg, err + var err error = nil + msg := &CreateDocument{} + + return msg, err } func DecodeCreateElementNode(reader BytesReader) (Message, error) { - var err error = nil - msg := &CreateElementNode{} - if msg.ID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &CreateElementNode{} + if msg.ID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.ParentID, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.index, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Tag, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.SVG, err = reader.ReadBoolean(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeCreateTextNode(reader BytesReader) (Message, error) { - var err error = nil - msg := &CreateTextNode{} - if msg.ID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &CreateTextNode{} + if msg.ID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.ParentID, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Index, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeMoveNode(reader BytesReader) (Message, error) { - var err error = nil - msg := &MoveNode{} - if msg.ID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &MoveNode{} + if msg.ID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.ParentID, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Index, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeRemoveNode(reader BytesReader) (Message, error) { - var err error = nil - msg := &RemoveNode{} - if msg.ID, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + var err error = nil + msg := &RemoveNode{} + if msg.ID, err = reader.ReadUint(); err != nil { + return nil, err + } + return msg, err } func DecodeSetNodeAttribute(reader BytesReader) (Message, error) { - var err error = nil - msg := &SetNodeAttribute{} - if msg.ID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &SetNodeAttribute{} + if msg.ID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Name, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Value, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeRemoveNodeAttribute(reader BytesReader) (Message, error) { - var err error = nil - msg := &RemoveNodeAttribute{} - if msg.ID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &RemoveNodeAttribute{} + if msg.ID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Name, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeSetNodeData(reader BytesReader) (Message, error) { - var err error = nil - msg := &SetNodeData{} - if msg.ID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &SetNodeData{} + if msg.ID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Data, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeSetCSSData(reader BytesReader) (Message, error) { - var err error = nil - msg := &SetCSSData{} - if msg.ID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &SetCSSData{} + if msg.ID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Data, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeSetNodeScroll(reader BytesReader) (Message, error) { - var err error = nil - msg := &SetNodeScroll{} - if msg.ID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &SetNodeScroll{} + if msg.ID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.X, err = reader.ReadInt(); err != nil { - return nil, err - } + return nil, err + } if msg.Y, err = reader.ReadInt(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeSetInputTarget(reader BytesReader) (Message, error) { - var err error = nil - msg := &SetInputTarget{} - if msg.ID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &SetInputTarget{} + if msg.ID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Label, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeSetInputValue(reader BytesReader) (Message, error) { - var err error = nil - msg := &SetInputValue{} - if msg.ID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &SetInputValue{} + if msg.ID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Value, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Mask, err = reader.ReadInt(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeSetInputChecked(reader BytesReader) (Message, error) { - var err error = nil - msg := &SetInputChecked{} - if msg.ID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &SetInputChecked{} + if msg.ID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Checked, err = reader.ReadBoolean(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeMouseMove(reader BytesReader) (Message, error) { - var err error = nil - msg := &MouseMove{} - if msg.X, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &MouseMove{} + if msg.X, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Y, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeNetworkRequestDeprecated(reader BytesReader) (Message, error) { - var err error = nil - msg := &NetworkRequestDeprecated{} - if msg.Type, err = reader.ReadString(); err != nil { - return nil, err - } + var err error = nil + msg := &NetworkRequestDeprecated{} + if msg.Type, err = reader.ReadString(); err != nil { + return nil, err + } if msg.Method, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.URL, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Request, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Response, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Status, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Duration, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeConsoleLog(reader BytesReader) (Message, error) { - var err error = nil - msg := &ConsoleLog{} - if msg.Level, err = reader.ReadString(); err != nil { - return nil, err - } + var err error = nil + msg := &ConsoleLog{} + if msg.Level, err = reader.ReadString(); err != nil { + return nil, err + } if msg.Value, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodePageLoadTiming(reader BytesReader) (Message, error) { - var err error = nil - msg := &PageLoadTiming{} - if msg.RequestStart, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &PageLoadTiming{} + if msg.RequestStart, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.ResponseStart, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.ResponseEnd, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.DomContentLoadedEventStart, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.DomContentLoadedEventEnd, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.LoadEventStart, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.LoadEventEnd, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.FirstPaint, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.FirstContentfulPaint, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodePageRenderTiming(reader BytesReader) (Message, error) { - var err error = nil - msg := &PageRenderTiming{} - if msg.SpeedIndex, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &PageRenderTiming{} + if msg.SpeedIndex, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.VisuallyComplete, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.TimeToInteractive, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeJSExceptionDeprecated(reader BytesReader) (Message, error) { - var err error = nil - msg := &JSExceptionDeprecated{} - if msg.Name, err = reader.ReadString(); err != nil { - return nil, err - } + var err error = nil + msg := &JSExceptionDeprecated{} + if msg.Name, err = reader.ReadString(); err != nil { + return nil, err + } if msg.Message, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Payload, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeIntegrationEvent(reader BytesReader) (Message, error) { - var err error = nil - msg := &IntegrationEvent{} - if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &IntegrationEvent{} + if msg.Timestamp, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Source, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Name, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Message, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Payload, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeCustomEvent(reader BytesReader) (Message, error) { - var err error = nil - msg := &CustomEvent{} - if msg.Name, err = reader.ReadString(); err != nil { - return nil, err - } + var err error = nil + msg := &CustomEvent{} + if msg.Name, err = reader.ReadString(); err != nil { + return nil, err + } if msg.Payload, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeUserID(reader BytesReader) (Message, error) { - var err error = nil - msg := &UserID{} - if msg.ID, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + var err error = nil + msg := &UserID{} + if msg.ID, err = reader.ReadString(); err != nil { + return nil, err + } + return msg, err } func DecodeUserAnonymousID(reader BytesReader) (Message, error) { - var err error = nil - msg := &UserAnonymousID{} - if msg.ID, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + var err error = nil + msg := &UserAnonymousID{} + if msg.ID, err = reader.ReadString(); err != nil { + return nil, err + } + return msg, err } func DecodeMetadata(reader BytesReader) (Message, error) { - var err error = nil - msg := &Metadata{} - if msg.Key, err = reader.ReadString(); err != nil { - return nil, err - } + var err error = nil + msg := &Metadata{} + if msg.Key, err = reader.ReadString(); err != nil { + return nil, err + } if msg.Value, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodePageEventDeprecated(reader BytesReader) (Message, error) { - var err error = nil - msg := &PageEventDeprecated{} - if msg.MessageID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &PageEventDeprecated{} + if msg.MessageID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.URL, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Referrer, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Loaded, err = reader.ReadBoolean(); err != nil { - return nil, err - } + return nil, err + } if msg.RequestStart, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.ResponseStart, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.ResponseEnd, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.DomContentLoadedEventStart, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.DomContentLoadedEventEnd, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.LoadEventStart, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.LoadEventEnd, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.FirstPaint, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.FirstContentfulPaint, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.SpeedIndex, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.VisuallyComplete, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.TimeToInteractive, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeInputEvent(reader BytesReader) (Message, error) { - var err error = nil - msg := &InputEvent{} - if msg.MessageID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &InputEvent{} + if msg.MessageID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Value, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.ValueMasked, err = reader.ReadBoolean(); err != nil { - return nil, err - } + return nil, err + } if msg.Label, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodePageEvent(reader BytesReader) (Message, error) { - var err error = nil - msg := &PageEvent{} - if msg.MessageID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &PageEvent{} + if msg.MessageID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.URL, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Referrer, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Loaded, err = reader.ReadBoolean(); err != nil { - return nil, err - } + return nil, err + } if msg.RequestStart, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.ResponseStart, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.ResponseEnd, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.DomContentLoadedEventStart, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.DomContentLoadedEventEnd, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.LoadEventStart, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.LoadEventEnd, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.FirstPaint, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.FirstContentfulPaint, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.SpeedIndex, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.VisuallyComplete, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.TimeToInteractive, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.WebVitals, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeStringDictGlobal(reader BytesReader) (Message, error) { - var err error = nil - msg := &StringDictGlobal{} - if msg.Key, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &StringDictGlobal{} + if msg.Key, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Value, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeSetNodeAttributeDictGlobal(reader BytesReader) (Message, error) { - var err error = nil - msg := &SetNodeAttributeDictGlobal{} - if msg.ID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &SetNodeAttributeDictGlobal{} + if msg.ID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Name, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Value, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeCSSInsertRule(reader BytesReader) (Message, error) { - var err error = nil - msg := &CSSInsertRule{} - if msg.ID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &CSSInsertRule{} + if msg.ID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Rule, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Index, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeCSSDeleteRule(reader BytesReader) (Message, error) { - var err error = nil - msg := &CSSDeleteRule{} - if msg.ID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &CSSDeleteRule{} + if msg.ID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Index, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeFetch(reader BytesReader) (Message, error) { - var err error = nil - msg := &Fetch{} - if msg.Method, err = reader.ReadString(); err != nil { - return nil, err - } + var err error = nil + msg := &Fetch{} + if msg.Method, err = reader.ReadString(); err != nil { + return nil, err + } if msg.URL, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Request, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Response, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Status, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Duration, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeProfiler(reader BytesReader) (Message, error) { - var err error = nil - msg := &Profiler{} - if msg.Name, err = reader.ReadString(); err != nil { - return nil, err - } + var err error = nil + msg := &Profiler{} + if msg.Name, err = reader.ReadString(); err != nil { + return nil, err + } if msg.Duration, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Args, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Result, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeOTable(reader BytesReader) (Message, error) { - var err error = nil - msg := &OTable{} - if msg.Key, err = reader.ReadString(); err != nil { - return nil, err - } + var err error = nil + msg := &OTable{} + if msg.Key, err = reader.ReadString(); err != nil { + return nil, err + } if msg.Value, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeStateAction(reader BytesReader) (Message, error) { - var err error = nil - msg := &StateAction{} - if msg.Type, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + var err error = nil + msg := &StateAction{} + if msg.Type, err = reader.ReadString(); err != nil { + return nil, err + } + return msg, err } func DecodeReduxDeprecated(reader BytesReader) (Message, error) { - var err error = nil - msg := &ReduxDeprecated{} - if msg.Action, err = reader.ReadString(); err != nil { - return nil, err - } + var err error = nil + msg := &ReduxDeprecated{} + if msg.Action, err = reader.ReadString(); err != nil { + return nil, err + } if msg.State, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Duration, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeVuex(reader BytesReader) (Message, error) { - var err error = nil - msg := &Vuex{} - if msg.Mutation, err = reader.ReadString(); err != nil { - return nil, err - } + var err error = nil + msg := &Vuex{} + if msg.Mutation, err = reader.ReadString(); err != nil { + return nil, err + } if msg.State, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeMobX(reader BytesReader) (Message, error) { - var err error = nil - msg := &MobX{} - if msg.Type, err = reader.ReadString(); err != nil { - return nil, err - } + var err error = nil + msg := &MobX{} + if msg.Type, err = reader.ReadString(); err != nil { + return nil, err + } if msg.Payload, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeNgRx(reader BytesReader) (Message, error) { - var err error = nil - msg := &NgRx{} - if msg.Action, err = reader.ReadString(); err != nil { - return nil, err - } + var err error = nil + msg := &NgRx{} + if msg.Action, err = reader.ReadString(); err != nil { + return nil, err + } if msg.State, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Duration, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeGraphQLDeprecated(reader BytesReader) (Message, error) { - var err error = nil - msg := &GraphQLDeprecated{} - if msg.OperationKind, err = reader.ReadString(); err != nil { - return nil, err - } + var err error = nil + msg := &GraphQLDeprecated{} + if msg.OperationKind, err = reader.ReadString(); err != nil { + return nil, err + } if msg.OperationName, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Variables, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Response, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Duration, err = reader.ReadInt(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodePerformanceTrack(reader BytesReader) (Message, error) { - var err error = nil - msg := &PerformanceTrack{} - if msg.Frames, err = reader.ReadInt(); err != nil { - return nil, err - } + var err error = nil + msg := &PerformanceTrack{} + if msg.Frames, err = reader.ReadInt(); err != nil { + return nil, err + } if msg.Ticks, err = reader.ReadInt(); err != nil { - return nil, err - } + return nil, err + } if msg.TotalJSHeapSize, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.UsedJSHeapSize, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeStringDictDeprecated(reader BytesReader) (Message, error) { - var err error = nil - msg := &StringDictDeprecated{} - if msg.Key, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &StringDictDeprecated{} + if msg.Key, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Value, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeSetNodeAttributeDictDeprecated(reader BytesReader) (Message, error) { - var err error = nil - msg := &SetNodeAttributeDictDeprecated{} - if msg.ID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &SetNodeAttributeDictDeprecated{} + if msg.ID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.NameKey, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.ValueKey, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeStringDict(reader BytesReader) (Message, error) { - var err error = nil - msg := &StringDict{} - if msg.Key, err = reader.ReadString(); err != nil { - return nil, err - } + var err error = nil + msg := &StringDict{} + if msg.Key, err = reader.ReadString(); err != nil { + return nil, err + } if msg.Value, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeSetNodeAttributeDict(reader BytesReader) (Message, error) { - var err error = nil - msg := &SetNodeAttributeDict{} - if msg.ID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &SetNodeAttributeDict{} + if msg.ID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Name, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Value, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeResourceTimingDeprecatedDeprecated(reader BytesReader) (Message, error) { - var err error = nil - msg := &ResourceTimingDeprecatedDeprecated{} - if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &ResourceTimingDeprecatedDeprecated{} + if msg.Timestamp, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Duration, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.TTFB, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.HeaderSize, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.EncodedBodySize, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.DecodedBodySize, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.URL, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Initiator, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeConnectionInformation(reader BytesReader) (Message, error) { - var err error = nil - msg := &ConnectionInformation{} - if msg.Downlink, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &ConnectionInformation{} + if msg.Downlink, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Type, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeSetPageVisibility(reader BytesReader) (Message, error) { - var err error = nil - msg := &SetPageVisibility{} - if msg.hidden, err = reader.ReadBoolean(); err != nil { - return nil, err - } - return msg, err + var err error = nil + msg := &SetPageVisibility{} + if msg.hidden, err = reader.ReadBoolean(); err != nil { + return nil, err + } + return msg, err } func DecodePerformanceTrackAggr(reader BytesReader) (Message, error) { - var err error = nil - msg := &PerformanceTrackAggr{} - if msg.TimestampStart, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &PerformanceTrackAggr{} + if msg.TimestampStart, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.TimestampEnd, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.MinFPS, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.AvgFPS, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.MaxFPS, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.MinCPU, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.AvgCPU, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.MaxCPU, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.MinTotalJSHeapSize, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.AvgTotalJSHeapSize, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.MaxTotalJSHeapSize, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.MinUsedJSHeapSize, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.AvgUsedJSHeapSize, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.MaxUsedJSHeapSize, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeLoadFontFace(reader BytesReader) (Message, error) { - var err error = nil - msg := &LoadFontFace{} - if msg.ParentID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &LoadFontFace{} + if msg.ParentID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Family, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Source, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Descriptors, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeSetNodeFocus(reader BytesReader) (Message, error) { - var err error = nil - msg := &SetNodeFocus{} - if msg.ID, err = reader.ReadInt(); err != nil { - return nil, err - } - return msg, err + var err error = nil + msg := &SetNodeFocus{} + if msg.ID, err = reader.ReadInt(); err != nil { + return nil, err + } + return msg, err } func DecodeLongTask(reader BytesReader) (Message, error) { - var err error = nil - msg := &LongTask{} - if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &LongTask{} + if msg.Timestamp, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Duration, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Context, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.ContainerType, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.ContainerSrc, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.ContainerId, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.ContainerName, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeSetNodeAttributeURLBased(reader BytesReader) (Message, error) { - var err error = nil - msg := &SetNodeAttributeURLBased{} - if msg.ID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &SetNodeAttributeURLBased{} + if msg.ID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Name, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Value, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.BaseURL, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeSetCSSDataURLBased(reader BytesReader) (Message, error) { - var err error = nil - msg := &SetCSSDataURLBased{} - if msg.ID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &SetCSSDataURLBased{} + if msg.ID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Data, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.BaseURL, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeIssueEventDeprecated(reader BytesReader) (Message, error) { - var err error = nil - msg := &IssueEventDeprecated{} - if msg.MessageID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &IssueEventDeprecated{} + if msg.MessageID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Type, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.ContextString, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Context, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Payload, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeTechnicalInfo(reader BytesReader) (Message, error) { - var err error = nil - msg := &TechnicalInfo{} - if msg.Type, err = reader.ReadString(); err != nil { - return nil, err - } + var err error = nil + msg := &TechnicalInfo{} + if msg.Type, err = reader.ReadString(); err != nil { + return nil, err + } if msg.Value, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeCustomIssue(reader BytesReader) (Message, error) { - var err error = nil - msg := &CustomIssue{} - if msg.Name, err = reader.ReadString(); err != nil { - return nil, err - } + var err error = nil + msg := &CustomIssue{} + if msg.Name, err = reader.ReadString(); err != nil { + return nil, err + } if msg.Payload, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeAssetCache(reader BytesReader) (Message, error) { - var err error = nil - msg := &AssetCache{} - if msg.URL, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + var err error = nil + msg := &AssetCache{} + if msg.URL, err = reader.ReadString(); err != nil { + return nil, err + } + return msg, err } func DecodeCSSInsertRuleURLBased(reader BytesReader) (Message, error) { - var err error = nil - msg := &CSSInsertRuleURLBased{} - if msg.ID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &CSSInsertRuleURLBased{} + if msg.ID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Rule, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Index, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.BaseURL, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeMouseClick(reader BytesReader) (Message, error) { - var err error = nil - msg := &MouseClick{} - if msg.ID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &MouseClick{} + if msg.ID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.HesitationTime, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Label, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Selector, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.NormalizedX, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.NormalizedY, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeMouseClickDeprecated(reader BytesReader) (Message, error) { - var err error = nil - msg := &MouseClickDeprecated{} - if msg.ID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &MouseClickDeprecated{} + if msg.ID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.HesitationTime, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Label, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Selector, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeCreateIFrameDocument(reader BytesReader) (Message, error) { - var err error = nil - msg := &CreateIFrameDocument{} - if msg.FrameID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &CreateIFrameDocument{} + if msg.FrameID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.ID, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeAdoptedSSReplaceURLBased(reader BytesReader) (Message, error) { - var err error = nil - msg := &AdoptedSSReplaceURLBased{} - if msg.SheetID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &AdoptedSSReplaceURLBased{} + if msg.SheetID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Text, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.BaseURL, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeAdoptedSSReplace(reader BytesReader) (Message, error) { - var err error = nil - msg := &AdoptedSSReplace{} - if msg.SheetID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &AdoptedSSReplace{} + if msg.SheetID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Text, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeAdoptedSSInsertRuleURLBased(reader BytesReader) (Message, error) { - var err error = nil - msg := &AdoptedSSInsertRuleURLBased{} - if msg.SheetID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &AdoptedSSInsertRuleURLBased{} + if msg.SheetID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Rule, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Index, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.BaseURL, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeAdoptedSSInsertRule(reader BytesReader) (Message, error) { - var err error = nil - msg := &AdoptedSSInsertRule{} - if msg.SheetID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &AdoptedSSInsertRule{} + if msg.SheetID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Rule, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Index, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeAdoptedSSDeleteRule(reader BytesReader) (Message, error) { - var err error = nil - msg := &AdoptedSSDeleteRule{} - if msg.SheetID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &AdoptedSSDeleteRule{} + if msg.SheetID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Index, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeAdoptedSSAddOwner(reader BytesReader) (Message, error) { - var err error = nil - msg := &AdoptedSSAddOwner{} - if msg.SheetID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &AdoptedSSAddOwner{} + if msg.SheetID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.ID, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeAdoptedSSRemoveOwner(reader BytesReader) (Message, error) { - var err error = nil - msg := &AdoptedSSRemoveOwner{} - if msg.SheetID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &AdoptedSSRemoveOwner{} + if msg.SheetID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.ID, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeJSException(reader BytesReader) (Message, error) { - var err error = nil - msg := &JSException{} - if msg.Name, err = reader.ReadString(); err != nil { - return nil, err - } + var err error = nil + msg := &JSException{} + if msg.Name, err = reader.ReadString(); err != nil { + return nil, err + } if msg.Message, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Payload, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Metadata, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeZustand(reader BytesReader) (Message, error) { - var err error = nil - msg := &Zustand{} - if msg.Mutation, err = reader.ReadString(); err != nil { - return nil, err - } + var err error = nil + msg := &Zustand{} + if msg.Mutation, err = reader.ReadString(); err != nil { + return nil, err + } if msg.State, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeBatchMeta(reader BytesReader) (Message, error) { - var err error = nil - msg := &BatchMeta{} - if msg.PageNo, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &BatchMeta{} + if msg.PageNo, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.FirstIndex, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Timestamp, err = reader.ReadInt(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeBatchMetadata(reader BytesReader) (Message, error) { - var err error = nil - msg := &BatchMetadata{} - if msg.Version, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &BatchMetadata{} + if msg.Version, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.PageNo, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.FirstIndex, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Timestamp, err = reader.ReadInt(); err != nil { - return nil, err - } + return nil, err + } if msg.Location, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodePartitionedMessage(reader BytesReader) (Message, error) { - var err error = nil - msg := &PartitionedMessage{} - if msg.PartNo, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &PartitionedMessage{} + if msg.PartNo, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.PartTotal, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeNetworkRequest(reader BytesReader) (Message, error) { - var err error = nil - msg := &NetworkRequest{} - if msg.Type, err = reader.ReadString(); err != nil { - return nil, err - } + var err error = nil + msg := &NetworkRequest{} + if msg.Type, err = reader.ReadString(); err != nil { + return nil, err + } if msg.Method, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.URL, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Request, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Response, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Status, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Duration, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.TransferredBodySize, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeWSChannel(reader BytesReader) (Message, error) { - var err error = nil - msg := &WSChannel{} - if msg.ChType, err = reader.ReadString(); err != nil { - return nil, err - } + var err error = nil + msg := &WSChannel{} + if msg.ChType, err = reader.ReadString(); err != nil { + return nil, err + } if msg.ChannelName, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Data, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Dir, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.MessageType, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeResourceTiming(reader BytesReader) (Message, error) { - var err error = nil - msg := &ResourceTiming{} - if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &ResourceTiming{} + if msg.Timestamp, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Duration, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.TTFB, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.HeaderSize, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.EncodedBodySize, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.DecodedBodySize, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.URL, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Initiator, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.TransferredSize, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Cached, err = reader.ReadBoolean(); err != nil { - return nil, err - } + return nil, err + } if msg.Queueing, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.DnsLookup, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.InitialConnection, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.SSL, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.ContentDownload, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Total, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Stalled, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err +} + +func DecodeIncident(reader BytesReader) (Message, error) { + var err error = nil + msg := &Incident{} + if msg.Label, err = reader.ReadString(); err != nil { + return nil, err + } + if msg.StartTime, err = reader.ReadInt(); err != nil { + return nil, err + } + if msg.EndTime, err = reader.ReadInt(); err != nil { + return nil, err + } + return msg, err } func DecodeLongAnimationTask(reader BytesReader) (Message, error) { - var err error = nil - msg := &LongAnimationTask{} - if msg.Name, err = reader.ReadString(); err != nil { - return nil, err - } + var err error = nil + msg := &LongAnimationTask{} + if msg.Name, err = reader.ReadString(); err != nil { + return nil, err + } if msg.Duration, err = reader.ReadInt(); err != nil { - return nil, err - } + return nil, err + } if msg.BlockingDuration, err = reader.ReadInt(); err != nil { - return nil, err - } + return nil, err + } if msg.FirstUIEventTimestamp, err = reader.ReadInt(); err != nil { - return nil, err - } + return nil, err + } if msg.StartTime, err = reader.ReadInt(); err != nil { - return nil, err - } + return nil, err + } if msg.Scripts, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeInputChange(reader BytesReader) (Message, error) { - var err error = nil - msg := &InputChange{} - if msg.ID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &InputChange{} + if msg.ID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Value, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.ValueMasked, err = reader.ReadBoolean(); err != nil { - return nil, err - } + return nil, err + } if msg.Label, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.HesitationTime, err = reader.ReadInt(); err != nil { - return nil, err - } + return nil, err + } if msg.InputDuration, err = reader.ReadInt(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeSelectionChange(reader BytesReader) (Message, error) { - var err error = nil - msg := &SelectionChange{} - if msg.SelectionStart, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &SelectionChange{} + if msg.SelectionStart, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.SelectionEnd, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Selection, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeMouseThrashing(reader BytesReader) (Message, error) { - var err error = nil - msg := &MouseThrashing{} - if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + var err error = nil + msg := &MouseThrashing{} + if msg.Timestamp, err = reader.ReadUint(); err != nil { + return nil, err + } + return msg, err } func DecodeUnbindNodes(reader BytesReader) (Message, error) { - var err error = nil - msg := &UnbindNodes{} - if msg.TotalRemovedPercent, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + var err error = nil + msg := &UnbindNodes{} + if msg.TotalRemovedPercent, err = reader.ReadUint(); err != nil { + return nil, err + } + return msg, err } func DecodeResourceTimingDeprecated(reader BytesReader) (Message, error) { - var err error = nil - msg := &ResourceTimingDeprecated{} - if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &ResourceTimingDeprecated{} + if msg.Timestamp, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Duration, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.TTFB, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.HeaderSize, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.EncodedBodySize, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.DecodedBodySize, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.URL, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Initiator, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.TransferredSize, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Cached, err = reader.ReadBoolean(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeTabChange(reader BytesReader) (Message, error) { - var err error = nil - msg := &TabChange{} - if msg.TabId, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + var err error = nil + msg := &TabChange{} + if msg.TabId, err = reader.ReadString(); err != nil { + return nil, err + } + return msg, err } func DecodeTabData(reader BytesReader) (Message, error) { - var err error = nil - msg := &TabData{} - if msg.TabId, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + var err error = nil + msg := &TabData{} + if msg.TabId, err = reader.ReadString(); err != nil { + return nil, err + } + return msg, err } func DecodeCanvasNode(reader BytesReader) (Message, error) { - var err error = nil - msg := &CanvasNode{} - if msg.NodeId, err = reader.ReadString(); err != nil { - return nil, err - } + var err error = nil + msg := &CanvasNode{} + if msg.NodeId, err = reader.ReadString(); err != nil { + return nil, err + } if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeTagTrigger(reader BytesReader) (Message, error) { - var err error = nil - msg := &TagTrigger{} - if msg.TagId, err = reader.ReadInt(); err != nil { - return nil, err - } - return msg, err + var err error = nil + msg := &TagTrigger{} + if msg.TagId, err = reader.ReadInt(); err != nil { + return nil, err + } + return msg, err } func DecodeRedux(reader BytesReader) (Message, error) { - var err error = nil - msg := &Redux{} - if msg.Action, err = reader.ReadString(); err != nil { - return nil, err - } + var err error = nil + msg := &Redux{} + if msg.Action, err = reader.ReadString(); err != nil { + return nil, err + } if msg.State, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Duration, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.ActionTime, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeSetPageLocation(reader BytesReader) (Message, error) { - var err error = nil - msg := &SetPageLocation{} - if msg.URL, err = reader.ReadString(); err != nil { - return nil, err - } + var err error = nil + msg := &SetPageLocation{} + if msg.URL, err = reader.ReadString(); err != nil { + return nil, err + } if msg.Referrer, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.NavigationStart, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.DocumentTitle, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeGraphQL(reader BytesReader) (Message, error) { - var err error = nil - msg := &GraphQL{} - if msg.OperationKind, err = reader.ReadString(); err != nil { - return nil, err - } + var err error = nil + msg := &GraphQL{} + if msg.OperationKind, err = reader.ReadString(); err != nil { + return nil, err + } if msg.OperationName, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Variables, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Response, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Duration, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeWebVitals(reader BytesReader) (Message, error) { - var err error = nil - msg := &WebVitals{} - if msg.Name, err = reader.ReadString(); err != nil { - return nil, err - } + var err error = nil + msg := &WebVitals{} + if msg.Name, err = reader.ReadString(); err != nil { + return nil, err + } if msg.Value, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeIssueEvent(reader BytesReader) (Message, error) { - var err error = nil - msg := &IssueEvent{} - if msg.MessageID, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &IssueEvent{} + if msg.MessageID, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Type, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.ContextString, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Context, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Payload, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.URL, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeSessionEnd(reader BytesReader) (Message, error) { - var err error = nil - msg := &SessionEnd{} - if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &SessionEnd{} + if msg.Timestamp, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.EncryptionKey, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeSessionSearch(reader BytesReader) (Message, error) { - var err error = nil - msg := &SessionSearch{} - if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &SessionSearch{} + if msg.Timestamp, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Partition, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeMobileSessionStart(reader BytesReader) (Message, error) { - var err error = nil - msg := &MobileSessionStart{} - if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &MobileSessionStart{} + if msg.Timestamp, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.ProjectID, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.TrackerVersion, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.RevID, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.UserUUID, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.UserOS, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.UserOSVersion, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.UserDevice, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.UserDeviceType, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.UserCountry, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeMobileSessionEnd(reader BytesReader) (Message, error) { - var err error = nil - msg := &MobileSessionEnd{} - if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + var err error = nil + msg := &MobileSessionEnd{} + if msg.Timestamp, err = reader.ReadUint(); err != nil { + return nil, err + } + return msg, err } func DecodeMobileMetadata(reader BytesReader) (Message, error) { - var err error = nil - msg := &MobileMetadata{} - if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &MobileMetadata{} + if msg.Timestamp, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Length, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Key, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Value, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeMobileEvent(reader BytesReader) (Message, error) { - var err error = nil - msg := &MobileEvent{} - if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &MobileEvent{} + if msg.Timestamp, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Length, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Name, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Payload, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeMobileUserID(reader BytesReader) (Message, error) { - var err error = nil - msg := &MobileUserID{} - if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &MobileUserID{} + if msg.Timestamp, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Length, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.ID, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeMobileUserAnonymousID(reader BytesReader) (Message, error) { - var err error = nil - msg := &MobileUserAnonymousID{} - if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &MobileUserAnonymousID{} + if msg.Timestamp, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Length, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.ID, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeMobileScreenChanges(reader BytesReader) (Message, error) { - var err error = nil - msg := &MobileScreenChanges{} - if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &MobileScreenChanges{} + if msg.Timestamp, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Length, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.X, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Y, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Width, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Height, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeMobileCrash(reader BytesReader) (Message, error) { - var err error = nil - msg := &MobileCrash{} - if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &MobileCrash{} + if msg.Timestamp, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Length, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Name, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Reason, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Stacktrace, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeMobileViewComponentEvent(reader BytesReader) (Message, error) { - var err error = nil - msg := &MobileViewComponentEvent{} - if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &MobileViewComponentEvent{} + if msg.Timestamp, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Length, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.ScreenName, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.ViewName, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Visible, err = reader.ReadBoolean(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeMobileClickEvent(reader BytesReader) (Message, error) { - var err error = nil - msg := &MobileClickEvent{} - if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &MobileClickEvent{} + if msg.Timestamp, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Length, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Label, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.X, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Y, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeMobileInputEvent(reader BytesReader) (Message, error) { - var err error = nil - msg := &MobileInputEvent{} - if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &MobileInputEvent{} + if msg.Timestamp, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Length, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Value, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.ValueMasked, err = reader.ReadBoolean(); err != nil { - return nil, err - } + return nil, err + } if msg.Label, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeMobilePerformanceEvent(reader BytesReader) (Message, error) { - var err error = nil - msg := &MobilePerformanceEvent{} - if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &MobilePerformanceEvent{} + if msg.Timestamp, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Length, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Name, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Value, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeMobileLog(reader BytesReader) (Message, error) { - var err error = nil - msg := &MobileLog{} - if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &MobileLog{} + if msg.Timestamp, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Length, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Severity, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Content, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeMobileInternalError(reader BytesReader) (Message, error) { - var err error = nil - msg := &MobileInternalError{} - if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &MobileInternalError{} + if msg.Timestamp, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Length, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Content, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeMobileNetworkCall(reader BytesReader) (Message, error) { - var err error = nil - msg := &MobileNetworkCall{} - if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &MobileNetworkCall{} + if msg.Timestamp, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Length, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Type, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Method, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.URL, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Request, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Response, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Status, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Duration, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeMobileSwipeEvent(reader BytesReader) (Message, error) { - var err error = nil - msg := &MobileSwipeEvent{} - if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &MobileSwipeEvent{} + if msg.Timestamp, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Length, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Label, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.X, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Y, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.Direction, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeMobileBatchMeta(reader BytesReader) (Message, error) { - var err error = nil - msg := &MobileBatchMeta{} - if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &MobileBatchMeta{} + if msg.Timestamp, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Length, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.FirstIndex, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeMobilePerformanceAggregated(reader BytesReader) (Message, error) { - var err error = nil - msg := &MobilePerformanceAggregated{} - if msg.TimestampStart, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &MobilePerformanceAggregated{} + if msg.TimestampStart, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.TimestampEnd, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.MinFPS, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.AvgFPS, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.MaxFPS, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.MinCPU, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.AvgCPU, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.MaxCPU, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.MinMemory, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.AvgMemory, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.MaxMemory, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.MinBattery, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.AvgBattery, err = reader.ReadUint(); err != nil { - return nil, err - } + return nil, err + } if msg.MaxBattery, err = reader.ReadUint(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func DecodeMobileIssueEvent(reader BytesReader) (Message, error) { - var err error = nil - msg := &MobileIssueEvent{} - if msg.Timestamp, err = reader.ReadUint(); err != nil { - return nil, err - } + var err error = nil + msg := &MobileIssueEvent{} + if msg.Timestamp, err = reader.ReadUint(); err != nil { + return nil, err + } if msg.Type, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.ContextString, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Context, err = reader.ReadString(); err != nil { - return nil, err - } + return nil, err + } if msg.Payload, err = reader.ReadString(); err != nil { - return nil, err - } - return msg, err + return nil, err + } + return msg, err } func ReadMessage(t uint64, reader BytesReader) (Message, error) { @@ -2331,6 +2346,8 @@ func ReadMessage(t uint64, reader BytesReader) (Message, error) { return DecodeWSChannel(reader) case 85: return DecodeResourceTiming(reader) + case 87: + return DecodeIncident(reader) case 89: return DecodeLongAnimationTask(reader) case 112: diff --git a/ee/api/.gitignore b/ee/api/.gitignore index 61bc09c37..80beeee41 100644 --- a/ee/api/.gitignore +++ b/ee/api/.gitignore @@ -201,16 +201,17 @@ Pipfile.lock /chalicelib/core/metrics/heatmaps /chalicelib/core/metrics/product_analytics /chalicelib/core/metrics/product_anaytics2.py -/chalicelib/core/events +/chalicelib/core/events* /chalicelib/core/feature_flags.py /chalicelib/core/issue_tracking/* /chalicelib/core/issues.py +/chalicelib/core/issues/ /chalicelib/core/jobs.py /chalicelib/core/log_tools/* /chalicelib/core/metadata.py /chalicelib/core/mobile.py /chalicelib/core/saved_search.py -/chalicelib/core/sessions/*.py +/chalicelib/core/sessions/**/*.py /chalicelib/core/sessions/sessions_viewed /chalicelib/core/metrics/modules /chalicelib/core/socket_ios.py diff --git a/ee/api/Pipfile b/ee/api/Pipfile index f136ab14f..cf41528a8 100644 --- a/ee/api/Pipfile +++ b/ee/api/Pipfile @@ -21,6 +21,8 @@ python-decouple = "==3.8" pydantic = {extras = ["email"], version = "==2.11.4"} apscheduler = "==3.11.0" python3-saml = "==1.16.0" +lxml = "==5.3.0" +xmlsec = "==1.3.14" python-multipart = "==0.0.20" redis = "==6.1.0" azure-storage-blob = "==12.25.1" diff --git a/ee/api/clean-dev.sh b/ee/api/clean-dev.sh index 1e849fabe..455109b6a 100755 --- a/ee/api/clean-dev.sh +++ b/ee/api/clean-dev.sh @@ -101,4 +101,4 @@ rm -rf ./chalicelib/core/errors/errors_details.py rm -rf ./chalicelib/core/notes.py rm -rf ./chalicelib/utils/contextual_validators.py rm -rf ./routers/subs/product_analytics.py -rm -rf ./schemas/product_analytics.py \ No newline at end of file +rm -rf ./schemas/product_analytics.py diff --git a/ee/api/requirements.txt b/ee/api/requirements.txt index 347dcdde4..7d2897ece 100644 --- a/ee/api/requirements.txt +++ b/ee/api/requirements.txt @@ -19,7 +19,8 @@ apscheduler==3.11.0 # TODO: enable after xmlsec fix https://github.com/xmlsec/python-xmlsec/issues/252 #--no-binary is used to avoid libxml2 library version incompatibilities between xmlsec and lxml python3-saml==1.16.0 ---no-binary=lxml +lxml==5.3.0 --no-binary=lxml +xmlsec==1.3.14 --no-binary=xmlsec python-multipart==0.0.20 diff --git a/ee/api/routers/core_dynamic.py b/ee/api/routers/core_dynamic.py index 4bf63e360..1554ae827 100644 --- a/ee/api/routers/core_dynamic.py +++ b/ee/api/routers/core_dynamic.py @@ -275,8 +275,7 @@ def get_projects(context: schemas.CurrentContext = Depends(OR_context)): def search_sessions(projectId: int, data: schemas.SessionsSearchPayloadSchema = \ Depends(contextual_validators.validate_contextual_payload), context: schemas.CurrentContext = Depends(OR_context)): - data = sessions_search.search_sessions(data=data, project=context.project, user_id=context.user_id, - platform=context.project.platform) + data = sessions_search.search_sessions(data=data, project=context.project, user_id=context.user_id) return {'data': data} @@ -285,8 +284,7 @@ def search_sessions(projectId: int, data: schemas.SessionsSearchPayloadSchema = def session_ids_search(projectId: int, data: schemas.SessionsSearchPayloadSchema = \ Depends(contextual_validators.validate_contextual_payload), context: schemas.CurrentContext = Depends(OR_context)): - data = sessions_search.search_sessions(data=data, project=context.project, user_id=context.user_id, ids_only=True, - platform=context.project.platform) + data = sessions_search.search_sessions(data=data, project=context.project, user_id=context.user_id, ids_only=True) return {'data': data} diff --git a/ee/api/schemas/__init__.py b/ee/api/schemas/__init__.py index 845d2ce5c..d60c7398d 100644 --- a/ee/api/schemas/__init__.py +++ b/ee/api/schemas/__init__.py @@ -3,4 +3,4 @@ from .schemas_ee import * from .assist_stats_schema import * from .product_analytics import * from . import overrides as _overrides -from .schemas import _PaginatedSchema as PaginatedSchema \ No newline at end of file +from .schemas import _PaginatedSchema as PaginatedSchema diff --git a/ee/connectors/msgcodec/messages.py b/ee/connectors/msgcodec/messages.py index 7aabdc46f..83030ef62 100644 --- a/ee/connectors/msgcodec/messages.py +++ b/ee/connectors/msgcodec/messages.py @@ -829,6 +829,15 @@ class ResourceTiming(Message): self.stalled = stalled +class Incident(Message): + __id__ = 87 + + def __init__(self, label, start_time, end_time): + self.label = label + self.start_time = start_time + self.end_time = end_time + + class LongAnimationTask(Message): __id__ = 89 diff --git a/ee/connectors/msgcodec/messages.pyx b/ee/connectors/msgcodec/messages.pyx index 1c9893ef8..800160971 100644 --- a/ee/connectors/msgcodec/messages.pyx +++ b/ee/connectors/msgcodec/messages.pyx @@ -1241,6 +1241,19 @@ cdef class ResourceTiming(PyMessage): self.stalled = stalled +cdef class Incident(PyMessage): + cdef public int __id__ + cdef public str label + cdef public long start_time + cdef public long end_time + + def __init__(self, str label, long start_time, long end_time): + self.__id__ = 87 + self.label = label + self.start_time = start_time + self.end_time = end_time + + cdef class LongAnimationTask(PyMessage): cdef public int __id__ cdef public str name diff --git a/ee/connectors/msgcodec/msgcodec.py b/ee/connectors/msgcodec/msgcodec.py index 5db27b325..43926ed5c 100644 --- a/ee/connectors/msgcodec/msgcodec.py +++ b/ee/connectors/msgcodec/msgcodec.py @@ -750,6 +750,13 @@ class MessageCodec(Codec): stalled=self.read_uint(reader) ) + if message_id == 87: + return Incident( + label=self.read_string(reader), + start_time=self.read_int(reader), + end_time=self.read_int(reader) + ) + if message_id == 89: return LongAnimationTask( name=self.read_string(reader), diff --git a/ee/connectors/msgcodec/msgcodec.pyx b/ee/connectors/msgcodec/msgcodec.pyx index 7b8fcb976..cfdeaf8f6 100644 --- a/ee/connectors/msgcodec/msgcodec.pyx +++ b/ee/connectors/msgcodec/msgcodec.pyx @@ -848,6 +848,13 @@ cdef class MessageCodec: stalled=self.read_uint(reader) ) + if message_id == 87: + return Incident( + label=self.read_string(reader), + start_time=self.read_int(reader), + end_time=self.read_int(reader) + ) + if message_id == 89: return LongAnimationTask( name=self.read_string(reader), diff --git a/ee/scripts/schema/db/init_dbs/clickhouse/1.22.0/1.22.0.sql b/ee/scripts/schema/db/init_dbs/clickhouse/1.22.0/1.22.0.sql index 49b5c808f..483e6b08f 100644 --- a/ee/scripts/schema/db/init_dbs/clickhouse/1.22.0/1.22.0.sql +++ b/ee/scripts/schema/db/init_dbs/clickhouse/1.22.0/1.22.0.sql @@ -1,3 +1,16 @@ +SELECT 1 +FROM (SELECT throwIf(platform = 'ios', 'IOS sessions found') + FROM experimental.sessions) AS raw +LIMIT 1; + +SELECT 1 +FROM (SELECT throwIf(platform = 'android', 'Android sessions found') + FROM experimental.sessions) AS raw +LIMIT 1; + +ALTER TABLE experimental.sessions + MODIFY COLUMN platform Enum8('web'=1,'mobile'=2) DEFAULT 'web'; + CREATE OR REPLACE FUNCTION openreplay_version AS() -> 'v1.22.0-ee'; SET allow_experimental_json_type = 1; diff --git a/ee/scripts/schema/db/init_dbs/clickhouse/1.23.0/1.23.0.sql b/ee/scripts/schema/db/init_dbs/clickhouse/1.23.0/1.23.0.sql index 953c86662..5227bff5d 100644 --- a/ee/scripts/schema/db/init_dbs/clickhouse/1.23.0/1.23.0.sql +++ b/ee/scripts/schema/db/init_dbs/clickhouse/1.23.0/1.23.0.sql @@ -1,3 +1,16 @@ +SELECT 1 +FROM (SELECT throwIf(platform = 'ios', 'IOS sessions found') + FROM experimental.sessions) AS raw +LIMIT 1; + +SELECT 1 +FROM (SELECT throwIf(platform = 'android', 'Android sessions found') + FROM experimental.sessions) AS raw +LIMIT 1; + +ALTER TABLE experimental.sessions + MODIFY COLUMN platform Enum8('web'=1,'mobile'=2) DEFAULT 'web'; + CREATE OR REPLACE FUNCTION openreplay_version AS() -> 'v1.23.0-ee'; DROP TABLE IF EXISTS product_analytics.all_events; @@ -41,26 +54,27 @@ CREATE TABLE IF NOT EXISTS product_analytics.event_properties event_name String, property_name String, value_type String, + auto_captured BOOL, _timestamp DateTime DEFAULT now() ) ENGINE = ReplacingMergeTree(_timestamp) - ORDER BY (project_id, event_name, property_name, value_type); + ORDER BY (project_id, event_name, property_name, value_type, auto_captured); CREATE MATERIALIZED VIEW IF NOT EXISTS product_analytics.event_properties_extractor_mv TO product_analytics.event_properties AS SELECT project_id, `$event_name` AS event_name, property_name, - JSONType(JSONExtractRaw(toString(`$properties`), property_name)) AS value_type + toString(JSONType(JSONExtractRaw(toString(`$properties`), property_name))) AS value_type, + `$auto_captured` AS auto_captured FROM product_analytics.events - ARRAY JOIN JSONExtractKeys(toString(`$properties`)) as property_name; - -CREATE MATERIALIZED VIEW IF NOT EXISTS product_analytics.event_cproperties_extractor - TO product_analytics.event_properties AS + ARRAY JOIN JSONExtractKeys(toString(`$properties`)) as property_name +UNION DISTINCT SELECT project_id, `$event_name` AS event_name, property_name, - JSONType(JSONExtractRaw(toString(`properties`), property_name)) AS value_type + toString(JSONType(JSONExtractRaw(toString(`properties`), property_name))) AS value_type, + `$auto_captured` AS auto_captured FROM product_analytics.events ARRAY JOIN JSONExtractKeys(toString(`properties`)) as property_name; @@ -105,10 +119,8 @@ FROM product_analytics.events WHERE (all_properties.display_name != '' OR all_properties.description != '') AND is_event_property) AS old_data - ON (events.project_id = old_data.project_id AND property_name = old_data.property_name); - -CREATE MATERIALIZED VIEW IF NOT EXISTS product_analytics.all_cproperties_extractor_mv - TO product_analytics.all_properties AS + ON (events.project_id = old_data.project_id AND property_name = old_data.property_name) +UNION DISTINCT SELECT project_id, property_name, TRUE AS is_event_property, @@ -155,7 +167,7 @@ FROM product_analytics.events WHERE randCanonical() < 0.5 -- This randomly skips inserts AND value != '' LIMIT 2 BY project_id,property_name -UNION ALL +UNION DISTINCT SELECT project_id, property_name, TRUE AS is_event_property, @@ -225,6 +237,16 @@ SELECT project_id, _timestamp FROM product_analytics.events ARRAY JOIN JSONExtractKeys(toString(`$properties`)) as property_name +WHERE length(value) > 0 AND isNull(toFloat64OrNull(value)) + AND _timestamp > now() - INTERVAL 1 MONTH +UNION DISTINCT +SELECT project_id, + `$event_name` AS event_name, + property_name, + JSONExtractString(toString(`properties`), property_name) AS value, + _timestamp +FROM product_analytics.events + ARRAY JOIN JSONExtractKeys(toString(`properties`)) as property_name WHERE length(value) > 0 AND isNull(toFloat64OrNull(value)) AND _timestamp > now() - INTERVAL 1 MONTH; diff --git a/ee/scripts/schema/db/init_dbs/clickhouse/create/init_schema.sql b/ee/scripts/schema/db/init_dbs/clickhouse/create/init_schema.sql index 6c32c70c6..8ccf94fda 100644 --- a/ee/scripts/schema/db/init_dbs/clickhouse/create/init_schema.sql +++ b/ee/scripts/schema/db/init_dbs/clickhouse/create/init_schema.sql @@ -106,7 +106,7 @@ CREATE TABLE IF NOT EXISTS experimental.sessions user_country Enum8('UN'=-128, 'RW'=-127, 'SO'=-126, 'YE'=-125, 'IQ'=-124, 'SA'=-123, 'IR'=-122, 'CY'=-121, 'TZ'=-120, 'SY'=-119, 'AM'=-118, 'KE'=-117, 'CD'=-116, 'DJ'=-115, 'UG'=-114, 'CF'=-113, 'SC'=-112, 'JO'=-111, 'LB'=-110, 'KW'=-109, 'OM'=-108, 'QA'=-107, 'BH'=-106, 'AE'=-105, 'IL'=-104, 'TR'=-103, 'ET'=-102, 'ER'=-101, 'EG'=-100, 'SD'=-99, 'GR'=-98, 'BI'=-97, 'EE'=-96, 'LV'=-95, 'AZ'=-94, 'LT'=-93, 'SJ'=-92, 'GE'=-91, 'MD'=-90, 'BY'=-89, 'FI'=-88, 'AX'=-87, 'UA'=-86, 'MK'=-85, 'HU'=-84, 'BG'=-83, 'AL'=-82, 'PL'=-81, 'RO'=-80, 'XK'=-79, 'ZW'=-78, 'ZM'=-77, 'KM'=-76, 'MW'=-75, 'LS'=-74, 'BW'=-73, 'MU'=-72, 'SZ'=-71, 'RE'=-70, 'ZA'=-69, 'YT'=-68, 'MZ'=-67, 'MG'=-66, 'AF'=-65, 'PK'=-64, 'BD'=-63, 'TM'=-62, 'TJ'=-61, 'LK'=-60, 'BT'=-59, 'IN'=-58, 'MV'=-57, 'IO'=-56, 'NP'=-55, 'MM'=-54, 'UZ'=-53, 'KZ'=-52, 'KG'=-51, 'TF'=-50, 'HM'=-49, 'CC'=-48, 'PW'=-47, 'VN'=-46, 'TH'=-45, 'ID'=-44, 'LA'=-43, 'TW'=-42, 'PH'=-41, 'MY'=-40, 'CN'=-39, 'HK'=-38, 'BN'=-37, 'MO'=-36, 'KH'=-35, 'KR'=-34, 'JP'=-33, 'KP'=-32, 'SG'=-31, 'CK'=-30, 'TL'=-29, 'RU'=-28, 'MN'=-27, 'AU'=-26, 'CX'=-25, 'MH'=-24, 'FM'=-23, 'PG'=-22, 'SB'=-21, 'TV'=-20, 'NR'=-19, 'VU'=-18, 'NC'=-17, 'NF'=-16, 'NZ'=-15, 'FJ'=-14, 'LY'=-13, 'CM'=-12, 'SN'=-11, 'CG'=-10, 'PT'=-9, 'LR'=-8, 'CI'=-7, 'GH'=-6, 'GQ'=-5, 'NG'=-4, 'BF'=-3, 'TG'=-2, 'GW'=-1, 'MR'=0, 'BJ'=1, 'GA'=2, 'SL'=3, 'ST'=4, 'GI'=5, 'GM'=6, 'GN'=7, 'TD'=8, 'NE'=9, 'ML'=10, 'EH'=11, 'TN'=12, 'ES'=13, 'MA'=14, 'MT'=15, 'DZ'=16, 'FO'=17, 'DK'=18, 'IS'=19, 'GB'=20, 'CH'=21, 'SE'=22, 'NL'=23, 'AT'=24, 'BE'=25, 'DE'=26, 'LU'=27, 'IE'=28, 'MC'=29, 'FR'=30, 'AD'=31, 'LI'=32, 'JE'=33, 'IM'=34, 'GG'=35, 'SK'=36, 'CZ'=37, 'NO'=38, 'VA'=39, 'SM'=40, 'IT'=41, 'SI'=42, 'ME'=43, 'HR'=44, 'BA'=45, 'AO'=46, 'NA'=47, 'SH'=48, 'BV'=49, 'BB'=50, 'CV'=51, 'GY'=52, 'GF'=53, 'SR'=54, 'PM'=55, 'GL'=56, 'PY'=57, 'UY'=58, 'BR'=59, 'FK'=60, 'GS'=61, 'JM'=62, 'DO'=63, 'CU'=64, 'MQ'=65, 'BS'=66, 'BM'=67, 'AI'=68, 'TT'=69, 'KN'=70, 'DM'=71, 'AG'=72, 'LC'=73, 'TC'=74, 'AW'=75, 'VG'=76, 'VC'=77, 'MS'=78, 'MF'=79, 'BL'=80, 'GP'=81, 'GD'=82, 'KY'=83, 'BZ'=84, 'SV'=85, 'GT'=86, 'HN'=87, 'NI'=88, 'CR'=89, 'VE'=90, 'EC'=91, 'CO'=92, 'PA'=93, 'HT'=94, 'AR'=95, 'CL'=96, 'BO'=97, 'PE'=98, 'MX'=99, 'PF'=100, 'PN'=101, 'KI'=102, 'TK'=103, 'TO'=104, 'WF'=105, 'WS'=106, 'NU'=107, 'MP'=108, 'GU'=109, 'PR'=110, 'VI'=111, 'UM'=112, 'AS'=113, 'CA'=114, 'US'=115, 'PS'=116, 'RS'=117, 'AQ'=118, 'SX'=119, 'CW'=120, 'BQ'=121, 'SS'=122,'BU'=123, 'VD'=124, 'YD'=125, 'DD'=126), user_city LowCardinality(String), user_state LowCardinality(String), - platform Enum8('web'=1,'ios'=2,'android'=3) DEFAULT 'web', + platform Enum8('web'=1,'mobile'=2) DEFAULT 'web', datetime DateTime, timezone LowCardinality(Nullable(String)), duration UInt32, @@ -134,7 +134,7 @@ CREATE TABLE IF NOT EXISTS experimental.sessions metadata_8 Nullable(String), metadata_9 Nullable(String), metadata_10 Nullable(String), - _timestamp DateTime DEFAULT now() + _timestamp DateTime DEFAULT now() ) ENGINE = ReplacingMergeTree(_timestamp) PARTITION BY toYYYYMMDD(datetime) ORDER BY (project_id, datetime, session_id) @@ -676,29 +676,29 @@ CREATE TABLE IF NOT EXISTS product_analytics.event_properties event_name String, property_name String, value_type String, + auto_captured BOOL, _timestamp DateTime DEFAULT now() ) ENGINE = ReplacingMergeTree(_timestamp) - ORDER BY (project_id, event_name, property_name, value_type); + ORDER BY (project_id, event_name, property_name, value_type, auto_captured); -- ----------------- This is experimental, if it doesn't work, we need to do it in db worker ------------- --- Incremental materialized view to fill event_properties using $properties +-- Incremental materialized view to fill event_properties using $properties & properties CREATE MATERIALIZED VIEW IF NOT EXISTS product_analytics.event_properties_extractor_mv TO product_analytics.event_properties AS SELECT project_id, `$event_name` AS event_name, property_name, - JSONType(JSONExtractRaw(toString(`$properties`), property_name)) AS value_type + toString(JSONType(JSONExtractRaw(toString(`$properties`), property_name))) AS value_type, + `$auto_captured` AS auto_captured FROM product_analytics.events - ARRAY JOIN JSONExtractKeys(toString(`$properties`)) as property_name; - --- Incremental materialized view to fill event_properties using properties -CREATE MATERIALIZED VIEW IF NOT EXISTS product_analytics.event_cproperties_extractor - TO product_analytics.event_properties AS + ARRAY JOIN JSONExtractKeys(toString(`$properties`)) as property_name +UNION DISTINCT SELECT project_id, `$event_name` AS event_name, property_name, - JSONType(JSONExtractRaw(toString(`properties`), property_name)) AS value_type + toString(JSONType(JSONExtractRaw(toString(`properties`), property_name))) AS value_type, + `$auto_captured` AS auto_captured FROM product_analytics.events ARRAY JOIN JSONExtractKeys(toString(`properties`)) as property_name; -- -------- END --------- @@ -724,7 +724,7 @@ CREATE TABLE IF NOT EXISTS product_analytics.all_properties -- ----------------- This is experimental, if it doesn't work, we need to do it in db worker ------------- --- Incremental materialized view to fill all_properties using $properties +-- Incremental materialized view to fill all_properties using $properties and properties CREATE MATERIALIZED VIEW IF NOT EXISTS product_analytics.all_properties_extractor_mv TO product_analytics.all_properties AS SELECT project_id, @@ -748,11 +748,8 @@ FROM product_analytics.events WHERE (all_properties.display_name != '' OR all_properties.description != '') AND is_event_property) AS old_data - ON (events.project_id = old_data.project_id AND property_name = old_data.property_name); - --- Incremental materialized view to fill all_properties using properties -CREATE MATERIALIZED VIEW IF NOT EXISTS product_analytics.all_cproperties_extractor_mv - TO product_analytics.all_properties AS + ON (events.project_id = old_data.project_id AND property_name = old_data.property_name) +UNION DISTINCT SELECT project_id, property_name, TRUE AS is_event_property, @@ -802,7 +799,7 @@ FROM product_analytics.events WHERE randCanonical() < 0.5 -- This randomly skips inserts AND value != '' LIMIT 2 BY project_id,property_name -UNION ALL +UNION DISTINCT -- using union because each table should be the target of 1 single refreshable MV SELECT project_id, property_name, @@ -873,6 +870,16 @@ SELECT project_id, _timestamp FROM product_analytics.events ARRAY JOIN JSONExtractKeys(toString(`$properties`)) as property_name +WHERE length(value) > 0 AND isNull(toFloat64OrNull(value)) + AND _timestamp > now() - INTERVAL 1 MONTH +UNION DISTINCT +SELECT project_id, + `$event_name` AS event_name, + property_name, + JSONExtractString(toString(`properties`), property_name) AS value, + _timestamp +FROM product_analytics.events + ARRAY JOIN JSONExtractKeys(toString(`properties`)) as property_name WHERE length(value) > 0 AND isNull(toFloat64OrNull(value)) AND _timestamp > now() - INTERVAL 1 MONTH; diff --git a/ee/scripts/schema/db/init_dbs/postgresql/1.23.0/1.23.0.sql b/ee/scripts/schema/db/init_dbs/postgresql/1.23.0/1.23.0.sql index 718a6e693..9c878f57a 100644 --- a/ee/scripts/schema/db/init_dbs/postgresql/1.23.0/1.23.0.sql +++ b/ee/scripts/schema/db/init_dbs/postgresql/1.23.0/1.23.0.sql @@ -23,6 +23,8 @@ DROP SCHEMA IF EXISTS or_cache CASCADE; ALTER TABLE public.tenants ALTER COLUMN scope_state SET DEFAULT 2; +ALTER TYPE issue_type ADD VALUE IF NOT EXISTS 'incident'; + COMMIT; \elif :is_next diff --git a/ee/scripts/schema/db/init_dbs/postgresql/init_schema.sql b/ee/scripts/schema/db/init_dbs/postgresql/init_schema.sql index 4701bc53f..caf4e7467 100644 --- a/ee/scripts/schema/db/init_dbs/postgresql/init_schema.sql +++ b/ee/scripts/schema/db/init_dbs/postgresql/init_schema.sql @@ -352,7 +352,8 @@ CREATE TYPE issue_type AS ENUM ( 'custom', 'js_exception', 'mouse_thrashing', - 'app_crash' + 'app_crash', + 'incident' ); CREATE TABLE public.issues diff --git a/frontend/app/components/Charts/SankeyChart.tsx b/frontend/app/components/Charts/SankeyChart.tsx index 6f51140e0..f675fc570 100644 --- a/frontend/app/components/Charts/SankeyChart.tsx +++ b/frontend/app/components/Charts/SankeyChart.tsx @@ -195,7 +195,7 @@ const EChartsSankey: React.FC = (props) => { header: { fontWeight: '600', fontSize: 12, - color: '#333', + color: 'var(--color-gray-darkest)', overflow: 'truncate', paddingBottom: '.5rem', paddingLeft: '14px', @@ -203,16 +203,16 @@ const EChartsSankey: React.FC = (props) => { }, body: { fontSize: 12, - color: '#000', + color: 'var(--color-black)', }, percentage: { fontSize: 12, - color: '#454545', + color: 'var(--color-gray-dark)', }, sessions: { fontSize: 12, fontFamily: "mono, 'monospace', sans-serif", - color: '#999999', + color: 'var(--color-gray-dark)', }, clickIcon: { backgroundColor: { @@ -266,6 +266,7 @@ const EChartsSankey: React.FC = (props) => { }, tooltip: { formatter: sankeyTooltip(echartNodes, nodeValues), + backgroundColor: 'var(--color-white)', }, nodeAlign: 'left', nodeWidth: 40, diff --git a/frontend/app/components/Charts/utils.ts b/frontend/app/components/Charts/utils.ts index c20733dcc..076add36f 100644 --- a/frontend/app/components/Charts/utils.ts +++ b/frontend/app/components/Charts/utils.ts @@ -102,18 +102,18 @@ export function customTooltipFormatter(uuid: string) {
${fullname}
- +
-
+
Total:
@@ -127,7 +127,7 @@ export function customTooltipFormatter(uuid: string) { (window as any).__seriesColorMap?.[uuid]?.[partnerName] || '#999'; str += `
-
+
${isPrevious ? 'Current' : 'Previous'} Total:
@@ -168,9 +168,9 @@ export function customTooltipFormatter(uuid: string) {
${seriesName}
@@ -179,7 +179,7 @@ export function customTooltipFormatter(uuid: string) {
-
+
${firstTs ? formatTimeOrDate(firstTs) : categoryLabel}
@@ -194,7 +194,7 @@ export function customTooltipFormatter(uuid: string) { (window as any).__seriesColorMap?.[uuid]?.[partnerName] || '#999'; tooltipContent += `
-
+
${secondTs ? formatTimeOrDate(secondTs) : categoryLabel}
@@ -229,13 +229,13 @@ function buildCompareTag(val: number, prevVal: number): string { return `
${arrow} ${absDelta} @@ -290,7 +290,7 @@ export function createSeries( datasetId, encode: { x: 'idx', y: fullName }, lineStyle: dashed ? { type: 'dashed' } : undefined, - showSymbol: false, + showSymbol: data.chart.length === 1, // custom flag to hide prev data from legend _hideInLegend: hideFromLegend, itemStyle: { opacity: 1 }, diff --git a/frontend/app/components/Client/Projects/TagForm.tsx b/frontend/app/components/Client/Projects/TagForm.tsx index 1026b71e1..f0193066f 100644 --- a/frontend/app/components/Client/Projects/TagForm.tsx +++ b/frontend/app/components/Client/Projects/TagForm.tsx @@ -1,10 +1,10 @@ import React from 'react'; -import { Button, Form, Input, Space, Modal } from 'antd'; +import { Button, Form, Input, Space } from 'antd'; import { Trash } from 'UI/Icons'; import { useStore } from '@/mstore'; import { useModal } from 'Components/ModalContext'; import { useTranslation } from 'react-i18next'; - +import { confirm } from 'UI'; interface Props { tag: any; projectId: number; @@ -23,14 +23,16 @@ function TagForm(props: Props) { }; const onDelete = async () => { - Modal.confirm({ - title: t('Tag'), - content: t('Are you sure you want to remove?'), - onOk: async () => { - await tagWatchStore.deleteTag(tag.tagId, projectId); - closeModal(); - }, - }); + if ( + await confirm({ + header: t('Remove Tag'), + confirmButton: t('Remove'), + confirmation: t('Are you sure you want to remove this tag?'), + }) + ) { + await tagWatchStore.deleteTag(tag.tagId, projectId); + closeModal(); + } }; const onSave = async () => { diff --git a/frontend/app/components/Dashboard/components/Alerts/AlertForm/BottomButtons.tsx b/frontend/app/components/Dashboard/components/Alerts/AlertForm/BottomButtons.tsx index 1acc57fd8..90751e4e4 100644 --- a/frontend/app/components/Dashboard/components/Alerts/AlertForm/BottomButtons.tsx +++ b/frontend/app/components/Dashboard/components/Alerts/AlertForm/BottomButtons.tsx @@ -23,6 +23,7 @@ function BottomButtons({ + + ); +} + export default observer(ChatInput); diff --git a/frontend/app/components/Kai/components/ChatLog.tsx b/frontend/app/components/Kai/components/ChatLog.tsx index 9b015ad22..76fccb584 100644 --- a/frontend/app/components/Kai/components/ChatLog.tsx +++ b/frontend/app/components/Kai/components/ChatLog.tsx @@ -1,25 +1,28 @@ import React from 'react'; import ChatInput from './ChatInput'; import ChatMsg, { ChatNotice } from './ChatMsg'; +import Ideas from './Ideas'; import { Loader } from 'UI'; import { kaiStore } from '../KaiStore'; import { observer } from 'mobx-react-lite'; +import EmbedPlayer from './EmbedPlayer'; function ChatLog({ projectId, threadId, - userLetter, - onTitleChange, initialMsg, + chatTitle, setInitialMsg, + onCancel, }: { projectId: string; threadId: any; - userLetter: string; - onTitleChange: (title: string | null) => void; initialMsg: string | null; setInitialMsg: (msg: string | null) => void; + chatTitle: string | null; + onCancel: () => void; }) { + const [embedSession, setEmbedSession] = React.useState(null); const messages = kaiStore.messages; const loading = kaiStore.loadingChat; const chatRef = React.useRef(null); @@ -31,7 +34,7 @@ function ChatLog({ void kaiStore.getChat(settings.projectId, threadId); } if (threadId) { - kaiStore.createChatManager(settings, onTitleChange, initialMsg); + kaiStore.createChatManager(settings, initialMsg); } return () => { kaiStore.clearChat(); @@ -50,23 +53,38 @@ function ChatLog({ }); }, [messages.length, processingStage]); - const lastHumanMsgInd: null | number = kaiStore.lastHumanMessage.index; + const lastKaiMessageInd: null | number = kaiStore.lastKaiMessage.index; + const lastHumanMsgInd: number | null = kaiStore.lastHumanMessage.index; + const showIdeas = + !processingStage && lastKaiMessageInd === messages.length - 1; return (
-
+ {embedSession ? ( + setEmbedSession(null)} + /> + ) : null} +
{messages.map((msg, index) => ( setEmbedSession(session)} + canEdit={ + processingStage === null && + msg.isUser && + index === lastHumanMsgInd + } /> ))} @@ -76,9 +94,17 @@ function ChatLog({ duration={processingStage.duration} /> ) : null} + {showIdeas ? ( + onSubmit(query)} + projectId={projectId} + threadId={threadId} + inChat + /> + ) : null}
-
- +
+
diff --git a/frontend/app/components/Kai/components/ChatMsg.tsx b/frontend/app/components/Kai/components/ChatMsg.tsx index 27f89a660..7a1d6d8dc 100644 --- a/frontend/app/components/Kai/components/ChatMsg.tsx +++ b/frontend/app/components/Kai/components/ChatMsg.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Icon, CopyButton } from 'UI'; +import { CopyButton, Icon } from 'UI'; import { observer } from 'mobx-react-lite'; import cn from 'classnames'; import Markdown from 'react-markdown'; @@ -8,8 +8,7 @@ import { Loader, ThumbsUp, ThumbsDown, - ListRestart, - FileDown, + SquarePen, Clock, ChartLine, } from 'lucide-react'; @@ -20,17 +19,22 @@ import { durationFormatted } from 'App/date'; import WidgetChart from '@/components/Dashboard/components/WidgetChart'; import Widget from 'App/mstore/types/widget'; import { useTranslation } from 'react-i18next'; +import SessionItem from 'Shared/SessionItem'; function ChatMsg({ userName, siteId, canEdit, message, + chatTitle, + onReplay, }: { message: Message; userName?: string; canEdit?: boolean; siteId: string; + chatTitle: string | null; + onReplay: (session: any) => void; }) { const { t } = useTranslation(); const [metric, setMetric] = React.useState(null); @@ -47,13 +51,14 @@ function ChatMsg({ const isEditing = kaiStore.replacing && messageId === kaiStore.replacing; const [isProcessing, setIsProcessing] = React.useState(false); const bodyRef = React.useRef(null); + const chartRef = React.useRef(null); const onEdit = () => { kaiStore.editMessage(text, messageId); }; const onCancelEdit = () => { kaiStore.setQueryText(''); kaiStore.setReplacing(null); - } + }; const onFeedback = (feedback: 'like' | 'dislike', messageId: string) => { kaiStore.sendMsgFeedback(feedback, messageId, siteId); }; @@ -65,19 +70,79 @@ function ChatMsg({ setIsProcessing(false); return; } + const userPrompt = kaiStore.getPreviousMessage(message.messageId); import('jspdf') - .then(({ jsPDF }) => { + .then(async ({ jsPDF }) => { const doc = new jsPDF(); - doc.addImage('/assets/img/logo-img.png', 80, 3, 30, 5); - doc.html(bodyRef.current!, { + const blockWidth = 170; // mm + const content = bodyRef.current!.cloneNode(true) as HTMLElement; + if (userPrompt) { + const titleHeader = document.createElement('h2'); + titleHeader.textContent = userPrompt.text; + titleHeader.style.marginBottom = '10px'; + content.prepend(titleHeader); + } + // insert logo /assets/img/logo-img.png + const logo = new Image(); + logo.src = '/assets/img/logo-img.png'; + logo.style.width = '130px'; + const container = document.createElement('div'); + container.style.display = 'flex'; + container.style.alignItems = 'center'; + container.style.justifyContent = 'center'; + container.style.marginBottom = '10mm'; + container.style.width = `${blockWidth}mm`; + container.appendChild(logo); + content.prepend(container); + content.querySelectorAll('ul').forEach((ul) => { + const frag = document.createDocumentFragment(); + ul.querySelectorAll('li').forEach((li) => { + const div = document.createElement('div'); + div.textContent = '• ' + li.textContent; + frag.appendChild(div); + }); + ul.replaceWith(frag); + }); + content.querySelectorAll('h1,h2,h3,h4,h5,h6').forEach((el) => { + (el as HTMLElement).style.letterSpacing = '0.5px'; + }); + content.querySelectorAll('*').forEach((node) => { + node.childNodes.forEach((child) => { + if (child.nodeType === Node.TEXT_NODE) { + const txt = child.textContent || ''; + const replaced = txt.replace(/-/g, '–'); + if (replaced !== txt) child.textContent = replaced; + } + }); + }); + if (metric && chartRef.current) { + const { default: html2canvas } = await import('html2canvas'); + const metricContainer = chartRef.current; + const image = await html2canvas(metricContainer, { + backgroundColor: null, + scale: 2, + }); + const imgData = image.toDataURL('image/png'); + const imgHeight = (image.height * blockWidth) / image.width; + content.appendChild( + Object.assign(document.createElement('img'), { + src: imgData, + style: `width: ${blockWidth}mm; height: ${imgHeight}mm; margin-top: 10px;`, + }), + ); + } + doc.html(content, { callback: function (doc) { - doc.save('document.pdf'); + doc.save((chatTitle ?? 'document') + '.pdf'); }, - margin: [10, 10, 10, 10], + // top, bottom, ?, left + margin: [10, 10, 20, 20], x: 0, y: 0, - width: 190, // Target width - windowWidth: 675, // Window width for rendering + // Target width + width: blockWidth, + // Window width for rendering + windowWidth: 675, }); }) .catch((e) => { @@ -107,35 +172,25 @@ function ChatMsg({ setLoadingChart(false); } }; + + const metricData = metric?.data; + React.useEffect(() => { + if (!chart_data && metricData) { + const hasValues = + metricData.values?.length > 0 || metricData.chart?.length > 0; + if (hasValues) { + kaiStore.saveLatestChart(messageId, siteId); + } + } + }, [metricData, chart_data]); return ( -
- {isUser ? ( -
- {userName} -
- ) : ( -
- -
- )} -
+
+
{text}
{metric ? ( -
- +
+ +
+ ) : null} + {message.sessions ? ( +
+ {message.sessions.map((session) => ( +
+ { + e.preventDefault(); + e.stopPropagation(); + onReplay(session); + }} + slim + /> +
+ ))}
) : null} {isUser ? ( - <> -
- -
{t('Edit')}
-
-
-
{t('Cancel')}
-
- +
+ {canEdit && !isEditing ? ( + + + + ) : null} + {isEditing ? ( + + ) : null} + bodyRef.current?.innerHTML} + content={text} + isIcon + format={'text/html'} + /> +
) : (
{duration ? : null} @@ -182,14 +257,14 @@ function ChatMsg({ tooltip="Like this answer" onClick={() => onFeedback('like', messageId)} > - + onFeedback('dislike', messageId)} > - + {supports_visualization ? ( - + ) : null} - +
)} diff --git a/frontend/app/components/Kai/components/ChatsModal.tsx b/frontend/app/components/Kai/components/ChatsModal.tsx index a39d358f0..4165328fb 100644 --- a/frontend/app/components/Kai/components/ChatsModal.tsx +++ b/frontend/app/components/Kai/components/ChatsModal.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { splitByDate } from '../utils'; import { useQuery } from '@tanstack/react-query'; -import { MessagesSquare, Trash } from 'lucide-react'; +import { MessagesSquare, Trash, X } from 'lucide-react'; import { kaiService } from 'App/services'; import { toast } from 'react-toastify'; import { useTranslation } from 'react-i18next'; @@ -11,9 +11,11 @@ import { observer } from 'mobx-react-lite'; function ChatsModal({ onSelect, projectId, + onHide, }: { onSelect: (threadId: string, title: string) => void; projectId: string; + onHide: () => void; }) { const { t } = useTranslation(); const { usage } = kaiStore; @@ -44,10 +46,22 @@ function ChatsModal({ refetch(); }; return ( -
+
- {t('Chats')} + {t('Previous Chats')} +
+
+ +
{usage.percent > 80 ? (
@@ -58,16 +72,20 @@ function ChatsModal({
) : null} {isPending ? ( -
{t('Loading chats')}...
+
+ {t('Loading chats')}... +
) : (
- {datedCollections.map((col) => ( - + {datedCollections.map((col, i) => ( + + + ))}
)} @@ -87,8 +105,8 @@ function ChatCollection({ date: string; }) { return ( -
-
{date}
+
+
{date}
); diff --git a/frontend/app/components/Kai/components/EmbedPlayer.tsx b/frontend/app/components/Kai/components/EmbedPlayer.tsx new file mode 100644 index 000000000..6d4074f6d --- /dev/null +++ b/frontend/app/components/Kai/components/EmbedPlayer.tsx @@ -0,0 +1,75 @@ +import React from 'react'; +import cn from 'classnames'; +import { useStore } from 'App/mstore'; +import { Loader } from 'UI'; +import { observer } from 'mobx-react-lite'; +import MobileClipsPlayer from 'App/components/Session/MobileClipsPlayer'; +import ClipsPlayer from 'App/components/Session/ClipsPlayer'; +import Session from '@/types/session/session'; + +interface Clip { + sessionId: string | undefined; + range: [number, number]; + message: string; +} + +function EmbedPlayer({ + session, + onClose, +}: { + session: Session; + onClose: () => void; +}) { + const { projectsStore } = useStore(); + const clip = { + sessionId: session.sessionId, + range: [0, session.durationMs], + message: '', + }; + const { isMobile } = projectsStore; + + const onBgClick = (e: React.MouseEvent) => { + if (e.target === e.currentTarget) { + onClose(); + } + }; + return ( +
+
+ {isMobile ? ( + + ) : ( + + )} +
+
+ ); +} + +export default observer(EmbedPlayer); diff --git a/frontend/app/components/Kai/components/Ideas.tsx b/frontend/app/components/Kai/components/Ideas.tsx index 1cd2f86e2..771849423 100644 --- a/frontend/app/components/Kai/components/Ideas.tsx +++ b/frontend/app/components/Kai/components/Ideas.tsx @@ -1,30 +1,84 @@ import React from 'react'; -import { Lightbulb, MoveRight } from 'lucide-react'; +import cn from 'classnames'; +import { useQuery } from '@tanstack/react-query'; +import { kaiService } from 'App/services'; +import { useTranslation } from 'react-i18next'; -function Ideas({ onClick }: { onClick: (query: string) => void }) { +function Ideas({ + onClick, + projectId, + threadId = null, + inChat, + limited, +}: { + onClick: (query: string) => void; + projectId: string; + threadId?: string | null; + inChat?: boolean; + limited?: boolean; +}) { + const { t } = useTranslation(); + const { data: suggestedPromptIdeas = [], isPending } = useQuery({ + queryKey: ['kai', projectId, 'chats', threadId, 'prompt-suggestions'], + queryFn: () => kaiService.getPromptSuggestions(projectId, threadId), + staleTime: 1000 * 60, + }); + const ideas = React.useMemo(() => { + const defaultPromptIdeas = [ + 'Top user journeys', + 'Where do users drop off', + 'Failed network requests today', + ]; + const result = suggestedPromptIdeas; + const targetSize = 3; + while (result.length < targetSize && defaultPromptIdeas.length) { + result.push(defaultPromptIdeas.pop()); + } + return result; + }, [suggestedPromptIdeas.length]); return ( - <> +
- - Ideas: + {inChat ? 'Suggested Follow-up Questions' : 'Suggested Ideas:'}
- - - - + {isPending ? ( +
+ {t('Generating ideas')}... +
+ ) : ( +
+ {ideas.map((title) => ( + + ))} +
+ )} +
); } -function IdeaItem({ title, onClick }: { title: string, onClick: (query: string) => void }) { +function IdeaItem({ + title, + onClick, + limited, +}: { + title: string; + onClick: (query: string) => void; + limited?: boolean; +}) { return (
onClick(title)} - className={ - 'flex items-center gap-2 cursor-pointer text-gray-dark hover:text-black' - } + onClick={() => (limited ? null : onClick(title))} + className={cn( + 'cursor-pointer text-gray-dark hover:text-black rounded-full px-4 py-2 shadow border', + limited ? 'bg-gray-lightest cursor-not-allowed' : 'bg-white', + )} > - - {title} + {title}
); } diff --git a/frontend/app/components/Kai/components/IntroSection.tsx b/frontend/app/components/Kai/components/IntroSection.tsx index 71a69b99c..4afc7ed75 100644 --- a/frontend/app/components/Kai/components/IntroSection.tsx +++ b/frontend/app/components/Kai/components/IntroSection.tsx @@ -2,23 +2,35 @@ import React from 'react'; import ChatInput from './ChatInput'; import Ideas from './Ideas'; -function IntroSection({ onAsk }: { onAsk: (query: string) => void }) { +function IntroSection({ + onAsk, + onCancel, + userName, + projectId, + limited, +}: { + onAsk: (query: string) => void; + projectId: string; + onCancel: () => void; + userName: string; + limited?: boolean; +}) { const isLoading = false; return ( <> -
- Kai is your AI assistant, delivering smart insights in response to your - queries. -
-
- {/* null} />*/} - -
- onAsk(query)} /> +
+
+ Hey {userName}, how can I help you? +
+ +
+ onAsk(query)} projectId={projectId} />
-
-
- OpenReplay AI can make mistakes. Verify its outputs.
); diff --git a/frontend/app/components/Kai/components/Usage.tsx b/frontend/app/components/Kai/components/Usage.tsx index 9870c2b87..a2af47fa7 100644 --- a/frontend/app/components/Kai/components/Usage.tsx +++ b/frontend/app/components/Kai/components/Usage.tsx @@ -2,23 +2,23 @@ import React from 'react'; import { kaiStore } from '../KaiStore'; import { observer } from 'mobx-react-lite'; import { Progress, Tooltip } from 'antd'; -const getUsageColor = (percent: number) => { - return 'disabled-text'; -}; function Usage() { - const { usage } = kaiStore; - const color = getUsageColor(usage.percent); + const usage = kaiStore.usage; if (usage.total === 0) { return null; } + + const roundPercent = Math.round((usage.used / usage.total) * 100); return (
void; isHighlight?: boolean; + isFull?: boolean; } function ClipsPlayer(props: Props) { - const { clip, currentIndex, isCurrent, onClose, isHighlight } = props; + const { clip, currentIndex, isCurrent, onClose, isHighlight, isFull } = props; const { sessionStore } = useStore(); const { prefetched } = sessionStore; const [windowActive, setWindowActive] = useState(!document.hidden); @@ -146,6 +147,7 @@ function ClipsPlayer(props: Props) { onClose={onClose} range={clip.range} session={session!} + isFull={isFull} /> ) : ( diff --git a/frontend/app/components/Session/Player/ClipPlayer/ClipPlayerContent.tsx b/frontend/app/components/Session/Player/ClipPlayer/ClipPlayerContent.tsx index ddf267669..cfaee07cf 100644 --- a/frontend/app/components/Session/Player/ClipPlayer/ClipPlayerContent.tsx +++ b/frontend/app/components/Session/Player/ClipPlayer/ClipPlayerContent.tsx @@ -19,13 +19,14 @@ interface Props { isHighlight?: boolean; message?: string; isMobile?: boolean; + isFull?: boolean; } function ClipPlayerContent(props: Props) { const playerContext = React.useContext(PlayerContext); const screenWrapper = React.useRef(null); const { time } = playerContext.store.get(); - const { range } = props; + const { range, isFull } = props; React.useEffect(() => { if (!playerContext.player) return; @@ -90,7 +91,7 @@ function ClipPlayerContent(props: Props) {
{props.message}
) : null} - +
); diff --git a/frontend/app/components/Session/Player/ClipPlayer/ClipPlayerControls.tsx b/frontend/app/components/Session/Player/ClipPlayer/ClipPlayerControls.tsx index 6d2dc0f82..19ca0e96e 100644 --- a/frontend/app/components/Session/Player/ClipPlayer/ClipPlayerControls.tsx +++ b/frontend/app/components/Session/Player/ClipPlayer/ClipPlayerControls.tsx @@ -15,9 +15,11 @@ import { useTranslation } from 'react-i18next'; function ClipPlayerControls({ session, range, + isFull, }: { session: Session; range: [number, number]; + isFull?: boolean; }) { const { t } = useTranslation(); const { projectsStore } = useStore(); @@ -47,7 +49,7 @@ function ClipPlayerControls({
diff --git a/frontend/app/components/Session/Player/ClipPlayer/ClipPlayerHeader.tsx b/frontend/app/components/Session/Player/ClipPlayer/ClipPlayerHeader.tsx index 75d8b6951..b7fd37c9e 100644 --- a/frontend/app/components/Session/Player/ClipPlayer/ClipPlayerHeader.tsx +++ b/frontend/app/components/Session/Player/ClipPlayer/ClipPlayerHeader.tsx @@ -16,12 +16,13 @@ interface Props { range: [number, number]; onClose?: () => void; isHighlight?: boolean; + isFull?: boolean; } function ClipPlayerHeader(props: Props) { const { t } = useTranslation(); const { projectsStore } = useStore(); - const { session, range, onClose, isHighlight } = props; + const { session, range, onClose, isHighlight, isFull } = props; const { siteId } = projectsStore; const { message } = App.useApp(); @@ -33,7 +34,7 @@ function ClipPlayerHeader(props: Props) { }; return (
- {isHighlight ? : null} + {isHighlight && !isFull ? : null} diff --git a/frontend/app/components/Session_/EventsBlock/EventGroupWrapper.tsx b/frontend/app/components/Session_/EventsBlock/EventGroupWrapper.tsx index 92f89bcea..10a404c6e 100644 --- a/frontend/app/components/Session_/EventsBlock/EventGroupWrapper.tsx +++ b/frontend/app/components/Session_/EventsBlock/EventGroupWrapper.tsx @@ -1,5 +1,5 @@ import { TYPES } from 'Types/session/event'; -import React from 'react'; +import React, { useMemo } from 'react'; import { observer } from 'mobx-react-lite'; import { useStore } from 'App/mstore'; import UxtEvent from 'Components/Session_/EventsBlock/UxtEvent'; @@ -32,6 +32,7 @@ function EventGroupWrapper(props) { presentInSearch, isNote, isTabChange, + isIncident, filterOutNote, } = props; const { t } = useTranslation(); @@ -57,6 +58,15 @@ function EventGroupWrapper(props) { /> ); } + if (isIncident) { + return ( + + ) + } if (isLocation) { return ( { + if (isSearched) { + return '#F0A930'; + } + if (props.isPrev) { + return '#A7BFFF'; + } + if (props.isCurrent) { + return '#394EFF'; + } + return 'transparent'; + }, [isSearched, props.isPrev, props.isCurrent]); + return ( <>
@@ -172,4 +190,22 @@ function TabChange({ from, to, activeUrl, onClick }) { ); }; +function Incident({ label, onClick }: { label: string; onClick: () => void }) { + const { t } = useTranslation(); + return ( +
+
+ +
+ {t('Incident')} + {label} +
+
+
+ ); +}; + export default observer(EventGroupWrapper); diff --git a/frontend/app/components/Session_/EventsBlock/EventsBlock.tsx b/frontend/app/components/Session_/EventsBlock/EventsBlock.tsx index b9240c12b..19988dc73 100644 --- a/frontend/app/components/Session_/EventsBlock/EventsBlock.tsx +++ b/frontend/app/components/Session_/EventsBlock/EventsBlock.tsx @@ -34,8 +34,9 @@ function EventsBlock(props: IProps) { const { notesStore, uxtestingStore, uiPlayerStore, sessionStore } = useStore(); const session = sessionStore.current; - const { notesWithEvents } = session; - const { uxtVideo } = session; + const notesWithEvents = session.notesWithEvents; + const incidents = session.incidents; + const uxtVideo = session.uxtVideo; const { filteredEvents } = sessionStore; const query = sessionStore.eventsQuery; const { eventsIndex } = sessionStore; @@ -86,26 +87,28 @@ function EventsBlock(props: IProps) { } }); } - const eventsWithMobxNotes = [...notesWithEvents, ...notes] - .sort(sortEvents); + const eventsWithMobxNotes = [...incidents, ...notesWithEvents, ...notes, ].sort(sortEvents); const filteredTabEvents = query.length - ? tabChangeEvents - .filter((e => (e.activeUrl as string).includes(query))) - : tabChangeEvents; - const list = mergeEventLists( - query.length > 0 ? filteredEvents : eventsWithMobxNotes, - filteredTabEvents + ? tabChangeEvents.filter((e) => (e.activeUrl as string).includes(query)) + : tabChangeEvents; + return mergeEventLists( + filteredLength > 0 ? filteredEvents : eventsWithMobxNotes, + tabChangeEvents, ) - if (zoomEnabled) { - return list.filter((e) => + .filter((e) => zoomEnabled - ? 'time' in e - ? e.time >= zoomStartTs && e.time <= zoomEndTs - : false - : true - ).filter((e: any) => !e.noteId && e.type !== 'TABCHANGE' && uiPlayerStore.showOnlySearchEvents ? e.isHighlighted : true); - } - return list; + ? 'time' in e + ? e.time >= zoomStartTs && e.time <= zoomEndTs + : false + : true, + ) + .filter((e: any) => + !e.noteId && + e.type !== 'TABCHANGE' && + uiPlayerStore.showOnlySearchEvents + ? e.isHighlighted + : true, + ); }, [ filteredLength, query, @@ -114,15 +117,17 @@ function EventsBlock(props: IProps) { zoomEnabled, zoomStartTs, zoomEndTs, - uiPlayerStore.showOnlySearchEvents + uiPlayerStore.showOnlySearchEvents, ]); + const findLastFitting = React.useCallback( (time: number) => { - if (!usedEvents.length) return 0; - let i = usedEvents.length - 1; + const allEvents = usedEvents.concat(incidents); + if (!allEvents.length) return 0; + let i = allEvents.length - 1; if (time > endTime / 2) { - while (i >= 0) { - const event = usedEvents[i]; + while (i > 0) { + const event = allEvents[i]; if ('time' in event && event.time <= time) break; i--; } @@ -130,18 +135,18 @@ function EventsBlock(props: IProps) { } let l = 0; while (l < i) { - const event = usedEvents[l]; + const event = allEvents[l]; if ('time' in event && event.time >= time) break; l++; } return l; }, - [usedEvents, time, endTime], + [usedEvents, incidents, time, endTime], ); useEffect(() => { setCurrentTimeEventIndex(findLastFitting(time)); - }, []) + }, [time]); const write = ({ target: { value }, @@ -195,9 +200,10 @@ function EventsBlock(props: IProps) { const event = usedEvents[index]; const isNote = 'noteId' in event; const isTabChange = 'type' in event && event.type === 'TABCHANGE'; + const isIncident = 'type' in event && event.type === 'INCIDENT'; const isCurrent = index === currentTimeEventIndex; const isPrev = index < currentTimeEventIndex; - const isSearched = event.isHighlighted + const isSearched = event.isHighlighted; return ( Object.values(tabStates)[0]?.eventList.filter((e) => { @@ -39,10 +41,25 @@ function EventsList() {
))} + {incidents?.map((i) => { + const width = getTimelineEventWidth(endTime, (i as any).time, (i as any).endTime - sessionStart); + return ( + +
+ + ) + })} ); } diff --git a/frontend/app/components/Session_/Player/Controls/getTimelineEventWidth.ts b/frontend/app/components/Session_/Player/Controls/getTimelineEventWidth.ts new file mode 100644 index 000000000..954eaaf33 --- /dev/null +++ b/frontend/app/components/Session_/Player/Controls/getTimelineEventWidth.ts @@ -0,0 +1,21 @@ +import { getTimelinePosition } from '@/utils'; + +export function getTimelineEventWidth( + sessionDuration: number, + eventStart: number, + eventEnd: number, +): number | string { + if (eventStart < 0) { + eventStart = 0; + } + if (eventEnd > sessionDuration) { + eventEnd = sessionDuration; + } + if (eventStart === eventEnd) { + return '2px'; + } + + const width = ((eventEnd - eventStart) / sessionDuration) * 100; + + return width < 1 ? '4px' : width; +} diff --git a/frontend/app/components/shared/SessionFilters/SessionFilters.tsx b/frontend/app/components/shared/SessionFilters/SessionFilters.tsx index a4f060426..80ff27bca 100644 --- a/frontend/app/components/shared/SessionFilters/SessionFilters.tsx +++ b/frontend/app/components/shared/SessionFilters/SessionFilters.tsx @@ -35,14 +35,11 @@ function SessionFilters() { useEffect(() => { // Add default location/screen filter if no filters are present - if (searchStore.instance.filters.length === 0) { - searchStore.addFilterByKeyAndValue( - activeProject?.platform === 'web' - ? FilterKey.LOCATION - : FilterKey.VIEW_MOBILE, - '', - 'isAny', - ); + if ( + searchStore.instance.filters.length === 0 && + activeProject?.platform === 'web' + ) { + searchStore.addFilterByKeyAndValue(FilterKey.LOCATION, '', 'isAny'); } void reloadTags(); }, [projectsStore.activeSiteId, activeProject]); @@ -65,7 +62,7 @@ function SessionFilters() { }; const onFilterMove = (newFilters: any) => { - searchStore.updateSearch({ ...appliedFilter, filters: newFilters}); + searchStore.updateSearch({ ...appliedFilter, filters: newFilters }); // debounceFetch(); }; diff --git a/frontend/app/components/shared/SessionItem/PlayLink/PlayLink.tsx b/frontend/app/components/shared/SessionItem/PlayLink/PlayLink.tsx index ce6b2f5c3..35a949510 100644 --- a/frontend/app/components/shared/SessionItem/PlayLink/PlayLink.tsx +++ b/frontend/app/components/shared/SessionItem/PlayLink/PlayLink.tsx @@ -10,7 +10,7 @@ import { Icon, Link } from 'UI'; import { useStore } from 'App/mstore'; const PLAY_ICON_NAMES = { - notPlayed: 'play-fill', + notPlayed: 'play-v2', played: 'play-circle-light', } as const; @@ -76,10 +76,14 @@ function PlayLink(props: Props) { rel={props.newTab ? 'noopener noreferrer' : undefined} >
- +
- +
); diff --git a/frontend/app/components/shared/SessionItem/SessionItem.tsx b/frontend/app/components/shared/SessionItem/SessionItem.tsx index af42caf1d..f4591e2b2 100644 --- a/frontend/app/components/shared/SessionItem/SessionItem.tsx +++ b/frontend/app/components/shared/SessionItem/SessionItem.tsx @@ -71,6 +71,7 @@ interface Props { bookmarked?: boolean; toggleFavorite?: (sessionId: string) => void; query?: string; + slim?: boolean; } const PREFETCH_STATE = { @@ -81,7 +82,8 @@ const PREFETCH_STATE = { function SessionItem(props: RouteComponentProps & Props) { const { location } = useHistory(); - const { settingsStore, sessionStore, searchStore, searchStoreLive } = useStore(); + const { settingsStore, sessionStore, searchStore, searchStoreLive } = + useStore(); const { timezone, shownTimezone } = settingsStore.sessionSettings; const { t } = useTranslation(); const [prefetchState, setPrefetched] = useState(PREFETCH_STATE.none); @@ -99,6 +101,7 @@ function SessionItem(props: RouteComponentProps & Props) { isDisabled, live: propsLive, isAdd, + slim, } = props; const { @@ -176,7 +179,7 @@ function SessionItem(props: RouteComponentProps & Props) { await sessionStore.getFirstMob(sessionId); setPrefetched(PREFETCH_STATE.fetched); } catch (e) { - setPrefetched(PREFETCH_STATE.none) + setPrefetched(PREFETCH_STATE.none); console.error('Error while prefetching first mob', e); } }, [prefetchState, live, isAssist, isMobile, sessionStore, sessionId]); @@ -245,13 +248,13 @@ function SessionItem(props: RouteComponentProps & Props) { ); }, [startedAt, timezone, userTimezone]); - const onMetaClick = (meta: { name: string, value: string }) => { + const onMetaClick = (meta: { name: string; value: string }) => { if (isAssist) { - searchStoreLive.addFilterByKeyAndValue(meta.name, meta.value) + searchStoreLive.addFilterByKeyAndValue(meta.name, meta.value); } else { searchStore.addFilterByKeyAndValue(meta.name, meta.value); } - } + }; return (
e.stopPropagation()} onMouseEnter={handleHover} @@ -291,13 +298,16 @@ function SessionItem(props: RouteComponentProps & Props) {
- {_metaList.length > 0 && ( - + {!slim && _metaList.length > 0 && ( + )}
)}
@@ -343,7 +358,7 @@ function SessionItem(props: RouteComponentProps & Props) { : 'Event'}
- + )}
@@ -353,9 +368,12 @@ function SessionItem(props: RouteComponentProps & Props) {
-
+
)} {userOs && userBrowser && ( - + )} {userOs && ( )} {userOs && ( - + )} )}
diff --git a/frontend/app/components/shared/SessionsTabOverview/components/SessionTags/SessionTags.tsx b/frontend/app/components/shared/SessionsTabOverview/components/SessionTags/SessionTags.tsx index 018e0b389..a84f5cae4 100644 --- a/frontend/app/components/shared/SessionsTabOverview/components/SessionTags/SessionTags.tsx +++ b/frontend/app/components/shared/SessionsTabOverview/components/SessionTags/SessionTags.tsx @@ -1,6 +1,6 @@ import { issues_types, types } from 'Types/session/issue'; import { Grid, Segmented } from 'antd'; -import { Angry, CircleAlert, Skull, WifiOff, ChevronDown } from 'lucide-react'; +import { Angry, CircleAlert, Skull, WifiOff, ChevronDown, MessageCircleWarning } from 'lucide-react'; import { observer } from 'mobx-react-lite'; import React, { useState, useEffect, useRef } from 'react'; import { useStore } from 'App/mstore'; @@ -15,6 +15,7 @@ const tagIcons = { [types.CLICK_RAGE]: , [types.CRASH]: , [types.TAP_RAGE]: , + [types.INCIDENT]: , } as Record; function SessionTags() { diff --git a/frontend/app/components/ui/CopyButton/CopyButton.tsx b/frontend/app/components/ui/CopyButton/CopyButton.tsx index f82375914..9628eac8d 100644 --- a/frontend/app/components/ui/CopyButton/CopyButton.tsx +++ b/frontend/app/components/ui/CopyButton/CopyButton.tsx @@ -1,7 +1,7 @@ import React, { useState } from 'react'; import copy from 'copy-to-clipboard'; import { Button, Tooltip } from 'antd'; -import { ClipboardCopy, ClipboardCheck } from 'lucide-react'; +import { Copy, Check } from 'lucide-react'; interface Props { content: string; @@ -30,10 +30,10 @@ function CopyButton({ setTimeout(() => { setCopied(false); }, 1000); - } + }; const copyHandler = () => { setCopied(true); - const contentIsGetter = !!getHtml + const contentIsGetter = !!getHtml; const textContent = contentIsGetter ? getHtml() : content; const isHttps = window.location.protocol === 'https:'; if (!isHttps) { @@ -43,15 +43,16 @@ function CopyButton({ } const blob = new Blob([textContent], { type: format }); const cbItem = new ClipboardItem({ - [format]: blob - }) - navigator.clipboard.write([cbItem]) - .catch(e => { + [format]: blob, + }); + navigator.clipboard + .write([cbItem]) + .catch((e) => { copy(textContent); }) .finally(() => { - reset() - }) + reset(); + }); }; if (isIcon) { @@ -62,7 +63,11 @@ function CopyButton({ onClick={copyHandler} size={size} icon={ - copied ? : + copied ? ( + + ) : ( + + ) } /> diff --git a/frontend/app/components/ui/Icons/export_pdf.tsx b/frontend/app/components/ui/Icons/export_pdf.tsx new file mode 100644 index 000000000..c267c5d8d --- /dev/null +++ b/frontend/app/components/ui/Icons/export_pdf.tsx @@ -0,0 +1,18 @@ +/* Auto-generated, do not edit */ +import React from 'react'; + +interface Props { + size?: number | string; + width?: number | string; + height?: number | string; + fill?: string; +} + +function Export_pdf(props: Props) { + const { size = 14, width = size, height = size, fill = '' } = props; + return ( + + ); +} + +export default Export_pdf; diff --git a/frontend/app/components/ui/Icons/funnel_message_circle_warning.tsx b/frontend/app/components/ui/Icons/funnel_message_circle_warning.tsx new file mode 100644 index 000000000..2789a8f3d --- /dev/null +++ b/frontend/app/components/ui/Icons/funnel_message_circle_warning.tsx @@ -0,0 +1,18 @@ +/* Auto-generated, do not edit */ +import React from 'react'; + +interface Props { + size?: number | string; + width?: number | string; + height?: number | string; + fill?: string; +} + +function Funnel_message_circle_warning(props: Props) { + const { size = 14, width = size, height = size, fill = '' } = props; + return ( + + ); +} + +export default Funnel_message_circle_warning; diff --git a/frontend/app/components/ui/Icons/index.ts b/frontend/app/components/ui/Icons/index.ts index 8223bf185..976eeba73 100644 --- a/frontend/app/components/ui/Icons/index.ts +++ b/frontend/app/components/ui/Icons/index.ts @@ -211,6 +211,7 @@ export { default as Exclamation_circle_fill } from './exclamation_circle_fill'; export { default as Exclamation_circle } from './exclamation_circle'; export { default as Exclamation_triangle } from './exclamation_triangle'; export { default as Explosion } from './explosion'; +export { default as Export_pdf } from './export_pdf'; export { default as External_link_alt } from './external_link_alt'; export { default as Eye_slash_fill } from './eye_slash_fill'; export { default as Eye_slash } from './eye_slash'; @@ -288,6 +289,7 @@ export { default as Funnel_hdd_fill } from './funnel_hdd_fill'; export { default as Funnel_hourglass_top } from './funnel_hourglass_top'; export { default as Funnel_image_fill } from './funnel_image_fill'; export { default as Funnel_image } from './funnel_image'; +export { default as Funnel_message_circle_warning } from './funnel_message_circle_warning'; export { default as Funnel_microchip } from './funnel_microchip'; export { default as Funnel_mouse } from './funnel_mouse'; export { default as Funnel_patch_exclamation_fill } from './funnel_patch_exclamation_fill'; @@ -353,6 +355,7 @@ export { default as Integrations_teams } from './integrations_teams'; export { default as Integrations_vuejs } from './integrations_vuejs'; export { default as Integrations_zustand } from './integrations_zustand'; export { default as Journal_code } from './journal_code'; +export { default as Kai_mono } from './kai_mono'; export { default as Kai } from './kai'; export { default as Kai_colored } from './kai_colored'; export { default as Key } from './key'; @@ -413,9 +416,14 @@ export { default as Play_circle_bold } from './play_circle_bold'; export { default as Play_circle_light } from './play_circle_light'; export { default as Play_circle } from './play_circle'; export { default as Play_fill_new } from './play_fill_new'; +export { default as Play_fill_v2_assist } from './play_fill_v2_assist'; +export { default as Play_fill_v2 } from './play_fill_v2'; export { default as Play_fill } from './play_fill'; export { default as Play_hover } from './play_hover'; +export { default as Play_v2_assist } from './play_v2_assist'; +export { default as Play_v2 } from './play_v2'; export { default as Play } from './play'; +export { default as Played_v2 } from './played_v2'; export { default as Plug } from './plug'; export { default as Plus_circle } from './plus_circle'; export { default as Plus } from './plus'; diff --git a/frontend/app/components/ui/Icons/kai_mono.tsx b/frontend/app/components/ui/Icons/kai_mono.tsx new file mode 100644 index 000000000..2248858d9 --- /dev/null +++ b/frontend/app/components/ui/Icons/kai_mono.tsx @@ -0,0 +1,18 @@ +/* Auto-generated, do not edit */ +import React from 'react'; + +interface Props { + size?: number | string; + width?: number | string; + height?: number | string; + fill?: string; +} + +function Kai_mono(props: Props) { + const { size = 14, width = size, height = size, fill = '' } = props; + return ( + + ); +} + +export default Kai_mono; diff --git a/frontend/app/components/ui/Icons/play_fill_v2.tsx b/frontend/app/components/ui/Icons/play_fill_v2.tsx new file mode 100644 index 000000000..abba72052 --- /dev/null +++ b/frontend/app/components/ui/Icons/play_fill_v2.tsx @@ -0,0 +1,18 @@ +/* Auto-generated, do not edit */ +import React from 'react'; + +interface Props { + size?: number | string; + width?: number | string; + height?: number | string; + fill?: string; +} + +function Play_fill_v2(props: Props) { + const { size = 14, width = size, height = size, fill = '' } = props; + return ( + + ); +} + +export default Play_fill_v2; diff --git a/frontend/app/components/ui/Icons/play_fill_v2_assist.tsx b/frontend/app/components/ui/Icons/play_fill_v2_assist.tsx new file mode 100644 index 000000000..1f28fb078 --- /dev/null +++ b/frontend/app/components/ui/Icons/play_fill_v2_assist.tsx @@ -0,0 +1,18 @@ +/* Auto-generated, do not edit */ +import React from 'react'; + +interface Props { + size?: number | string; + width?: number | string; + height?: number | string; + fill?: string; +} + +function Play_fill_v2_assist(props: Props) { + const { size = 14, width = size, height = size, fill = '' } = props; + return ( + + ); +} + +export default Play_fill_v2_assist; diff --git a/frontend/app/components/ui/Icons/play_new.tsx b/frontend/app/components/ui/Icons/play_new.tsx new file mode 100644 index 000000000..b3ed49239 --- /dev/null +++ b/frontend/app/components/ui/Icons/play_new.tsx @@ -0,0 +1,18 @@ +/* Auto-generated, do not edit */ +import React from 'react'; + +interface Props { + size?: number | string; + width?: number | string; + height?: number | string; + fill?: string; +} + +function Play_new(props: Props) { + const { size = 14, width = size, height = size, fill = '' } = props; + return ( + + ); +} + +export default Play_new; diff --git a/frontend/app/components/ui/Icons/play_v2.tsx b/frontend/app/components/ui/Icons/play_v2.tsx new file mode 100644 index 000000000..fea80e7e3 --- /dev/null +++ b/frontend/app/components/ui/Icons/play_v2.tsx @@ -0,0 +1,18 @@ +/* Auto-generated, do not edit */ +import React from 'react'; + +interface Props { + size?: number | string; + width?: number | string; + height?: number | string; + fill?: string; +} + +function Play_v2(props: Props) { + const { size = 14, width = size, height = size, fill = '' } = props; + return ( + + ); +} + +export default Play_v2; diff --git a/frontend/app/components/ui/Icons/play_v2_assist.tsx b/frontend/app/components/ui/Icons/play_v2_assist.tsx new file mode 100644 index 000000000..b22498527 --- /dev/null +++ b/frontend/app/components/ui/Icons/play_v2_assist.tsx @@ -0,0 +1,18 @@ +/* Auto-generated, do not edit */ +import React from 'react'; + +interface Props { + size?: number | string; + width?: number | string; + height?: number | string; + fill?: string; +} + +function Play_v2_assist(props: Props) { + const { size = 14, width = size, height = size, fill = '' } = props; + return ( + + ); +} + +export default Play_v2_assist; diff --git a/frontend/app/components/ui/Icons/played_v2.tsx b/frontend/app/components/ui/Icons/played_v2.tsx new file mode 100644 index 000000000..0f6e7fa6a --- /dev/null +++ b/frontend/app/components/ui/Icons/played_v2.tsx @@ -0,0 +1,18 @@ +/* Auto-generated, do not edit */ +import React from 'react'; + +interface Props { + size?: number | string; + width?: number | string; + height?: number | string; + fill?: string; +} + +function Played_v2(props: Props) { + const { size = 14, width = size, height = size, fill = '' } = props; + return ( + + ); +} + +export default Played_v2; diff --git a/frontend/app/components/ui/SVG.tsx b/frontend/app/components/ui/SVG.tsx index 36dedf09d..777dec734 100644 --- a/frontend/app/components/ui/SVG.tsx +++ b/frontend/app/components/ui/SVG.tsx @@ -213,6 +213,7 @@ import { Exclamation_circle, Exclamation_triangle, Explosion, + Export_pdf, External_link_alt, Eye_slash_fill, Eye_slash, @@ -290,6 +291,7 @@ import { Funnel_hourglass_top, Funnel_image_fill, Funnel_image, + Funnel_message_circle_warning, Funnel_microchip, Funnel_mouse, Funnel_patch_exclamation_fill, @@ -355,6 +357,7 @@ import { Integrations_vuejs, Integrations_zustand, Journal_code, + Kai_mono, Kai, Kai_colored, Key, @@ -415,9 +418,14 @@ import { Play_circle_light, Play_circle, Play_fill_new, + Play_fill_v2_assist, + Play_fill_v2, Play_fill, Play_hover, + Play_v2_assist, + Play_v2, Play, + Played_v2, Plug, Plus_circle, Plus, @@ -487,7 +495,7 @@ import { Zoom_in } from './Icons' -export type IconNames = 'activity' | 'analytics' | 'anchor' | 'arrow-bar-left' | 'arrow-clockwise' | 'arrow-counterclockwise' | 'arrow-down-short' | 'arrow-down-up' | 'arrow-down' | 'arrow-repeat' | 'arrow-right-short' | 'arrow-up-short' | 'arrow-up' | 'avatar/icn_avatar1' | 'avatar/icn_avatar10' | 'avatar/icn_avatar11' | 'avatar/icn_avatar12' | 'avatar/icn_avatar13' | 'avatar/icn_avatar14' | 'avatar/icn_avatar15' | 'avatar/icn_avatar16' | 'avatar/icn_avatar17' | 'avatar/icn_avatar18' | 'avatar/icn_avatar19' | 'avatar/icn_avatar2' | 'avatar/icn_avatar20' | 'avatar/icn_avatar21' | 'avatar/icn_avatar22' | 'avatar/icn_avatar23' | 'avatar/icn_avatar3' | 'avatar/icn_avatar4' | 'avatar/icn_avatar5' | 'avatar/icn_avatar6' | 'avatar/icn_avatar7' | 'avatar/icn_avatar8' | 'avatar/icn_avatar9' | 'ban' | 'bar-chart-line' | 'bar-pencil' | 'battery-charging' | 'battery' | 'bell-plus' | 'bell-slash' | 'bell' | 'binoculars' | 'book' | 'bookmark' | 'broadcast' | 'browser/browser' | 'browser/chrome' | 'browser/edge' | 'browser/electron' | 'browser/facebook' | 'browser/firefox' | 'browser/ie' | 'browser/opera' | 'browser/safari' | 'buildings' | 'bullhorn' | 'calendar' | 'call' | 'camera-video-off' | 'camera-video' | 'camera' | 'card-list' | 'card-text' | 'caret-down-fill' | 'caret-right-fill' | 'chat-dots' | 'chat-left-text' | 'chat-square-quote' | 'check-circle-fill' | 'check-circle' | 'check' | 'chevron-down' | 'chevron-left' | 'chevron-right' | 'chevron-up' | 'circle-fill' | 'circle' | 'click-hesitation' | 'click-rage' | 'clipboard-check' | 'clock-history' | 'clock' | 'close' | 'code' | 'cog' | 'cogs' | 'collection-play' | 'collection' | 'color/apple' | 'color/browser/chrome' | 'color/browser/edge' | 'color/browser/facebook' | 'color/browser/firefox' | 'color/browser/google' | 'color/browser/opera' | 'color/browser/safari' | 'color/browser/unknown' | 'color/browser/whale' | 'color/chrome' | 'color/country/de' | 'color/country/fr' | 'color/country/gb' | 'color/country/in' | 'color/country/us' | 'color/de' | 'color/device/desktop' | 'color/device/mobile' | 'color/device/tablet' | 'color/device/unkown' | 'color/edge' | 'color/fedora' | 'color/firefox' | 'color/fr' | 'color/gb' | 'color/in' | 'color/issues/bad_request' | 'color/issues/click_rage' | 'color/issues/cpu' | 'color/issues/crash' | 'color/issues/custom' | 'color/issues/dead_click' | 'color/issues/errors' | 'color/issues/excessive_scrolling' | 'color/issues/js_exception' | 'color/issues/memory' | 'color/issues/missing_resource' | 'color/issues/mouse_thrashing' | 'color/issues/slow_page_load' | 'color/microsoft' | 'color/opera' | 'color/os/android' | 'color/os/apple' | 'color/os/elementary' | 'color/os/fedora' | 'color/os/ios' | 'color/os/linux' | 'color/os/macos' | 'color/os/microsoft' | 'color/os/ubuntu' | 'color/os/unkown' | 'color/safari' | 'color/ubuntu' | 'color/us' | 'columns-gap' | 'console/error' | 'console/exception' | 'console/info' | 'console/warning' | 'console' | 'controller' | 'cookies' | 'copy' | 'credit-card-2-back' | 'cross' | 'cubes' | 'cursor-trash' | 'cypress' | 'dash' | 'dashboard-icn' | 'dashboards/circle-alert' | 'dashboards/cohort-chart' | 'dashboards/heatmap-2' | 'dashboards/user-journey' | 'db-icons/icn-card-clickMap' | 'db-icons/icn-card-errors' | 'db-icons/icn-card-funnel' | 'db-icons/icn-card-funnels' | 'db-icons/icn-card-insights' | 'db-icons/icn-card-library' | 'db-icons/icn-card-mapchart' | 'db-icons/icn-card-pathAnalysis' | 'db-icons/icn-card-performance' | 'db-icons/icn-card-resources' | 'db-icons/icn-card-table' | 'db-icons/icn-card-timeseries' | 'db-icons/icn-card-webVitals' | 'desktop' | 'device' | 'diagram-3' | 'dizzy' | 'door-closed' | 'download' | 'drag' | 'edit' | 'ellipsis-v' | 'emoji-dizzy' | 'enter' | 'envelope-check' | 'envelope-paper' | 'envelope-x' | 'envelope' | 'errors-icon' | 'event/click' | 'event/click_hesitation' | 'event/clickrage' | 'event/code' | 'event/i-cursor' | 'event/input' | 'event/input_hesitation' | 'event/link' | 'event/location' | 'event/mouse_thrashing' | 'event/resize' | 'event/view' | 'exclamation-circle-fill' | 'exclamation-circle' | 'exclamation-triangle' | 'explosion' | 'external-link-alt' | 'eye-slash-fill' | 'eye-slash' | 'eye' | 'fetch-request' | 'fetch' | 'fflag-multi' | 'fflag-single' | 'file-bar-graph' | 'file-code' | 'file-medical-alt' | 'file-pdf' | 'file' | 'files' | 'filetype-js' | 'filetype-pdf' | 'filter' | 'filters/arrow-return-right' | 'filters/browser' | 'filters/chevrons-up-down' | 'filters/click' | 'filters/clickrage' | 'filters/code' | 'filters/console' | 'filters/country' | 'filters/cpu-load' | 'filters/custom' | 'filters/device' | 'filters/dom-complete' | 'filters/duration' | 'filters/error' | 'filters/fetch-failed' | 'filters/fetch' | 'filters/file-code' | 'filters/graphql' | 'filters/i-cursor' | 'filters/input' | 'filters/lcpt' | 'filters/link' | 'filters/location' | 'filters/memory-load' | 'filters/metadata' | 'filters/os' | 'filters/perfromance-network-request' | 'filters/platform' | 'filters/referrer' | 'filters/resize' | 'filters/rev-id' | 'filters/screen' | 'filters/state-action' | 'filters/tag-element' | 'filters/ttfb' | 'filters/user-alt' | 'filters/userid' | 'filters/view' | 'flag-na' | 'folder-plus' | 'folder2' | 'fullscreen' | 'funnel/cpu-fill' | 'funnel/cpu' | 'funnel/dizzy' | 'funnel/emoji-angry-fill' | 'funnel/emoji-angry' | 'funnel/emoji-dizzy-fill' | 'funnel/exclamation-circle-fill' | 'funnel/exclamation-circle' | 'funnel/file-earmark-break-fill' | 'funnel/file-earmark-break' | 'funnel/file-earmark-minus-fill' | 'funnel/file-earmark-minus' | 'funnel/file-medical-alt' | 'funnel/file-x' | 'funnel/hdd-fill' | 'funnel/hourglass-top' | 'funnel/image-fill' | 'funnel/image' | 'funnel/microchip' | 'funnel/mouse' | 'funnel/patch-exclamation-fill' | 'funnel/sd-card' | 'funnel-fill' | 'funnel' | 'gear' | 'github' | 'graph-up' | 'grid-3x3' | 'grid-check' | 'grid' | 'hash' | 'headset' | 'history' | 'ic-errors' | 'ic-network' | 'ic-rage' | 'ic-resources' | 'icn_fetch-request' | 'icn_referrer' | 'icn_url' | 'id-card' | 'image' | 'info-circle-fill' | 'info-circle' | 'info-square' | 'info' | 'input-hesitation' | 'inspect' | 'integrations/assist' | 'integrations/bugsnag-text' | 'integrations/bugsnag' | 'integrations/cloudwatch-text' | 'integrations/cloudwatch' | 'integrations/datadog' | 'integrations/dynatrace' | 'integrations/elasticsearch-text' | 'integrations/elasticsearch' | 'integrations/github' | 'integrations/graphql' | 'integrations/jira-text' | 'integrations/jira' | 'integrations/mobx' | 'integrations/newrelic-text' | 'integrations/newrelic' | 'integrations/ngrx' | 'integrations/openreplay-text' | 'integrations/openreplay' | 'integrations/redux' | 'integrations/rollbar-text' | 'integrations/rollbar' | 'integrations/segment' | 'integrations/sentry-text' | 'integrations/sentry' | 'integrations/slack-bw' | 'integrations/slack' | 'integrations/stackdriver' | 'integrations/sumologic-text' | 'integrations/sumologic' | 'integrations/teams-white' | 'integrations/teams' | 'integrations/vuejs' | 'integrations/zustand' | 'journal-code' | 'kai' | 'kai_colored' | 'key' | 'keyboard' | 'layers-half' | 'lightbulb-on' | 'lightbulb' | 'link-45deg' | 'list-alt' | 'list-ul' | 'list' | 'low-disc-space' | 'magic' | 'map-marker-alt' | 'memory-ios' | 'memory' | 'metadata-more' | 'mic-mute' | 'mic' | 'minus' | 'mobile' | 'mouse-alt' | 'mouse-pointer-click' | 'network' | 'next1' | 'no-dashboard' | 'no-metrics-chart' | 'no-metrics' | 'no-recordings' | 'orIcn' | 'orSpot' | 'orspotOutline' | 'os/android' | 'os/chrome_os' | 'os/fedora' | 'os/ios' | 'os/linux' | 'os/mac_os_x' | 'os/other' | 'os/ubuntu' | 'os/windows' | 'os' | 'pause-circle-fill' | 'pause-fill' | 'pause' | 'pdf-download' | 'pencil-stop' | 'pencil' | 'people' | 'percent' | 'performance-icon' | 'person-border' | 'person-fill' | 'person' | 'pie-chart-fill' | 'pin-fill' | 'play-circle-bold' | 'play-circle-light' | 'play-circle' | 'play-fill-new' | 'play-fill' | 'play-hover' | 'play' | 'plug' | 'plus-circle' | 'plus' | 'prev1' | 'pulse' | 'puppeteer' | 'puzzle-piece' | 'puzzle' | 'pwright' | 'question-circle' | 'question-lg' | 'quotes' | 'record-circle-fill' | 'record-circle' | 'record2' | 'redo' | 'redux' | 'referrer' | 'remote-control' | 'resources-icon' | 'safe' | 'sandglass' | 'search' | 'server' | 'share-alt' | 'shield-lock' | 'side_menu_closed' | 'side_menu_open' | 'signpost-split' | 'signup' | 'slack' | 'slash-circle' | 'sleep' | 'sliders' | 'social/slack' | 'social/trello' | 'sparkles' | 'speedometer2' | 'spinner' | 'square-mouse-pointer' | 'star' | 'step-forward' | 'stickies' | 'stop-record-circle' | 'stopwatch' | 'store' | 'sync-alt' | 'table' | 'tags' | 'terminal' | 'thermometer-sun' | 'toggles' | 'tools' | 'trash' | 'turtle' | 'user-alt' | 'user-circle' | 'user-friends' | 'user-journey' | 'user-switch' | 'users' | 'vendors/graphql' | 'web-vitals' | 'wifi' | 'window-x' | 'window' | 'zoom-in'; +export type IconNames = 'activity' | 'analytics' | 'anchor' | 'arrow-bar-left' | 'arrow-clockwise' | 'arrow-counterclockwise' | 'arrow-down-short' | 'arrow-down-up' | 'arrow-down' | 'arrow-repeat' | 'arrow-right-short' | 'arrow-up-short' | 'arrow-up' | 'avatar/icn_avatar1' | 'avatar/icn_avatar10' | 'avatar/icn_avatar11' | 'avatar/icn_avatar12' | 'avatar/icn_avatar13' | 'avatar/icn_avatar14' | 'avatar/icn_avatar15' | 'avatar/icn_avatar16' | 'avatar/icn_avatar17' | 'avatar/icn_avatar18' | 'avatar/icn_avatar19' | 'avatar/icn_avatar2' | 'avatar/icn_avatar20' | 'avatar/icn_avatar21' | 'avatar/icn_avatar22' | 'avatar/icn_avatar23' | 'avatar/icn_avatar3' | 'avatar/icn_avatar4' | 'avatar/icn_avatar5' | 'avatar/icn_avatar6' | 'avatar/icn_avatar7' | 'avatar/icn_avatar8' | 'avatar/icn_avatar9' | 'ban' | 'bar-chart-line' | 'bar-pencil' | 'battery-charging' | 'battery' | 'bell-plus' | 'bell-slash' | 'bell' | 'binoculars' | 'book' | 'bookmark' | 'broadcast' | 'browser/browser' | 'browser/chrome' | 'browser/edge' | 'browser/electron' | 'browser/facebook' | 'browser/firefox' | 'browser/ie' | 'browser/opera' | 'browser/safari' | 'buildings' | 'bullhorn' | 'calendar' | 'call' | 'camera-video-off' | 'camera-video' | 'camera' | 'card-list' | 'card-text' | 'caret-down-fill' | 'caret-right-fill' | 'chat-dots' | 'chat-left-text' | 'chat-square-quote' | 'check-circle-fill' | 'check-circle' | 'check' | 'chevron-down' | 'chevron-left' | 'chevron-right' | 'chevron-up' | 'circle-fill' | 'circle' | 'click-hesitation' | 'click-rage' | 'clipboard-check' | 'clock-history' | 'clock' | 'close' | 'code' | 'cog' | 'cogs' | 'collection-play' | 'collection' | 'color/apple' | 'color/browser/chrome' | 'color/browser/edge' | 'color/browser/facebook' | 'color/browser/firefox' | 'color/browser/google' | 'color/browser/opera' | 'color/browser/safari' | 'color/browser/unknown' | 'color/browser/whale' | 'color/chrome' | 'color/country/de' | 'color/country/fr' | 'color/country/gb' | 'color/country/in' | 'color/country/us' | 'color/de' | 'color/device/desktop' | 'color/device/mobile' | 'color/device/tablet' | 'color/device/unkown' | 'color/edge' | 'color/fedora' | 'color/firefox' | 'color/fr' | 'color/gb' | 'color/in' | 'color/issues/bad_request' | 'color/issues/click_rage' | 'color/issues/cpu' | 'color/issues/crash' | 'color/issues/custom' | 'color/issues/dead_click' | 'color/issues/errors' | 'color/issues/excessive_scrolling' | 'color/issues/js_exception' | 'color/issues/memory' | 'color/issues/missing_resource' | 'color/issues/mouse_thrashing' | 'color/issues/slow_page_load' | 'color/microsoft' | 'color/opera' | 'color/os/android' | 'color/os/apple' | 'color/os/elementary' | 'color/os/fedora' | 'color/os/ios' | 'color/os/linux' | 'color/os/macos' | 'color/os/microsoft' | 'color/os/ubuntu' | 'color/os/unkown' | 'color/safari' | 'color/ubuntu' | 'color/us' | 'columns-gap' | 'console/error' | 'console/exception' | 'console/info' | 'console/warning' | 'console' | 'controller' | 'cookies' | 'copy' | 'credit-card-2-back' | 'cross' | 'cubes' | 'cursor-trash' | 'cypress' | 'dash' | 'dashboard-icn' | 'dashboards/circle-alert' | 'dashboards/cohort-chart' | 'dashboards/heatmap-2' | 'dashboards/user-journey' | 'db-icons/icn-card-clickMap' | 'db-icons/icn-card-errors' | 'db-icons/icn-card-funnel' | 'db-icons/icn-card-funnels' | 'db-icons/icn-card-insights' | 'db-icons/icn-card-library' | 'db-icons/icn-card-mapchart' | 'db-icons/icn-card-pathAnalysis' | 'db-icons/icn-card-performance' | 'db-icons/icn-card-resources' | 'db-icons/icn-card-table' | 'db-icons/icn-card-timeseries' | 'db-icons/icn-card-webVitals' | 'desktop' | 'device' | 'diagram-3' | 'dizzy' | 'door-closed' | 'download' | 'drag' | 'edit' | 'ellipsis-v' | 'emoji-dizzy' | 'enter' | 'envelope-check' | 'envelope-paper' | 'envelope-x' | 'envelope' | 'errors-icon' | 'event/click' | 'event/click_hesitation' | 'event/clickrage' | 'event/code' | 'event/i-cursor' | 'event/input' | 'event/input_hesitation' | 'event/link' | 'event/location' | 'event/mouse_thrashing' | 'event/resize' | 'event/view' | 'exclamation-circle-fill' | 'exclamation-circle' | 'exclamation-triangle' | 'explosion' | 'export-pdf' | 'external-link-alt' | 'eye-slash-fill' | 'eye-slash' | 'eye' | 'fetch-request' | 'fetch' | 'fflag-multi' | 'fflag-single' | 'file-bar-graph' | 'file-code' | 'file-medical-alt' | 'file-pdf' | 'file' | 'files' | 'filetype-js' | 'filetype-pdf' | 'filter' | 'filters/arrow-return-right' | 'filters/browser' | 'filters/chevrons-up-down' | 'filters/click' | 'filters/clickrage' | 'filters/code' | 'filters/console' | 'filters/country' | 'filters/cpu-load' | 'filters/custom' | 'filters/device' | 'filters/dom-complete' | 'filters/duration' | 'filters/error' | 'filters/fetch-failed' | 'filters/fetch' | 'filters/file-code' | 'filters/graphql' | 'filters/i-cursor' | 'filters/input' | 'filters/lcpt' | 'filters/link' | 'filters/location' | 'filters/memory-load' | 'filters/metadata' | 'filters/os' | 'filters/perfromance-network-request' | 'filters/platform' | 'filters/referrer' | 'filters/resize' | 'filters/rev-id' | 'filters/screen' | 'filters/state-action' | 'filters/tag-element' | 'filters/ttfb' | 'filters/user-alt' | 'filters/userid' | 'filters/view' | 'flag-na' | 'folder-plus' | 'folder2' | 'fullscreen' | 'funnel/cpu-fill' | 'funnel/cpu' | 'funnel/dizzy' | 'funnel/emoji-angry-fill' | 'funnel/emoji-angry' | 'funnel/emoji-dizzy-fill' | 'funnel/exclamation-circle-fill' | 'funnel/exclamation-circle' | 'funnel/file-earmark-break-fill' | 'funnel/file-earmark-break' | 'funnel/file-earmark-minus-fill' | 'funnel/file-earmark-minus' | 'funnel/file-medical-alt' | 'funnel/file-x' | 'funnel/hdd-fill' | 'funnel/hourglass-top' | 'funnel/image-fill' | 'funnel/image' | 'funnel/message-circle-warning' | 'funnel/microchip' | 'funnel/mouse' | 'funnel/patch-exclamation-fill' | 'funnel/sd-card' | 'funnel-fill' | 'funnel' | 'gear' | 'github' | 'graph-up' | 'grid-3x3' | 'grid-check' | 'grid' | 'hash' | 'headset' | 'history' | 'ic-errors' | 'ic-network' | 'ic-rage' | 'ic-resources' | 'icn_fetch-request' | 'icn_referrer' | 'icn_url' | 'id-card' | 'image' | 'info-circle-fill' | 'info-circle' | 'info-square' | 'info' | 'input-hesitation' | 'inspect' | 'integrations/assist' | 'integrations/bugsnag-text' | 'integrations/bugsnag' | 'integrations/cloudwatch-text' | 'integrations/cloudwatch' | 'integrations/datadog' | 'integrations/dynatrace' | 'integrations/elasticsearch-text' | 'integrations/elasticsearch' | 'integrations/github' | 'integrations/graphql' | 'integrations/jira-text' | 'integrations/jira' | 'integrations/mobx' | 'integrations/newrelic-text' | 'integrations/newrelic' | 'integrations/ngrx' | 'integrations/openreplay-text' | 'integrations/openreplay' | 'integrations/redux' | 'integrations/rollbar-text' | 'integrations/rollbar' | 'integrations/segment' | 'integrations/sentry-text' | 'integrations/sentry' | 'integrations/slack-bw' | 'integrations/slack' | 'integrations/stackdriver' | 'integrations/sumologic-text' | 'integrations/sumologic' | 'integrations/teams-white' | 'integrations/teams' | 'integrations/vuejs' | 'integrations/zustand' | 'journal-code' | 'kai-mono' | 'kai' | 'kai_colored' | 'key' | 'keyboard' | 'layers-half' | 'lightbulb-on' | 'lightbulb' | 'link-45deg' | 'list-alt' | 'list-ul' | 'list' | 'low-disc-space' | 'magic' | 'map-marker-alt' | 'memory-ios' | 'memory' | 'metadata-more' | 'mic-mute' | 'mic' | 'minus' | 'mobile' | 'mouse-alt' | 'mouse-pointer-click' | 'network' | 'next1' | 'no-dashboard' | 'no-metrics-chart' | 'no-metrics' | 'no-recordings' | 'orIcn' | 'orSpot' | 'orspotOutline' | 'os/android' | 'os/chrome_os' | 'os/fedora' | 'os/ios' | 'os/linux' | 'os/mac_os_x' | 'os/other' | 'os/ubuntu' | 'os/windows' | 'os' | 'pause-circle-fill' | 'pause-fill' | 'pause' | 'pdf-download' | 'pencil-stop' | 'pencil' | 'people' | 'percent' | 'performance-icon' | 'person-border' | 'person-fill' | 'person' | 'pie-chart-fill' | 'pin-fill' | 'play-circle-bold' | 'play-circle-light' | 'play-circle' | 'play-fill-new' | 'play-fill-v2-assist' | 'play-fill-v2' | 'play-fill' | 'play-hover' | 'play-v2-assist' | 'play-v2' | 'play' | 'played-v2' | 'plug' | 'plus-circle' | 'plus' | 'prev1' | 'pulse' | 'puppeteer' | 'puzzle-piece' | 'puzzle' | 'pwright' | 'question-circle' | 'question-lg' | 'quotes' | 'record-circle-fill' | 'record-circle' | 'record2' | 'redo' | 'redux' | 'referrer' | 'remote-control' | 'resources-icon' | 'safe' | 'sandglass' | 'search' | 'server' | 'share-alt' | 'shield-lock' | 'side_menu_closed' | 'side_menu_open' | 'signpost-split' | 'signup' | 'slack' | 'slash-circle' | 'sleep' | 'sliders' | 'social/slack' | 'social/trello' | 'sparkles' | 'speedometer2' | 'spinner' | 'square-mouse-pointer' | 'star' | 'step-forward' | 'stickies' | 'stop-record-circle' | 'stopwatch' | 'store' | 'sync-alt' | 'table' | 'tags' | 'terminal' | 'thermometer-sun' | 'toggles' | 'tools' | 'trash' | 'turtle' | 'user-alt' | 'user-circle' | 'user-friends' | 'user-journey' | 'user-switch' | 'users' | 'vendors/graphql' | 'web-vitals' | 'wifi' | 'window-x' | 'window' | 'zoom-in'; interface Props { name: IconNames; @@ -1135,6 +1143,9 @@ const SVG = (props: Props) => { case 'explosion': return ; + // case 'export-pdf': + case 'export-pdf': return ; + // case 'external-link-alt': case 'external-link-alt': return ; @@ -1366,6 +1377,9 @@ const SVG = (props: Props) => { // case 'funnel/image': case 'funnel/image': return ; + // case 'funnel/message-circle-warning': + case 'funnel/message-circle-warning': return ; + // case 'funnel/microchip': case 'funnel/microchip': return ; @@ -1561,6 +1575,9 @@ const SVG = (props: Props) => { // case 'journal-code': case 'journal-code': return ; + // case 'kai-mono': + case 'kai-mono': return ; + case 'kai': return ; @@ -1741,15 +1758,30 @@ const SVG = (props: Props) => { // case 'play-fill-new': case 'play-fill-new': return ; + // case 'play-fill-v2-assist': + case 'play-fill-v2-assist': return ; + + // case 'play-fill-v2': + case 'play-fill-v2': return ; + // case 'play-fill': case 'play-fill': return ; // case 'play-hover': case 'play-hover': return ; + // case 'play-v2-assist': + case 'play-v2-assist': return ; + + // case 'play-v2': + case 'play-v2': return ; + case 'play': return ; + // case 'played-v2': + case 'played-v2': return ; + case 'plug': return ; diff --git a/frontend/app/initialize.tsx b/frontend/app/initialize.tsx index d569a2f34..19f5b59e7 100644 --- a/frontend/app/initialize.tsx +++ b/frontend/app/initialize.tsx @@ -1,6 +1,7 @@ import './styles/index.css'; import './styles/global.css'; import React from 'react'; +import '@ant-design/v5-patch-for-react-19'; import { createRoot } from 'react-dom/client'; import './init'; import { HTML5Backend } from 'react-dnd-html5-backend'; @@ -98,8 +99,9 @@ const ThemedApp: React.FC = () => { colorBorderSecondary: cssVar('gray-light'), headerBg: cssVar('gray-lightest'), rowHoverBg: cssVar('gray-lightest'), - headerSortHoverBg: cssVar('gray-lighter'), - headerSortActiveBg: cssVar('gray-lighter') + headerSortHoverBg: cssVar('gray-light'), + headerSortActiveBg: cssVar('gray-light'), + fixedHeaderSortActiveBg: cssVar('gray-light'), }, Modal: { colorBgElevated: cssVar('white'), @@ -120,8 +122,8 @@ const ThemedApp: React.FC = () => { }, Tag: { defaultBg: cssVar('gray-lightest'), - defaultColor: cssVar('gray-darkest') - } + defaultColor: cssVar('gray-darkest'), + }, }, token: { colorPrimary: cssVar('main'), @@ -143,7 +145,7 @@ const ThemedApp: React.FC = () => { fontSize: 14, fontFamily: "'Roboto', 'ArialMT', 'Arial'", fontWeightStrong: 400, - colorSplit: cssVar('gray-light') + colorSplit: cssVar('gray-light'), }, }; diff --git a/frontend/app/layout/SideMenu.tsx b/frontend/app/layout/SideMenu.tsx index bf4803160..5b2de2054 100644 --- a/frontend/app/layout/SideMenu.tsx +++ b/frontend/app/layout/SideMenu.tsx @@ -29,6 +29,7 @@ import { spotOnlyCats, } from './data'; import { useTranslation } from 'react-i18next'; +import { tag } from '@/components/Session_/Inspector/inspector.css'; const { Text } = Typography; @@ -104,7 +105,7 @@ function SideMenu(props: Props) { modules.includes(MODULES.USABILITY_TESTS), item.isAdmin && !isAdmin, item.isEnterprise && !isEnterprise, - item.key === MENU.KAI && !hasAi + item.key === MENU.KAI && !hasAi, ].some((cond) => cond); return { ...item, hidden: isHidden }; @@ -118,7 +119,15 @@ function SideMenu(props: Props) { hidden: allItemsHidden, }; }); - }, [isAdmin, isEnterprise, isPreferencesActive, modules, spotOnly, siteId, i18n.language]); + }, [ + isAdmin, + isEnterprise, + isPreferencesActive, + modules, + spotOnly, + siteId, + i18n.language, + ]); const menuRoutes: any = { [MENU.EXIT]: () => @@ -216,7 +225,10 @@ function SideMenu(props: Props) { color={isActive ? 'teal' : 'black'} /> } - className={cn('!rounded-lg hover-fill-teal', isActive ? 'color-main' : 'color-black')} + className={cn( + '!rounded-lg hover-fill-teal', + isActive ? 'color-main' : 'color-black', + )} > {item.label} @@ -235,7 +247,10 @@ function SideMenu(props: Props) { /> } style={{ paddingLeft: '20px' }} - className={cn('!rounded-lg !pe-0', isActive ? 'color-main' : 'color-black')} + className={cn( + '!rounded-lg !pe-0', + isActive ? 'color-main' : 'color-black', + )} itemIcon={ item.leading ? ( {item.label} - - {t('Beta')} -
); @@ -285,7 +293,20 @@ function SideMenu(props: Props) { })} key={child.key} > - {child.label} +
+ {child.label} + {child.tag ? ( +
+ + {child.tag.label} + +
+ ) : null} +
))} @@ -301,7 +322,10 @@ function SideMenu(props: Props) { /> } style={{ paddingLeft: '20px' }} - className={cn('!rounded-lg hover-fill-teal', isActive ? 'color-main' : 'color-black')} + className={cn( + '!rounded-lg hover-fill-teal', + isActive ? 'color-main' : 'color-black', + )} itemIcon={ item.leading ? ( - {item.label} +
+ {item.label} + {item.tag ? ( +
+ + {item.tag.label} + +
+ ) : null} +
); })} diff --git a/frontend/app/layout/data.ts b/frontend/app/layout/data.ts index 96b998d90..30a7d785d 100644 --- a/frontend/app/layout/data.ts +++ b/frontend/app/layout/data.ts @@ -1,5 +1,5 @@ import { TFunction } from 'i18next'; -import { IconNames } from "../components/ui/SVG"; +import { IconNames } from '../components/ui/SVG'; import React from 'react'; export interface MenuItem { @@ -99,7 +99,15 @@ export const categories: (t: TFunction) => Category[] = (t) => [ title: '', key: 'kai', items: [ - { label: t('Kai'), key: MENU.KAI, icon: 'kai' }, + { + label: t('Kai'), + key: MENU.KAI, + icon: 'kai-mono', + tag: { + label: t('New'), + color: '#394DFE', + }, + }, ], }, { diff --git a/frontend/app/mstore/dashboardStore.ts b/frontend/app/mstore/dashboardStore.ts index a36393f29..f3ce84316 100644 --- a/frontend/app/mstore/dashboardStore.ts +++ b/frontend/app/mstore/dashboardStore.ts @@ -1,12 +1,13 @@ import { makeAutoObservable, runInAction, reaction } from 'mobx'; import { dashboardService, metricService } from 'App/services'; import { toast } from 'react-toastify'; -import Period, { LAST_24_HOURS, LAST_7_DAYS } from 'Types/app/period'; +import Period, { LAST_24_HOURS } from 'Types/app/period'; import { getRE } from 'App/utils'; import Filter from './types/filter'; import Widget from './types/widget'; import Dashboard from './types/dashboard'; import { calculateGranularities } from '@/components/Dashboard/components/WidgetDateRange/RangeGranularity'; +import { CUSTOM_RANGE } from '@/dateRange'; interface DashboardFilter { query?: string; @@ -59,20 +60,20 @@ export default class DashboardStore { () => this.period, (period) => { this.createDensity(period.getDuration()); - } - ) + }, + ); } resetDensity = () => { this.createDensity(this.period.getDuration()); - } + }; createDensity = (duration: number) => { const densityOpts = calculateGranularities(duration); const defaultOption = densityOpts[densityOpts.length - 2]; - this.setDensity(defaultOption.key) - } + this.setDensity(defaultOption.key); + }; setDensity = (density: number) => { this.selectedDensity = density; @@ -365,7 +366,7 @@ export default class DashboardStore { getDashboardById = async (dashboardId: string) => { if (!this.listFetched) { - const maxWait = (5*1000)/250; + const maxWait = (5 * 1000) / 250; let count = 0; await new Promise((resolve) => { const interval = setInterval(() => { @@ -379,7 +380,7 @@ export default class DashboardStore { } count++; }, 250); - }) + }); } const dashboard = this.dashboards.find((d) => d.dashboardId == dashboardId); @@ -464,6 +465,17 @@ export default class DashboardStore { } } + resetPeriod = () => { + if (this.period) { + const range = this.period.rangeName; + if (range !== CUSTOM_RANGE) { + this.period = Period({ rangeName: this.period.rangeName }); + } else { + this.period = Period({ rangeName: LAST_24_HOURS }); + } + } + }; + setPeriod(period: any) { this.period = Period({ start: period.start, @@ -536,9 +548,9 @@ export default class DashboardStore { const data = await metricService.getMetricChartData( metric, params, - isSaved + isSaved, ); - const res = metric.setData(data, period, isComparison, data.density) + const res = metric.setData(data, period, isComparison, data.density); resolve(res); } catch (error) { reject(error); diff --git a/frontend/app/mstore/sessionStore.ts b/frontend/app/mstore/sessionStore.ts index c283a465f..42b4161ce 100644 --- a/frontend/app/mstore/sessionStore.ts +++ b/frontend/app/mstore/sessionStore.ts @@ -344,7 +344,7 @@ export default class SessionStore { events: evData.events.map((e) => ({ ...e, isHighlighted: checkEventWithFilters(e, searchStore.instance.filters) - })) + })), }); } catch (e) { console.error('Failed to fetch events', e); @@ -359,6 +359,7 @@ export default class SessionStore { stackEvents = [], userEvents = [], userTesting = [], + incidents = [], } = eventsData; const filterEvents = filter.events as Record[]; @@ -399,6 +400,7 @@ export default class SessionStore { userEvents, stackEvents, userTesting, + incidents, ); this.current = session; this.eventsIndex = matching; diff --git a/frontend/app/player/web/Lists.ts b/frontend/app/player/web/Lists.ts index 0d4914c7c..4cfdab840 100644 --- a/frontend/app/player/web/Lists.ts +++ b/frontend/app/player/web/Lists.ts @@ -62,6 +62,7 @@ const SIMPLE_LIST_NAMES = [ 'exceptions', 'profiles', 'frustrations', + 'incidents', ] as const; const MARKED_LIST_NAMES = [ 'log', diff --git a/frontend/app/player/web/messages/RawMessageReader.gen.ts b/frontend/app/player/web/messages/RawMessageReader.gen.ts index 54c9d29c2..9d364ae34 100644 --- a/frontend/app/player/web/messages/RawMessageReader.gen.ts +++ b/frontend/app/player/web/messages/RawMessageReader.gen.ts @@ -773,6 +773,18 @@ export default class RawMessageReader extends PrimitiveReader { }; } + case 87: { + const label = this.readString(); if (label === null) { return resetPointer() } + const startTime = this.readInt(); if (startTime === null) { return resetPointer() } + const endTime = this.readInt(); if (endTime === null) { return resetPointer() } + return { + tp: MType.Incident, + label, + startTime, + endTime, + }; + } + case 89: { const name = this.readString(); if (name === null) { return resetPointer() } const duration = this.readInt(); if (duration === null) { return resetPointer() } diff --git a/frontend/app/player/web/messages/message.gen.ts b/frontend/app/player/web/messages/message.gen.ts index 32d4d3df1..2a2bc73ee 100644 --- a/frontend/app/player/web/messages/message.gen.ts +++ b/frontend/app/player/web/messages/message.gen.ts @@ -63,6 +63,7 @@ import type { RawNetworkRequest, RawWsChannel, RawResourceTiming, + RawIncident, RawLongAnimationTask, RawSelectionChange, RawMouseThrashing, @@ -207,6 +208,8 @@ export type WsChannel = RawWsChannel & Timed export type ResourceTiming = RawResourceTiming & Timed +export type Incident = RawIncident & Timed + export type LongAnimationTask = RawLongAnimationTask & Timed export type SelectionChange = RawSelectionChange & Timed diff --git a/frontend/app/player/web/messages/raw.gen.ts b/frontend/app/player/web/messages/raw.gen.ts index e6ca247e2..b04064c8d 100644 --- a/frontend/app/player/web/messages/raw.gen.ts +++ b/frontend/app/player/web/messages/raw.gen.ts @@ -61,6 +61,7 @@ export const enum MType { NetworkRequest = 83, WsChannel = 84, ResourceTiming = 85, + Incident = 87, LongAnimationTask = 89, SelectionChange = 113, MouseThrashing = 114, @@ -521,6 +522,13 @@ export interface RawResourceTiming { stalled: number, } +export interface RawIncident { + tp: MType.Incident, + label: string, + startTime: number, + endTime: number, +} + export interface RawLongAnimationTask { tp: MType.LongAnimationTask, name: string, @@ -695,4 +703,4 @@ export interface RawMobileIssueEvent { } -export type RawMessage = RawTimestamp | RawSetPageLocationDeprecated | RawSetViewportSize | RawSetViewportScroll | RawCreateDocument | RawCreateElementNode | RawCreateTextNode | RawMoveNode | RawRemoveNode | RawSetNodeAttribute | RawRemoveNodeAttribute | RawSetNodeData | RawSetCssData | RawSetNodeScroll | RawSetInputValue | RawSetInputChecked | RawMouseMove | RawNetworkRequestDeprecated | RawConsoleLog | RawStringDictGlobal | RawSetNodeAttributeDictGlobal | RawCssInsertRule | RawCssDeleteRule | RawFetch | RawProfiler | RawOTable | RawReduxDeprecated | RawVuex | RawMobX | RawNgRx | RawGraphQlDeprecated | RawPerformanceTrack | RawStringDictDeprecated | RawSetNodeAttributeDictDeprecated | RawStringDict | RawSetNodeAttributeDict | RawResourceTimingDeprecatedDeprecated | RawConnectionInformation | RawSetPageVisibility | RawLoadFontFace | RawSetNodeFocus | RawLongTask | RawSetNodeAttributeURLBased | RawSetCssDataURLBased | RawCssInsertRuleURLBased | RawMouseClick | RawMouseClickDeprecated | RawCreateIFrameDocument | RawAdoptedSsReplaceURLBased | RawAdoptedSsReplace | RawAdoptedSsInsertRuleURLBased | RawAdoptedSsInsertRule | RawAdoptedSsDeleteRule | RawAdoptedSsAddOwner | RawAdoptedSsRemoveOwner | RawZustand | RawNetworkRequest | RawWsChannel | RawResourceTiming | RawLongAnimationTask | RawSelectionChange | RawMouseThrashing | RawResourceTimingDeprecated | RawTabChange | RawTabData | RawCanvasNode | RawTagTrigger | RawRedux | RawSetPageLocation | RawGraphQl | RawMobileEvent | RawMobileScreenChanges | RawMobileClickEvent | RawMobileInputEvent | RawMobilePerformanceEvent | RawMobileLog | RawMobileInternalError | RawMobileNetworkCall | RawMobileSwipeEvent | RawMobileIssueEvent; +export type RawMessage = RawTimestamp | RawSetPageLocationDeprecated | RawSetViewportSize | RawSetViewportScroll | RawCreateDocument | RawCreateElementNode | RawCreateTextNode | RawMoveNode | RawRemoveNode | RawSetNodeAttribute | RawRemoveNodeAttribute | RawSetNodeData | RawSetCssData | RawSetNodeScroll | RawSetInputValue | RawSetInputChecked | RawMouseMove | RawNetworkRequestDeprecated | RawConsoleLog | RawStringDictGlobal | RawSetNodeAttributeDictGlobal | RawCssInsertRule | RawCssDeleteRule | RawFetch | RawProfiler | RawOTable | RawReduxDeprecated | RawVuex | RawMobX | RawNgRx | RawGraphQlDeprecated | RawPerformanceTrack | RawStringDictDeprecated | RawSetNodeAttributeDictDeprecated | RawStringDict | RawSetNodeAttributeDict | RawResourceTimingDeprecatedDeprecated | RawConnectionInformation | RawSetPageVisibility | RawLoadFontFace | RawSetNodeFocus | RawLongTask | RawSetNodeAttributeURLBased | RawSetCssDataURLBased | RawCssInsertRuleURLBased | RawMouseClick | RawMouseClickDeprecated | RawCreateIFrameDocument | RawAdoptedSsReplaceURLBased | RawAdoptedSsReplace | RawAdoptedSsInsertRuleURLBased | RawAdoptedSsInsertRule | RawAdoptedSsDeleteRule | RawAdoptedSsAddOwner | RawAdoptedSsRemoveOwner | RawZustand | RawNetworkRequest | RawWsChannel | RawResourceTiming | RawIncident | RawLongAnimationTask | RawSelectionChange | RawMouseThrashing | RawResourceTimingDeprecated | RawTabChange | RawTabData | RawCanvasNode | RawTagTrigger | RawRedux | RawSetPageLocation | RawGraphQl | RawMobileEvent | RawMobileScreenChanges | RawMobileClickEvent | RawMobileInputEvent | RawMobilePerformanceEvent | RawMobileLog | RawMobileInternalError | RawMobileNetworkCall | RawMobileSwipeEvent | RawMobileIssueEvent; diff --git a/frontend/app/player/web/messages/tracker-legacy.gen.ts b/frontend/app/player/web/messages/tracker-legacy.gen.ts index cef13cce6..ccbdc11a0 100644 --- a/frontend/app/player/web/messages/tracker-legacy.gen.ts +++ b/frontend/app/player/web/messages/tracker-legacy.gen.ts @@ -62,6 +62,7 @@ export const TP_MAP = { 83: MType.NetworkRequest, 84: MType.WsChannel, 85: MType.ResourceTiming, + 87: MType.Incident, 89: MType.LongAnimationTask, 113: MType.SelectionChange, 114: MType.MouseThrashing, diff --git a/frontend/app/player/web/messages/tracker.gen.ts b/frontend/app/player/web/messages/tracker.gen.ts index 0c6958268..4607f9860 100644 --- a/frontend/app/player/web/messages/tracker.gen.ts +++ b/frontend/app/player/web/messages/tracker.gen.ts @@ -510,6 +510,13 @@ type TrResourceTiming = [ stalled: number, ] +type TrIncident = [ + type: 87, + label: string, + startTime: number, + endTime: number, +] + type TrLongAnimationTask = [ type: 89, name: string, @@ -614,7 +621,7 @@ type TrWebVitals = [ ] -export type TrackerMessage = TrTimestamp | TrSetPageLocationDeprecated | TrSetViewportSize | TrSetViewportScroll | TrCreateDocument | TrCreateElementNode | TrCreateTextNode | TrMoveNode | TrRemoveNode | TrSetNodeAttribute | TrRemoveNodeAttribute | TrSetNodeData | TrSetNodeScroll | TrSetInputTarget | TrSetInputValue | TrSetInputChecked | TrMouseMove | TrNetworkRequestDeprecated | TrConsoleLog | TrPageLoadTiming | TrPageRenderTiming | TrCustomEvent | TrUserID | TrUserAnonymousID | TrMetadata | TrStringDictGlobal | TrSetNodeAttributeDictGlobal | TrCSSInsertRule | TrCSSDeleteRule | TrFetch | TrProfiler | TrOTable | TrStateAction | TrReduxDeprecated | TrVuex | TrMobX | TrNgRx | TrGraphQLDeprecated | TrPerformanceTrack | TrStringDictDeprecated | TrSetNodeAttributeDictDeprecated | TrStringDict | TrSetNodeAttributeDict | TrResourceTimingDeprecatedDeprecated | TrConnectionInformation | TrSetPageVisibility | TrLoadFontFace | TrSetNodeFocus | TrLongTask | TrSetNodeAttributeURLBased | TrSetCSSDataURLBased | TrTechnicalInfo | TrCustomIssue | TrCSSInsertRuleURLBased | TrMouseClick | TrMouseClickDeprecated | TrCreateIFrameDocument | TrAdoptedSSReplaceURLBased | TrAdoptedSSInsertRuleURLBased | TrAdoptedSSDeleteRule | TrAdoptedSSAddOwner | TrAdoptedSSRemoveOwner | TrJSException | TrZustand | TrBatchMetadata | TrPartitionedMessage | TrNetworkRequest | TrWSChannel | TrResourceTiming | TrLongAnimationTask | TrInputChange | TrSelectionChange | TrMouseThrashing | TrUnbindNodes | TrResourceTimingDeprecated | TrTabChange | TrTabData | TrCanvasNode | TrTagTrigger | TrRedux | TrSetPageLocation | TrGraphQL | TrWebVitals +export type TrackerMessage = TrTimestamp | TrSetPageLocationDeprecated | TrSetViewportSize | TrSetViewportScroll | TrCreateDocument | TrCreateElementNode | TrCreateTextNode | TrMoveNode | TrRemoveNode | TrSetNodeAttribute | TrRemoveNodeAttribute | TrSetNodeData | TrSetNodeScroll | TrSetInputTarget | TrSetInputValue | TrSetInputChecked | TrMouseMove | TrNetworkRequestDeprecated | TrConsoleLog | TrPageLoadTiming | TrPageRenderTiming | TrCustomEvent | TrUserID | TrUserAnonymousID | TrMetadata | TrStringDictGlobal | TrSetNodeAttributeDictGlobal | TrCSSInsertRule | TrCSSDeleteRule | TrFetch | TrProfiler | TrOTable | TrStateAction | TrReduxDeprecated | TrVuex | TrMobX | TrNgRx | TrGraphQLDeprecated | TrPerformanceTrack | TrStringDictDeprecated | TrSetNodeAttributeDictDeprecated | TrStringDict | TrSetNodeAttributeDict | TrResourceTimingDeprecatedDeprecated | TrConnectionInformation | TrSetPageVisibility | TrLoadFontFace | TrSetNodeFocus | TrLongTask | TrSetNodeAttributeURLBased | TrSetCSSDataURLBased | TrTechnicalInfo | TrCustomIssue | TrCSSInsertRuleURLBased | TrMouseClick | TrMouseClickDeprecated | TrCreateIFrameDocument | TrAdoptedSSReplaceURLBased | TrAdoptedSSInsertRuleURLBased | TrAdoptedSSDeleteRule | TrAdoptedSSAddOwner | TrAdoptedSSRemoveOwner | TrJSException | TrZustand | TrBatchMetadata | TrPartitionedMessage | TrNetworkRequest | TrWSChannel | TrResourceTiming | TrIncident | TrLongAnimationTask | TrInputChange | TrSelectionChange | TrMouseThrashing | TrUnbindNodes | TrResourceTimingDeprecated | TrTabChange | TrTabData | TrCanvasNode | TrTagTrigger | TrRedux | TrSetPageLocation | TrGraphQL | TrWebVitals export default function translate(tMsg: TrackerMessage): RawMessage | null { switch(tMsg[0]) { @@ -1148,6 +1155,15 @@ export default function translate(tMsg: TrackerMessage): RawMessage | null { } } + case 87: { + return { + tp: MType.Incident, + label: tMsg[1], + startTime: tMsg[2], + endTime: tMsg[3], + } + } + case 89: { return { tp: MType.LongAnimationTask, diff --git a/frontend/app/styles/global.css b/frontend/app/styles/global.css index 068b7857e..b6154b6d2 100644 --- a/frontend/app/styles/global.css +++ b/frontend/app/styles/global.css @@ -25,6 +25,11 @@ img { stroke-width: 1.5px; } +.reset .lucide { + stroke-width: revert-layer; +} + + .ant-pagination-simple-pager input { min-width: 80px; } diff --git a/frontend/app/styles/main.css b/frontend/app/styles/main.css index b36892bb6..9cb9cd5cc 100644 --- a/frontend/app/styles/main.css +++ b/frontend/app/styles/main.css @@ -417,16 +417,6 @@ svg { margin-bottom: 6px!important; } -.markdown-body ul { - list-style-type: none; /* Remove default bullets */ -} -.markdown-body ul li:before { - content: "•"; /* Use standard bullet character */ - display: inline-block; - width: 1em; - margin-left: -1em; -} - .ant-tooltip { max-width: 640px; } diff --git a/frontend/app/svg/icons/export-pdf.svg b/frontend/app/svg/icons/export-pdf.svg new file mode 100644 index 000000000..9bc497e2b --- /dev/null +++ b/frontend/app/svg/icons/export-pdf.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/frontend/app/svg/icons/funnel/message-circle-warning.svg b/frontend/app/svg/icons/funnel/message-circle-warning.svg new file mode 100644 index 000000000..723cfce0b --- /dev/null +++ b/frontend/app/svg/icons/funnel/message-circle-warning.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/app/svg/icons/kai-mono.svg b/frontend/app/svg/icons/kai-mono.svg new file mode 100644 index 000000000..97738455d --- /dev/null +++ b/frontend/app/svg/icons/kai-mono.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/frontend/app/svg/icons/play-fill-v2-assist.svg b/frontend/app/svg/icons/play-fill-v2-assist.svg new file mode 100644 index 000000000..79ff10a89 --- /dev/null +++ b/frontend/app/svg/icons/play-fill-v2-assist.svg @@ -0,0 +1,6 @@ + + + + diff --git a/frontend/app/svg/icons/play-fill-v2.svg b/frontend/app/svg/icons/play-fill-v2.svg new file mode 100644 index 000000000..1c2c732ce --- /dev/null +++ b/frontend/app/svg/icons/play-fill-v2.svg @@ -0,0 +1,6 @@ + + + + diff --git a/frontend/app/svg/icons/play-v2-assist.svg b/frontend/app/svg/icons/play-v2-assist.svg new file mode 100644 index 000000000..a885bffe9 --- /dev/null +++ b/frontend/app/svg/icons/play-v2-assist.svg @@ -0,0 +1,6 @@ + + + + diff --git a/frontend/app/svg/icons/play-v2.svg b/frontend/app/svg/icons/play-v2.svg new file mode 100644 index 000000000..a9aa5f578 --- /dev/null +++ b/frontend/app/svg/icons/play-v2.svg @@ -0,0 +1,6 @@ + + + + diff --git a/frontend/app/svg/icons/played-v2.svg b/frontend/app/svg/icons/played-v2.svg new file mode 100644 index 000000000..58d7a97aa --- /dev/null +++ b/frontend/app/svg/icons/played-v2.svg @@ -0,0 +1,6 @@ + + + + diff --git a/frontend/app/types/session/event.ts b/frontend/app/types/session/event.ts index 2eeb568c4..b3435de85 100644 --- a/frontend/app/types/session/event.ts +++ b/frontend/app/types/session/event.ts @@ -10,6 +10,7 @@ const IOS_VIEW = 'VIEW'; const UXT_EVENT = 'UXT_EVENT'; const TOUCH = 'TAP'; const SWIPE = 'SWIPE'; +const INCIDENT = 'INCIDENT'; export const TYPES = { CONSOLE, @@ -24,6 +25,7 @@ export const TYPES = { SWIPE, TAPRAGE, UXT_EVENT, + INCIDENT, }; export type EventType = @@ -35,7 +37,8 @@ export type EventType = | typeof CLICKRAGE | typeof IOS_VIEW | typeof TOUCH - | typeof SWIPE; + | typeof SWIPE + | typeof INCIDENT interface IEvent { time: number; @@ -99,6 +102,12 @@ export interface LocationEvent extends IEvent { webVitals: string | null; } +export interface IncidentEvent extends IEvent { + label: string; + startTime: number; + endTime: number; +} + export type EventData = | ConsoleEvent | ClickEvent @@ -276,6 +285,21 @@ export class Location extends Event { } } +export class Incident extends Event { + readonly name = 'Incident'; + + readonly type = CUSTOM; + + constructor(evt: IncidentEvent) { + super(evt); + Object.assign(this, { + ...evt, + label: evt.label || 'User signaled an incident', + type: 'INCIDENT', + }); + } +} + export type InjectedEvent = | Console | Click @@ -283,7 +307,8 @@ export type InjectedEvent = | Location | Touch | Swipe - | UxtEvent; + | UxtEvent + | Incident; export default function (event: EventData) { if ('allow_typing' in event) { @@ -307,6 +332,8 @@ export default function (event: EventData) { return new Click(event as ClickEvent, true); case SWIPE: return new Swipe(event as SwipeEvent); + case INCIDENT: + return new Incident(event as IncidentEvent); default: return console.error(`Unknown event type: ${event.type}`); } diff --git a/frontend/app/types/session/issue.ts b/frontend/app/types/session/issue.ts index 6aaf1245b..3972eecef 100644 --- a/frontend/app/types/session/issue.ts +++ b/frontend/app/types/session/issue.ts @@ -1,4 +1,3 @@ -import i18next, { TFunction } from 'i18next'; import Record from 'Types/Record'; export const types = { @@ -10,6 +9,7 @@ export const types = { MOUSE_THRASHING: 'mouse_thrashing', TAP_RAGE: 'tap_rage', DEAD_CLICK: 'dead_click', + INCIDENT: 'incident', } as const; type TypeKeys = keyof typeof types; @@ -75,6 +75,14 @@ export const issues_types = [ name: 'Mouse Thrashing', icon: 'cursor-trash', }, + { + type: types.INCIDENT, + visible: true, + order: 7, + name: 'Incidents', + icon: 'funnel/message-circle-warning', + // isEvent: false, + } // { 'type': 'memory', 'visible': true, 'order': 4, 'name': 'High Memory', 'icon': 'funnel/sd-card' }, // { 'type': 'vault', 'visible': true, 'order': 5, 'name': 'Vault', 'icon': 'safe' }, // { 'type': 'bookmark', 'visible': true, 'order': 5, 'name': 'Bookmarks', 'icon': 'safe' }, diff --git a/frontend/app/types/session/session.ts b/frontend/app/types/session/session.ts index 8e578b99c..8c0b90d7e 100644 --- a/frontend/app/types/session/session.ts +++ b/frontend/app/types/session/session.ts @@ -1,7 +1,7 @@ import { Duration } from 'luxon'; import { Note } from 'App/services/NotesService'; import { toJS } from 'mobx'; -import SessionEvent, { TYPES, EventData, InjectedEvent } from './event'; +import SessionEvent, { TYPES, EventData, InjectedEvent, Incident } from './event'; import StackEvent from './stackEvent'; import SessionError, { IError } from './error'; import Issue, { IIssue, types as issueTypes } from './issue'; @@ -145,6 +145,7 @@ export interface ISession { isMobileNative?: boolean; audio?: string; assistOnly?: boolean; + incidents?: Array; } const emptyValues = { @@ -284,6 +285,8 @@ export default class Session { frustrations: Array; + incidents: Array + timezone?: ISession['timezone']; platform: ISession['platform']; @@ -329,6 +332,7 @@ export default class Session { canvasURL = [], uxtVideo = [], videoURL = [], + incidents = [], ...session } = sessionData; const duration = Duration.fromMillis( @@ -446,6 +450,7 @@ export default class Session { userEvents: any[] = [], stackEvents: any[] = [], userTestingEvents: any[] = [], + incidents: any[] = [], ) { const exceptions = (errors as IError[])?.map((e) => new SessionError(e)) || []; @@ -506,6 +511,11 @@ export default class Session { const frustrationList = [...frustrationEvents, ...frustrationIssues].sort(sortEvents) || []; + const incidentsList = incidents.sort((a, b) => a.startTime - b.startTime).map((i) => ({ + ...i, + time: i.startTime - this.startedAt, + })).map((i) => new Incident(i)); + const mixedEventsWithIssues = mergeEventLists( events, frustrationIssues.filter((i) => i.type !== issueTypes.DEAD_CLICK), @@ -524,6 +534,7 @@ export default class Session { this.frustrations = frustrationList; this.crashes = crashes || []; this.addedEvents = true; + this.incidents = incidentsList; return this; } diff --git a/frontend/package.json b/frontend/package.json index 09ff850b5..da9804b01 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -23,6 +23,7 @@ }, "dependencies": { "@ant-design/icons": "^5.2.5", + "@ant-design/v5-patch-for-react-19": "^1.0.3", "@babel/plugin-transform-private-methods": "^7.27.1", "@codewonders/html2canvas": "^1.0.2", "@eslint/js": "^9.26.0", diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 41516929c..bfe632beb 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -110,6 +110,17 @@ __metadata: languageName: node linkType: hard +"@ant-design/v5-patch-for-react-19@npm:^1.0.3": + version: 1.0.3 + resolution: "@ant-design/v5-patch-for-react-19@npm:1.0.3" + peerDependencies: + antd: ">=5.22.6" + react: ">=19.0.0" + react-dom: ">=19.0.0" + checksum: 10c1/68854c78dc29085858988c94cb0d67319516403bf3903a362e7006b331b46b4bdf598f0f7d27984164763aea46bb01808699990f39b3ec0969eec6e6dff75a53 + languageName: node + linkType: hard + "@babel/cli@npm:^7.27.2": version: 7.27.2 resolution: "@babel/cli@npm:7.27.2" @@ -3153,21 +3164,21 @@ __metadata: languageName: node linkType: hard -"@tanstack/query-core@npm:5.76.0": - version: 5.76.0 - resolution: "@tanstack/query-core@npm:5.76.0" - checksum: 10c1/597ce43f09380e6d638b277de668967a4d3429ceb0bf7b51203ff0c21eaef8cc8006d190a49e3b69129d1484f920ebbe9ad7f04d2e4161c718b331d6e1a4c236 +"@tanstack/query-core@npm:5.76.2": + version: 5.76.2 + resolution: "@tanstack/query-core@npm:5.76.2" + checksum: 10c1/b20f5c581e556b0f6319889f38226608c40a0cacdcf8aff14c78c508804a20686552a70d928df76a633e7ea237f2c514ce2c4792cd8e3d430d531c91547d74cd languageName: node linkType: hard "@tanstack/react-query@npm:^5.76.0": - version: 5.76.1 - resolution: "@tanstack/react-query@npm:5.76.1" + version: 5.76.2 + resolution: "@tanstack/react-query@npm:5.76.2" dependencies: - "@tanstack/query-core": "npm:5.76.0" + "@tanstack/query-core": "npm:5.76.2" peerDependencies: react: ^18 || ^19 - checksum: 10c1/899d86cbab243f90056394dd96aef87a73d0faf976c5dac4bed85746aea278b433cd7d767c4caeafa089a0a02920d2a48b62018f2e1dacac85dffa5f6bb2e316 + checksum: 10c1/cc994355e1c934305e69d98d45cb9e4c3faaaf99e290ac5d89913c60916c1e314be7a59cc19673868cf4c6f3907a8d5dc5239d0be7889362351627884ce7078b languageName: node linkType: hard @@ -7211,9 +7222,9 @@ __metadata: linkType: hard "electron-to-chromium@npm:^1.5.149": - version: 1.5.155 - resolution: "electron-to-chromium@npm:1.5.155" - checksum: 10c1/9c11698f48a6f95b31751c2ddb7222a477c3d87679743b99a2fb12ba7f85d50affbdc678a56b3142ade5fe869bfc4721782673aab7d276fd9124513823116675 + version: 1.5.157 + resolution: "electron-to-chromium@npm:1.5.157" + checksum: 10c1/5d5f36b2b53b95cba41deff68e73df2d2756f6ec74c3dad691e11af20f8de58944ab04e31e64a27d2bd18176ca0ce885c72e32836ac8c8bf4a1f91f798e83af4 languageName: node linkType: hard @@ -7371,25 +7382,25 @@ __metadata: linkType: hard "es-abstract@npm:^1.17.5, es-abstract@npm:^1.23.2, es-abstract@npm:^1.23.3, es-abstract@npm:^1.23.5, es-abstract@npm:^1.23.6, es-abstract@npm:^1.23.9": - version: 1.23.9 - resolution: "es-abstract@npm:1.23.9" + version: 1.23.10 + resolution: "es-abstract@npm:1.23.10" dependencies: array-buffer-byte-length: "npm:^1.0.2" arraybuffer.prototype.slice: "npm:^1.0.4" available-typed-arrays: "npm:^1.0.7" call-bind: "npm:^1.0.8" - call-bound: "npm:^1.0.3" + call-bound: "npm:^1.0.4" data-view-buffer: "npm:^1.0.2" data-view-byte-length: "npm:^1.0.2" data-view-byte-offset: "npm:^1.0.1" es-define-property: "npm:^1.0.1" es-errors: "npm:^1.3.0" - es-object-atoms: "npm:^1.0.0" + es-object-atoms: "npm:^1.1.1" es-set-tostringtag: "npm:^2.1.0" es-to-primitive: "npm:^1.3.0" function.prototype.name: "npm:^1.1.8" - get-intrinsic: "npm:^1.2.7" - get-proto: "npm:^1.0.0" + get-intrinsic: "npm:^1.3.0" + get-proto: "npm:^1.0.1" get-symbol-description: "npm:^1.1.0" globalthis: "npm:^1.0.4" gopd: "npm:^1.2.0" @@ -7405,13 +7416,13 @@ __metadata: is-shared-array-buffer: "npm:^1.0.4" is-string: "npm:^1.1.1" is-typed-array: "npm:^1.1.15" - is-weakref: "npm:^1.1.0" + is-weakref: "npm:^1.1.1" math-intrinsics: "npm:^1.1.0" - object-inspect: "npm:^1.13.3" + object-inspect: "npm:^1.13.4" object-keys: "npm:^1.1.1" object.assign: "npm:^4.1.7" own-keys: "npm:^1.0.1" - regexp.prototype.flags: "npm:^1.5.3" + regexp.prototype.flags: "npm:^1.5.4" safe-array-concat: "npm:^1.1.3" safe-push-apply: "npm:^1.0.0" safe-regex-test: "npm:^1.1.0" @@ -7424,8 +7435,8 @@ __metadata: typed-array-byte-offset: "npm:^1.0.4" typed-array-length: "npm:^1.0.7" unbox-primitive: "npm:^1.1.0" - which-typed-array: "npm:^1.1.18" - checksum: 10c1/15eb33c9296cc13c10ed8a3d417f1c41d30a82b01721330de04cff03d67c0b8b0777ecc1c7fac1931b4c49ee4d85aff6d8cf73bf5354b30d166f43ed03b0cc96 + which-typed-array: "npm:^1.1.19" + checksum: 10c1/43c8e3dce404a5c371178bf5791b8e806df4177e394b29576e7dd91ef8e8560e7c84acb741708917ad5a8f5077cbae79758bbcedc9d504baa4635f476b257cf7 languageName: node linkType: hard @@ -10101,7 +10112,7 @@ __metadata: languageName: node linkType: hard -"is-weakref@npm:^1.0.2, is-weakref@npm:^1.1.0": +"is-weakref@npm:^1.0.2, is-weakref@npm:^1.1.1": version: 1.1.1 resolution: "is-weakref@npm:1.1.1" dependencies: @@ -11352,9 +11363,9 @@ __metadata: linkType: hard "lottie-web@npm:^5.10.2": - version: 5.12.2 - resolution: "lottie-web@npm:5.12.2" - checksum: 10c1/3c87c49202b35c77081c82ea842286b252fff7ff6470028633693c16457abb062a5d4ddfa270c599aa383f41106f20a54a221bfd1aee77163b8a7309f2bfa2a1 + version: 5.13.0 + resolution: "lottie-web@npm:5.13.0" + checksum: 10c1/93eb84f936d9d65681b3466b4c5ef0f74ec7cea7d80cdc25739204d1226d3422bdbe90a0bfa72cbc2bfd9ea3e4f3c9c8897f0eed8e2ea48132338121ca30015b languageName: node linkType: hard @@ -12746,7 +12757,7 @@ __metadata: languageName: node linkType: hard -"object-inspect@npm:^1.13.3": +"object-inspect@npm:^1.13.3, object-inspect@npm:^1.13.4": version: 1.13.4 resolution: "object-inspect@npm:1.13.4" checksum: 10c1/e8aa027ddd771b884e64eff9c02112c047709a96af507997437e3085ef097739c584d274828df22ae3fee51645687d0e98a50daa3546092d0aaffca1a57d7790 @@ -12894,6 +12905,7 @@ __metadata: resolution: "openreplay@workspace:." dependencies: "@ant-design/icons": "npm:^5.2.5" + "@ant-design/v5-patch-for-react-19": "npm:^1.0.3" "@babel/cli": "npm:^7.27.2" "@babel/core": "npm:^7.27.1" "@babel/node": "npm:^7.27.1" @@ -15024,8 +15036,8 @@ __metadata: linkType: hard "react-i18next@npm:^15.5.1": - version: 15.5.1 - resolution: "react-i18next@npm:15.5.1" + version: 15.5.2 + resolution: "react-i18next@npm:15.5.2" dependencies: "@babel/runtime": "npm:^7.25.0" html-parse-stringify: "npm:^3.0.1" @@ -15040,7 +15052,7 @@ __metadata: optional: true typescript: optional: true - checksum: 10c1/9b160c9d89fc13499af7738bfaf275f7affd247675636124a4984035405f835fe23e0d7965308237aef1c8a17c729dd07ddc0432e2bf5c095771d5ca272c3b4a + checksum: 10c1/02ba24aacebe320817e4d4936d15f347a3293363ecb9adb40e1dcaff288cb4e14f2a1e9420e4fb85d36abfba65aeacb384fcaabed0d7977129bf6ecce97ba174 languageName: node linkType: hard @@ -15377,7 +15389,7 @@ __metadata: languageName: node linkType: hard -"regexp.prototype.flags@npm:^1.5.3": +"regexp.prototype.flags@npm:^1.5.3, regexp.prototype.flags@npm:^1.5.4": version: 1.5.4 resolution: "regexp.prototype.flags@npm:1.5.4" dependencies: @@ -18328,7 +18340,7 @@ __metadata: languageName: node linkType: hard -"which-typed-array@npm:^1.1.16, which-typed-array@npm:^1.1.18, which-typed-array@npm:^1.1.2": +"which-typed-array@npm:^1.1.16, which-typed-array@npm:^1.1.19, which-typed-array@npm:^1.1.2": version: 1.1.19 resolution: "which-typed-array@npm:1.1.19" dependencies: diff --git a/mobs/messages.rb b/mobs/messages.rb index 2dddad994..c0a9bb0ea 100644 --- a/mobs/messages.rb +++ b/mobs/messages.rb @@ -542,6 +542,12 @@ message 85, 'ResourceTiming', :replayer => :devtools do uint 'Stalled' end +message 87, 'Incident', :replayer => :devtools do + string 'Label' + int 'StartTime' + int 'EndTime' +end + message 89, 'LongAnimationTask', :replayer => :devtools do string 'Name' int 'Duration' @@ -653,4 +659,4 @@ message 127, 'SessionSearch', :tracker => false, :replayer => false do uint 'Partition' end -# FREE 2, 35, 36, 65, 85, 86, 87, 88, 89 +# FREE 2, 35, 36, 65, 87, 88, 89 diff --git a/scripts/docker-compose/nginx.conf b/scripts/docker-compose/nginx.conf index 198644bb4..9fa68e477 100644 --- a/scripts/docker-compose/nginx.conf +++ b/scripts/docker-compose/nginx.conf @@ -54,6 +54,25 @@ server { add_header 'Access-Control-Allow-Headers' 'Content-Type,Authorization,Content-Encoding'; add_header 'Access-Control-Expose-Headers' 'Content-Length'; } + location /integrations/ { + rewrite ^/integrations/(.*) /$1 break; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + proxy_set_header X-Forwarded-For $real_ip; + proxy_set_header X-Forwarded-Host $real_ip; + proxy_set_header X-Real-IP $real_ip; + proxy_set_header Host $host; + proxy_pass http://integrations-openreplay:8080; + proxy_read_timeout 300; + proxy_connect_timeout 120; + proxy_send_timeout 300; + # CORS Headers + add_header 'Access-Control-Allow-Origin' '*'; + add_header 'Access-Control-Allow-Methods' 'POST,PATCH,OPTIONS,DELETE'; + add_header 'Access-Control-Allow-Headers' 'Content-Type,Authorization,Content-Encoding,X-Openreplay-Batch'; + add_header 'Access-Control-Expose-Headers' 'Content-Length'; + } location /api/ { rewrite ^/api/(.*) /$1 break; diff --git a/scripts/helmcharts/databases/charts/clickhouse/templates/configmap.yaml b/scripts/helmcharts/databases/charts/clickhouse/templates/configmap.yaml index 709e0929e..4fdd5709d 100644 --- a/scripts/helmcharts/databases/charts/clickhouse/templates/configmap.yaml +++ b/scripts/helmcharts/databases/charts/clickhouse/templates/configmap.yaml @@ -1,3 +1,4 @@ +{{- if .Values.configOverride.serverConfig }} --- apiVersion: v1 kind: ConfigMap @@ -8,6 +9,7 @@ data: {{ $filename }}: |- {{ $content | indent 4 }} {{- end }} +{{- end }} --- apiVersion: v1 kind: ConfigMap diff --git a/scripts/helmcharts/databases/charts/clickhouse/values.yaml b/scripts/helmcharts/databases/charts/clickhouse/values.yaml index 641d80bab..68a42f494 100644 --- a/scripts/helmcharts/databases/charts/clickhouse/values.yaml +++ b/scripts/helmcharts/databases/charts/clickhouse/values.yaml @@ -87,27 +87,26 @@ storageSize: 100Gi configOverride: serverConfig: zz-server-override.xml: |- - # - # - # information - # true - # - # - # - # 0.0.0.0 - # 100 - # 64 - # 2 - # fair_round_robin - # 102400000000 - # 10000 - # 0.8 - # - # 26214 - # + + + information + true + + + + 0.0.0.0 + 100 + # another-config.xml: |- # - # value + # 64 + # 2 + # fair_round_robin + # 102400000000 + # 10000 + # 0.8 + # + # 26214 # userConfig: zz-user-override.xml: |- diff --git a/scripts/helmcharts/openreplay/Chart.yaml b/scripts/helmcharts/openreplay/Chart.yaml index 71f89e366..664a32226 100644 --- a/scripts/helmcharts/openreplay/Chart.yaml +++ b/scripts/helmcharts/openreplay/Chart.yaml @@ -37,3 +37,7 @@ dependencies: repository: file://charts/connector version: 0.1.1 condition: connector.enabled + - name: assist-api + repository: file://charts/assist-api + version: 0.1.1 + condition: assist-api.enabled diff --git a/scripts/helmcharts/openreplay/charts/assist-api/.helmignore b/scripts/helmcharts/openreplay/charts/assist-api/.helmignore new file mode 100644 index 000000000..0e8a0eb36 --- /dev/null +++ b/scripts/helmcharts/openreplay/charts/assist-api/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/scripts/helmcharts/openreplay/charts/assist-api/Chart.yaml b/scripts/helmcharts/openreplay/charts/assist-api/Chart.yaml new file mode 100644 index 000000000..498f81dd6 --- /dev/null +++ b/scripts/helmcharts/openreplay/charts/assist-api/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: assist-api +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rassist-apiing +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.1 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +AppVersion: "v1.22.0" diff --git a/scripts/helmcharts/openreplay/charts/assist-api/templates/NOTES.txt b/scripts/helmcharts/openreplay/charts/assist-api/templates/NOTES.txt new file mode 100644 index 000000000..f5106914d --- /dev/null +++ b/scripts/helmcharts/openreplay/charts/assist-api/templates/NOTES.txt @@ -0,0 +1,22 @@ +1. Get the application URL by running these commands: +{{- if .Values.ingress.enabled }} +{{- range $host := .Values.ingress.hosts }} + {{- range .paths }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} + {{- end }} +{{- end }} +{{- else if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "assist-api.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "assist-api.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "assist-api.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "assist-api.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT +{{- end }} diff --git a/scripts/helmcharts/openreplay/charts/assist-api/templates/_helpers.tpl b/scripts/helmcharts/openreplay/charts/assist-api/templates/_helpers.tpl new file mode 100644 index 000000000..568007bc7 --- /dev/null +++ b/scripts/helmcharts/openreplay/charts/assist-api/templates/_helpers.tpl @@ -0,0 +1,65 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "assist-api.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "assist-api.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "assist-api.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "assist-api.labels" -}} +helm.sh/chart: {{ include "assist-api.chart" . }} +{{ include "assist-api.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.global.appLabels }} +{{- .Values.global.appLabels | toYaml | nindent 0}} +{{- end}} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "assist-api.selectorLabels" -}} +app.kubernetes.io/name: {{ include "assist-api.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "assist-api.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "assist-api.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/scripts/helmcharts/openreplay/charts/assist-api/templates/deployment.yaml b/scripts/helmcharts/openreplay/charts/assist-api/templates/deployment.yaml new file mode 100644 index 000000000..232b9528f --- /dev/null +++ b/scripts/helmcharts/openreplay/charts/assist-api/templates/deployment.yaml @@ -0,0 +1,101 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "assist-api.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "assist-api.labels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "assist-api.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "assist-api.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "assist-api.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + shareProcessNamespace: true + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + {{- if .Values.global.enterpriseEditionLicense }} + image: "{{ tpl .Values.image.repository . }}:{{ .Values.image.tag | default .Chart.AppVersion }}-ee" + {{- else }} + image: "{{ tpl .Values.image.repository . }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + {{- end }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if .Values.healthCheck}} + {{- .Values.healthCheck | toYaml | nindent 10}} + {{- end}} + env: + - name: LICENSE_KEY + value: '{{ .Values.global.enterpriseEditionLicense }}' + - name: ASSIST_KEY + value: {{ .Values.global.assistKey }} + - name: pg_password + {{- if .Values.global.postgresql.existingSecret }} + valueFrom: + secretKeyRef: + name: {{ .Values.global.postgresql.existingSecret }} + key: postgresql-postgres-password + {{- else }} + value: '{{ .Values.global.postgresql.postgresqlPassword }}' + {{- end}} + - name: POSTGRES_STRING + value: 'postgres://{{ .Values.global.postgresql.postgresqlUser }}:$(pg_password)@{{ .Values.global.postgresql.postgresqlHost }}:{{ .Values.global.postgresql.postgresqlPort }}/{{ .Values.global.postgresql.postgresqlDatabase }}' + - name: REDIS_CACHE_ENABLED + value: {{ if .Values.global.enterpriseEditionLicense }}"true"{{ else }}"false"{{ end }} + {{- include "openreplay.env.redis_string" .Values.global.redis | nindent 12 }} + {{- range $key, $val := .Values.global.env }} + - name: {{ $key }} + value: '{{ $val }}' + {{- end }} + {{- range $key, $val := .Values.env }} + - name: {{ $key }} + value: '{{ $val }}' + {{- end}} + ports: + {{- range $key, $val := .Values.service.ports }} + - name: {{ $key }} + containerPort: {{ $val }} + protocol: TCP + {{- end }} + volumeMounts: + {{- include "openreplay.volume.redis_ca_certificate.mount" .Values.global.redis | nindent 12 }} + {{- with .Values.persistence.mounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.resources | nindent 12 }} + volumes: + {{- with .Values.persistence.volumes }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- include "openreplay.volume.redis_ca_certificate" .Values.global.redis | nindent 8 }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/scripts/helmcharts/openreplay/charts/assist-api/templates/hpa.yaml b/scripts/helmcharts/openreplay/charts/assist-api/templates/hpa.yaml new file mode 100644 index 000000000..04f9e7961 --- /dev/null +++ b/scripts/helmcharts/openreplay/charts/assist-api/templates/hpa.yaml @@ -0,0 +1,33 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "assist-api.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "assist-api.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "assist-api.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/scripts/helmcharts/openreplay/charts/assist-api/templates/service.yaml b/scripts/helmcharts/openreplay/charts/assist-api/templates/service.yaml new file mode 100644 index 000000000..6838d1702 --- /dev/null +++ b/scripts/helmcharts/openreplay/charts/assist-api/templates/service.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "assist-api.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "assist-api.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + {{- range $key, $val := .Values.service.ports }} + - port: {{ $val }} + targetPort: {{ $key }} + protocol: TCP + name: {{ $key }} + {{- end}} + selector: + {{- include "assist-api.selectorLabels" . | nindent 4 }} diff --git a/scripts/helmcharts/openreplay/charts/assist-api/templates/serviceMonitor.yaml b/scripts/helmcharts/openreplay/charts/assist-api/templates/serviceMonitor.yaml new file mode 100644 index 000000000..c57c21606 --- /dev/null +++ b/scripts/helmcharts/openreplay/charts/assist-api/templates/serviceMonitor.yaml @@ -0,0 +1,18 @@ +{{- if and ( .Capabilities.APIVersions.Has "monitoring.coreos.com/v1" ) ( .Values.serviceMonitor.enabled ) }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "assist-api.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "assist-api.labels" . | nindent 4 }} + {{- if .Values.serviceMonitor.additionalLabels }} + {{- toYaml .Values.serviceMonitor.additionalLabels | nindent 4 }} + {{- end }} +spec: + endpoints: + {{- .Values.serviceMonitor.scrapeConfigs | toYaml | nindent 4 }} + selector: + matchLabels: + {{- include "assist-api.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/scripts/helmcharts/openreplay/charts/assist-api/templates/serviceaccount.yaml b/scripts/helmcharts/openreplay/charts/assist-api/templates/serviceaccount.yaml new file mode 100644 index 000000000..06db808ac --- /dev/null +++ b/scripts/helmcharts/openreplay/charts/assist-api/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "assist-api.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "assist-api.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/scripts/helmcharts/openreplay/charts/assist-api/templates/tests/test-connection.yaml b/scripts/helmcharts/openreplay/charts/assist-api/templates/tests/test-connection.yaml new file mode 100644 index 000000000..57e38f294 --- /dev/null +++ b/scripts/helmcharts/openreplay/charts/assist-api/templates/tests/test-connection.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "assist-api.fullname" . }}-test-connection" + labels: + {{- include "assist-api.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "assist-api.fullname" . }}:{{ .Values.service.port }}'] + restartPolicy: Never diff --git a/scripts/helmcharts/openreplay/charts/assist-api/values.yaml b/scripts/helmcharts/openreplay/charts/assist-api/values.yaml new file mode 100644 index 000000000..f5bf928e0 --- /dev/null +++ b/scripts/helmcharts/openreplay/charts/assist-api/values.yaml @@ -0,0 +1,119 @@ +# Default values for openreplay. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +image: + repository: "{{ .Values.global.openReplayContainerRegistry }}/assist-api" + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "" + +imagePullSecrets: [] +nameOverride: "assist-api" +fullnameOverride: "assist-api-openreplay" + +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + +podAnnotations: {} + +securityContext: + runAsUser: 1001 + runAsGroup: 1001 +podSecurityContext: + runAsUser: 1001 + runAsGroup: 1001 + fsGroup: 1001 + fsGroupChangePolicy: "OnRootMismatch" + # podSecurityContext: {} + # fsGroup: 2000 + + # securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +#service: +# type: ClusterIP +# port: 9000 + +serviceMonitor: + enabled: false + additionalLabels: + release: observability + scrapeConfigs: + - port: metrics + honorLabels: true + interval: 15s + path: /metrics + scheme: http + scrapeTimeout: 10s + +service: + type: ClusterIP + ports: + http: 8080 + metrics: 8888 + +ingress: + enabled: false + className: "{{ .Values.global.ingress.controller.ingressClassResource.name }}" + annotations: + nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" + nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + tls: + secretName: openreplay-ssl + +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m +# memory: 128Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 5 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +env: + CLEAR_SOCKET_TIME: 720 + + +nodeSelector: {} + +tolerations: [] + +affinity: {} + + +persistence: {} + # # Spec of spec.template.spec.containers[*].volumeMounts + # mounts: + # - name: kafka-ssl + # mountPath: /opt/kafka/ssl + # # Spec of spec.template.spec.volumes + # volumes: + # - name: kafka-ssl + # secret: +# secretName: kafka-ssl diff --git a/scripts/helmcharts/openreplay/charts/assist/templates/deployment.yaml b/scripts/helmcharts/openreplay/charts/assist/templates/deployment.yaml index a4af9a9f8..d12498255 100644 --- a/scripts/helmcharts/openreplay/charts/assist/templates/deployment.yaml +++ b/scripts/helmcharts/openreplay/charts/assist/templates/deployment.yaml @@ -49,32 +49,18 @@ spec: value: {{ .Values.global.assistKey }} - name: AWS_DEFAULT_REGION value: "{{ .Values.global.s3.region }}" - - name: S3_HOST - {{- if contains "minio" .Values.global.s3.endpoint }} - value: '{{ ternary "https" "http" .Values.global.ORSecureAccess}}://{{ .Values.global.domainName }}:{{ ternary .Values.global.ingress.controller.service.ports.https .Values.global.ingress.controller.service.ports.http .Values.global.ORSecureAccess }}' - {{- else}} - value: '{{ .Values.global.s3.endpoint }}' - {{- end}} - - name: S3_KEY - {{- if .Values.global.s3.existingSecret }} - valueFrom: - secretKeyRef: - name: {{ .Values.global.s3.existingSecret }} - key: access-key - {{- else }} - value: {{ .Values.global.s3.accessKey }} - {{- end }} - - name: S3_SECRET - {{- if .Values.global.s3.existingSecret }} - valueFrom: - secretKeyRef: - name: {{ .Values.global.s3.existingSecret }} - key: secret-key - {{- else }} - value: {{ .Values.global.s3.secretKey }} - {{- end }} - name: REDIS_URL - value: {{ .Values.global.redis.redisHost }} + value: {{ default .Values.global.redis.redisHost .Values.redisHost }} + {{- if .Values.global.enterpriseEditionLicense }} + - name: COMPRESSION + value: "true" + - name: port + value: "9000" + - name: CACHE_REFRESH_INTERVAL_SECONDS + value: '5' + - name: debug + value: '0' + {{- end}} {{- range $key, $val := .Values.global.env }} - name: {{ $key }} value: '{{ $val }}' diff --git a/scripts/helmcharts/openreplay/charts/assist/templates/ingress.yaml b/scripts/helmcharts/openreplay/charts/assist/templates/ingress.yaml index 41436c679..df355cefe 100644 --- a/scripts/helmcharts/openreplay/charts/assist/templates/ingress.yaml +++ b/scripts/helmcharts/openreplay/charts/assist/templates/ingress.yaml @@ -10,25 +10,6 @@ metadata: {{- include "assist.labels" . | nindent 4 }} annotations: nginx.ingress.kubernetes.io/rewrite-target: /$1 - nginx.ingress.kubernetes.io/configuration-snippet: | - #set $sticky_used "no"; - #if ($sessionid != "") { - # set $sticky_used "yes"; - #} - - #add_header X-Debug-Session-ID $sessionid; - #add_header X-Debug-Session-Type "wss"; - #add_header X-Sticky-Session-Used $sticky_used; - #add_header X-Upstream-Server $upstream_addr; - - proxy_hide_header access-control-allow-headers; - proxy_hide_header Access-Control-Allow-Origin; - add_header 'Access-Control-Allow-Origin' $http_origin always; - add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS' always; - add_header 'Access-Control-Allow-Headers' 'sessionid, Content-Type, Authorization' always; - add_header 'Access-Control-Max-Age' 1728000; - add_header 'Content-Type' 'text/plain charset=UTF-8'; - nginx.ingress.kubernetes.io/upstream-hash-by: $sessionid {{- with .Values.ingress.annotations }} diff --git a/scripts/helmcharts/openreplay/charts/chalice/templates/deployment.yaml b/scripts/helmcharts/openreplay/charts/chalice/templates/deployment.yaml index 3d86796a7..a18256e30 100644 --- a/scripts/helmcharts/openreplay/charts/chalice/templates/deployment.yaml +++ b/scripts/helmcharts/openreplay/charts/chalice/templates/deployment.yaml @@ -59,7 +59,7 @@ spec: - name: sourcemaps_reader value: "http://sourcemapreader-openreplay.{{.Release.Namespace}}.{{.Values.global.clusterDomain}}:9000/%s/sourcemaps" - name: ASSIST_URL - value: "http://assist-openreplay.{{.Release.Namespace}}.{{.Values.global.clusterDomain}}:9001/assist/%s" + value: {{ include "openreplay.assist_url" . }} - name: ASSIST_JWT_SECRET value: {{ .Values.global.assistJWTSecret }} - name: JWT_SECRET diff --git a/scripts/helmcharts/openreplay/templates/_helpers.tpl b/scripts/helmcharts/openreplay/templates/_helpers.tpl index e239d2f8f..82419631f 100644 --- a/scripts/helmcharts/openreplay/templates/_helpers.tpl +++ b/scripts/helmcharts/openreplay/templates/_helpers.tpl @@ -161,3 +161,11 @@ Create the volume mount config for redis TLS certificates {{- printf "postgres://%s:$(pg_password)@%s:%s/%s" .Values.global.postgresql.postgresqlUser .Values.global.postgresql.postgresqlHost .Values.global.postgresql.postgresqlPort .Values.global.postgresql.postgresqlDatabase -}} {{- end -}} {{- end}} + +{{- define "openreplay.assist_url"}} +{{- if .Values.global.enterpriseEditionLicense }} +{{- printf "http://assist-api-openreplay.%s.%s:9001/assist/%%s" .Release.Namespace .Values.global.clusterDomain }} +{{- else}} +{{- printf "http://assist-openreplay.%s.%s:9001/assist/%%s" .Release.Namespace .Values.global.clusterDomain }} +{{- end}} +{{- end}} diff --git a/scripts/helmcharts/openreplay/values.yaml b/scripts/helmcharts/openreplay/values.yaml index 8be97a2dc..627db73c6 100644 --- a/scripts/helmcharts/openreplay/values.yaml +++ b/scripts/helmcharts/openreplay/values.yaml @@ -47,6 +47,8 @@ vault: &vault {{- with secret "database/creds/db-app" -}} POSTGRES_STRING=postgres://{{.Data.username}}:{{.Data.password}}@postgresql.db.svc.cluster.local:5432/postgres {{- end -}} +assist-api: + enabled: false minio: # Force initialize minio, even if the instance is not provisioned by OR diff --git a/scripts/schema/db/init_dbs/clickhouse/1.22.0/1.22.0.sql b/scripts/schema/db/init_dbs/clickhouse/1.22.0/1.22.0.sql index 279c9517e..41e214db0 100644 --- a/scripts/schema/db/init_dbs/clickhouse/1.22.0/1.22.0.sql +++ b/scripts/schema/db/init_dbs/clickhouse/1.22.0/1.22.0.sql @@ -106,7 +106,7 @@ CREATE TABLE IF NOT EXISTS experimental.sessions user_country Enum8('UN'=-128, 'RW'=-127, 'SO'=-126, 'YE'=-125, 'IQ'=-124, 'SA'=-123, 'IR'=-122, 'CY'=-121, 'TZ'=-120, 'SY'=-119, 'AM'=-118, 'KE'=-117, 'CD'=-116, 'DJ'=-115, 'UG'=-114, 'CF'=-113, 'SC'=-112, 'JO'=-111, 'LB'=-110, 'KW'=-109, 'OM'=-108, 'QA'=-107, 'BH'=-106, 'AE'=-105, 'IL'=-104, 'TR'=-103, 'ET'=-102, 'ER'=-101, 'EG'=-100, 'SD'=-99, 'GR'=-98, 'BI'=-97, 'EE'=-96, 'LV'=-95, 'AZ'=-94, 'LT'=-93, 'SJ'=-92, 'GE'=-91, 'MD'=-90, 'BY'=-89, 'FI'=-88, 'AX'=-87, 'UA'=-86, 'MK'=-85, 'HU'=-84, 'BG'=-83, 'AL'=-82, 'PL'=-81, 'RO'=-80, 'XK'=-79, 'ZW'=-78, 'ZM'=-77, 'KM'=-76, 'MW'=-75, 'LS'=-74, 'BW'=-73, 'MU'=-72, 'SZ'=-71, 'RE'=-70, 'ZA'=-69, 'YT'=-68, 'MZ'=-67, 'MG'=-66, 'AF'=-65, 'PK'=-64, 'BD'=-63, 'TM'=-62, 'TJ'=-61, 'LK'=-60, 'BT'=-59, 'IN'=-58, 'MV'=-57, 'IO'=-56, 'NP'=-55, 'MM'=-54, 'UZ'=-53, 'KZ'=-52, 'KG'=-51, 'TF'=-50, 'HM'=-49, 'CC'=-48, 'PW'=-47, 'VN'=-46, 'TH'=-45, 'ID'=-44, 'LA'=-43, 'TW'=-42, 'PH'=-41, 'MY'=-40, 'CN'=-39, 'HK'=-38, 'BN'=-37, 'MO'=-36, 'KH'=-35, 'KR'=-34, 'JP'=-33, 'KP'=-32, 'SG'=-31, 'CK'=-30, 'TL'=-29, 'RU'=-28, 'MN'=-27, 'AU'=-26, 'CX'=-25, 'MH'=-24, 'FM'=-23, 'PG'=-22, 'SB'=-21, 'TV'=-20, 'NR'=-19, 'VU'=-18, 'NC'=-17, 'NF'=-16, 'NZ'=-15, 'FJ'=-14, 'LY'=-13, 'CM'=-12, 'SN'=-11, 'CG'=-10, 'PT'=-9, 'LR'=-8, 'CI'=-7, 'GH'=-6, 'GQ'=-5, 'NG'=-4, 'BF'=-3, 'TG'=-2, 'GW'=-1, 'MR'=0, 'BJ'=1, 'GA'=2, 'SL'=3, 'ST'=4, 'GI'=5, 'GM'=6, 'GN'=7, 'TD'=8, 'NE'=9, 'ML'=10, 'EH'=11, 'TN'=12, 'ES'=13, 'MA'=14, 'MT'=15, 'DZ'=16, 'FO'=17, 'DK'=18, 'IS'=19, 'GB'=20, 'CH'=21, 'SE'=22, 'NL'=23, 'AT'=24, 'BE'=25, 'DE'=26, 'LU'=27, 'IE'=28, 'MC'=29, 'FR'=30, 'AD'=31, 'LI'=32, 'JE'=33, 'IM'=34, 'GG'=35, 'SK'=36, 'CZ'=37, 'NO'=38, 'VA'=39, 'SM'=40, 'IT'=41, 'SI'=42, 'ME'=43, 'HR'=44, 'BA'=45, 'AO'=46, 'NA'=47, 'SH'=48, 'BV'=49, 'BB'=50, 'CV'=51, 'GY'=52, 'GF'=53, 'SR'=54, 'PM'=55, 'GL'=56, 'PY'=57, 'UY'=58, 'BR'=59, 'FK'=60, 'GS'=61, 'JM'=62, 'DO'=63, 'CU'=64, 'MQ'=65, 'BS'=66, 'BM'=67, 'AI'=68, 'TT'=69, 'KN'=70, 'DM'=71, 'AG'=72, 'LC'=73, 'TC'=74, 'AW'=75, 'VG'=76, 'VC'=77, 'MS'=78, 'MF'=79, 'BL'=80, 'GP'=81, 'GD'=82, 'KY'=83, 'BZ'=84, 'SV'=85, 'GT'=86, 'HN'=87, 'NI'=88, 'CR'=89, 'VE'=90, 'EC'=91, 'CO'=92, 'PA'=93, 'HT'=94, 'AR'=95, 'CL'=96, 'BO'=97, 'PE'=98, 'MX'=99, 'PF'=100, 'PN'=101, 'KI'=102, 'TK'=103, 'TO'=104, 'WF'=105, 'WS'=106, 'NU'=107, 'MP'=108, 'GU'=109, 'PR'=110, 'VI'=111, 'UM'=112, 'AS'=113, 'CA'=114, 'US'=115, 'PS'=116, 'RS'=117, 'AQ'=118, 'SX'=119, 'CW'=120, 'BQ'=121, 'SS'=122,'BU'=123, 'VD'=124, 'YD'=125, 'DD'=126), user_city LowCardinality(String), user_state LowCardinality(String), - platform Enum8('web'=1,'ios'=2,'android'=3) DEFAULT 'web', + platform Enum8('web'=1,'mobile'=2) DEFAULT 'web', datetime DateTime, timezone LowCardinality(Nullable(String)), duration UInt32, diff --git a/scripts/schema/db/init_dbs/clickhouse/1.23.0/1.23.0.sql b/scripts/schema/db/init_dbs/clickhouse/1.23.0/1.23.0.sql index d8472807d..02e75fd53 100644 --- a/scripts/schema/db/init_dbs/clickhouse/1.23.0/1.23.0.sql +++ b/scripts/schema/db/init_dbs/clickhouse/1.23.0/1.23.0.sql @@ -1,3 +1,16 @@ +SELECT 1 +FROM (SELECT throwIf(platform = 'ios', 'IOS sessions found') + FROM experimental.sessions) AS raw +LIMIT 1; + +SELECT 1 +FROM (SELECT throwIf(platform = 'android', 'Android sessions found') + FROM experimental.sessions) AS raw +LIMIT 1; + +ALTER TABLE experimental.sessions + MODIFY COLUMN platform Enum8('web'=1,'mobile'=2) DEFAULT 'web'; + CREATE OR REPLACE FUNCTION openreplay_version AS() -> 'v1.23.0'; @@ -52,26 +65,27 @@ CREATE TABLE IF NOT EXISTS product_analytics.event_properties event_name String, property_name String, value_type String, + auto_captured BOOL, _timestamp DateTime DEFAULT now() ) ENGINE = ReplacingMergeTree(_timestamp) - ORDER BY (project_id, event_name, property_name, value_type); + ORDER BY (project_id, event_name, property_name, value_type, auto_captured); CREATE MATERIALIZED VIEW IF NOT EXISTS product_analytics.event_properties_extractor_mv TO product_analytics.event_properties AS SELECT project_id, `$event_name` AS event_name, property_name, - JSONType(JSONExtractRaw(toString(`$properties`), property_name)) AS value_type + toString(JSONType(JSONExtractRaw(toString(`$properties`), property_name))) AS value_type, + `$auto_captured` AS auto_captured FROM product_analytics.events - ARRAY JOIN JSONExtractKeys(toString(`$properties`)) as property_name; - -CREATE MATERIALIZED VIEW IF NOT EXISTS product_analytics.event_cproperties_extractor - TO product_analytics.event_properties AS + ARRAY JOIN JSONExtractKeys(toString(`$properties`)) as property_name +UNION DISTINCT SELECT project_id, `$event_name` AS event_name, property_name, - JSONType(JSONExtractRaw(toString(`properties`), property_name)) AS value_type + toString(JSONType(JSONExtractRaw(toString(`properties`), property_name))) AS value_type, + `$auto_captured` AS auto_captured FROM product_analytics.events ARRAY JOIN JSONExtractKeys(toString(`properties`)) as property_name; @@ -116,10 +130,8 @@ FROM product_analytics.events WHERE (all_properties.display_name != '' OR all_properties.description != '') AND is_event_property) AS old_data - ON (events.project_id = old_data.project_id AND property_name = old_data.property_name); - -CREATE MATERIALIZED VIEW IF NOT EXISTS product_analytics.all_cproperties_extractor_mv - TO product_analytics.all_properties AS + ON (events.project_id = old_data.project_id AND property_name = old_data.property_name) +UNION DISTINCT SELECT project_id, property_name, TRUE AS is_event_property, @@ -166,7 +178,7 @@ FROM product_analytics.events WHERE randCanonical() < 0.5 -- This randomly skips inserts AND value != '' LIMIT 2 BY project_id,property_name -UNION ALL +UNION DISTINCT SELECT project_id, property_name, TRUE AS is_event_property, @@ -237,6 +249,16 @@ SELECT project_id, _timestamp FROM product_analytics.events ARRAY JOIN JSONExtractKeys(toString(`$properties`)) as property_name +WHERE length(value) > 0 AND isNull(toFloat64OrNull(value)) + AND _timestamp > now() - INTERVAL 1 MONTH +UNION DISTINCT +SELECT project_id, + `$event_name` AS event_name, + property_name, + JSONExtractString(toString(`properties`), property_name) AS value, + _timestamp +FROM product_analytics.events + ARRAY JOIN JSONExtractKeys(toString(`properties`)) as property_name WHERE length(value) > 0 AND isNull(toFloat64OrNull(value)) AND _timestamp > now() - INTERVAL 1 MONTH; diff --git a/scripts/schema/db/init_dbs/clickhouse/create/init_schema.sql b/scripts/schema/db/init_dbs/clickhouse/create/init_schema.sql index b9cb4b173..fb55b5805 100644 --- a/scripts/schema/db/init_dbs/clickhouse/create/init_schema.sql +++ b/scripts/schema/db/init_dbs/clickhouse/create/init_schema.sql @@ -106,7 +106,7 @@ CREATE TABLE IF NOT EXISTS experimental.sessions user_country Enum8('UN'=-128, 'RW'=-127, 'SO'=-126, 'YE'=-125, 'IQ'=-124, 'SA'=-123, 'IR'=-122, 'CY'=-121, 'TZ'=-120, 'SY'=-119, 'AM'=-118, 'KE'=-117, 'CD'=-116, 'DJ'=-115, 'UG'=-114, 'CF'=-113, 'SC'=-112, 'JO'=-111, 'LB'=-110, 'KW'=-109, 'OM'=-108, 'QA'=-107, 'BH'=-106, 'AE'=-105, 'IL'=-104, 'TR'=-103, 'ET'=-102, 'ER'=-101, 'EG'=-100, 'SD'=-99, 'GR'=-98, 'BI'=-97, 'EE'=-96, 'LV'=-95, 'AZ'=-94, 'LT'=-93, 'SJ'=-92, 'GE'=-91, 'MD'=-90, 'BY'=-89, 'FI'=-88, 'AX'=-87, 'UA'=-86, 'MK'=-85, 'HU'=-84, 'BG'=-83, 'AL'=-82, 'PL'=-81, 'RO'=-80, 'XK'=-79, 'ZW'=-78, 'ZM'=-77, 'KM'=-76, 'MW'=-75, 'LS'=-74, 'BW'=-73, 'MU'=-72, 'SZ'=-71, 'RE'=-70, 'ZA'=-69, 'YT'=-68, 'MZ'=-67, 'MG'=-66, 'AF'=-65, 'PK'=-64, 'BD'=-63, 'TM'=-62, 'TJ'=-61, 'LK'=-60, 'BT'=-59, 'IN'=-58, 'MV'=-57, 'IO'=-56, 'NP'=-55, 'MM'=-54, 'UZ'=-53, 'KZ'=-52, 'KG'=-51, 'TF'=-50, 'HM'=-49, 'CC'=-48, 'PW'=-47, 'VN'=-46, 'TH'=-45, 'ID'=-44, 'LA'=-43, 'TW'=-42, 'PH'=-41, 'MY'=-40, 'CN'=-39, 'HK'=-38, 'BN'=-37, 'MO'=-36, 'KH'=-35, 'KR'=-34, 'JP'=-33, 'KP'=-32, 'SG'=-31, 'CK'=-30, 'TL'=-29, 'RU'=-28, 'MN'=-27, 'AU'=-26, 'CX'=-25, 'MH'=-24, 'FM'=-23, 'PG'=-22, 'SB'=-21, 'TV'=-20, 'NR'=-19, 'VU'=-18, 'NC'=-17, 'NF'=-16, 'NZ'=-15, 'FJ'=-14, 'LY'=-13, 'CM'=-12, 'SN'=-11, 'CG'=-10, 'PT'=-9, 'LR'=-8, 'CI'=-7, 'GH'=-6, 'GQ'=-5, 'NG'=-4, 'BF'=-3, 'TG'=-2, 'GW'=-1, 'MR'=0, 'BJ'=1, 'GA'=2, 'SL'=3, 'ST'=4, 'GI'=5, 'GM'=6, 'GN'=7, 'TD'=8, 'NE'=9, 'ML'=10, 'EH'=11, 'TN'=12, 'ES'=13, 'MA'=14, 'MT'=15, 'DZ'=16, 'FO'=17, 'DK'=18, 'IS'=19, 'GB'=20, 'CH'=21, 'SE'=22, 'NL'=23, 'AT'=24, 'BE'=25, 'DE'=26, 'LU'=27, 'IE'=28, 'MC'=29, 'FR'=30, 'AD'=31, 'LI'=32, 'JE'=33, 'IM'=34, 'GG'=35, 'SK'=36, 'CZ'=37, 'NO'=38, 'VA'=39, 'SM'=40, 'IT'=41, 'SI'=42, 'ME'=43, 'HR'=44, 'BA'=45, 'AO'=46, 'NA'=47, 'SH'=48, 'BV'=49, 'BB'=50, 'CV'=51, 'GY'=52, 'GF'=53, 'SR'=54, 'PM'=55, 'GL'=56, 'PY'=57, 'UY'=58, 'BR'=59, 'FK'=60, 'GS'=61, 'JM'=62, 'DO'=63, 'CU'=64, 'MQ'=65, 'BS'=66, 'BM'=67, 'AI'=68, 'TT'=69, 'KN'=70, 'DM'=71, 'AG'=72, 'LC'=73, 'TC'=74, 'AW'=75, 'VG'=76, 'VC'=77, 'MS'=78, 'MF'=79, 'BL'=80, 'GP'=81, 'GD'=82, 'KY'=83, 'BZ'=84, 'SV'=85, 'GT'=86, 'HN'=87, 'NI'=88, 'CR'=89, 'VE'=90, 'EC'=91, 'CO'=92, 'PA'=93, 'HT'=94, 'AR'=95, 'CL'=96, 'BO'=97, 'PE'=98, 'MX'=99, 'PF'=100, 'PN'=101, 'KI'=102, 'TK'=103, 'TO'=104, 'WF'=105, 'WS'=106, 'NU'=107, 'MP'=108, 'GU'=109, 'PR'=110, 'VI'=111, 'UM'=112, 'AS'=113, 'CA'=114, 'US'=115, 'PS'=116, 'RS'=117, 'AQ'=118, 'SX'=119, 'CW'=120, 'BQ'=121, 'SS'=122,'BU'=123, 'VD'=124, 'YD'=125, 'DD'=126), user_city LowCardinality(String), user_state LowCardinality(String), - platform Enum8('web'=1,'ios'=2,'android'=3) DEFAULT 'web', + platform Enum8('web'=1,'mobile'=2) DEFAULT 'web', datetime DateTime, timezone LowCardinality(Nullable(String)), duration UInt32, @@ -222,6 +222,7 @@ CREATE TABLE IF NOT EXISTS experimental.ios_events SET allow_experimental_json_type = 1; +SET enable_json_type = 1; CREATE DATABASE IF NOT EXISTS product_analytics; @@ -572,29 +573,29 @@ CREATE TABLE IF NOT EXISTS product_analytics.event_properties event_name String, property_name String, value_type String, + auto_captured BOOL, _timestamp DateTime DEFAULT now() ) ENGINE = ReplacingMergeTree(_timestamp) - ORDER BY (project_id, event_name, property_name, value_type); + ORDER BY (project_id, event_name, property_name, value_type, auto_captured); -- ----------------- This is experimental, if it doesn't work, we need to do it in db worker ------------- --- Incremental materialized view to fill event_properties using $properties +-- Incremental materialized view to fill event_properties using $properties & properties CREATE MATERIALIZED VIEW IF NOT EXISTS product_analytics.event_properties_extractor_mv TO product_analytics.event_properties AS SELECT project_id, `$event_name` AS event_name, property_name, - JSONType(JSONExtractRaw(toString(`$properties`), property_name)) AS value_type + toString(JSONType(JSONExtractRaw(toString(`$properties`), property_name))) AS value_type, + `$auto_captured` AS auto_captured FROM product_analytics.events - ARRAY JOIN JSONExtractKeys(toString(`$properties`)) as property_name; - --- Incremental materialized view to fill event_properties using properties -CREATE MATERIALIZED VIEW IF NOT EXISTS product_analytics.event_cproperties_extractor - TO product_analytics.event_properties AS + ARRAY JOIN JSONExtractKeys(toString(`$properties`)) as property_name +UNION DISTINCT SELECT project_id, `$event_name` AS event_name, property_name, - JSONType(JSONExtractRaw(toString(`properties`), property_name)) AS value_type + toString(JSONType(JSONExtractRaw(toString(`properties`), property_name))) AS value_type, + `$auto_captured` AS auto_captured FROM product_analytics.events ARRAY JOIN JSONExtractKeys(toString(`properties`)) as property_name; -- -------- END --------- @@ -620,7 +621,7 @@ CREATE TABLE IF NOT EXISTS product_analytics.all_properties -- ----------------- This is experimental, if it doesn't work, we need to do it in db worker ------------- --- Incremental materialized view to fill all_properties using $properties +-- Incremental materialized view to fill all_properties using $properties and properties CREATE MATERIALIZED VIEW IF NOT EXISTS product_analytics.all_properties_extractor_mv TO product_analytics.all_properties AS SELECT project_id, @@ -644,11 +645,8 @@ FROM product_analytics.events WHERE (all_properties.display_name != '' OR all_properties.description != '') AND is_event_property) AS old_data - ON (events.project_id = old_data.project_id AND property_name = old_data.property_name); - --- Incremental materialized view to fill all_properties using properties -CREATE MATERIALIZED VIEW IF NOT EXISTS product_analytics.all_cproperties_extractor_mv - TO product_analytics.all_properties AS + ON (events.project_id = old_data.project_id AND property_name = old_data.property_name) +UNION DISTINCT SELECT project_id, property_name, TRUE AS is_event_property, @@ -698,7 +696,7 @@ FROM product_analytics.events WHERE randCanonical() < 0.5 -- This randomly skips inserts AND value != '' LIMIT 2 BY project_id,property_name -UNION ALL +UNION DISTINCT -- using union because each table should be the target of 1 single refreshable MV SELECT project_id, property_name, @@ -769,6 +767,16 @@ SELECT project_id, _timestamp FROM product_analytics.events ARRAY JOIN JSONExtractKeys(toString(`$properties`)) as property_name +WHERE length(value) > 0 AND isNull(toFloat64OrNull(value)) + AND _timestamp > now() - INTERVAL 1 MONTH +UNION DISTINCT +SELECT project_id, + `$event_name` AS event_name, + property_name, + JSONExtractString(toString(`properties`), property_name) AS value, + _timestamp +FROM product_analytics.events + ARRAY JOIN JSONExtractKeys(toString(`properties`)) as property_name WHERE length(value) > 0 AND isNull(toFloat64OrNull(value)) AND _timestamp > now() - INTERVAL 1 MONTH; @@ -797,4 +805,3 @@ FROM product_analytics.autocomplete_event_properties WHERE length(value) > 0 AND autocomplete_event_properties._timestamp > now() - INTERVAL 1 MONTH GROUP BY project_id, event_name, property_name, value; - diff --git a/scripts/schema/db/init_dbs/postgresql/1.23.0/1.23.0.sql b/scripts/schema/db/init_dbs/postgresql/1.23.0/1.23.0.sql index 8003f6753..36f9e8d6d 100644 --- a/scripts/schema/db/init_dbs/postgresql/1.23.0/1.23.0.sql +++ b/scripts/schema/db/init_dbs/postgresql/1.23.0/1.23.0.sql @@ -23,6 +23,8 @@ DROP SCHEMA IF EXISTS or_cache CASCADE; ALTER TABLE public.tenants ALTER COLUMN scope_state SET DEFAULT 2; +ALTER TYPE issue_type ADD VALUE IF NOT EXISTS 'incident'; + COMMIT; \elif :is_next diff --git a/scripts/schema/db/init_dbs/postgresql/init_schema.sql b/scripts/schema/db/init_dbs/postgresql/init_schema.sql index 7c6eb396e..2df44883a 100644 --- a/scripts/schema/db/init_dbs/postgresql/init_schema.sql +++ b/scripts/schema/db/init_dbs/postgresql/init_schema.sql @@ -314,7 +314,8 @@ CREATE TYPE issue_type AS ENUM ( 'custom', 'js_exception', 'mouse_thrashing', - 'app_crash' + 'app_crash', + 'incident' ); CREATE TABLE public.issues diff --git a/spot/assets/main.css b/spot/assets/main.css index bd6213e1d..7184c49c7 100644 --- a/spot/assets/main.css +++ b/spot/assets/main.css @@ -1,3 +1,4 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; \ No newline at end of file +@import "tailwindcss"; +@plugin "daisyui" { + themes: light --default; +} diff --git a/spot/bun.lock b/spot/bun.lock new file mode 100644 index 000000000..3b5080844 --- /dev/null +++ b/spot/bun.lock @@ -0,0 +1,1500 @@ +{ + "lockfileVersion": 1, + "workspaces": { + "": { + "name": "wxt-starter", + "dependencies": { + "@neodrag/solid": "^2.3.0", + "@openreplay/network-proxy": "^1.1.0", + "@tailwindcss/postcss": "^4.1.7", + "@tailwindcss/vite": "^4.1.7", + "@thedutchcoder/postcss-rem-to-px": "^0.0.2", + "autoprefixer": "^10.4.21", + "postcss": "^8.5.3", + "prettier": "^3.5.3", + "solid-js": "^1.9.7", + "tailwindcss": "4.1.7", + "web-vitals": "^4.2.4", + }, + "devDependencies": { + "@wxt-dev/module-solid": "^1.1.3", + "daisyui": "5.0.37", + "typescript": "^5.8.2", + "wxt": "0.20.6", + }, + }, + }, + "packages": { + "@1natsu/wait-element": ["@1natsu/wait-element@4.1.2", "", { "dependencies": { "defu": "^6.1.4", "many-keys-map": "^2.0.1" } }, "sha512-qWxSJD+Q5b8bKOvESFifvfZ92DuMsY+03SBNjTO34ipJLP6mZ9yK4bQz/vlh48aEQXoJfaZBqUwKL5BdI5iiWw=="], + + "@aklinker1/rollup-plugin-visualizer": ["@aklinker1/rollup-plugin-visualizer@5.12.0", "", { "dependencies": { "open": "^8.4.0", "picomatch": "^2.3.1", "source-map": "^0.7.4", "yargs": "^17.5.1" }, "peerDependencies": { "rollup": "2.x || 3.x || 4.x" }, "bin": { "rollup-plugin-visualizer": "dist/bin/cli.js" } }, "sha512-X24LvEGw6UFmy0lpGJDmXsMyBD58XmX1bbwsaMLhNoM+UMQfQ3b2RtC+nz4b/NoRK5r6QJSKJHBNVeUdwqybaQ=="], + + "@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="], + + "@ampproject/remapping": ["@ampproject/remapping@2.3.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw=="], + + "@babel/code-frame": ["@babel/code-frame@7.24.7", "", { "dependencies": { "@babel/highlight": "^7.24.7", "picocolors": "^1.0.0" } }, "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA=="], + + "@babel/compat-data": ["@babel/compat-data@7.25.4", "", {}, "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ=="], + + "@babel/core": ["@babel/core@7.25.2", "", { "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.24.7", "@babel/generator": "^7.25.0", "@babel/helper-compilation-targets": "^7.25.2", "@babel/helper-module-transforms": "^7.25.2", "@babel/helpers": "^7.25.0", "@babel/parser": "^7.25.0", "@babel/template": "^7.25.0", "@babel/traverse": "^7.25.2", "@babel/types": "^7.25.2", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA=="], + + "@babel/generator": ["@babel/generator@7.25.5", "", { "dependencies": { "@babel/types": "^7.25.4", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" } }, "sha512-abd43wyLfbWoxC6ahM8xTkqLpGB2iWBVyuKC9/srhFunCd1SDNrV1s72bBpK4hLj8KLzHBBcOblvLQZBNw9r3w=="], + + "@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.25.2", "", { "dependencies": { "@babel/compat-data": "^7.25.2", "@babel/helper-validator-option": "^7.24.8", "browserslist": "^4.23.1", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw=="], + + "@babel/helper-module-imports": ["@babel/helper-module-imports@7.24.7", "", { "dependencies": { "@babel/traverse": "^7.24.7", "@babel/types": "^7.24.7" } }, "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA=="], + + "@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.25.2", "", { "dependencies": { "@babel/helper-module-imports": "^7.24.7", "@babel/helper-simple-access": "^7.24.7", "@babel/helper-validator-identifier": "^7.24.7", "@babel/traverse": "^7.25.2" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ=="], + + "@babel/helper-plugin-utils": ["@babel/helper-plugin-utils@7.24.8", "", {}, "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg=="], + + "@babel/helper-simple-access": ["@babel/helper-simple-access@7.24.7", "", { "dependencies": { "@babel/traverse": "^7.24.7", "@babel/types": "^7.24.7" } }, "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg=="], + + "@babel/helper-string-parser": ["@babel/helper-string-parser@7.24.8", "", {}, "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ=="], + + "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.24.7", "", {}, "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w=="], + + "@babel/helper-validator-option": ["@babel/helper-validator-option@7.24.8", "", {}, "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q=="], + + "@babel/helpers": ["@babel/helpers@7.25.0", "", { "dependencies": { "@babel/template": "^7.25.0", "@babel/types": "^7.25.0" } }, "sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw=="], + + "@babel/highlight": ["@babel/highlight@7.24.7", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" } }, "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw=="], + + "@babel/parser": ["@babel/parser@7.25.4", "", { "dependencies": { "@babel/types": "^7.25.4" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-nq+eWrOgdtu3jG5Os4TQP3x3cLA8hR8TvJNjD8vnPa20WGycimcparWnLK4jJhElTK6SDyuJo1weMKO/5LpmLA=="], + + "@babel/plugin-syntax-jsx": ["@babel/plugin-syntax-jsx@7.24.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.24.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ=="], + + "@babel/runtime": ["@babel/runtime@7.27.0", "", { "dependencies": { "regenerator-runtime": "^0.14.0" } }, "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw=="], + + "@babel/template": ["@babel/template@7.25.0", "", { "dependencies": { "@babel/code-frame": "^7.24.7", "@babel/parser": "^7.25.0", "@babel/types": "^7.25.0" } }, "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q=="], + + "@babel/traverse": ["@babel/traverse@7.25.4", "", { "dependencies": { "@babel/code-frame": "^7.24.7", "@babel/generator": "^7.25.4", "@babel/parser": "^7.25.4", "@babel/template": "^7.25.0", "@babel/types": "^7.25.4", "debug": "^4.3.1", "globals": "^11.1.0" } }, "sha512-VJ4XsrD+nOvlXyLzmLzUs/0qjFS4sK30te5yEFlvbbUNEgKaVb2BHZUpAL+ttLPQAHNrsI3zZisbfha5Cvr8vg=="], + + "@babel/types": ["@babel/types@7.25.4", "", { "dependencies": { "@babel/helper-string-parser": "^7.24.8", "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" } }, "sha512-zQ1ijeeCXVEh+aNL0RlmkPkG8HUiDcU2pzQQFjtbntgAczRASFzj4H+6+bV+dy1ntKR14I/DypeuRG1uma98iQ=="], + + "@devicefarmer/adbkit": ["@devicefarmer/adbkit@3.3.8", "", { "dependencies": { "@devicefarmer/adbkit-logcat": "^2.1.2", "@devicefarmer/adbkit-monkey": "~1.2.1", "bluebird": "~3.7", "commander": "^9.1.0", "debug": "~4.3.1", "node-forge": "^1.3.1", "split": "~1.0.1" }, "bin": { "adbkit": "bin/adbkit" } }, "sha512-7rBLLzWQnBwutH2WZ0EWUkQdihqrnLYCUMaB44hSol9e0/cdIhuNFcqZO0xNheAU6qqHVA8sMiLofkYTgb+lmw=="], + + "@devicefarmer/adbkit-logcat": ["@devicefarmer/adbkit-logcat@2.1.3", "", {}, "sha512-yeaGFjNBc/6+svbDeul1tNHtNChw6h8pSHAt5D+JsedUrMTN7tla7B15WLDyekxsuS2XlZHRxpuC6m92wiwCNw=="], + + "@devicefarmer/adbkit-monkey": ["@devicefarmer/adbkit-monkey@1.2.1", "", {}, "sha512-ZzZY/b66W2Jd6NHbAhLyDWOEIBWC11VizGFk7Wx7M61JZRz7HR9Cq5P+65RKWUU7u6wgsE8Lmh9nE4Mz+U2eTg=="], + + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.4", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q=="], + + "@esbuild/android-arm": ["@esbuild/android-arm@0.25.4", "", { "os": "android", "cpu": "arm" }, "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ=="], + + "@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.4", "", { "os": "android", "cpu": "arm64" }, "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A=="], + + "@esbuild/android-x64": ["@esbuild/android-x64@0.25.4", "", { "os": "android", "cpu": "x64" }, "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ=="], + + "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g=="], + + "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A=="], + + "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.4", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ=="], + + "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.4", "", { "os": "freebsd", "cpu": "x64" }, "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ=="], + + "@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.4", "", { "os": "linux", "cpu": "arm" }, "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ=="], + + "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ=="], + + "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.4", "", { "os": "linux", "cpu": "ia32" }, "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ=="], + + "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.4", "", { "os": "linux", "cpu": "none" }, "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA=="], + + "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.4", "", { "os": "linux", "cpu": "none" }, "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg=="], + + "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag=="], + + "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.4", "", { "os": "linux", "cpu": "none" }, "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA=="], + + "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g=="], + + "@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.4", "", { "os": "linux", "cpu": "x64" }, "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA=="], + + "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.4", "", { "os": "none", "cpu": "arm64" }, "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ=="], + + "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.4", "", { "os": "none", "cpu": "x64" }, "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw=="], + + "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.4", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A=="], + + "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.4", "", { "os": "openbsd", "cpu": "x64" }, "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw=="], + + "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.4", "", { "os": "sunos", "cpu": "x64" }, "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q=="], + + "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ=="], + + "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.4", "", { "os": "win32", "cpu": "ia32" }, "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg=="], + + "@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.4", "", { "os": "win32", "cpu": "x64" }, "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ=="], + + "@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="], + + "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.5", "", { "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg=="], + + "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], + + "@jridgewell/set-array": ["@jridgewell/set-array@1.2.1", "", {}, "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A=="], + + "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.0", "", {}, "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="], + + "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.25", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="], + + "@neodrag/solid": ["@neodrag/solid@2.3.0", "", { "peerDependencies": { "solid-js": "^1.0.0" } }, "sha512-j6EAqCx3NbFNv3NiutPLudLmYBfcRGZoezAvODwwmMtEl4BR+i3n5PhxQCbc5rsw8Zf6AoOW7TJ3onah291v8w=="], + + "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="], + + "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="], + + "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="], + + "@openreplay/network-proxy": ["@openreplay/network-proxy@1.1.3", "", {}, "sha512-0w25xSK8Cr3y9trQKCEa7PQb2cf8m0nFbkqoxAKoyYCZTdE/e0pQ1ufcJaxzW/nYn4PVMDMmPnXcMOurCNnhvg=="], + + "@pnpm/config.env-replace": ["@pnpm/config.env-replace@1.1.0", "", {}, "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w=="], + + "@pnpm/network.ca-file": ["@pnpm/network.ca-file@1.0.2", "", { "dependencies": { "graceful-fs": "4.2.10" } }, "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA=="], + + "@pnpm/npm-conf": ["@pnpm/npm-conf@2.3.1", "", { "dependencies": { "@pnpm/config.env-replace": "^1.1.0", "@pnpm/network.ca-file": "^1.0.1", "config-chain": "^1.1.11" } }, "sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw=="], + + "@rollup/pluginutils": ["@rollup/pluginutils@5.1.4", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ=="], + + "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.21.0", "", { "os": "android", "cpu": "arm" }, "sha512-WTWD8PfoSAJ+qL87lE7votj3syLavxunWhzCnx3XFxFiI/BA/r3X7MUM8dVrH8rb2r4AiO8jJsr3ZjdaftmnfA=="], + + "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.21.0", "", { "os": "android", "cpu": "arm64" }, "sha512-a1sR2zSK1B4eYkiZu17ZUZhmUQcKjk2/j9Me2IDjk1GHW7LB5Z35LEzj9iJch6gtUfsnvZs1ZNyDW2oZSThrkA=="], + + "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.21.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-zOnKWLgDld/svhKO5PD9ozmL6roy5OQ5T4ThvdYZLpiOhEGY+dp2NwUmxK0Ld91LrbjrvtNAE0ERBwjqhZTRAA=="], + + "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.21.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-7doS8br0xAkg48SKE2QNtMSFPFUlRdw9+votl27MvT46vo44ATBmdZdGysOevNELmZlfd+NEa0UYOA8f01WSrg=="], + + "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.41.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-GSxU6r5HnWij7FoSo7cZg3l5GPg4HFLkzsFFh0N/b16q5buW1NAWuCJ+HMtIdUEi6XF0qH+hN0TEd78laRp7Dg=="], + + "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.41.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-KGiGKGDg8qLRyOWmk6IeiHJzsN/OYxO6nSbT0Vj4MwjS2XQy/5emsmtoqLAabqrohbgLWJ5GV3s/ljdrIr8Qjg=="], + + "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.21.0", "", { "os": "linux", "cpu": "arm" }, "sha512-pWJsfQjNWNGsoCq53KjMtwdJDmh/6NubwQcz52aEwLEuvx08bzcy6tOUuawAOncPnxz/3siRtd8hiQ32G1y8VA=="], + + "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.21.0", "", { "os": "linux", "cpu": "arm" }, "sha512-efRIANsz3UHZrnZXuEvxS9LoCOWMGD1rweciD6uJQIx2myN3a8Im1FafZBzh7zk1RJ6oKcR16dU3UPldaKd83w=="], + + "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.21.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-ZrPhydkTVhyeGTW94WJ8pnl1uroqVHM3j3hjdquwAcWnmivjAwOYjTEAuEDeJvGX7xv3Z9GAvrBkEzCgHq9U1w=="], + + "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.21.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-cfaupqd+UEFeURmqNP2eEvXqgbSox/LHOyN9/d2pSdV8xTrjdg3NgOFJCtc1vQ/jEke1qD0IejbBfxleBPHnPw=="], + + "@rollup/rollup-linux-loongarch64-gnu": ["@rollup/rollup-linux-loongarch64-gnu@4.41.0", "", { "os": "linux", "cpu": "none" }, "sha512-WbnJaxPv1gPIm6S8O/Wg+wfE/OzGSXlBMbOe4ie+zMyykMOeqmgD1BhPxZQuDqwUN+0T/xOFtL2RUWBspnZj3w=="], + + "@rollup/rollup-linux-powerpc64le-gnu": ["@rollup/rollup-linux-powerpc64le-gnu@4.21.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-ZKPan1/RvAhrUylwBXC9t7B2hXdpb/ufeu22pG2psV7RN8roOfGurEghw1ySmX/CmDDHNTDDjY3lo9hRlgtaHg=="], + + "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.21.0", "", { "os": "linux", "cpu": "none" }, "sha512-H1eRaCwd5E8eS8leiS+o/NqMdljkcb1d6r2h4fKSsCXQilLKArq6WS7XBLDu80Yz+nMqHVFDquwcVrQmGr28rg=="], + + "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.41.0", "", { "os": "linux", "cpu": "none" }, "sha512-ieQljaZKuJpmWvd8gW87ZmSFwid6AxMDk5bhONJ57U8zT77zpZ/TPKkU9HpnnFrM4zsgr4kiGuzbIbZTGi7u9A=="], + + "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.21.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-zJ4hA+3b5tu8u7L58CCSI0A9N1vkfwPhWd/puGXwtZlsB5bTkwDNW/+JCU84+3QYmKpLi+XvHdmrlwUwDA6kqw=="], + + "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.21.0", "", { "os": "linux", "cpu": "x64" }, "sha512-e2hrvElFIh6kW/UNBQK/kzqMNY5mO+67YtEh9OA65RM5IJXYTWiXjX6fjIiPaqOkBthYF1EqgiZ6OXKcQsM0hg=="], + + "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.21.0", "", { "os": "linux", "cpu": "x64" }, "sha512-1vvmgDdUSebVGXWX2lIcgRebqfQSff0hMEkLJyakQ9JQUbLDkEaMsPTLOmyccyC6IJ/l3FZuJbmrBw/u0A0uCQ=="], + + "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.21.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-s5oFkZ/hFcrlAyBTONFY1TWndfyre1wOMwU+6KCpm/iatybvrRgmZVM+vCFwxmC5ZhdlgfE0N4XorsDpi7/4XQ=="], + + "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.21.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-G9+TEqRnAA6nbpqyUqgTiopmnfgnMkR3kMukFBDsiyy23LZvUCpiUwjTRx6ezYCjJODXrh52rBR9oXvm+Fp5wg=="], + + "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.21.0", "", { "os": "win32", "cpu": "x64" }, "sha512-2jsCDZwtQvRhejHLfZ1JY6w6kEuEtfF9nzYsZxzSlNVKDX+DpsDJ+Rbjkm74nvg2rdx0gwBS+IMdvwJuq3S9pQ=="], + + "@tailwindcss/node": ["@tailwindcss/node@4.1.7", "", { "dependencies": { "@ampproject/remapping": "^2.3.0", "enhanced-resolve": "^5.18.1", "jiti": "^2.4.2", "lightningcss": "1.30.1", "magic-string": "^0.30.17", "source-map-js": "^1.2.1", "tailwindcss": "4.1.7" } }, "sha512-9rsOpdY9idRI2NH6CL4wORFY0+Q6fnx9XP9Ju+iq/0wJwGD5IByIgFmwVbyy4ymuyprj8Qh4ErxMKTUL4uNh3g=="], + + "@tailwindcss/oxide": ["@tailwindcss/oxide@4.1.7", "", { "dependencies": { "detect-libc": "^2.0.4", "tar": "^7.4.3" }, "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.7", "@tailwindcss/oxide-darwin-arm64": "4.1.7", "@tailwindcss/oxide-darwin-x64": "4.1.7", "@tailwindcss/oxide-freebsd-x64": "4.1.7", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.7", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.7", "@tailwindcss/oxide-linux-arm64-musl": "4.1.7", "@tailwindcss/oxide-linux-x64-gnu": "4.1.7", "@tailwindcss/oxide-linux-x64-musl": "4.1.7", "@tailwindcss/oxide-wasm32-wasi": "4.1.7", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.7", "@tailwindcss/oxide-win32-x64-msvc": "4.1.7" } }, "sha512-5SF95Ctm9DFiUyjUPnDGkoKItPX/k+xifcQhcqX5RA85m50jw1pT/KzjdvlqxRja45Y52nR4MR9fD1JYd7f8NQ=="], + + "@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.1.7", "", { "os": "android", "cpu": "arm64" }, "sha512-IWA410JZ8fF7kACus6BrUwY2Z1t1hm0+ZWNEzykKmMNM09wQooOcN/VXr0p/WJdtHZ90PvJf2AIBS/Ceqx1emg=="], + + "@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.1.7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-81jUw9To7fimGGkuJ2W5h3/oGonTOZKZ8C2ghm/TTxbwvfSiFSDPd6/A/KE2N7Jp4mv3Ps9OFqg2fEKgZFfsvg=="], + + "@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.1.7", "", { "os": "darwin", "cpu": "x64" }, "sha512-q77rWjEyGHV4PdDBtrzO0tgBBPlQWKY7wZK0cUok/HaGgbNKecegNxCGikuPJn5wFAlIywC3v+WMBt0PEBtwGw=="], + + "@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.1.7", "", { "os": "freebsd", "cpu": "x64" }, "sha512-RfmdbbK6G6ptgF4qqbzoxmH+PKfP4KSVs7SRlTwcbRgBwezJkAO3Qta/7gDy10Q2DcUVkKxFLXUQO6J3CRvBGw=="], + + "@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.1.7", "", { "os": "linux", "cpu": "arm" }, "sha512-OZqsGvpwOa13lVd1z6JVwQXadEobmesxQ4AxhrwRiPuE04quvZHWn/LnihMg7/XkN+dTioXp/VMu/p6A5eZP3g=="], + + "@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.1.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-voMvBTnJSfKecJxGkoeAyW/2XRToLZ227LxswLAwKY7YslG/Xkw9/tJNH+3IVh5bdYzYE7DfiaPbRkSHFxY1xA=="], + + "@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.1.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-PjGuNNmJeKHnP58M7XyjJyla8LPo+RmwHQpBI+W/OxqrwojyuCQ+GUtygu7jUqTEexejZHr/z3nBc/gTiXBj4A=="], + + "@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.1.7", "", { "os": "linux", "cpu": "x64" }, "sha512-HMs+Va+ZR3gC3mLZE00gXxtBo3JoSQxtu9lobbZd+DmfkIxR54NO7Z+UQNPsa0P/ITn1TevtFxXTpsRU7qEvWg=="], + + "@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.1.7", "", { "os": "linux", "cpu": "x64" }, "sha512-MHZ6jyNlutdHH8rd+YTdr3QbXrHXqwIhHw9e7yXEBcQdluGwhpQY2Eku8UZK6ReLaWtQ4gijIv5QoM5eE+qlsA=="], + + "@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.1.7", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@emnapi/wasi-threads": "^1.0.2", "@napi-rs/wasm-runtime": "^0.2.9", "@tybys/wasm-util": "^0.9.0", "tslib": "^2.8.0" }, "cpu": "none" }, "sha512-ANaSKt74ZRzE2TvJmUcbFQ8zS201cIPxUDm5qez5rLEwWkie2SkGtA4P+GPTj+u8N6JbPrC8MtY8RmJA35Oo+A=="], + + "@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.1.7", "", { "os": "win32", "cpu": "arm64" }, "sha512-HUiSiXQ9gLJBAPCMVRk2RT1ZrBjto7WvqsPBwUrNK2BcdSxMnk19h4pjZjI7zgPhDxlAbJSumTC4ljeA9y0tEw=="], + + "@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.1.7", "", { "os": "win32", "cpu": "x64" }, "sha512-rYHGmvoHiLJ8hWucSfSOEmdCBIGZIq7SpkPRSqLsH2Ab2YUNgKeAPT1Fi2cx3+hnYOrAb0jp9cRyode3bBW4mQ=="], + + "@tailwindcss/postcss": ["@tailwindcss/postcss@4.1.7", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "@tailwindcss/node": "4.1.7", "@tailwindcss/oxide": "4.1.7", "postcss": "^8.4.41", "tailwindcss": "4.1.7" } }, "sha512-88g3qmNZn7jDgrrcp3ZXEQfp9CVox7xjP1HN2TFKI03CltPVd/c61ydn5qJJL8FYunn0OqBaW5HNUga0kmPVvw=="], + + "@tailwindcss/vite": ["@tailwindcss/vite@4.1.7", "", { "dependencies": { "@tailwindcss/node": "4.1.7", "@tailwindcss/oxide": "4.1.7", "tailwindcss": "4.1.7" }, "peerDependencies": { "vite": "^5.2.0 || ^6" } }, "sha512-tYa2fO3zDe41I7WqijyVbRd8oWT0aEID1Eokz5hMT6wShLIHj3yvwj9XbfuloHP9glZ6H+aG2AN/+ZrxJ1Y5RQ=="], + + "@thedutchcoder/postcss-rem-to-px": ["@thedutchcoder/postcss-rem-to-px@0.0.2", "", { "peerDependencies": { "postcss": "^8.3.0" } }, "sha512-M2T3bJSTgLtZF8+KDYDtSDAFGuTlaxYfitpjkmNswnfJ8AjbQ/g7NC+bqgAAViYWFV9I3tdrQuQ3Bu8j7GrjwA=="], + + "@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="], + + "@types/babel__generator": ["@types/babel__generator@7.6.8", "", { "dependencies": { "@babel/types": "^7.0.0" } }, "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw=="], + + "@types/babel__template": ["@types/babel__template@7.4.4", "", { "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A=="], + + "@types/babel__traverse": ["@types/babel__traverse@7.20.6", "", { "dependencies": { "@babel/types": "^7.20.7" } }, "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg=="], + + "@types/estree": ["@types/estree@1.0.5", "", {}, "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw=="], + + "@types/filesystem": ["@types/filesystem@0.0.36", "", { "dependencies": { "@types/filewriter": "*" } }, "sha512-vPDXOZuannb9FZdxgHnqSwAG/jvdGM8Wq+6N4D/d80z+D4HWH+bItqsZaVRQykAn6WEVeEkLm2oQigyHtgb0RA=="], + + "@types/filewriter": ["@types/filewriter@0.0.33", "", {}, "sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g=="], + + "@types/har-format": ["@types/har-format@1.2.16", "", {}, "sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A=="], + + "@types/minimatch": ["@types/minimatch@3.0.5", "", {}, "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ=="], + + "@types/node": ["@types/node@22.5.0", "", { "dependencies": { "undici-types": "~6.19.2" } }, "sha512-DkFrJOe+rfdHTqqMg0bSNlGlQ85hSoh2TPzZyhHsXnMtligRWpxUySiyw8FY14ITt24HVCiQPWxS3KO/QlGmWg=="], + + "@types/yauzl": ["@types/yauzl@2.10.3", "", { "dependencies": { "@types/node": "*" } }, "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q=="], + + "@webext-core/fake-browser": ["@webext-core/fake-browser@1.3.2", "", { "dependencies": { "lodash.merge": "^4.6.2" } }, "sha512-jFyPWWz+VkHAC9DRIiIPOyu6X/KlC8dYqSKweHz6tsDb86QawtVgZSpYcM+GOQBlZc5DHFo92jJ7cIq4uBnU0A=="], + + "@webext-core/isolated-element": ["@webext-core/isolated-element@1.1.2", "", { "dependencies": { "is-potential-custom-element-name": "^1.0.1" } }, "sha512-CNHYhsIR8TPkPb+4yqTIuzaGnVn/Fshev5fyoPW+/8Cyc93tJbCjP9PC1XSK6fDWu+xASdPHLZaoa2nWAYoxeQ=="], + + "@webext-core/match-patterns": ["@webext-core/match-patterns@1.0.3", "", {}, "sha512-NY39ACqCxdKBmHgw361M9pfJma8e4AZo20w9AY+5ZjIj1W2dvXC8J31G5fjfOGbulW9w4WKpT8fPooi0mLkn9A=="], + + "@wxt-dev/browser": ["@wxt-dev/browser@0.0.317", "", { "dependencies": { "@types/filesystem": "*", "@types/har-format": "*" } }, "sha512-tpFr/OJjTlGY7FLIr950fNi9fIBLQQ9pRVDDajeqEMip5LsXFAxpbF4I1GAGUkdTJEghKQ8P5N9XnsAdbPBAOQ=="], + + "@wxt-dev/module-solid": ["@wxt-dev/module-solid@1.1.3", "", { "dependencies": { "vite-plugin-solid": "^2.10.2" }, "peerDependencies": { "wxt": ">=0.19.16" } }, "sha512-iQthYvhe3OieJTLSq9z6747cYKHZ7XOVX/Cl5Rop/k+gcJ795u0j4lvVs3Tn+55uAC7xEye0eG2sLocaXZDZcg=="], + + "@wxt-dev/storage": ["@wxt-dev/storage@1.1.1", "", { "dependencies": { "async-mutex": "^0.5.0", "dequal": "^2.0.3" } }, "sha512-H1vYWeoWz03INV4r+sLYDFil88b3rgMMfgGp/EXy3bLbveJeiMiFs/G0bsBN2Ra87Iqlf2oVYRb/ABQpAugbew=="], + + "acorn": ["acorn@8.14.1", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg=="], + + "adm-zip": ["adm-zip@0.5.15", "", {}, "sha512-jYPWSeOA8EFoZnucrKCNihqBjoEGQSU4HKgHYQgKNEQ0pQF9a/DYuo/+fAxY76k4qe75LUlLWpAM1QWcBMTOKw=="], + + "ansi-align": ["ansi-align@3.0.1", "", { "dependencies": { "string-width": "^4.1.0" } }, "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w=="], + + "ansi-escapes": ["ansi-escapes@7.0.0", "", { "dependencies": { "environment": "^1.0.0" } }, "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw=="], + + "ansi-regex": ["ansi-regex@6.0.1", "", {}, "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA=="], + + "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], + + "any-promise": ["any-promise@1.3.0", "", {}, "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="], + + "array-differ": ["array-differ@4.0.0", "", {}, "sha512-Q6VPTLMsmXZ47ENG3V+wQyZS1ZxXMxFyYzA+Z/GMrJ6yIutAIEf9wTyroTzmGjNfox9/h3GdGBCVh43GVFx4Uw=="], + + "array-union": ["array-union@3.0.1", "", {}, "sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw=="], + + "async": ["async@3.2.6", "", {}, "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA=="], + + "async-mutex": ["async-mutex@0.5.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA=="], + + "atomic-sleep": ["atomic-sleep@1.0.0", "", {}, "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ=="], + + "atomically": ["atomically@2.0.3", "", { "dependencies": { "stubborn-fs": "^1.2.5", "when-exit": "^2.1.1" } }, "sha512-kU6FmrwZ3Lx7/7y3hPS5QnbJfaohcIul5fGqf7ok+4KklIEk9tJ0C2IQPdacSbVUWv6zVHXEBWoWd6NrVMT7Cw=="], + + "autoprefixer": ["autoprefixer@10.4.21", "", { "dependencies": { "browserslist": "^4.24.4", "caniuse-lite": "^1.0.30001702", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": { "autoprefixer": "bin/autoprefixer" } }, "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ=="], + + "babel-plugin-jsx-dom-expressions": ["babel-plugin-jsx-dom-expressions@0.38.1", "", { "dependencies": { "@babel/helper-module-imports": "7.18.6", "@babel/plugin-syntax-jsx": "^7.18.6", "@babel/types": "^7.20.7", "html-entities": "2.3.3", "validate-html-nesting": "^1.2.1" }, "peerDependencies": { "@babel/core": "^7.20.12" } }, "sha512-4FD4H69Cu4jHx2uLDEvx4YC5T/fC/Dmaafhsm8hXm7SjHYzjr09gBVyHdoFza+91f/g9e6tIzjbLCMkOXwmlew=="], + + "babel-preset-solid": ["babel-preset-solid@1.8.19", "", { "dependencies": { "babel-plugin-jsx-dom-expressions": "^0.38.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-F3MoUdx3i4znhStnXUBno+5kGSbvhpbGrPgqfRPrS8W7foVJUOSd1/F9QDyd9dgClHfr+J7V14931eu1PEDDMQ=="], + + "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], + + "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="], + + "big-integer": ["big-integer@1.6.52", "", {}, "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg=="], + + "bl": ["bl@5.1.0", "", { "dependencies": { "buffer": "^6.0.3", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ=="], + + "bluebird": ["bluebird@3.7.2", "", {}, "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="], + + "boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="], + + "boxen": ["boxen@8.0.1", "", { "dependencies": { "ansi-align": "^3.0.1", "camelcase": "^8.0.0", "chalk": "^5.3.0", "cli-boxes": "^3.0.0", "string-width": "^7.2.0", "type-fest": "^4.21.0", "widest-line": "^5.0.0", "wrap-ansi": "^9.0.0" } }, "sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw=="], + + "bplist-parser": ["bplist-parser@0.2.0", "", { "dependencies": { "big-integer": "^1.6.44" } }, "sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw=="], + + "brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="], + + "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], + + "browserslist": ["browserslist@4.24.5", "", { "dependencies": { "caniuse-lite": "^1.0.30001716", "electron-to-chromium": "^1.5.149", "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-FDToo4Wo82hIdgc1CQ+NQD0hEhmpPjrZ3hiUgwgOG6IuTdlpr8jdjyG24P6cNP1yJpTLzS5OcGgSw0xmDU1/Tw=="], + + "buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="], + + "buffer-crc32": ["buffer-crc32@0.2.13", "", {}, "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ=="], + + "buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="], + + "bundle-name": ["bundle-name@4.1.0", "", { "dependencies": { "run-applescript": "^7.0.0" } }, "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q=="], + + "c12": ["c12@3.0.4", "", { "dependencies": { "chokidar": "^4.0.3", "confbox": "^0.2.2", "defu": "^6.1.4", "dotenv": "^16.5.0", "exsolve": "^1.0.5", "giget": "^2.0.0", "jiti": "^2.4.2", "ohash": "^2.0.11", "pathe": "^2.0.3", "perfect-debounce": "^1.0.0", "pkg-types": "^2.1.0", "rc9": "^2.1.2" }, "peerDependencies": { "magicast": "^0.3.5" }, "optionalPeers": ["magicast"] }, "sha512-t5FaZTYbbCtvxuZq9xxIruYydrAGsJ+8UdP0pZzMiK2xl/gNiSOy0OxhLzHUEEb0m1QXYqfzfvyIFEmz/g9lqg=="], + + "cac": ["cac@6.7.14", "", {}, "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ=="], + + "camelcase": ["camelcase@8.0.0", "", {}, "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA=="], + + "caniuse-lite": ["caniuse-lite@1.0.30001718", "", {}, "sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw=="], + + "chalk": ["chalk@5.3.0", "", {}, "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w=="], + + "chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="], + + "chownr": ["chownr@3.0.0", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="], + + "chrome-launcher": ["chrome-launcher@1.1.2", "", { "dependencies": { "@types/node": "*", "escape-string-regexp": "^4.0.0", "is-wsl": "^2.2.0", "lighthouse-logger": "^2.0.1" }, "bin": { "print-chrome-path": "bin/print-chrome-path.js" } }, "sha512-YclTJey34KUm5jB1aEJCq807bSievi7Nb/TU4Gu504fUYi3jw3KCIaH6L7nFWQhdEgH3V+wCh+kKD1P5cXnfxw=="], + + "ci-info": ["ci-info@4.2.0", "", {}, "sha512-cYY9mypksY8NRqgDB1XD1RiJL338v/551niynFTGkZOO2LHuB2OmOYxDIe/ttN9AHwrqdum1360G3ald0W9kCg=="], + + "citty": ["citty@0.1.6", "", { "dependencies": { "consola": "^3.2.3" } }, "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ=="], + + "cli-boxes": ["cli-boxes@3.0.0", "", {}, "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g=="], + + "cli-cursor": ["cli-cursor@5.0.0", "", { "dependencies": { "restore-cursor": "^5.0.0" } }, "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw=="], + + "cli-highlight": ["cli-highlight@2.1.11", "", { "dependencies": { "chalk": "^4.0.0", "highlight.js": "^10.7.1", "mz": "^2.4.0", "parse5": "^5.1.1", "parse5-htmlparser2-tree-adapter": "^6.0.0", "yargs": "^16.0.0" }, "bin": { "highlight": "bin/highlight" } }, "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg=="], + + "cli-spinners": ["cli-spinners@2.9.2", "", {}, "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg=="], + + "cli-truncate": ["cli-truncate@4.0.0", "", { "dependencies": { "slice-ansi": "^5.0.0", "string-width": "^7.0.0" } }, "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA=="], + + "cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="], + + "clone": ["clone@1.0.4", "", {}, "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg=="], + + "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], + + "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], + + "colorette": ["colorette@2.0.20", "", {}, "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w=="], + + "commander": ["commander@9.5.0", "", {}, "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ=="], + + "concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="], + + "concat-stream": ["concat-stream@1.6.2", "", { "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^2.2.2", "typedarray": "^0.0.6" } }, "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw=="], + + "confbox": ["confbox@0.2.2", "", {}, "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ=="], + + "config-chain": ["config-chain@1.1.13", "", { "dependencies": { "ini": "^1.3.4", "proto-list": "~1.2.1" } }, "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ=="], + + "configstore": ["configstore@7.0.0", "", { "dependencies": { "atomically": "^2.0.3", "dot-prop": "^9.0.0", "graceful-fs": "^4.2.11", "xdg-basedir": "^5.1.0" } }, "sha512-yk7/5PN5im4qwz0WFZW3PXnzHgPu9mX29Y8uZ3aefe2lBPC1FYttWZRcaW9fKkT0pBCJyuQ2HfbmPVaODi9jcQ=="], + + "consola": ["consola@3.4.2", "", {}, "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA=="], + + "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="], + + "core-util-is": ["core-util-is@1.0.3", "", {}, "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="], + + "cross-spawn": ["cross-spawn@7.0.3", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w=="], + + "css-select": ["css-select@5.1.0", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg=="], + + "css-what": ["css-what@6.1.0", "", {}, "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw=="], + + "cssom": ["cssom@0.5.0", "", {}, "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw=="], + + "csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="], + + "daisyui": ["daisyui@5.0.37", "", {}, "sha512-PLc+MhWAqTwolygEGPDi+ac+OsFqIt9nZylTIiyVlEx8loYL7Pt7hNWb8cp5pQQ9dhjYnda1ERiuM6OsJmvPGw=="], + + "debounce": ["debounce@1.2.1", "", {}, "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug=="], + + "debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="], + + "deep-extend": ["deep-extend@0.6.0", "", {}, "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="], + + "default-browser": ["default-browser@5.2.1", "", { "dependencies": { "bundle-name": "^4.1.0", "default-browser-id": "^5.0.0" } }, "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg=="], + + "default-browser-id": ["default-browser-id@5.0.0", "", {}, "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA=="], + + "defaults": ["defaults@1.0.4", "", { "dependencies": { "clone": "^1.0.2" } }, "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A=="], + + "define-lazy-prop": ["define-lazy-prop@3.0.0", "", {}, "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg=="], + + "defu": ["defu@6.1.4", "", {}, "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg=="], + + "dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="], + + "destr": ["destr@2.0.3", "", {}, "sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ=="], + + "detect-libc": ["detect-libc@2.0.4", "", {}, "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA=="], + + "dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="], + + "domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="], + + "domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="], + + "domutils": ["domutils@3.1.0", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA=="], + + "dot-prop": ["dot-prop@9.0.0", "", { "dependencies": { "type-fest": "^4.18.2" } }, "sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ=="], + + "dotenv": ["dotenv@16.5.0", "", {}, "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg=="], + + "dotenv-expand": ["dotenv-expand@12.0.2", "", { "dependencies": { "dotenv": "^16.4.5" } }, "sha512-lXpXz2ZE1cea1gL4sz2Ipj8y4PiVjytYr3Ij0SWoms1PGxIv7m2CRKuRuCRtHdVuvM/hNJPMxt5PbhboNC4dPQ=="], + + "electron-to-chromium": ["electron-to-chromium@1.5.157", "", {}, "sha512-/0ybgsQd1muo8QlnuTpKwtl0oX5YMlUGbm8xyqgDU00motRkKFFbUJySAQBWcY79rVqNLWIWa87BGVGClwAB2w=="], + + "emoji-regex": ["emoji-regex@10.3.0", "", {}, "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw=="], + + "end-of-stream": ["end-of-stream@1.4.4", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q=="], + + "enhanced-resolve": ["enhanced-resolve@5.18.1", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg=="], + + "entities": ["entities@6.0.0", "", {}, "sha512-aKstq2TDOndCn4diEyp9Uq/Flu2i1GlLkc6XIDQSDMuaFE3OPW5OphLCyQ5SpSJZTb4reN+kTcYru5yIfXoRPw=="], + + "environment": ["environment@1.1.0", "", {}, "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q=="], + + "error-ex": ["error-ex@1.3.2", "", { "dependencies": { "is-arrayish": "^0.2.1" } }, "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g=="], + + "es-module-lexer": ["es-module-lexer@1.7.0", "", {}, "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA=="], + + "es6-error": ["es6-error@4.1.1", "", {}, "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg=="], + + "esbuild": ["esbuild@0.25.4", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.4", "@esbuild/android-arm": "0.25.4", "@esbuild/android-arm64": "0.25.4", "@esbuild/android-x64": "0.25.4", "@esbuild/darwin-arm64": "0.25.4", "@esbuild/darwin-x64": "0.25.4", "@esbuild/freebsd-arm64": "0.25.4", "@esbuild/freebsd-x64": "0.25.4", "@esbuild/linux-arm": "0.25.4", "@esbuild/linux-arm64": "0.25.4", "@esbuild/linux-ia32": "0.25.4", "@esbuild/linux-loong64": "0.25.4", "@esbuild/linux-mips64el": "0.25.4", "@esbuild/linux-ppc64": "0.25.4", "@esbuild/linux-riscv64": "0.25.4", "@esbuild/linux-s390x": "0.25.4", "@esbuild/linux-x64": "0.25.4", "@esbuild/netbsd-arm64": "0.25.4", "@esbuild/netbsd-x64": "0.25.4", "@esbuild/openbsd-arm64": "0.25.4", "@esbuild/openbsd-x64": "0.25.4", "@esbuild/sunos-x64": "0.25.4", "@esbuild/win32-arm64": "0.25.4", "@esbuild/win32-ia32": "0.25.4", "@esbuild/win32-x64": "0.25.4" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q=="], + + "escalade": ["escalade@3.1.2", "", {}, "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA=="], + + "escape-goat": ["escape-goat@4.0.0", "", {}, "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg=="], + + "escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], + + "estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="], + + "eventemitter3": ["eventemitter3@5.0.1", "", {}, "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="], + + "execa": ["execa@7.2.0", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.1", "human-signals": "^4.3.0", "is-stream": "^3.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^5.1.0", "onetime": "^6.0.0", "signal-exit": "^3.0.7", "strip-final-newline": "^3.0.0" } }, "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA=="], + + "exsolve": ["exsolve@1.0.5", "", {}, "sha512-pz5dvkYYKQ1AHVrgOzBKWeP4u4FRb3a6DNK2ucr0OoNwYIU4QWsJ+NM36LLzORT+z845MzKHHhpXiUF5nvQoJg=="], + + "extract-zip": ["extract-zip@2.0.1", "", { "dependencies": { "debug": "^4.1.1", "get-stream": "^5.1.0", "yauzl": "^2.10.0" }, "optionalDependencies": { "@types/yauzl": "^2.9.1" }, "bin": "cli.js" }, "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg=="], + + "fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="], + + "fast-redact": ["fast-redact@3.5.0", "", {}, "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A=="], + + "fastq": ["fastq@1.17.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w=="], + + "fd-slicer": ["fd-slicer@1.1.0", "", { "dependencies": { "pend": "~1.2.0" } }, "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g=="], + + "fdir": ["fdir@6.4.4", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg=="], + + "filesize": ["filesize@10.1.6", "", {}, "sha512-sJslQKU2uM33qH5nqewAwVB2QgR6w1aMNsYUp3aN5rMRyXEwJGmZvaWzeJFNTOXWlHQyBFCWrdj3fV/fsTOX8w=="], + + "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], + + "firefox-profile": ["firefox-profile@4.7.0", "", { "dependencies": { "adm-zip": "~0.5.x", "fs-extra": "^11.2.0", "ini": "^4.1.3", "minimist": "^1.2.8", "xml2js": "^0.6.2" }, "bin": { "firefox-profile": "lib/cli.js" } }, "sha512-aGApEu5bfCNbA4PGUZiRJAIU6jKmghV2UVdklXAofnNtiDjqYw0czLS46W7IfFqVKgKhFB8Ao2YoNGHY4BoIMQ=="], + + "formdata-node": ["formdata-node@6.0.3", "", {}, "sha512-8e1++BCiTzUno9v5IZ2J6bv4RU+3UKDmqWUQD0MIMVCd9AdhWkO1gw57oo1mNEX1dMq2EGI+FbWz4B92pscSQg=="], + + "fraction.js": ["fraction.js@4.3.7", "", {}, "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew=="], + + "fs-extra": ["fs-extra@11.3.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew=="], + + "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], + + "fx-runner": ["fx-runner@1.4.0", "", { "dependencies": { "commander": "2.9.0", "shell-quote": "1.7.3", "spawn-sync": "1.0.15", "when": "3.7.7", "which": "1.2.4", "winreg": "0.0.12" }, "bin": "bin/fx-runner" }, "sha512-rci1g6U0rdTg6bAaBboP7XdRu01dzTAaKXxFf+PUqGuCv6Xu7o8NZdY1D5MvKGIjb6EdS1g3VlXOgksir1uGkg=="], + + "gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="], + + "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="], + + "get-east-asian-width": ["get-east-asian-width@1.2.0", "", {}, "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA=="], + + "get-port-please": ["get-port-please@3.1.2", "", {}, "sha512-Gxc29eLs1fbn6LQ4jSU4vXjlwyZhF5HsGuMAa7gqBP4Rw4yxxltyDUuF5MBclFzDTXO+ACchGQoeela4DSfzdQ=="], + + "get-stream": ["get-stream@5.2.0", "", { "dependencies": { "pump": "^3.0.0" } }, "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA=="], + + "giget": ["giget@2.0.0", "", { "dependencies": { "citty": "^0.1.6", "consola": "^3.4.0", "defu": "^6.1.4", "node-fetch-native": "^1.6.6", "nypm": "^0.6.0", "pathe": "^2.0.3" }, "bin": { "giget": "dist/cli.mjs" } }, "sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA=="], + + "glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], + + "glob-to-regexp": ["glob-to-regexp@0.4.1", "", {}, "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="], + + "global-directory": ["global-directory@4.0.1", "", { "dependencies": { "ini": "4.1.1" } }, "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q=="], + + "globals": ["globals@11.12.0", "", {}, "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="], + + "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], + + "graceful-readlink": ["graceful-readlink@1.0.1", "", {}, "sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w=="], + + "growly": ["growly@1.3.0", "", {}, "sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw=="], + + "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], + + "highlight.js": ["highlight.js@10.7.3", "", {}, "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A=="], + + "hookable": ["hookable@5.5.3", "", {}, "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ=="], + + "html-entities": ["html-entities@2.3.3", "", {}, "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA=="], + + "html-escaper": ["html-escaper@3.0.3", "", {}, "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ=="], + + "htmlparser2": ["htmlparser2@10.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.2.1", "entities": "^6.0.0" } }, "sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g=="], + + "human-signals": ["human-signals@4.3.1", "", {}, "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ=="], + + "ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], + + "immediate": ["immediate@3.0.6", "", {}, "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="], + + "import-meta-resolve": ["import-meta-resolve@4.1.0", "", {}, "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw=="], + + "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], + + "ini": ["ini@4.1.3", "", {}, "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg=="], + + "is-absolute": ["is-absolute@0.1.7", "", { "dependencies": { "is-relative": "^0.1.0" } }, "sha512-Xi9/ZSn4NFapG8RP98iNPMOeaV3mXPisxKxzKtHVqr3g56j/fBn+yZmnxSVAA8lmZbl2J9b/a4kJvfU3hqQYgA=="], + + "is-arrayish": ["is-arrayish@0.2.1", "", {}, "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="], + + "is-docker": ["is-docker@2.2.1", "", { "bin": "cli.js" }, "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ=="], + + "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], + + "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="], + + "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="], + + "is-in-ci": ["is-in-ci@1.0.0", "", { "bin": { "is-in-ci": "cli.js" } }, "sha512-eUuAjybVTHMYWm/U+vBO1sY/JOCgoPCXRxzdju0K+K0BiGW0SChEL1MLC0PoCIR1OlPo5YAp8HuQoUlsWEICwg=="], + + "is-inside-container": ["is-inside-container@1.0.0", "", { "dependencies": { "is-docker": "^3.0.0" }, "bin": "cli.js" }, "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA=="], + + "is-installed-globally": ["is-installed-globally@1.0.0", "", { "dependencies": { "global-directory": "^4.0.1", "is-path-inside": "^4.0.0" } }, "sha512-K55T22lfpQ63N4KEN57jZUAaAYqYHEe8veb/TycJRk9DdSCLLcovXz/mL6mOnhQaZsQGwPhuFopdQIlqGSEjiQ=="], + + "is-interactive": ["is-interactive@2.0.0", "", {}, "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ=="], + + "is-npm": ["is-npm@6.0.0", "", {}, "sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ=="], + + "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], + + "is-path-inside": ["is-path-inside@4.0.0", "", {}, "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA=="], + + "is-plain-object": ["is-plain-object@2.0.4", "", { "dependencies": { "isobject": "^3.0.1" } }, "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og=="], + + "is-potential-custom-element-name": ["is-potential-custom-element-name@1.0.1", "", {}, "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ=="], + + "is-primitive": ["is-primitive@3.0.1", "", {}, "sha512-GljRxhWvlCNRfZyORiH77FwdFwGcMO620o37EOYC0ORWdq+WYNVqW0w2Juzew4M+L81l6/QS3t5gkkihyRqv9w=="], + + "is-relative": ["is-relative@0.1.3", "", {}, "sha512-wBOr+rNM4gkAZqoLRJI4myw5WzzIdQosFAAbnvfXP5z1LyzgAI3ivOKehC5KfqlQJZoihVhirgtCBj378Eg8GA=="], + + "is-stream": ["is-stream@3.0.0", "", {}, "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA=="], + + "is-unicode-supported": ["is-unicode-supported@2.0.0", "", {}, "sha512-FRdAyx5lusK1iHG0TWpVtk9+1i+GjrzRffhDg4ovQ7mcidMQ6mj+MhKPmvh7Xwyv5gIS06ns49CA7Sqg7lC22Q=="], + + "is-what": ["is-what@4.1.16", "", {}, "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A=="], + + "is-wsl": ["is-wsl@3.1.0", "", { "dependencies": { "is-inside-container": "^1.0.0" } }, "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw=="], + + "isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="], + + "isexe": ["isexe@1.1.2", "", {}, "sha512-d2eJzK691yZwPHcv1LbeAOa91yMJ9QmfTgSO1oXB65ezVhXQsxBac2vEB4bMVms9cGzaA99n6V2viHMq82VLDw=="], + + "isobject": ["isobject@3.0.1", "", {}, "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg=="], + + "jiti": ["jiti@2.4.2", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A=="], + + "js-tokens": ["js-tokens@9.0.1", "", {}, "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ=="], + + "jsesc": ["jsesc@2.5.2", "", { "bin": "bin/jsesc" }, "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA=="], + + "json-parse-even-better-errors": ["json-parse-even-better-errors@3.0.2", "", {}, "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ=="], + + "json5": ["json5@2.2.3", "", { "bin": "lib/cli.js" }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="], + + "jsonfile": ["jsonfile@6.1.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ=="], + + "jszip": ["jszip@3.10.1", "", { "dependencies": { "lie": "~3.3.0", "pako": "~1.0.2", "readable-stream": "~2.3.6", "setimmediate": "^1.0.5" } }, "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g=="], + + "kleur": ["kleur@3.0.3", "", {}, "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w=="], + + "ky": ["ky@1.8.1", "", {}, "sha512-7Bp3TpsE+L+TARSnnDpk3xg8Idi8RwSLdj6CMbNWoOARIrGrbuLGusV0dYwbZOm4bB3jHNxSw8Wk/ByDqJEnDw=="], + + "latest-version": ["latest-version@9.0.0", "", { "dependencies": { "package-json": "^10.0.0" } }, "sha512-7W0vV3rqv5tokqkBAFV1LbR7HPOWzXQDpDgEuib/aJ1jsZZx6x3c2mBI+TJhJzOhkGeaLbCKEHXEXLfirtG2JA=="], + + "lie": ["lie@3.3.0", "", { "dependencies": { "immediate": "~3.0.5" } }, "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ=="], + + "lighthouse-logger": ["lighthouse-logger@2.0.1", "", { "dependencies": { "debug": "^2.6.9", "marky": "^1.2.2" } }, "sha512-ioBrW3s2i97noEmnXxmUq7cjIcVRjT5HBpAYy8zE11CxU9HqlWHHeRxfeN1tn8F7OEMVPIC9x1f8t3Z7US9ehQ=="], + + "lightningcss": ["lightningcss@1.30.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-darwin-arm64": "1.30.1", "lightningcss-darwin-x64": "1.30.1", "lightningcss-freebsd-x64": "1.30.1", "lightningcss-linux-arm-gnueabihf": "1.30.1", "lightningcss-linux-arm64-gnu": "1.30.1", "lightningcss-linux-arm64-musl": "1.30.1", "lightningcss-linux-x64-gnu": "1.30.1", "lightningcss-linux-x64-musl": "1.30.1", "lightningcss-win32-arm64-msvc": "1.30.1", "lightningcss-win32-x64-msvc": "1.30.1" } }, "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg=="], + + "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.30.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ=="], + + "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.30.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA=="], + + "lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.30.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig=="], + + "lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.30.1", "", { "os": "linux", "cpu": "arm" }, "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q=="], + + "lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.30.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw=="], + + "lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.30.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ=="], + + "lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.30.1", "", { "os": "linux", "cpu": "x64" }, "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw=="], + + "lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.30.1", "", { "os": "linux", "cpu": "x64" }, "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ=="], + + "lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.30.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA=="], + + "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.30.1", "", { "os": "win32", "cpu": "x64" }, "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg=="], + + "lines-and-columns": ["lines-and-columns@2.0.4", "", {}, "sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A=="], + + "linkedom": ["linkedom@0.18.10", "", { "dependencies": { "css-select": "^5.1.0", "cssom": "^0.5.0", "html-escaper": "^3.0.3", "htmlparser2": "^10.0.0", "uhyphen": "^0.2.0" } }, "sha512-ESCqVAtme2GI3zZnlVRidiydByV6WmPlmKeFzFVQslADiAO2Wi+H6xL/5kr/pUOESjEoVb2Eb3cYFJ/TQhQOWA=="], + + "listr2": ["listr2@8.2.4", "", { "dependencies": { "cli-truncate": "^4.0.0", "colorette": "^2.0.20", "eventemitter3": "^5.0.1", "log-update": "^6.1.0", "rfdc": "^1.4.1", "wrap-ansi": "^9.0.0" } }, "sha512-opevsywziHd3zHCVQGAj8zu+Z3yHNkkoYhWIGnq54RrCVwLz0MozotJEDnKsIBLvkfLGN6BLOyAeRrYI0pKA4g=="], + + "local-pkg": ["local-pkg@1.1.1", "", { "dependencies": { "mlly": "^1.7.4", "pkg-types": "^2.0.1", "quansync": "^0.2.8" } }, "sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg=="], + + "lodash.camelcase": ["lodash.camelcase@4.3.0", "", {}, "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA=="], + + "lodash.kebabcase": ["lodash.kebabcase@4.1.1", "", {}, "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g=="], + + "lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="], + + "lodash.snakecase": ["lodash.snakecase@4.1.1", "", {}, "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw=="], + + "log-symbols": ["log-symbols@6.0.0", "", { "dependencies": { "chalk": "^5.3.0", "is-unicode-supported": "^1.3.0" } }, "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw=="], + + "log-update": ["log-update@6.1.0", "", { "dependencies": { "ansi-escapes": "^7.0.0", "cli-cursor": "^5.0.0", "slice-ansi": "^7.1.0", "strip-ansi": "^7.1.0", "wrap-ansi": "^9.0.0" } }, "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w=="], + + "lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="], + + "magic-string": ["magic-string@0.30.17", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA=="], + + "magicast": ["magicast@0.3.5", "", { "dependencies": { "@babel/parser": "^7.25.4", "@babel/types": "^7.25.4", "source-map-js": "^1.2.0" } }, "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ=="], + + "make-error": ["make-error@1.3.6", "", {}, "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw=="], + + "many-keys-map": ["many-keys-map@2.0.1", "", {}, "sha512-DHnZAD4phTbZ+qnJdjoNEVU1NecYoSdbOOoVmTDH46AuxDkEVh3MxTVpXq10GtcTC6mndN9dkv1rNfpjRcLnOw=="], + + "marky": ["marky@1.2.5", "", {}, "sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q=="], + + "merge-anything": ["merge-anything@5.1.7", "", { "dependencies": { "is-what": "^4.1.8" } }, "sha512-eRtbOb1N5iyH0tkQDAoQ4Ipsp/5qSR79Dzrz8hEPxRX10RWWR/iQXdoKmBSRCThY1Fh5EhISDtpSc93fpxUniQ=="], + + "merge-stream": ["merge-stream@2.0.0", "", {}, "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="], + + "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="], + + "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="], + + "mimic-fn": ["mimic-fn@4.0.0", "", {}, "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw=="], + + "mimic-function": ["mimic-function@5.0.1", "", {}, "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA=="], + + "minimatch": ["minimatch@10.0.1", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ=="], + + "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], + + "minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="], + + "minizlib": ["minizlib@3.0.2", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA=="], + + "mkdirp": ["mkdirp@3.0.1", "", { "bin": { "mkdirp": "dist/cjs/src/bin.js" } }, "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg=="], + + "mlly": ["mlly@1.7.4", "", { "dependencies": { "acorn": "^8.14.0", "pathe": "^2.0.1", "pkg-types": "^1.3.0", "ufo": "^1.5.4" } }, "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw=="], + + "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + + "multimatch": ["multimatch@6.0.0", "", { "dependencies": { "@types/minimatch": "^3.0.5", "array-differ": "^4.0.0", "array-union": "^3.0.1", "minimatch": "^3.0.4" } }, "sha512-I7tSVxHGPlmPN/enE3mS1aOSo6bWBfls+3HmuEeCUBCE7gWnm3cBXCBkpurzFjVRwC6Kld8lLaZ1Iv5vOcjvcQ=="], + + "mz": ["mz@2.7.0", "", { "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="], + + "nano-spawn": ["nano-spawn@0.2.1", "", {}, "sha512-/pULofvsF8mOVcl/nUeVXL/GYOEvc7eJWSIxa+K4OYUolvXa5zwSgevsn4eoHs1xvh/BO3vx/PZiD9+Ow2ZVuw=="], + + "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], + + "node-fetch-native": ["node-fetch-native@1.6.6", "", {}, "sha512-8Mc2HhqPdlIfedsuZoc3yioPuzp6b+L5jRCRY1QzuWZh2EGJVQrGppC6V6cF0bLdbW0+O2YpqCA25aF/1lvipQ=="], + + "node-forge": ["node-forge@1.3.1", "", {}, "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA=="], + + "node-notifier": ["node-notifier@10.0.1", "", { "dependencies": { "growly": "^1.3.0", "is-wsl": "^2.2.0", "semver": "^7.3.5", "shellwords": "^0.1.1", "uuid": "^8.3.2", "which": "^2.0.2" } }, "sha512-YX7TSyDukOZ0g+gmzjB6abKu+hTGvO8+8+gIFDsRCU2t8fLV/P2unmt+LGFaIa4y64aX98Qksa97rgz4vMNeLQ=="], + + "node-releases": ["node-releases@2.0.19", "", {}, "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw=="], + + "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], + + "normalize-range": ["normalize-range@0.1.2", "", {}, "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA=="], + + "npm-run-path": ["npm-run-path@5.3.0", "", { "dependencies": { "path-key": "^4.0.0" } }, "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ=="], + + "nth-check": ["nth-check@2.1.1", "", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="], + + "nypm": ["nypm@0.6.0", "", { "dependencies": { "citty": "^0.1.6", "consola": "^3.4.0", "pathe": "^2.0.3", "pkg-types": "^2.0.0", "tinyexec": "^0.3.2" }, "bin": { "nypm": "dist/cli.mjs" } }, "sha512-mn8wBFV9G9+UFHIrq+pZ2r2zL4aPau/by3kJb3cM7+5tQHMt6HGQB8FDIeKFYp8o0D2pnH6nVsO88N4AmUxIWg=="], + + "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], + + "ofetch": ["ofetch@1.3.4", "", { "dependencies": { "destr": "^2.0.3", "node-fetch-native": "^1.6.3", "ufo": "^1.5.3" } }, "sha512-KLIET85ik3vhEfS+3fDlc/BAZiAp+43QEC/yCo5zkNoY2YaKvNkOaFr/6wCFgFH1kuYQM5pMNi0Tg8koiIemtw=="], + + "ohash": ["ohash@2.0.11", "", {}, "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ=="], + + "on-exit-leak-free": ["on-exit-leak-free@2.1.2", "", {}, "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA=="], + + "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="], + + "onetime": ["onetime@7.0.0", "", { "dependencies": { "mimic-function": "^5.0.0" } }, "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ=="], + + "open": ["open@10.1.0", "", { "dependencies": { "default-browser": "^5.2.1", "define-lazy-prop": "^3.0.0", "is-inside-container": "^1.0.0", "is-wsl": "^3.1.0" } }, "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw=="], + + "ora": ["ora@8.2.0", "", { "dependencies": { "chalk": "^5.3.0", "cli-cursor": "^5.0.0", "cli-spinners": "^2.9.2", "is-interactive": "^2.0.0", "is-unicode-supported": "^2.0.0", "log-symbols": "^6.0.0", "stdin-discarder": "^0.2.2", "string-width": "^7.2.0", "strip-ansi": "^7.1.0" } }, "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw=="], + + "os-shim": ["os-shim@0.1.3", "", {}, "sha512-jd0cvB8qQ5uVt0lvCIexBaROw1KyKm5sbulg2fWOHjETisuCzWyt+eTZKEMs8v6HwzoGs8xik26jg7eCM6pS+A=="], + + "package-json": ["package-json@10.0.1", "", { "dependencies": { "ky": "^1.2.0", "registry-auth-token": "^5.0.2", "registry-url": "^6.0.1", "semver": "^7.6.0" } }, "sha512-ua1L4OgXSBdsu1FPb7F3tYH0F48a6kxvod4pLUlGY9COeJAJQNX/sNH2IiEmsxw7lqYiAwrdHMjz1FctOsyDQg=="], + + "pako": ["pako@1.0.11", "", {}, "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="], + + "parse-json": ["parse-json@7.1.1", "", { "dependencies": { "@babel/code-frame": "^7.21.4", "error-ex": "^1.3.2", "json-parse-even-better-errors": "^3.0.0", "lines-and-columns": "^2.0.3", "type-fest": "^3.8.0" } }, "sha512-SgOTCX/EZXtZxBE5eJ97P4yGM5n37BwRU+YMsH4vNzFqJV/oWFXXCmwFlgWUM4PrakybVOueJJ6pwHqSVhTFDw=="], + + "parse5": ["parse5@5.1.1", "", {}, "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug=="], + + "parse5-htmlparser2-tree-adapter": ["parse5-htmlparser2-tree-adapter@6.0.1", "", { "dependencies": { "parse5": "^6.0.1" } }, "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA=="], + + "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], + + "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], + + "pend": ["pend@1.2.0", "", {}, "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="], + + "perfect-debounce": ["perfect-debounce@1.0.0", "", {}, "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA=="], + + "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], + + "picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], + + "pino": ["pino@9.6.0", "", { "dependencies": { "atomic-sleep": "^1.0.0", "fast-redact": "^3.1.1", "on-exit-leak-free": "^2.1.0", "pino-abstract-transport": "^2.0.0", "pino-std-serializers": "^7.0.0", "process-warning": "^4.0.0", "quick-format-unescaped": "^4.0.3", "real-require": "^0.2.0", "safe-stable-stringify": "^2.3.1", "sonic-boom": "^4.0.1", "thread-stream": "^3.0.0" }, "bin": { "pino": "bin.js" } }, "sha512-i85pKRCt4qMjZ1+L7sy2Ag4t1atFcdbEt76+7iRJn1g2BvsnRMGu9p8pivl9fs63M2kF/A0OacFZhTub+m/qMg=="], + + "pino-abstract-transport": ["pino-abstract-transport@2.0.0", "", { "dependencies": { "split2": "^4.0.0" } }, "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw=="], + + "pino-std-serializers": ["pino-std-serializers@7.0.0", "", {}, "sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA=="], + + "pkg-types": ["pkg-types@2.1.0", "", { "dependencies": { "confbox": "^0.2.1", "exsolve": "^1.0.1", "pathe": "^2.0.3" } }, "sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A=="], + + "postcss": ["postcss@8.5.3", "", { "dependencies": { "nanoid": "^3.3.8", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A=="], + + "postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="], + + "prettier": ["prettier@3.5.3", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw=="], + + "process-nextick-args": ["process-nextick-args@2.0.1", "", {}, "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="], + + "process-warning": ["process-warning@4.0.1", "", {}, "sha512-3c2LzQ3rY9d0hc1emcsHhfT9Jwz0cChib/QN89oME2R451w5fy3f0afAhERFZAwrbDU43wk12d0ORBpDVME50Q=="], + + "promise-toolbox": ["promise-toolbox@0.21.0", "", { "dependencies": { "make-error": "^1.3.2" } }, "sha512-NV8aTmpwrZv+Iys54sSFOBx3tuVaOBvvrft5PNppnxy9xpU/akHbaWIril22AB22zaPgrgwKdD0KsrM0ptUtpg=="], + + "prompts": ["prompts@2.4.2", "", { "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" } }, "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q=="], + + "proto-list": ["proto-list@1.2.4", "", {}, "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA=="], + + "publish-browser-extension": ["publish-browser-extension@3.0.0", "", { "dependencies": { "cac": "^6.7.14", "cli-highlight": "^2.1.11", "consola": "^3.2.3", "dotenv": "^16.3.1", "extract-zip": "^2.0.1", "formdata-node": "^6.0.3", "listr2": "^8.0.1", "lodash.camelcase": "^4.3.0", "lodash.kebabcase": "^4.1.1", "lodash.snakecase": "^4.1.1", "ofetch": "^1.3.3", "open": "^9.1.0", "ora": "^6.3.1", "prompts": "^2.4.2", "zod": "^3.22.4" }, "bin": { "publish-extension": "bin/publish-extension.cjs" } }, "sha512-gwjH8mIepNqID2VqKIxzT6lmtvkcc5tcWYzrGSUdkeUFFFSHhGp9xx01EZ7j8wPq50dDe0XU5VNbHMAqr6wWAA=="], + + "pump": ["pump@3.0.0", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww=="], + + "pupa": ["pupa@3.1.0", "", { "dependencies": { "escape-goat": "^4.0.0" } }, "sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug=="], + + "quansync": ["quansync@0.2.10", "", {}, "sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A=="], + + "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], + + "quick-format-unescaped": ["quick-format-unescaped@4.0.4", "", {}, "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg=="], + + "rc": ["rc@1.2.8", "", { "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "bin": "cli.js" }, "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw=="], + + "rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="], + + "readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="], + + "readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="], + + "real-require": ["real-require@0.2.0", "", {}, "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg=="], + + "regenerator-runtime": ["regenerator-runtime@0.14.1", "", {}, "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="], + + "registry-auth-token": ["registry-auth-token@5.0.2", "", { "dependencies": { "@pnpm/npm-conf": "^2.1.0" } }, "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ=="], + + "registry-url": ["registry-url@6.0.1", "", { "dependencies": { "rc": "1.2.8" } }, "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q=="], + + "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="], + + "restore-cursor": ["restore-cursor@5.1.0", "", { "dependencies": { "onetime": "^7.0.0", "signal-exit": "^4.1.0" } }, "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA=="], + + "reusify": ["reusify@1.0.4", "", {}, "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw=="], + + "rfdc": ["rfdc@1.4.1", "", {}, "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="], + + "rollup": ["rollup@4.21.0", "", { "dependencies": { "@types/estree": "1.0.5" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.21.0", "@rollup/rollup-android-arm64": "4.21.0", "@rollup/rollup-darwin-arm64": "4.21.0", "@rollup/rollup-darwin-x64": "4.21.0", "@rollup/rollup-linux-arm-gnueabihf": "4.21.0", "@rollup/rollup-linux-arm-musleabihf": "4.21.0", "@rollup/rollup-linux-arm64-gnu": "4.21.0", "@rollup/rollup-linux-arm64-musl": "4.21.0", "@rollup/rollup-linux-powerpc64le-gnu": "4.21.0", "@rollup/rollup-linux-riscv64-gnu": "4.21.0", "@rollup/rollup-linux-s390x-gnu": "4.21.0", "@rollup/rollup-linux-x64-gnu": "4.21.0", "@rollup/rollup-linux-x64-musl": "4.21.0", "@rollup/rollup-win32-arm64-msvc": "4.21.0", "@rollup/rollup-win32-ia32-msvc": "4.21.0", "@rollup/rollup-win32-x64-msvc": "4.21.0", "fsevents": "~2.3.2" }, "bin": "dist/bin/rollup" }, "sha512-vo+S/lfA2lMS7rZ2Qoubi6I5hwZwzXeUIctILZLbHI+laNtvhhOIon2S1JksA5UEDQ7l3vberd0fxK44lTYjbQ=="], + + "run-applescript": ["run-applescript@7.0.0", "", {}, "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A=="], + + "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="], + + "safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], + + "safe-stable-stringify": ["safe-stable-stringify@2.5.0", "", {}, "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA=="], + + "sax": ["sax@1.4.1", "", {}, "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg=="], + + "scule": ["scule@1.3.0", "", {}, "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g=="], + + "semver": ["semver@6.3.1", "", { "bin": "bin/semver.js" }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "seroval": ["seroval@1.3.1", "", {}, "sha512-F+T9EQPdLzgdewgxnBh4mSc+vde+EOkU6dC9BDuu/bfGb+UyUlqM6t8znFCTPQSuai/ZcfFg0gu79h+bVW2O0w=="], + + "seroval-plugins": ["seroval-plugins@1.3.1", "", { "peerDependencies": { "seroval": "^1.0" } }, "sha512-dOlUoiI3fgZbQIcj6By+l865pzeWdP3XCSLdI3xlKnjCk5983yLWPsXytFOUI0BUZKG9qwqbj78n9yVcVwUqaQ=="], + + "set-value": ["set-value@4.1.0", "", { "dependencies": { "is-plain-object": "^2.0.4", "is-primitive": "^3.0.1" } }, "sha512-zTEg4HL0RwVrqcWs3ztF+x1vkxfm0lP+MQQFPiMJTKVceBwEV0A569Ou8l9IYQG8jOZdMVI1hGsc0tmeD2o/Lw=="], + + "setimmediate": ["setimmediate@1.0.5", "", {}, "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA=="], + + "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], + + "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], + + "shell-quote": ["shell-quote@1.7.3", "", {}, "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw=="], + + "shellwords": ["shellwords@0.1.1", "", {}, "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww=="], + + "signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], + + "sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="], + + "slice-ansi": ["slice-ansi@5.0.0", "", { "dependencies": { "ansi-styles": "^6.0.0", "is-fullwidth-code-point": "^4.0.0" } }, "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ=="], + + "solid-js": ["solid-js@1.9.7", "", { "dependencies": { "csstype": "^3.1.0", "seroval": "~1.3.0", "seroval-plugins": "~1.3.0" } }, "sha512-/saTKi8iWEM233n5OSi1YHCCuh66ZIQ7aK2hsToPe4tqGm7qAejU1SwNuTPivbWAYq7SjuHVVYxxuZQNRbICiw=="], + + "solid-refresh": ["solid-refresh@0.6.3", "", { "dependencies": { "@babel/generator": "^7.23.6", "@babel/helper-module-imports": "^7.22.15", "@babel/types": "^7.23.6" }, "peerDependencies": { "solid-js": "^1.3" } }, "sha512-F3aPsX6hVw9ttm5LYlth8Q15x6MlI/J3Dn+o3EQyRTtTxidepSTwAYdozt01/YA+7ObcciagGEyXIopGZzQtbA=="], + + "sonic-boom": ["sonic-boom@4.2.0", "", { "dependencies": { "atomic-sleep": "^1.0.0" } }, "sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww=="], + + "source-map": ["source-map@0.7.4", "", {}, "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA=="], + + "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], + + "source-map-support": ["source-map-support@0.5.21", "", { "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w=="], + + "spawn-sync": ["spawn-sync@1.0.15", "", { "dependencies": { "concat-stream": "^1.4.7", "os-shim": "^0.1.2" } }, "sha512-9DWBgrgYZzNghseho0JOuh+5fg9u6QWhAWa51QC7+U5rCheZ/j1DrEZnyE0RBBRqZ9uEXGPgSSM0nky6burpVw=="], + + "split": ["split@1.0.1", "", { "dependencies": { "through": "2" } }, "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg=="], + + "split2": ["split2@4.2.0", "", {}, "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg=="], + + "stdin-discarder": ["stdin-discarder@0.2.2", "", {}, "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ=="], + + "string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], + + "string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="], + + "strip-ansi": ["strip-ansi@7.1.0", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ=="], + + "strip-bom": ["strip-bom@5.0.0", "", {}, "sha512-p+byADHF7SzEcVnLvc/r3uognM1hUhObuHXxJcgLCfD194XAkaLbjq3Wzb0N5G2tgIjH0dgT708Z51QxMeu60A=="], + + "strip-final-newline": ["strip-final-newline@3.0.0", "", {}, "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw=="], + + "strip-json-comments": ["strip-json-comments@5.0.1", "", {}, "sha512-0fk9zBqO67Nq5M/m45qHCJxylV/DhBlIOVExqgOMiCCrzrhU6tCibRXNqE3jwJLftzE9SNuZtYbpzcO+i9FiKw=="], + + "strip-literal": ["strip-literal@2.1.1", "", { "dependencies": { "js-tokens": "^9.0.1" } }, "sha512-631UJ6O00eNGfMiWG78ck80dfBab8X6IVFB51jZK5Icd7XAs60Z5y7QdSd/wGIklnWvRbUNloVzhOKKmutxQ6Q=="], + + "stubborn-fs": ["stubborn-fs@1.2.5", "", {}, "sha512-H2N9c26eXjzL/S/K+i/RHHcFanE74dptvvjM8iwzwbVcWY/zjBbgRqF3K0DY4+OD+uTTASTBvDoxPDaPN02D7g=="], + + "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], + + "tailwindcss": ["tailwindcss@4.1.7", "", {}, "sha512-kr1o/ErIdNhTz8uzAYL7TpaUuzKIE6QPQ4qmSdxnoX/lo+5wmUHQA6h3L5yIqEImSRnAAURDirLu/BgiXGPAhg=="], + + "tapable": ["tapable@2.2.2", "", {}, "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg=="], + + "tar": ["tar@7.4.3", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.0.1", "mkdirp": "^3.0.1", "yallist": "^5.0.0" } }, "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw=="], + + "thenify": ["thenify@3.3.1", "", { "dependencies": { "any-promise": "^1.0.0" } }, "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw=="], + + "thenify-all": ["thenify-all@1.6.0", "", { "dependencies": { "thenify": ">= 3.1.0 < 4" } }, "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA=="], + + "thread-stream": ["thread-stream@3.1.0", "", { "dependencies": { "real-require": "^0.2.0" } }, "sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A=="], + + "through": ["through@2.3.8", "", {}, "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="], + + "tinyexec": ["tinyexec@0.3.2", "", {}, "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA=="], + + "tinyglobby": ["tinyglobby@0.2.13", "", { "dependencies": { "fdir": "^6.4.4", "picomatch": "^4.0.2" } }, "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw=="], + + "titleize": ["titleize@3.0.0", "", {}, "sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ=="], + + "tmp": ["tmp@0.2.3", "", {}, "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w=="], + + "to-fast-properties": ["to-fast-properties@2.0.0", "", {}, "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog=="], + + "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], + + "tslib": ["tslib@2.7.0", "", {}, "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA=="], + + "type-fest": ["type-fest@3.13.1", "", {}, "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g=="], + + "typedarray": ["typedarray@0.0.6", "", {}, "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA=="], + + "typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="], + + "ufo": ["ufo@1.5.4", "", {}, "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ=="], + + "uhyphen": ["uhyphen@0.2.0", "", {}, "sha512-qz3o9CHXmJJPGBdqzab7qAYuW8kQGKNEuoHFYrBwV6hWIMcpAmxDLXojcHfFr9US1Pe6zUswEIJIbLI610fuqA=="], + + "undici-types": ["undici-types@6.19.8", "", {}, "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="], + + "unimport": ["unimport@3.14.6", "", { "dependencies": { "@rollup/pluginutils": "^5.1.4", "acorn": "^8.14.0", "escape-string-regexp": "^5.0.0", "estree-walker": "^3.0.3", "fast-glob": "^3.3.3", "local-pkg": "^1.0.0", "magic-string": "^0.30.17", "mlly": "^1.7.4", "pathe": "^2.0.1", "picomatch": "^4.0.2", "pkg-types": "^1.3.0", "scule": "^1.3.0", "strip-literal": "^2.1.1", "unplugin": "^1.16.1" } }, "sha512-CYvbDaTT04Rh8bmD8jz3WPmHYZRG/NnvYVzwD6V1YAlvvKROlAeNDUBhkBGzNav2RKaeuXvlWYaa1V4Lfi/O0g=="], + + "universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="], + + "unplugin": ["unplugin@1.16.1", "", { "dependencies": { "acorn": "^8.14.0", "webpack-virtual-modules": "^0.6.2" } }, "sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w=="], + + "untildify": ["untildify@4.0.0", "", {}, "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw=="], + + "update-browserslist-db": ["update-browserslist-db@1.1.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw=="], + + "update-notifier": ["update-notifier@7.3.1", "", { "dependencies": { "boxen": "^8.0.1", "chalk": "^5.3.0", "configstore": "^7.0.0", "is-in-ci": "^1.0.0", "is-installed-globally": "^1.0.0", "is-npm": "^6.0.0", "latest-version": "^9.0.0", "pupa": "^3.1.0", "semver": "^7.6.3", "xdg-basedir": "^5.1.0" } }, "sha512-+dwUY4L35XFYEzE+OAL3sarJdUioVovq+8f7lcIJ7wnmnYQV5UD1Y/lcwaMSyaQ6Bj3JMj1XSTjZbNLHn/19yA=="], + + "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], + + "uuid": ["uuid@8.3.2", "", { "bin": "dist/bin/uuid" }, "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="], + + "validate-html-nesting": ["validate-html-nesting@1.2.2", "", {}, "sha512-hGdgQozCsQJMyfK5urgFcWEqsSSrK63Awe0t/IMR0bZ0QMtnuaiHzThW81guu3qx9abLi99NEuiaN6P9gVYsNg=="], + + "vite": ["vite@6.3.5", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ=="], + + "vite-node": ["vite-node@3.1.4", "", { "dependencies": { "cac": "^6.7.14", "debug": "^4.4.0", "es-module-lexer": "^1.7.0", "pathe": "^2.0.3", "vite": "^5.0.0 || ^6.0.0" }, "bin": { "vite-node": "vite-node.mjs" } }, "sha512-6enNwYnpyDo4hEgytbmc6mYWHXDHYEn0D1/rw4Q+tnHUGtKTJsn8T1YkX6Q18wI5LCrS8CTYlBaiCqxOy2kvUA=="], + + "vite-plugin-solid": ["vite-plugin-solid@2.10.2", "", { "dependencies": { "@babel/core": "^7.23.3", "@types/babel__core": "^7.20.4", "babel-preset-solid": "^1.8.4", "merge-anything": "^5.1.7", "solid-refresh": "^0.6.3", "vitefu": "^0.2.5" }, "peerDependencies": { "@testing-library/jest-dom": "^5.16.6 || ^5.17.0 || ^6.*", "solid-js": "^1.7.2", "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" }, "optionalPeers": ["@testing-library/jest-dom"] }, "sha512-AOEtwMe2baBSXMXdo+BUwECC8IFHcKS6WQV/1NEd+Q7vHPap5fmIhLcAzr+DUJ04/KHx/1UBU0l1/GWP+rMAPQ=="], + + "vitefu": ["vitefu@0.2.5", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" } }, "sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q=="], + + "watchpack": ["watchpack@2.4.2", "", { "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" } }, "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw=="], + + "wcwidth": ["wcwidth@1.0.1", "", { "dependencies": { "defaults": "^1.0.3" } }, "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg=="], + + "web-ext-run": ["web-ext-run@0.2.3", "", { "dependencies": { "@babel/runtime": "7.27.0", "@devicefarmer/adbkit": "3.3.8", "chrome-launcher": "1.1.2", "debounce": "1.2.1", "es6-error": "4.1.1", "firefox-profile": "4.7.0", "fx-runner": "1.4.0", "multimatch": "6.0.0", "node-notifier": "10.0.1", "parse-json": "7.1.1", "pino": "9.6.0", "promise-toolbox": "0.21.0", "set-value": "4.1.0", "source-map-support": "0.5.21", "strip-bom": "5.0.0", "strip-json-comments": "5.0.1", "tmp": "0.2.3", "update-notifier": "7.3.1", "watchpack": "2.4.2", "ws": "8.18.1", "zip-dir": "2.0.0" } }, "sha512-u/IiZaZ7dHFqTM1MLF27rBy8mS9fEEsqoOKL0u+kQdOLmEioA/0Szp67ADd3WAJZLd8/hO8cFST1IC/YMXKIjQ=="], + + "web-vitals": ["web-vitals@4.2.4", "", {}, "sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw=="], + + "webpack-virtual-modules": ["webpack-virtual-modules@0.6.2", "", {}, "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ=="], + + "when": ["when@3.7.7", "", {}, "sha512-9lFZp/KHoqH6bPKjbWqa+3Dg/K/r2v0X/3/G2x4DBGchVS2QX2VXL3cZV994WQVnTM1/PD71Az25nAzryEUugw=="], + + "when-exit": ["when-exit@2.1.4", "", {}, "sha512-4rnvd3A1t16PWzrBUcSDZqcAmsUIy4minDXT/CZ8F2mVDgd65i4Aalimgz1aQkRGU0iH5eT5+6Rx2TK8o443Pg=="], + + "which": ["which@1.2.4", "", { "dependencies": { "is-absolute": "^0.1.7", "isexe": "^1.1.1" }, "bin": "bin/which" }, "sha512-zDRAqDSBudazdfM9zpiI30Fu9ve47htYXcGi3ln0wfKu2a7SmrT6F3VDoYONu//48V8Vz4TdCRNPjtvyRO3yBA=="], + + "widest-line": ["widest-line@5.0.0", "", { "dependencies": { "string-width": "^7.0.0" } }, "sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA=="], + + "winreg": ["winreg@0.0.12", "", {}, "sha512-typ/+JRmi7RqP1NanzFULK36vczznSNN8kWVA9vIqXyv8GhghUlwhGp1Xj3Nms1FsPcNnsQrJOR10N58/nQ9hQ=="], + + "wrap-ansi": ["wrap-ansi@9.0.0", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q=="], + + "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], + + "ws": ["ws@8.18.1", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w=="], + + "wxt": ["wxt@0.20.6", "", { "dependencies": { "@1natsu/wait-element": "^4.1.2", "@aklinker1/rollup-plugin-visualizer": "5.12.0", "@webext-core/fake-browser": "^1.3.2", "@webext-core/isolated-element": "^1.1.2", "@webext-core/match-patterns": "^1.0.3", "@wxt-dev/browser": "0.0.317", "@wxt-dev/storage": "^1.0.0", "async-mutex": "^0.5.0", "c12": "^3.0.3", "cac": "^6.7.14", "chokidar": "^4.0.3", "ci-info": "^4.2.0", "consola": "^3.4.2", "defu": "^6.1.4", "dotenv": "^16.4.7", "dotenv-expand": "^12.0.1", "esbuild": "^0.25.0", "fast-glob": "^3.3.3", "filesize": "^10.1.6", "fs-extra": "^11.3.0", "get-port-please": "^3.1.2", "giget": "^1.2.3 || ^2.0.0", "hookable": "^5.5.3", "import-meta-resolve": "^4.1.0", "is-wsl": "^3.1.0", "json5": "^2.2.3", "jszip": "^3.10.1", "linkedom": "^0.18.9", "magicast": "^0.3.5", "minimatch": "^10.0.1", "nano-spawn": "^0.2.0", "normalize-path": "^3.0.0", "nypm": "^0.6.0", "ohash": "^2.0.11", "open": "^10.1.0", "ora": "^8.2.0", "perfect-debounce": "^1.0.0", "picocolors": "^1.1.1", "prompts": "^2.4.2", "publish-browser-extension": "^2.3.0 || ^3.0.0", "scule": "^1.3.0", "unimport": "^3.13.1 || ^4.0.0 || ^5.0.0", "vite": "^5.4.17 || ^6.2.5", "vite-node": "^2.1.4 || ^3.0.0", "web-ext-run": "^0.2.3" }, "bin": { "wxt": "bin/wxt.mjs", "wxt-publish-extension": "bin/wxt-publish-extension.cjs" } }, "sha512-CdExyv2yWfpmPWFjhrKBA+nUSHOTRpRKqScod66AaLpMQ0famZ18tM0+4a9m7oX4Pts1XZH4nw79XQp06QsC2Q=="], + + "xdg-basedir": ["xdg-basedir@5.1.0", "", {}, "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ=="], + + "xml2js": ["xml2js@0.6.2", "", { "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" } }, "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA=="], + + "xmlbuilder": ["xmlbuilder@11.0.1", "", {}, "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="], + + "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], + + "yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="], + + "yaml": ["yaml@2.5.0", "", { "bin": "bin.mjs" }, "sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw=="], + + "yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="], + + "yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], + + "yauzl": ["yauzl@2.10.0", "", { "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" } }, "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g=="], + + "zip-dir": ["zip-dir@2.0.0", "", { "dependencies": { "async": "^3.2.0", "jszip": "^3.2.2" } }, "sha512-uhlsJZWz26FLYXOD6WVuq+fIcZ3aBPGo/cFdiLlv3KNwpa52IF3ISV8fLhQLiqVu5No3VhlqlgthN6gehil1Dg=="], + + "zod": ["zod@3.23.8", "", {}, "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g=="], + + "@aklinker1/rollup-plugin-visualizer/open": ["open@8.4.2", "", { "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", "is-wsl": "^2.2.0" } }, "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ=="], + + "@babel/code-frame/picocolors": ["picocolors@1.0.1", "", {}, "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew=="], + + "@babel/core/debug": ["debug@4.3.6", "", { "dependencies": { "ms": "2.1.2" } }, "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg=="], + + "@babel/helper-compilation-targets/browserslist": ["browserslist@4.23.3", "", { "dependencies": { "caniuse-lite": "^1.0.30001646", "electron-to-chromium": "^1.5.4", "node-releases": "^2.0.18", "update-browserslist-db": "^1.1.0" }, "bin": "cli.js" }, "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA=="], + + "@babel/highlight/chalk": ["chalk@2.4.2", "", { "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="], + + "@babel/highlight/js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], + + "@babel/highlight/picocolors": ["picocolors@1.0.1", "", {}, "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew=="], + + "@babel/traverse/debug": ["debug@4.3.6", "", { "dependencies": { "ms": "2.1.2" } }, "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg=="], + + "@devicefarmer/adbkit/debug": ["debug@4.3.6", "", { "dependencies": { "ms": "2.1.2" } }, "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg=="], + + "@pnpm/network.ca-file/graceful-fs": ["graceful-fs@4.2.10", "", {}, "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="], + + "@rollup/pluginutils/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], + + "@rollup/pluginutils/picomatch": ["picomatch@4.0.2", "", {}, "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg=="], + + "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.4.3", "", { "dependencies": { "@emnapi/wasi-threads": "1.0.2", "tslib": "^2.4.0" }, "bundled": true }, "sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g=="], + + "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.4.3", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ=="], + + "@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.0.2", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA=="], + + "@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.10", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@tybys/wasm-util": "^0.9.0" }, "bundled": true }, "sha512-bCsCyeZEwVErsGmyPNSzwfwFn4OdxBj0mmv6hOFucB/k81Ojdu68RbZdxYsRQUPc9l6SU5F/cG+bXgWs3oUgsQ=="], + + "@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.9.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw=="], + + "@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + + "ansi-align/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + + "babel-plugin-jsx-dom-expressions/@babel/helper-module-imports": ["@babel/helper-module-imports@7.18.6", "", { "dependencies": { "@babel/types": "^7.18.6" } }, "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA=="], + + "bl/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], + + "boxen/type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="], + + "chrome-launcher/escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="], + + "chrome-launcher/is-wsl": ["is-wsl@2.2.0", "", { "dependencies": { "is-docker": "^2.0.0" } }, "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww=="], + + "citty/consola": ["consola@3.2.3", "", {}, "sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ=="], + + "cli-highlight/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], + + "cli-highlight/yargs": ["yargs@16.2.0", "", { "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.0", "y18n": "^5.0.5", "yargs-parser": "^20.2.2" } }, "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw=="], + + "cliui/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + + "cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "cliui/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], + + "config-chain/ini": ["ini@1.3.8", "", {}, "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="], + + "cross-spawn/which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], + + "dom-serializer/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], + + "dot-prop/type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="], + + "dotenv-expand/dotenv": ["dotenv@16.4.5", "", {}, "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg=="], + + "execa/get-stream": ["get-stream@6.0.1", "", {}, "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg=="], + + "execa/onetime": ["onetime@6.0.0", "", { "dependencies": { "mimic-fn": "^4.0.0" } }, "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ=="], + + "execa/signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="], + + "extract-zip/debug": ["debug@4.3.6", "", { "dependencies": { "ms": "2.1.2" } }, "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg=="], + + "fx-runner/commander": ["commander@2.9.0", "", { "dependencies": { "graceful-readlink": ">= 1.0.0" } }, "sha512-bmkUukX8wAOjHdN26xj5c4ctEV22TQ7dQYhSmuckKhToXrkUn0iIaolHdIxYYqD55nhpSPA9zPQ1yP57GdXP2A=="], + + "global-directory/ini": ["ini@4.1.1", "", {}, "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g=="], + + "htmlparser2/domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="], + + "is-inside-container/is-docker": ["is-docker@3.0.0", "", { "bin": "cli.js" }, "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ=="], + + "lighthouse-logger/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], + + "log-symbols/is-unicode-supported": ["is-unicode-supported@1.3.0", "", {}, "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ=="], + + "log-update/slice-ansi": ["slice-ansi@7.1.0", "", { "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" } }, "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg=="], + + "lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], + + "mlly/pkg-types": ["pkg-types@1.3.1", "", { "dependencies": { "confbox": "^0.1.8", "mlly": "^1.7.4", "pathe": "^2.0.1" } }, "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ=="], + + "multimatch/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="], + + "node-notifier/is-wsl": ["is-wsl@2.2.0", "", { "dependencies": { "is-docker": "^2.0.0" } }, "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww=="], + + "node-notifier/semver": ["semver@7.6.3", "", { "bin": "bin/semver.js" }, "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A=="], + + "node-notifier/which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], + + "npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="], + + "ofetch/node-fetch-native": ["node-fetch-native@1.6.4", "", {}, "sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ=="], + + "package-json/semver": ["semver@7.6.3", "", { "bin": "bin/semver.js" }, "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A=="], + + "parse5-htmlparser2-tree-adapter/parse5": ["parse5@6.0.1", "", {}, "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw=="], + + "publish-browser-extension/open": ["open@9.1.0", "", { "dependencies": { "default-browser": "^4.0.0", "define-lazy-prop": "^3.0.0", "is-inside-container": "^1.0.0", "is-wsl": "^2.2.0" } }, "sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg=="], + + "publish-browser-extension/ora": ["ora@6.3.1", "", { "dependencies": { "chalk": "^5.0.0", "cli-cursor": "^4.0.0", "cli-spinners": "^2.6.1", "is-interactive": "^2.0.0", "is-unicode-supported": "^1.1.0", "log-symbols": "^5.1.0", "stdin-discarder": "^0.1.0", "strip-ansi": "^7.0.1", "wcwidth": "^1.0.1" } }, "sha512-ERAyNnZOfqM+Ao3RAvIXkYh5joP220yf59gVe2X/cI6SiCxIdi4c9HZKZD8R6q/RDXEje1THBju6iExiSsgJaQ=="], + + "rc/ini": ["ini@1.3.8", "", {}, "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="], + + "rc/strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="], + + "slice-ansi/ansi-styles": ["ansi-styles@6.2.1", "", {}, "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="], + + "slice-ansi/is-fullwidth-code-point": ["is-fullwidth-code-point@4.0.0", "", {}, "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ=="], + + "source-map-support/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], + + "tinyglobby/picomatch": ["picomatch@4.0.2", "", {}, "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg=="], + + "unimport/picomatch": ["picomatch@4.0.2", "", {}, "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg=="], + + "unimport/pkg-types": ["pkg-types@1.3.1", "", { "dependencies": { "confbox": "^0.1.8", "mlly": "^1.7.4", "pathe": "^2.0.1" } }, "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ=="], + + "update-browserslist-db/escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], + + "update-notifier/semver": ["semver@7.6.3", "", { "bin": "bin/semver.js" }, "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A=="], + + "vite/picomatch": ["picomatch@4.0.2", "", {}, "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg=="], + + "vite/rollup": ["rollup@4.41.0", "", { "dependencies": { "@types/estree": "1.0.7" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.41.0", "@rollup/rollup-android-arm64": "4.41.0", "@rollup/rollup-darwin-arm64": "4.41.0", "@rollup/rollup-darwin-x64": "4.41.0", "@rollup/rollup-freebsd-arm64": "4.41.0", "@rollup/rollup-freebsd-x64": "4.41.0", "@rollup/rollup-linux-arm-gnueabihf": "4.41.0", "@rollup/rollup-linux-arm-musleabihf": "4.41.0", "@rollup/rollup-linux-arm64-gnu": "4.41.0", "@rollup/rollup-linux-arm64-musl": "4.41.0", "@rollup/rollup-linux-loongarch64-gnu": "4.41.0", "@rollup/rollup-linux-powerpc64le-gnu": "4.41.0", "@rollup/rollup-linux-riscv64-gnu": "4.41.0", "@rollup/rollup-linux-riscv64-musl": "4.41.0", "@rollup/rollup-linux-s390x-gnu": "4.41.0", "@rollup/rollup-linux-x64-gnu": "4.41.0", "@rollup/rollup-linux-x64-musl": "4.41.0", "@rollup/rollup-win32-arm64-msvc": "4.41.0", "@rollup/rollup-win32-ia32-msvc": "4.41.0", "@rollup/rollup-win32-x64-msvc": "4.41.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-HqMFpUbWlf/tvcxBFNKnJyzc7Lk+XO3FGc3pbNBLqEbOz0gPLRgcrlS3UF4MfUrVlstOaP/q0kM6GVvi+LrLRg=="], + + "vite-node/vite": ["vite@5.4.2", "", { "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.41", "rollup": "^4.20.0" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || >=20.0.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" }, "optionalPeers": ["less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser"], "bin": "bin/vite.js" }, "sha512-dDrQTRHp5C1fTFzcSaMxjk6vdpKvT+2/mIdE07Gw2ykehT49O0z/VHS3zZ8iV/Gh8BJJKHWOe5RjaNrW5xf/GA=="], + + "vite-plugin-solid/vite": ["vite@5.4.2", "", { "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.41", "rollup": "^4.20.0" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || >=20.0.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" }, "optionalPeers": ["less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser"], "bin": "bin/vite.js" }, "sha512-dDrQTRHp5C1fTFzcSaMxjk6vdpKvT+2/mIdE07Gw2ykehT49O0z/VHS3zZ8iV/Gh8BJJKHWOe5RjaNrW5xf/GA=="], + + "vitefu/vite": ["vite@5.4.2", "", { "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.41", "rollup": "^4.20.0" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || >=20.0.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" }, "optionalPeers": ["less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser"], "bin": "bin/vite.js" }, "sha512-dDrQTRHp5C1fTFzcSaMxjk6vdpKvT+2/mIdE07Gw2ykehT49O0z/VHS3zZ8iV/Gh8BJJKHWOe5RjaNrW5xf/GA=="], + + "wrap-ansi/ansi-styles": ["ansi-styles@6.2.1", "", {}, "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="], + + "yargs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + + "@aklinker1/rollup-plugin-visualizer/open/define-lazy-prop": ["define-lazy-prop@2.0.0", "", {}, "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og=="], + + "@aklinker1/rollup-plugin-visualizer/open/is-wsl": ["is-wsl@2.2.0", "", { "dependencies": { "is-docker": "^2.0.0" } }, "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww=="], + + "@babel/core/debug/ms": ["ms@2.1.2", "", {}, "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="], + + "@babel/helper-compilation-targets/browserslist/caniuse-lite": ["caniuse-lite@1.0.30001653", "", {}, "sha512-XGWQVB8wFQ2+9NZwZ10GxTYC5hk0Fa+q8cSkr0tgvMhYhMHP/QC+WTgrePMDBWiWc/pV+1ik82Al20XOK25Gcw=="], + + "@babel/helper-compilation-targets/browserslist/electron-to-chromium": ["electron-to-chromium@1.5.13", "", {}, "sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q=="], + + "@babel/helper-compilation-targets/browserslist/node-releases": ["node-releases@2.0.18", "", {}, "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g=="], + + "@babel/helper-compilation-targets/browserslist/update-browserslist-db": ["update-browserslist-db@1.1.0", "", { "dependencies": { "escalade": "^3.1.2", "picocolors": "^1.0.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ=="], + + "@babel/highlight/chalk/ansi-styles": ["ansi-styles@3.2.1", "", { "dependencies": { "color-convert": "^1.9.0" } }, "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA=="], + + "@babel/highlight/chalk/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="], + + "@babel/highlight/chalk/supports-color": ["supports-color@5.5.0", "", { "dependencies": { "has-flag": "^3.0.0" } }, "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow=="], + + "@babel/traverse/debug/ms": ["ms@2.1.2", "", {}, "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="], + + "@devicefarmer/adbkit/debug/ms": ["ms@2.1.2", "", {}, "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="], + + "ansi-align/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + + "ansi-align/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "cli-highlight/yargs/cliui": ["cliui@7.0.4", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" } }, "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ=="], + + "cli-highlight/yargs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + + "cli-highlight/yargs/yargs-parser": ["yargs-parser@20.2.9", "", {}, "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w=="], + + "cliui/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + + "cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + + "cross-spawn/which/isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], + + "extract-zip/debug/ms": ["ms@2.1.2", "", {}, "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="], + + "lighthouse-logger/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], + + "log-update/slice-ansi/ansi-styles": ["ansi-styles@6.2.1", "", {}, "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="], + + "log-update/slice-ansi/is-fullwidth-code-point": ["is-fullwidth-code-point@5.0.0", "", { "dependencies": { "get-east-asian-width": "^1.0.0" } }, "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA=="], + + "mlly/pkg-types/confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="], + + "multimatch/minimatch/brace-expansion": ["brace-expansion@1.1.11", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="], + + "node-notifier/which/isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], + + "publish-browser-extension/open/default-browser": ["default-browser@4.0.0", "", { "dependencies": { "bundle-name": "^3.0.0", "default-browser-id": "^3.0.0", "execa": "^7.1.1", "titleize": "^3.0.0" } }, "sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA=="], + + "publish-browser-extension/open/is-wsl": ["is-wsl@2.2.0", "", { "dependencies": { "is-docker": "^2.0.0" } }, "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww=="], + + "publish-browser-extension/ora/cli-cursor": ["cli-cursor@4.0.0", "", { "dependencies": { "restore-cursor": "^4.0.0" } }, "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg=="], + + "publish-browser-extension/ora/is-unicode-supported": ["is-unicode-supported@1.3.0", "", {}, "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ=="], + + "publish-browser-extension/ora/log-symbols": ["log-symbols@5.1.0", "", { "dependencies": { "chalk": "^5.0.0", "is-unicode-supported": "^1.1.0" } }, "sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA=="], + + "publish-browser-extension/ora/stdin-discarder": ["stdin-discarder@0.1.0", "", { "dependencies": { "bl": "^5.0.0" } }, "sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ=="], + + "unimport/pkg-types/confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="], + + "vite-node/vite/esbuild": ["esbuild@0.21.5", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.21.5", "@esbuild/android-arm": "0.21.5", "@esbuild/android-arm64": "0.21.5", "@esbuild/android-x64": "0.21.5", "@esbuild/darwin-arm64": "0.21.5", "@esbuild/darwin-x64": "0.21.5", "@esbuild/freebsd-arm64": "0.21.5", "@esbuild/freebsd-x64": "0.21.5", "@esbuild/linux-arm": "0.21.5", "@esbuild/linux-arm64": "0.21.5", "@esbuild/linux-ia32": "0.21.5", "@esbuild/linux-loong64": "0.21.5", "@esbuild/linux-mips64el": "0.21.5", "@esbuild/linux-ppc64": "0.21.5", "@esbuild/linux-riscv64": "0.21.5", "@esbuild/linux-s390x": "0.21.5", "@esbuild/linux-x64": "0.21.5", "@esbuild/netbsd-x64": "0.21.5", "@esbuild/openbsd-x64": "0.21.5", "@esbuild/sunos-x64": "0.21.5", "@esbuild/win32-arm64": "0.21.5", "@esbuild/win32-ia32": "0.21.5", "@esbuild/win32-x64": "0.21.5" }, "bin": "bin/esbuild" }, "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw=="], + + "vite-node/vite/postcss": ["postcss@8.4.41", "", { "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.0.1", "source-map-js": "^1.2.0" } }, "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ=="], + + "vite-plugin-solid/vite/esbuild": ["esbuild@0.21.5", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.21.5", "@esbuild/android-arm": "0.21.5", "@esbuild/android-arm64": "0.21.5", "@esbuild/android-x64": "0.21.5", "@esbuild/darwin-arm64": "0.21.5", "@esbuild/darwin-x64": "0.21.5", "@esbuild/freebsd-arm64": "0.21.5", "@esbuild/freebsd-x64": "0.21.5", "@esbuild/linux-arm": "0.21.5", "@esbuild/linux-arm64": "0.21.5", "@esbuild/linux-ia32": "0.21.5", "@esbuild/linux-loong64": "0.21.5", "@esbuild/linux-mips64el": "0.21.5", "@esbuild/linux-ppc64": "0.21.5", "@esbuild/linux-riscv64": "0.21.5", "@esbuild/linux-s390x": "0.21.5", "@esbuild/linux-x64": "0.21.5", "@esbuild/netbsd-x64": "0.21.5", "@esbuild/openbsd-x64": "0.21.5", "@esbuild/sunos-x64": "0.21.5", "@esbuild/win32-arm64": "0.21.5", "@esbuild/win32-ia32": "0.21.5", "@esbuild/win32-x64": "0.21.5" }, "bin": "bin/esbuild" }, "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw=="], + + "vite-plugin-solid/vite/postcss": ["postcss@8.4.41", "", { "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.0.1", "source-map-js": "^1.2.0" } }, "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ=="], + + "vite/rollup/@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.41.0", "", { "os": "android", "cpu": "arm" }, "sha512-KxN+zCjOYHGwCl4UCtSfZ6jrq/qi88JDUtiEFk8LELEHq2Egfc/FgW+jItZiOLRuQfb/3xJSgFuNPC9jzggX+A=="], + + "vite/rollup/@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.41.0", "", { "os": "android", "cpu": "arm64" }, "sha512-yDvqx3lWlcugozax3DItKJI5j05B0d4Kvnjx+5mwiUpWramVvmAByYigMplaoAQ3pvdprGCTCE03eduqE/8mPQ=="], + + "vite/rollup/@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.41.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-2KOU574vD3gzcPSjxO0eyR5iWlnxxtmW1F5CkNOHmMlueKNCQkxR6+ekgWyVnz6zaZihpUNkGxjsYrkTJKhkaw=="], + + "vite/rollup/@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.41.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-gE5ACNSxHcEZyP2BA9TuTakfZvULEW4YAOtxl/A/YDbIir/wPKukde0BNPlnBiP88ecaN4BJI2TtAd+HKuZPQQ=="], + + "vite/rollup/@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.41.0", "", { "os": "linux", "cpu": "arm" }, "sha512-46OzWeqEVQyX3N2/QdiU/CMXYDH/lSHpgfBkuhl3igpZiaB3ZIfSjKuOnybFVBQzjsLwkus2mjaESy8H41SzvA=="], + + "vite/rollup/@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.41.0", "", { "os": "linux", "cpu": "arm" }, "sha512-lfgW3KtQP4YauqdPpcUZHPcqQXmTmH4nYU0cplNeW583CMkAGjtImw4PKli09NFi2iQgChk4e9erkwlfYem6Lg=="], + + "vite/rollup/@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.41.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-nn8mEyzMbdEJzT7cwxgObuwviMx6kPRxzYiOl6o/o+ChQq23gfdlZcUNnt89lPhhz3BYsZ72rp0rxNqBSfqlqw=="], + + "vite/rollup/@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.41.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-l+QK99je2zUKGd31Gh+45c4pGDAqZSuWQiuRFCdHYC2CSiO47qUWsCcenrI6p22hvHZrDje9QjwSMAFL3iwXwQ=="], + + "vite/rollup/@rollup/rollup-linux-powerpc64le-gnu": ["@rollup/rollup-linux-powerpc64le-gnu@4.41.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-eRDWR5t67/b2g8Q/S8XPi0YdbKcCs4WQ8vklNnUYLaSWF+Cbv2axZsp4jni6/j7eKvMLYCYdcsv8dcU+a6QNFg=="], + + "vite/rollup/@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.41.0", "", { "os": "linux", "cpu": "none" }, "sha512-TWrZb6GF5jsEKG7T1IHwlLMDRy2f3DPqYldmIhnA2DVqvvhY2Ai184vZGgahRrg8k9UBWoSlHv+suRfTN7Ua4A=="], + + "vite/rollup/@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.41.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-/L3pW48SxrWAlVsKCN0dGLB2bi8Nv8pr5S5ocSM+S0XCn5RCVCXqi8GVtHFsOBBCSeR+u9brV2zno5+mg3S4Aw=="], + + "vite/rollup/@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.41.0", "", { "os": "linux", "cpu": "x64" }, "sha512-XMLeKjyH8NsEDCRptf6LO8lJk23o9wvB+dJwcXMaH6ZQbbkHu2dbGIUindbMtRN6ux1xKi16iXWu6q9mu7gDhQ=="], + + "vite/rollup/@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.41.0", "", { "os": "linux", "cpu": "x64" }, "sha512-m/P7LycHZTvSQeXhFmgmdqEiTqSV80zn6xHaQ1JSqwCtD1YGtwEK515Qmy9DcB2HK4dOUVypQxvhVSy06cJPEg=="], + + "vite/rollup/@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.41.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-4yodtcOrFHpbomJGVEqZ8fzD4kfBeCbpsUy5Pqk4RluXOdsWdjLnjhiKy2w3qzcASWd04fp52Xz7JKarVJ5BTg=="], + + "vite/rollup/@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.41.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-tmazCrAsKzdkXssEc65zIE1oC6xPHwfy9d5Ta25SRCDOZS+I6RypVVShWALNuU9bxIfGA0aqrmzlzoM5wO5SPQ=="], + + "vite/rollup/@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.41.0", "", { "os": "win32", "cpu": "x64" }, "sha512-h1J+Yzjo/X+0EAvR2kIXJDuTuyT7drc+t2ALY0nIcGPbTatNOf0VWdhEA2Z4AAjv6X1NJV7SYo5oCTYRJhSlVA=="], + + "vite/rollup/@types/estree": ["@types/estree@1.0.7", "", {}, "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ=="], + + "vitefu/vite/esbuild": ["esbuild@0.21.5", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.21.5", "@esbuild/android-arm": "0.21.5", "@esbuild/android-arm64": "0.21.5", "@esbuild/android-x64": "0.21.5", "@esbuild/darwin-arm64": "0.21.5", "@esbuild/darwin-x64": "0.21.5", "@esbuild/freebsd-arm64": "0.21.5", "@esbuild/freebsd-x64": "0.21.5", "@esbuild/linux-arm": "0.21.5", "@esbuild/linux-arm64": "0.21.5", "@esbuild/linux-ia32": "0.21.5", "@esbuild/linux-loong64": "0.21.5", "@esbuild/linux-mips64el": "0.21.5", "@esbuild/linux-ppc64": "0.21.5", "@esbuild/linux-riscv64": "0.21.5", "@esbuild/linux-s390x": "0.21.5", "@esbuild/linux-x64": "0.21.5", "@esbuild/netbsd-x64": "0.21.5", "@esbuild/openbsd-x64": "0.21.5", "@esbuild/sunos-x64": "0.21.5", "@esbuild/win32-arm64": "0.21.5", "@esbuild/win32-ia32": "0.21.5", "@esbuild/win32-x64": "0.21.5" }, "bin": "bin/esbuild" }, "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw=="], + + "vitefu/vite/postcss": ["postcss@8.4.41", "", { "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.0.1", "source-map-js": "^1.2.0" } }, "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ=="], + + "yargs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + + "yargs/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "@babel/helper-compilation-targets/browserslist/update-browserslist-db/picocolors": ["picocolors@1.0.1", "", {}, "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew=="], + + "@babel/highlight/chalk/ansi-styles/color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="], + + "@babel/highlight/chalk/supports-color/has-flag": ["has-flag@3.0.0", "", {}, "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="], + + "ansi-align/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + + "cli-highlight/yargs/cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "cli-highlight/yargs/cliui/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], + + "cli-highlight/yargs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + + "cli-highlight/yargs/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "publish-browser-extension/open/default-browser/bundle-name": ["bundle-name@3.0.0", "", { "dependencies": { "run-applescript": "^5.0.0" } }, "sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw=="], + + "publish-browser-extension/open/default-browser/default-browser-id": ["default-browser-id@3.0.0", "", { "dependencies": { "bplist-parser": "^0.2.0", "untildify": "^4.0.0" } }, "sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA=="], + + "publish-browser-extension/ora/cli-cursor/restore-cursor": ["restore-cursor@4.0.0", "", { "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" } }, "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg=="], + + "vite-node/vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.21.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="], + + "vite-node/vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.21.5", "", { "os": "android", "cpu": "arm" }, "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg=="], + + "vite-node/vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.21.5", "", { "os": "android", "cpu": "arm64" }, "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A=="], + + "vite-node/vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.21.5", "", { "os": "android", "cpu": "x64" }, "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA=="], + + "vite-node/vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.21.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ=="], + + "vite-node/vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.21.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw=="], + + "vite-node/vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.21.5", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g=="], + + "vite-node/vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.21.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ=="], + + "vite-node/vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.21.5", "", { "os": "linux", "cpu": "arm" }, "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA=="], + + "vite-node/vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.21.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q=="], + + "vite-node/vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.21.5", "", { "os": "linux", "cpu": "ia32" }, "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg=="], + + "vite-node/vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg=="], + + "vite-node/vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg=="], + + "vite-node/vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.21.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w=="], + + "vite-node/vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA=="], + + "vite-node/vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.21.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A=="], + + "vite-node/vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.21.5", "", { "os": "linux", "cpu": "x64" }, "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ=="], + + "vite-node/vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.21.5", "", { "os": "none", "cpu": "x64" }, "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg=="], + + "vite-node/vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.21.5", "", { "os": "openbsd", "cpu": "x64" }, "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow=="], + + "vite-node/vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.21.5", "", { "os": "sunos", "cpu": "x64" }, "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg=="], + + "vite-node/vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.21.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A=="], + + "vite-node/vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.21.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA=="], + + "vite-node/vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.21.5", "", { "os": "win32", "cpu": "x64" }, "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw=="], + + "vite-node/vite/postcss/nanoid": ["nanoid@3.3.7", "", { "bin": "bin/nanoid.cjs" }, "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g=="], + + "vite-node/vite/postcss/picocolors": ["picocolors@1.0.1", "", {}, "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew=="], + + "vite-node/vite/postcss/source-map-js": ["source-map-js@1.2.0", "", {}, "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg=="], + + "vite-plugin-solid/vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.21.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="], + + "vite-plugin-solid/vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.21.5", "", { "os": "android", "cpu": "arm" }, "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg=="], + + "vite-plugin-solid/vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.21.5", "", { "os": "android", "cpu": "arm64" }, "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A=="], + + "vite-plugin-solid/vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.21.5", "", { "os": "android", "cpu": "x64" }, "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA=="], + + "vite-plugin-solid/vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.21.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ=="], + + "vite-plugin-solid/vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.21.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw=="], + + "vite-plugin-solid/vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.21.5", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g=="], + + "vite-plugin-solid/vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.21.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ=="], + + "vite-plugin-solid/vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.21.5", "", { "os": "linux", "cpu": "arm" }, "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA=="], + + "vite-plugin-solid/vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.21.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q=="], + + "vite-plugin-solid/vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.21.5", "", { "os": "linux", "cpu": "ia32" }, "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg=="], + + "vite-plugin-solid/vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg=="], + + "vite-plugin-solid/vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg=="], + + "vite-plugin-solid/vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.21.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w=="], + + "vite-plugin-solid/vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA=="], + + "vite-plugin-solid/vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.21.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A=="], + + "vite-plugin-solid/vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.21.5", "", { "os": "linux", "cpu": "x64" }, "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ=="], + + "vite-plugin-solid/vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.21.5", "", { "os": "none", "cpu": "x64" }, "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg=="], + + "vite-plugin-solid/vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.21.5", "", { "os": "openbsd", "cpu": "x64" }, "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow=="], + + "vite-plugin-solid/vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.21.5", "", { "os": "sunos", "cpu": "x64" }, "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg=="], + + "vite-plugin-solid/vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.21.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A=="], + + "vite-plugin-solid/vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.21.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA=="], + + "vite-plugin-solid/vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.21.5", "", { "os": "win32", "cpu": "x64" }, "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw=="], + + "vite-plugin-solid/vite/postcss/nanoid": ["nanoid@3.3.7", "", { "bin": "bin/nanoid.cjs" }, "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g=="], + + "vite-plugin-solid/vite/postcss/picocolors": ["picocolors@1.0.1", "", {}, "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew=="], + + "vite-plugin-solid/vite/postcss/source-map-js": ["source-map-js@1.2.0", "", {}, "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg=="], + + "vitefu/vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.21.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="], + + "vitefu/vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.21.5", "", { "os": "android", "cpu": "arm" }, "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg=="], + + "vitefu/vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.21.5", "", { "os": "android", "cpu": "arm64" }, "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A=="], + + "vitefu/vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.21.5", "", { "os": "android", "cpu": "x64" }, "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA=="], + + "vitefu/vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.21.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ=="], + + "vitefu/vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.21.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw=="], + + "vitefu/vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.21.5", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g=="], + + "vitefu/vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.21.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ=="], + + "vitefu/vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.21.5", "", { "os": "linux", "cpu": "arm" }, "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA=="], + + "vitefu/vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.21.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q=="], + + "vitefu/vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.21.5", "", { "os": "linux", "cpu": "ia32" }, "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg=="], + + "vitefu/vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg=="], + + "vitefu/vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg=="], + + "vitefu/vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.21.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w=="], + + "vitefu/vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA=="], + + "vitefu/vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.21.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A=="], + + "vitefu/vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.21.5", "", { "os": "linux", "cpu": "x64" }, "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ=="], + + "vitefu/vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.21.5", "", { "os": "none", "cpu": "x64" }, "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg=="], + + "vitefu/vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.21.5", "", { "os": "openbsd", "cpu": "x64" }, "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow=="], + + "vitefu/vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.21.5", "", { "os": "sunos", "cpu": "x64" }, "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg=="], + + "vitefu/vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.21.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A=="], + + "vitefu/vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.21.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA=="], + + "vitefu/vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.21.5", "", { "os": "win32", "cpu": "x64" }, "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw=="], + + "vitefu/vite/postcss/nanoid": ["nanoid@3.3.7", "", { "bin": "bin/nanoid.cjs" }, "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g=="], + + "vitefu/vite/postcss/picocolors": ["picocolors@1.0.1", "", {}, "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew=="], + + "vitefu/vite/postcss/source-map-js": ["source-map-js@1.2.0", "", {}, "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg=="], + + "yargs/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + + "@babel/highlight/chalk/ansi-styles/color-convert/color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="], + + "cli-highlight/yargs/cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + + "cli-highlight/yargs/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + + "publish-browser-extension/open/default-browser/bundle-name/run-applescript": ["run-applescript@5.0.0", "", { "dependencies": { "execa": "^5.0.0" } }, "sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg=="], + + "publish-browser-extension/ora/cli-cursor/restore-cursor/onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="], + + "publish-browser-extension/ora/cli-cursor/restore-cursor/signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="], + + "publish-browser-extension/open/default-browser/bundle-name/run-applescript/execa": ["execa@5.1.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", "human-signals": "^2.1.0", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^4.0.1", "onetime": "^5.1.2", "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" } }, "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg=="], + + "publish-browser-extension/ora/cli-cursor/restore-cursor/onetime/mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="], + + "publish-browser-extension/open/default-browser/bundle-name/run-applescript/execa/get-stream": ["get-stream@6.0.1", "", {}, "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg=="], + + "publish-browser-extension/open/default-browser/bundle-name/run-applescript/execa/human-signals": ["human-signals@2.1.0", "", {}, "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw=="], + + "publish-browser-extension/open/default-browser/bundle-name/run-applescript/execa/is-stream": ["is-stream@2.0.1", "", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="], + + "publish-browser-extension/open/default-browser/bundle-name/run-applescript/execa/npm-run-path": ["npm-run-path@4.0.1", "", { "dependencies": { "path-key": "^3.0.0" } }, "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw=="], + + "publish-browser-extension/open/default-browser/bundle-name/run-applescript/execa/onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="], + + "publish-browser-extension/open/default-browser/bundle-name/run-applescript/execa/signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="], + + "publish-browser-extension/open/default-browser/bundle-name/run-applescript/execa/strip-final-newline": ["strip-final-newline@2.0.0", "", {}, "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA=="], + + "publish-browser-extension/open/default-browser/bundle-name/run-applescript/execa/onetime/mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="], + } +} diff --git a/spot/bun.lockb b/spot/bun.lockb deleted file mode 100755 index 18d7c5959..000000000 Binary files a/spot/bun.lockb and /dev/null differ diff --git a/spot/entrypoints/background.ts b/spot/entrypoints/background.ts index b393ca570..633385aa1 100644 --- a/spot/entrypoints/background.ts +++ b/spot/entrypoints/background.ts @@ -943,7 +943,7 @@ export default defineBackground(() => { }); } for (const tab of await chrome.tabs.query({})) { - if (tab.url?.match(/(chrome|chrome-extension):\/\//gi)) { + if (tab.url?.match(/(chrome|chrome-extension):\/\//gi) || !tab.id) { continue; } const res = await browser.scripting.executeScript({ @@ -953,6 +953,7 @@ export default defineBackground(() => { console.log('restoring content at', res) } await checkTokenValidity(); + void initializeOffscreenDocument(); }); void initializeOffscreenDocument(); @@ -965,13 +966,11 @@ export default defineBackground(() => { (c: { contextType: string }) => c.contextType === "OFFSCREEN_DOCUMENT", ); if (offscreenDocument) { - return; - // TODO: check manifestv3 for reloading context - // try { - // await browser.offscreen.closeDocument(); - // } catch (e) { - // console.trace(e) - // } + try { + await browser.offscreen.closeDocument(); + } catch (e) { + console.error("Spot: error closing old offscreen document", e); + } } try { diff --git a/spot/entrypoints/content/RecordingControls.tsx b/spot/entrypoints/content/RecordingControls.tsx index ecbef8c85..e36b70950 100644 --- a/spot/entrypoints/content/RecordingControls.tsx +++ b/spot/entrypoints/content/RecordingControls.tsx @@ -1,7 +1,7 @@ import { createSignal, onCleanup, createEffect } from "solid-js"; import { STATES, formatMsToTime } from "~/entrypoints/content/utils"; import micOn from "~/assets/mic-on.svg"; -import { createDraggable } from "@neodrag/solid"; +import { createDraggable } from '@neodrag/solid'; interface IRControls { pause: () => void; @@ -144,7 +144,7 @@ function RecordingControls({ {recording() ? (
{(option) => ( diff --git a/spot/entrypoints/popup/components/AudioPicker.tsx b/spot/entrypoints/popup/components/AudioPicker.tsx index 9d24198eb..e462a05a7 100644 --- a/spot/entrypoints/popup/components/AudioPicker.tsx +++ b/spot/entrypoints/popup/components/AudioPicker.tsx @@ -1,4 +1,4 @@ -import { Component, For } from "solid-js"; +import { Component } from "solid-js"; import micOff from "~/assets/mic-off-red.svg"; import micOn from "~/assets/mic-on-dark.svg"; import Dropdown from "~/entrypoints/popup/Dropdown"; diff --git a/spot/entrypoints/popup/hooks/useAudioDevices.ts b/spot/entrypoints/popup/hooks/useAudioDevices.ts index 25ae807d3..888831f3a 100644 --- a/spot/entrypoints/popup/hooks/useAudioDevices.ts +++ b/spot/entrypoints/popup/hooks/useAudioDevices.ts @@ -51,7 +51,7 @@ export function useAudioDevices() { void checkAudioDevices(); } }); - } else if (audioDevices.length > 0) { + } else if (audioDevices.length > 0 && selectedAudioDevice() === "") { chrome.storage.local.set({ audioPerm: granted }); setAudioDevices(audioDevices); setSelectedAudioDevice(audioDevices[0]?.id || ""); diff --git a/spot/package.json b/spot/package.json index a49dcb1bd..b6234d698 100644 --- a/spot/package.json +++ b/spot/package.json @@ -2,7 +2,7 @@ "name": "spot", "description": "manifest.json description", "private": true, - "version": "1.0.21", + "version": "1.0.24", "type": "module", "scripts": { "dev": "wxt", @@ -18,19 +18,21 @@ "dependencies": { "@neodrag/solid": "^2.3.0", "@openreplay/network-proxy": "^1.1.0", + "@tailwindcss/postcss": "^4.1.7", + "@tailwindcss/vite": "^4.1.7", "@thedutchcoder/postcss-rem-to-px": "^0.0.2", "autoprefixer": "^10.4.21", "postcss": "^8.5.3", "prettier": "^3.5.3", - "solid-js": "^1.9.5", - "tailwindcss": "^3.4.4", + "solid-js": "^1.9.7", + "tailwindcss": "4.1.7", "web-vitals": "^4.2.4" }, "devDependencies": { "@wxt-dev/module-solid": "^1.1.3", - "daisyui": "^4.12.10", + "daisyui": "5.0.37", "typescript": "^5.8.2", - "wxt": "0.19.29" + "wxt": "0.20.6" }, "packageManager": "yarn@4.5.3" } diff --git a/spot/postcss.config.js b/spot/postcss.config.js index cb3185f4b..f03d1f3ce 100644 --- a/spot/postcss.config.js +++ b/spot/postcss.config.js @@ -1,7 +1,7 @@ export default { plugins: { + "@tailwindcss/postcss": {}, "@thedutchcoder/postcss-rem-to-px": {}, - tailwindcss: {}, autoprefixer: {}, }, }; diff --git a/spot/wxt.config.ts b/spot/wxt.config.ts index 359679d6b..3095bdfb4 100644 --- a/spot/wxt.config.ts +++ b/spot/wxt.config.ts @@ -1,4 +1,5 @@ import { defineConfig } from "wxt"; +import tailwindcss from "@tailwindcss/vite"; // See https://wxt.dev/api/config.html export default defineConfig({ @@ -30,7 +31,12 @@ export default defineConfig({ "debugger", ], }, - runner: { + webExt: { chromiumArgs: ['--user-data-dir=./.wxt/chrome-data'], - } + }, + vite: (env) => ({ + plugins: [tailwindcss()], + resolve: { + conditions: ['development', 'browser', 'module', 'default'], + }}), }); diff --git a/tracker/tracker/CHANGELOG.md b/tracker/tracker/CHANGELOG.md index e0da1b36b..b460d9b02 100644 --- a/tracker/tracker/CHANGELOG.md +++ b/tracker/tracker/CHANGELOG.md @@ -2,6 +2,14 @@ - support for Long Animation Task tracking - support for timing information in resource tracking +- add incident events for tracker +```js +import { tracker } from '@openreplay/tracker' + +// call incident function and pass label, startTime, and endTime (label and endTime are optional) +tracker.incident({ label: 'incident', startTime: Date.now() }) + +``` ## 16.3.0 diff --git a/tracker/tracker/package.json b/tracker/tracker/package.json index 6487154fe..5ed723567 100644 --- a/tracker/tracker/package.json +++ b/tracker/tracker/package.json @@ -1,7 +1,7 @@ { "name": "@openreplay/tracker", "description": "The OpenReplay tracker main package", - "version": "17.0.0", + "version": "17.0.0-beta.0", "keywords": [ "logging", "replay" diff --git a/tracker/tracker/src/common/messages.gen.ts b/tracker/tracker/src/common/messages.gen.ts index 6ed1f3f82..e0b2251b9 100644 --- a/tracker/tracker/src/common/messages.gen.ts +++ b/tracker/tracker/src/common/messages.gen.ts @@ -71,6 +71,7 @@ export declare const enum Type { NetworkRequest = 83, WSChannel = 84, ResourceTiming = 85, + Incident = 87, LongAnimationTask = 89, InputChange = 112, SelectionChange = 113, @@ -593,6 +594,13 @@ export type ResourceTiming = [ /*stalled:*/ number, ] +export type Incident = [ + /*type:*/ Type.Incident, + /*label:*/ string, + /*startTime:*/ number, + /*endTime:*/ number, +] + export type LongAnimationTask = [ /*type:*/ Type.LongAnimationTask, /*name:*/ string, @@ -697,5 +705,5 @@ export type WebVitals = [ ] -type Message = Timestamp | SetPageLocationDeprecated | SetViewportSize | SetViewportScroll | CreateDocument | CreateElementNode | CreateTextNode | MoveNode | RemoveNode | SetNodeAttribute | RemoveNodeAttribute | SetNodeData | SetNodeScroll | SetInputTarget | SetInputValue | SetInputChecked | MouseMove | NetworkRequestDeprecated | ConsoleLog | PageLoadTiming | PageRenderTiming | CustomEvent | UserID | UserAnonymousID | Metadata | StringDictGlobal | SetNodeAttributeDictGlobal | CSSInsertRule | CSSDeleteRule | Fetch | Profiler | OTable | StateAction | ReduxDeprecated | Vuex | MobX | NgRx | GraphQLDeprecated | PerformanceTrack | StringDictDeprecated | SetNodeAttributeDictDeprecated | StringDict | SetNodeAttributeDict | ResourceTimingDeprecatedDeprecated | ConnectionInformation | SetPageVisibility | LoadFontFace | SetNodeFocus | LongTask | SetNodeAttributeURLBased | SetCSSDataURLBased | TechnicalInfo | CustomIssue | CSSInsertRuleURLBased | MouseClick | MouseClickDeprecated | CreateIFrameDocument | AdoptedSSReplaceURLBased | AdoptedSSInsertRuleURLBased | AdoptedSSDeleteRule | AdoptedSSAddOwner | AdoptedSSRemoveOwner | JSException | Zustand | BatchMetadata | PartitionedMessage | NetworkRequest | WSChannel | ResourceTiming | LongAnimationTask | InputChange | SelectionChange | MouseThrashing | UnbindNodes | ResourceTimingDeprecated | TabChange | TabData | CanvasNode | TagTrigger | Redux | SetPageLocation | GraphQL | WebVitals +type Message = Timestamp | SetPageLocationDeprecated | SetViewportSize | SetViewportScroll | CreateDocument | CreateElementNode | CreateTextNode | MoveNode | RemoveNode | SetNodeAttribute | RemoveNodeAttribute | SetNodeData | SetNodeScroll | SetInputTarget | SetInputValue | SetInputChecked | MouseMove | NetworkRequestDeprecated | ConsoleLog | PageLoadTiming | PageRenderTiming | CustomEvent | UserID | UserAnonymousID | Metadata | StringDictGlobal | SetNodeAttributeDictGlobal | CSSInsertRule | CSSDeleteRule | Fetch | Profiler | OTable | StateAction | ReduxDeprecated | Vuex | MobX | NgRx | GraphQLDeprecated | PerformanceTrack | StringDictDeprecated | SetNodeAttributeDictDeprecated | StringDict | SetNodeAttributeDict | ResourceTimingDeprecatedDeprecated | ConnectionInformation | SetPageVisibility | LoadFontFace | SetNodeFocus | LongTask | SetNodeAttributeURLBased | SetCSSDataURLBased | TechnicalInfo | CustomIssue | CSSInsertRuleURLBased | MouseClick | MouseClickDeprecated | CreateIFrameDocument | AdoptedSSReplaceURLBased | AdoptedSSInsertRuleURLBased | AdoptedSSDeleteRule | AdoptedSSAddOwner | AdoptedSSRemoveOwner | JSException | Zustand | BatchMetadata | PartitionedMessage | NetworkRequest | WSChannel | ResourceTiming | Incident | LongAnimationTask | InputChange | SelectionChange | MouseThrashing | UnbindNodes | ResourceTimingDeprecated | TabChange | TabData | CanvasNode | TagTrigger | Redux | SetPageLocation | GraphQL | WebVitals export default Message diff --git a/tracker/tracker/src/main/app/messages.gen.ts b/tracker/tracker/src/main/app/messages.gen.ts index 1421824ce..3d4aaace2 100644 --- a/tracker/tracker/src/main/app/messages.gen.ts +++ b/tracker/tracker/src/main/app/messages.gen.ts @@ -946,6 +946,19 @@ export function ResourceTiming( ] } +export function Incident( + label: string, + startTime: number, + endTime: number, +): Messages.Incident { + return [ + Messages.Type.Incident, + label, + startTime, + endTime, + ] +} + export function LongAnimationTask( name: string, duration: number, diff --git a/tracker/tracker/src/main/app/observer/observer.ts b/tracker/tracker/src/main/app/observer/observer.ts index 8f7db01f9..09e02caaf 100644 --- a/tracker/tracker/src/main/app/observer/observer.ts +++ b/tracker/tracker/src/main/app/observer/observer.ts @@ -43,6 +43,15 @@ async function parseUseEl( let [url, symbolId] = href.split('#') + if (!url && !symbolId) { + console.warn('Openreplay: Invalid xlink:href or href found on .') + return + } + + if (iconCache[symbolId]) { + return iconCache[symbolId] + } + // happens if svg spritemap is local, fastest case for us if (!url && symbolId) { const symbol = document.querySelector(href) @@ -61,16 +70,6 @@ async function parseUseEl( return } } - - if (!url && !symbolId) { - console.warn('Openreplay: Invalid xlink:href or href found on .') - return - } - - if (iconCache[symbolId]) { - return iconCache[symbolId] - } - let svgDoc: Document if (svgUrlCache[url]) { if (svgUrlCache[url] === 1) { diff --git a/tracker/tracker/src/main/app/observer/top_observer.ts b/tracker/tracker/src/main/app/observer/top_observer.ts index cca5cd0d1..741889922 100644 --- a/tracker/tracker/src/main/app/observer/top_observer.ts +++ b/tracker/tracker/src/main/app/observer/top_observer.ts @@ -14,7 +14,7 @@ export enum InlineCssMode { Disabled = 0, /** will attempt to record the linked css file as AdoptedStyleSheet object */ Inline = 1, - /** will fetch the file, then simulated AdoptedStyleSheets behavior programmaticaly for the replay */ + /** will fetch the file, then simulate AdoptedStyleSheets behavior programmaticaly for the replay */ InlineFetched = 2, /** will fetch the file, then save it as plain css inside