From 2362304a8c1649dca879be9222ce10b6884a0fc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B8ssum?= <1959615+joglr@users.noreply.github.com> Date: Mon, 8 May 2023 20:34:15 +0000 Subject: [PATCH 01/26] Prevent unnecessary renders --- src/components/FeedbackCard.tsx | 7 ++++--- src/components/GlobalInfo.tsx | 6 +++--- src/components/HiddenFiles.tsx | 6 +++--- src/components/Options.tsx | 5 +++-- src/components/SearchCard.tsx | 4 ++-- src/routes/$repo.$.tsx | 33 +++++++++++++++++++++++---------- 6 files changed, 38 insertions(+), 23 deletions(-) diff --git a/src/components/FeedbackCard.tsx b/src/components/FeedbackCard.tsx index 56e50a581..0840d7bbf 100644 --- a/src/components/FeedbackCard.tsx +++ b/src/components/FeedbackCard.tsx @@ -1,7 +1,8 @@ -import { mdiMessageDraw, mdiAlert, mdiTimelineQuestionOutline, mdiAlertCircleOutline, mdiForum } from "@mdi/js" +import { mdiMessageDraw, mdiAlertCircleOutline, mdiForum } from "@mdi/js" import Icon from "@mdi/react" +import { memo } from "react" -export function FeedbackCard() { +export const FeedbackCard = memo(function FeedbackCard() { return (
@@ -28,4 +29,4 @@ export function FeedbackCard() {
) -} +}) diff --git a/src/components/GlobalInfo.tsx b/src/components/GlobalInfo.tsx index 21d8b8c93..316a7a918 100644 --- a/src/components/GlobalInfo.tsx +++ b/src/components/GlobalInfo.tsx @@ -1,7 +1,7 @@ import { Form, Link, useLocation, useNavigate, useNavigation } from "@remix-run/react" import { dateTimeFormatShort } from "~/util" import { useData } from "../contexts/DataContext" -import { useEffect, useState } from "react" +import { memo, useEffect, useState } from "react" import { RevisionSelect } from "./RevisionSelect" import { mdiFolder, mdiRefresh, mdiArrowTopLeft } from "@mdi/js" import { Code } from "./util" @@ -11,7 +11,7 @@ import { useClient } from "~/hooks" const title = "Git Truck" const analyzingTitle = "Analyzing | Git Truck" -export function GlobalInfo() { +export const GlobalInfo = memo(function GlobalInfo() { const client = useClient() const { analyzerData, repo } = useData() const transitionState = useNavigation() @@ -87,4 +87,4 @@ export function GlobalInfo() {
) -} +}) diff --git a/src/components/HiddenFiles.tsx b/src/components/HiddenFiles.tsx index 02dbb9014..ffc3703ed 100644 --- a/src/components/HiddenFiles.tsx +++ b/src/components/HiddenFiles.tsx @@ -4,7 +4,7 @@ import { Form, useLocation, useNavigation } from "@remix-run/react" import { mdiEyeOff, mdiEye } from "@mdi/js" import { ChevronButton } from "./ChevronButton" import { Icon } from "@mdi/react" -import { useId } from "react" +import { memo, useId } from "react" function hiddenFileFormat(ignored: string) { if (!ignored.includes("/")) return ignored @@ -12,7 +12,7 @@ function hiddenFileFormat(ignored: string) { return split[split.length - 1] } -export function HiddenFiles() { +export const HiddenFiles = memo(function HiddenFiles() { const location = useLocation() const [expanded, setExpanded] = useBoolean(false) const navigationState = useNavigation() @@ -54,4 +54,4 @@ export function HiddenFiles() { ) : null} ) -} +}) diff --git a/src/components/Options.tsx b/src/components/Options.tsx index 52e46e1a1..136da3982 100644 --- a/src/components/Options.tsx +++ b/src/components/Options.tsx @@ -6,6 +6,7 @@ import { Chart, useOptions } from "../contexts/OptionsContext" import { CheckboxWithLabel } from "./util" import { Icon } from "@mdi/react" import { mdiChartBubble, mdiDatabaseOutline, mdiCogOutline } from "@mdi/js" +import { memo } from "react" function isMetricWithHistoricalOption(metric: MetricType) { switch (metric) { @@ -16,7 +17,7 @@ function isMetricWithHistoricalOption(metric: MetricType) { return false } -export function Options() { +export const Options = memo(function Options() { const { metricType, chartType, @@ -80,4 +81,4 @@ export function Options() { ) -} +}) diff --git a/src/components/SearchCard.tsx b/src/components/SearchCard.tsx index 8c568b8dc..be647ea4a 100644 --- a/src/components/SearchCard.tsx +++ b/src/components/SearchCard.tsx @@ -26,7 +26,7 @@ function findSearchResults(tree: HydratedGitTreeObject, searchString: string) { return searchResults } -export function SearchCard() { +export const SearchCard = memo(function SearchCard() { const searchFieldRef = useRef(null) const [isTransitioning, startTransition] = useTransition() const { setSearchText, searchText, searchResults, setSearchResults } = useSearch() @@ -76,7 +76,7 @@ export function SearchCard() { {searchResults.length > 0 ? : null} ) -} +}) const SearchResults = memo(function SearchResults() { const { setPath } = usePath() diff --git a/src/routes/$repo.$.tsx b/src/routes/$repo.$.tsx index 70646c89b..407bf7c7f 100644 --- a/src/routes/$repo.$.tsx +++ b/src/routes/$repo.$.tsx @@ -1,5 +1,6 @@ import { resolve } from "path" -import { useEffect, useRef, useState } from "react" +import type { Dispatch, SetStateAction } from "react" +import { memo, useEffect, useRef, useState } from "react" import { useBoolean, useMouse } from "react-use" import type { ActionFunction, LoaderArgs } from "@remix-run/node" import { redirect } from "@remix-run/node" @@ -196,7 +197,7 @@ export const ErrorBoundary = () => { ) } -function UpdateNotifier() { +const UpdateNotifier = memo(function UpdateNotifier() { const { gitTruckInfo } = useData() return (
@@ -207,7 +208,7 @@ function UpdateNotifier() {

) -} +}) export default function Repo() { const client = useClient() @@ -232,13 +233,7 @@ export default function Repo() {
- +
{client ? :
}
@@ -273,6 +268,24 @@ export default function Repo() { ) } +const FullscreenButton = memo(function FullscreenButton({ + setIsFullscreen, + isFullscreen, +}: { + setIsFullscreen: Dispatch> + isFullscreen: boolean +}) { + return ( + + ) +}) + function ChartWrapper({ hoveredObject, setHoveredObject, From c1c74f837c9433f7040be675817212cdb8254f06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B8ssum?= <1959615+joglr@users.noreply.github.com> Date: Mon, 8 May 2023 20:38:02 +0000 Subject: [PATCH 02/26] Defer legend arrow movement --- src/components/legend/Legend.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/legend/Legend.tsx b/src/components/legend/Legend.tsx index c4ef13a72..cf0522bf0 100644 --- a/src/components/legend/Legend.tsx +++ b/src/components/legend/Legend.tsx @@ -8,6 +8,7 @@ import { PointLegend } from "./PointLegend" import { SegmentLegend } from "./SegmentLegend" import { GradientLegend } from "./GradiantLegend" import type { HydratedGitObject } from "~/analyzer/model" +import { useDeferredValue } from "react" export type LegendType = "POINT" | "GRADIENT" | "SEGMENTS" @@ -22,6 +23,7 @@ export function Legend({ }) { const { metricType, authorshipType } = useOptions() const [metricsData] = useMetrics() + const deferredHoveredObject = useDeferredValue(hoveredObject) const metricCache = metricsData[authorshipType].get(metricType) ?? undefined @@ -30,13 +32,13 @@ export function Legend({ let legend: JSX.Element = <> switch (getMetricLegendType(metricType)) { case "POINT": - legend = + legend = break case "GRADIENT": - legend = + legend = break case "SEGMENTS": - legend = + legend = break } From f2582524194758139e195f4176e681018dbb5838 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B8ssum?= <1959615+joglr@users.noreply.github.com> Date: Wed, 17 May 2023 19:26:13 +0000 Subject: [PATCH 03/26] Update dependencies --- package-lock.json | 962 ++++++++++++++++++++++++++-------------------- package.json | 26 +- 2 files changed, 553 insertions(+), 435 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8aaa62020..1e453cc85 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,11 +15,11 @@ "@mdi/js": "^7.2.96", "@mdi/react": "^1.6.1", "@react-spring/web": "^9.7.2", - "@remix-run/dev": "^1.16.0", - "@remix-run/eslint-config": "^1.16.0", - "@remix-run/node": "^1.16.0", - "@remix-run/react": "^1.16.0", - "@remix-run/serve": "^1.16.0", + "@remix-run/dev": "^1.16.1", + "@remix-run/eslint-config": "^1.16.1", + "@remix-run/node": "^1.16.1", + "@remix-run/react": "^1.16.1", + "@remix-run/serve": "^1.16.1", "@styled-icons/material": "^10.47.0", "@styled-icons/material-outlined": "^10.47.0", "@styled-icons/octicons": "^10.47.0", @@ -27,12 +27,12 @@ "@types/color-convert": "^2.0.0", "@types/d3-hierarchy": "^3.1.2", "@types/jest": "^29.5.1", - "@types/react": "^18.2.5", + "@types/react": "^18.2.6", "@types/react-dom": "^18.2.4", - "@types/semver": "^7.3.13", + "@types/semver": "^7.5.0", "@types/yargs": "^17.0.24", - "@typescript-eslint/eslint-plugin": "^5.59.2", - "@typescript-eslint/parser": "^5.59.2", + "@typescript-eslint/eslint-plugin": "^5.59.6", + "@typescript-eslint/parser": "^5.59.6", "autoprefixer": "^10.4.14", "byte-size": "^8.1.1", "clsx": "^1.2.1", @@ -41,8 +41,8 @@ "d3-hierarchy": "^3.1.2", "distinct-colors": "^3.0.0", "dotenv": "^16.0.3", - "esbuild": "^0.17.18", - "eslint": "^8.39.0", + "esbuild": "^0.17.19", + "eslint": "^8.40.0", "eslint-config-prettier": "^8.8.0", "eslint-plugin-prettier": "^4.2.1", "eslint-plugin-react": "^7.32.2", @@ -60,7 +60,7 @@ "nanospinner": "^1.1.0", "open": "^8.4.2", "postcss": "^8.4.23", - "prettier-plugin-tailwindcss": "^0.2.8", + "prettier-plugin-tailwindcss": "^0.3.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-konami-code": "^2.3.0", @@ -68,7 +68,7 @@ "react-use-size": "^3.0.1", "remix-typedjson": "^0.1.7", "rimraf": "^5.0.0", - "semver": "^7.5.0", + "semver": "^7.5.1", "tailwindcss": "^3.3.2", "tiny-invariant": "^1.3.1", "ts-jest": "^29.1.0", @@ -228,12 +228,12 @@ } }, "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.18.9", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.21.5.tgz", + "integrity": "sha512-uNrjKztPLkUk7bpCNC0jEKDJzzkvel/W+HguzbN8krA+LPfC1CEobJEvAvGka2A/M+ViOqXdcRL0GqPUJSjx9g==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-explode-assignable-expression": "^7.18.6", - "@babel/types": "^7.18.9" + "@babel/types": "^7.21.5" }, "engines": { "node": ">=6.9.0" @@ -280,18 +280,20 @@ "license": "ISC" }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.21.0", + "version": "7.21.8", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.8.tgz", + "integrity": "sha512-+THiN8MqiH2AczyuZrnrKL6cAxFRRQDKW9h1YkBvbgKmAm6mwiacig1qT73DHIWMGo40GRnsEfN3LA+E6NtmSw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-environment-visitor": "^7.21.5", "@babel/helper-function-name": "^7.21.0", - "@babel/helper-member-expression-to-functions": "^7.21.0", + "@babel/helper-member-expression-to-functions": "^7.21.5", "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-replace-supers": "^7.20.7", + "@babel/helper-replace-supers": "^7.21.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", - "@babel/helper-split-export-declaration": "^7.18.6" + "@babel/helper-split-export-declaration": "^7.18.6", + "semver": "^6.3.0" }, "engines": { "node": ">=6.9.0" @@ -300,13 +302,24 @@ "@babel/core": "^7.0.0" } }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.21.0", + "version": "7.21.8", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.21.8.tgz", + "integrity": "sha512-zGuSdedkFtsFHGbexAvNuipg1hbtitDLo2XE8/uf6Y9sOQV1xsYX/2pNbtedp/X0eU1pIt+kGvaqHCowkRbS5g==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", - "regexpu-core": "^5.3.1" + "regexpu-core": "^5.3.1", + "semver": "^6.3.0" }, "engines": { "node": ">=6.9.0" @@ -315,10 +328,20 @@ "@babel/core": "^7.0.0" } }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/helper-define-polyfill-provider": { "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", + "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-compilation-targets": "^7.17.7", "@babel/helper-plugin-utils": "^7.16.7", @@ -333,8 +356,9 @@ }, "node_modules/@babel/helper-define-polyfill-provider/node_modules/semver": { "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver.js" } @@ -348,17 +372,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-explode-assignable-expression": { - "version": "7.18.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-function-name": { "version": "7.21.0", "dev": true, @@ -383,11 +396,12 @@ } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.21.0", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.21.5.tgz", + "integrity": "sha512-nIcGfgwpH2u4n9GG1HpStW5Ogx7x7ekiFHbjjFRKXbn5zUvqO9ZgotCO4x1aNbKn/x/xOUaXEhyNHCwtFCpxWg==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.21.0" + "@babel/types": "^7.21.5" }, "engines": { "node": ">=6.9.0" @@ -426,8 +440,9 @@ }, "node_modules/@babel/helper-optimise-call-expression": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", + "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/types": "^7.18.6" }, @@ -436,17 +451,19 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.20.2", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.21.5.tgz", + "integrity": "sha512-0WDaIlXKOX/3KfBK/dwP1oQGiPh6rjMkT7HIRv7i5RR2VUMwrx5ZL0dwBkKx7+SW1zwNdgjHd34IMk5ZjTeHVg==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-remap-async-to-generator": { "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", + "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-environment-visitor": "^7.18.9", @@ -461,16 +478,17 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.20.7", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.21.5.tgz", + "integrity": "sha512-/y7vBgsr9Idu4M6MprbOVUfH3vs7tsIfnVWv/Ml2xgwvyH6LTngdfbf5AdsKwkJy4zgy1X/kuNrEKvhhK28Yrg==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-member-expression-to-functions": "^7.20.7", + "@babel/helper-environment-visitor": "^7.21.5", + "@babel/helper-member-expression-to-functions": "^7.21.5", "@babel/helper-optimise-call-expression": "^7.18.6", "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.7", - "@babel/types": "^7.20.7" + "@babel/traverse": "^7.21.5", + "@babel/types": "^7.21.5" }, "engines": { "node": ">=6.9.0" @@ -490,8 +508,9 @@ }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz", + "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/types": "^7.20.0" }, @@ -537,8 +556,9 @@ }, "node_modules/@babel/helper-wrap-function": { "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz", + "integrity": "sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-function-name": "^7.19.0", "@babel/template": "^7.18.10", @@ -590,8 +610,9 @@ }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz", + "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, @@ -604,8 +625,9 @@ }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.20.7.tgz", + "integrity": "sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", @@ -620,8 +642,9 @@ }, "node_modules/@babel/plugin-proposal-async-generator-functions": { "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz", + "integrity": "sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-plugin-utils": "^7.20.2", @@ -637,8 +660,9 @@ }, "node_modules/@babel/plugin-proposal-class-properties": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", + "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -652,8 +676,9 @@ }, "node_modules/@babel/plugin-proposal-class-static-block": { "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.21.0.tgz", + "integrity": "sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.21.0", "@babel/helper-plugin-utils": "^7.20.2", @@ -668,8 +693,9 @@ }, "node_modules/@babel/plugin-proposal-dynamic-import": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", + "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-dynamic-import": "^7.8.3" @@ -683,8 +709,9 @@ }, "node_modules/@babel/plugin-proposal-export-namespace-from": { "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", + "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.9", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" @@ -698,8 +725,9 @@ }, "node_modules/@babel/plugin-proposal-json-strings": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", + "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-json-strings": "^7.8.3" @@ -713,8 +741,9 @@ }, "node_modules/@babel/plugin-proposal-logical-assignment-operators": { "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz", + "integrity": "sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" @@ -728,8 +757,9 @@ }, "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", + "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" @@ -743,8 +773,9 @@ }, "node_modules/@babel/plugin-proposal-numeric-separator": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", + "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-numeric-separator": "^7.10.4" @@ -758,8 +789,9 @@ }, "node_modules/@babel/plugin-proposal-object-rest-spread": { "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz", + "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/compat-data": "^7.20.5", "@babel/helper-compilation-targets": "^7.20.7", @@ -776,8 +808,9 @@ }, "node_modules/@babel/plugin-proposal-optional-catch-binding": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", + "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" @@ -791,8 +824,9 @@ }, "node_modules/@babel/plugin-proposal-optional-chaining": { "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz", + "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", @@ -807,8 +841,9 @@ }, "node_modules/@babel/plugin-proposal-private-methods": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", + "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -822,8 +857,9 @@ }, "node_modules/@babel/plugin-proposal-private-property-in-object": { "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0.tgz", + "integrity": "sha512-ha4zfehbJjc5MmXBlHec1igel5TJXXLDDRbuJ4+XT2TJcyD9/V1919BA8gMvsdHcNMBy4WBUBiRb3nw/EQUtBw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-create-class-features-plugin": "^7.21.0", @@ -839,8 +875,9 @@ }, "node_modules/@babel/plugin-proposal-unicode-property-regex": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", + "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -887,8 +924,9 @@ }, "node_modules/@babel/plugin-syntax-class-static-block": { "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -901,8 +939,9 @@ }, "node_modules/@babel/plugin-syntax-dynamic-import": { "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -912,8 +951,9 @@ }, "node_modules/@babel/plugin-syntax-export-namespace-from": { "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.3" }, @@ -923,8 +963,9 @@ }, "node_modules/@babel/plugin-syntax-import-assertions": { "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz", + "integrity": "sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.19.0" }, @@ -958,11 +999,12 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.18.6", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.21.4.tgz", + "integrity": "sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.20.2" }, "engines": { "node": ">=6.9.0" @@ -1039,8 +1081,9 @@ }, "node_modules/@babel/plugin-syntax-private-property-in-object": { "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -1066,11 +1109,12 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.20.0", + "version": "7.21.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.21.4.tgz", + "integrity": "sha512-xz0D39NvhQn4t4RNsHmDnnsaQizIlUkdtYvLs8La1BlfjQ6JEwxkJGeqJMW2tAXx+q6H+WFuUTXNdYVpEya0YA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.20.2" }, "engines": { "node": ">=6.9.0" @@ -1080,11 +1124,12 @@ } }, "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.20.7", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.21.5.tgz", + "integrity": "sha512-wb1mhwGOCaXHDTcsRYMKF9e5bbMgqwxtqa2Y1ifH96dXJPwbuLX9qHy3clhrxVqgMz7nyNXs8VkxdH8UBcjKqA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.21.5" }, "engines": { "node": ">=6.9.0" @@ -1095,8 +1140,9 @@ }, "node_modules/@babel/plugin-transform-async-to-generator": { "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz", + "integrity": "sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.18.6", "@babel/helper-plugin-utils": "^7.20.2", @@ -1111,8 +1157,9 @@ }, "node_modules/@babel/plugin-transform-block-scoped-functions": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", + "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, @@ -1125,8 +1172,9 @@ }, "node_modules/@babel/plugin-transform-block-scoping": { "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.21.0.tgz", + "integrity": "sha512-Mdrbunoh9SxwFZapeHVrwFmri16+oYotcZysSzhNIVDwIAb1UV+kvnxULSYq9J3/q5MDG+4X6w8QVgD1zhBXNQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.20.2" }, @@ -1139,8 +1187,9 @@ }, "node_modules/@babel/plugin-transform-classes": { "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.21.0.tgz", + "integrity": "sha512-RZhbYTCEUAe6ntPehC4hlslPWosNHDox+vAs4On/mCLRLfoDVHf6hVEd7kuxr1RnHwJmxFfUM3cZiZRmPxJPXQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-compilation-targets": "^7.20.7", @@ -1160,11 +1209,12 @@ } }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.20.7", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.21.5.tgz", + "integrity": "sha512-TR653Ki3pAwxBxUe8srfF3e4Pe3FTA46uaNHYyQwIoM4oWKSoOZiDNyHJ0oIoDIUPSRQbQG7jzgVBX3FPVne1Q==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-plugin-utils": "^7.21.5", "@babel/template": "^7.20.7" }, "engines": { @@ -1175,9 +1225,10 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.20.7", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.21.3.tgz", + "integrity": "sha512-bp6hwMFzuiE4HqYEyoGJ/V2LeIWn+hLVKc4pnj++E5XQptwhtcGmSayM029d/j2X1bPKGTlsyPwAubuU22KhMA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.20.2" }, @@ -1190,8 +1241,9 @@ }, "node_modules/@babel/plugin-transform-dotall-regex": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", + "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -1205,8 +1257,9 @@ }, "node_modules/@babel/plugin-transform-duplicate-keys": { "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", + "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.9" }, @@ -1219,8 +1272,9 @@ }, "node_modules/@babel/plugin-transform-exponentiation-operator": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", + "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -1233,11 +1287,12 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.21.0", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.21.5.tgz", + "integrity": "sha512-nYWpjKW/7j/I/mZkGVgHJXh4bA1sfdFnJoOXwJuj4m3Q2EraO/8ZyrkCau9P5tbHQk01RMSt6KYLCsW7730SXQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.21.5" }, "engines": { "node": ">=6.9.0" @@ -1248,8 +1303,9 @@ }, "node_modules/@babel/plugin-transform-function-name": { "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", + "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-compilation-targets": "^7.18.9", "@babel/helper-function-name": "^7.18.9", @@ -1264,8 +1320,9 @@ }, "node_modules/@babel/plugin-transform-literals": { "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", + "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.9" }, @@ -1278,8 +1335,9 @@ }, "node_modules/@babel/plugin-transform-member-expression-literals": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", + "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, @@ -1292,8 +1350,9 @@ }, "node_modules/@babel/plugin-transform-modules-amd": { "version": "7.20.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.20.11.tgz", + "integrity": "sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.20.11", "@babel/helper-plugin-utils": "^7.20.2" @@ -1306,13 +1365,14 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.21.2", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.21.5.tgz", + "integrity": "sha512-OVryBEgKUbtqMoB7eG2rs6UFexJi6Zj6FDXx+esBLPTCxCNxAY9o+8Di7IsUGJ+AVhp5ncK0fxWUBd0/1gPhrQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.21.2", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-simple-access": "^7.20.2" + "@babel/helper-module-transforms": "^7.21.5", + "@babel/helper-plugin-utils": "^7.21.5", + "@babel/helper-simple-access": "^7.21.5" }, "engines": { "node": ">=6.9.0" @@ -1323,8 +1383,9 @@ }, "node_modules/@babel/plugin-transform-modules-systemjs": { "version": "7.20.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.20.11.tgz", + "integrity": "sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-module-transforms": "^7.20.11", @@ -1340,8 +1401,9 @@ }, "node_modules/@babel/plugin-transform-modules-umd": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", + "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -1355,8 +1417,9 @@ }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz", + "integrity": "sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.20.5", "@babel/helper-plugin-utils": "^7.20.2" @@ -1370,8 +1433,9 @@ }, "node_modules/@babel/plugin-transform-new-target": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", + "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, @@ -1384,8 +1448,9 @@ }, "node_modules/@babel/plugin-transform-object-super": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", + "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6", "@babel/helper-replace-supers": "^7.18.6" @@ -1398,9 +1463,10 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.20.7", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.21.3.tgz", + "integrity": "sha512-Wxc+TvppQG9xWFYatvCGPvZ6+SIUxQ2ZdiBP+PHYMIjnPXD+uThCshaz4NZOnODAtBjjcVQQ/3OKs9LW28purQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.20.2" }, @@ -1413,8 +1479,9 @@ }, "node_modules/@babel/plugin-transform-property-literals": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", + "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, @@ -1487,11 +1554,12 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.20.5", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.21.5.tgz", + "integrity": "sha512-ZoYBKDb6LyMi5yCsByQ5jmXsHAQDDYeexT1Szvlmui+lADvfSecr5Dxd/PkrTC3pAD182Fcju1VQkB4oCp9M+w==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-plugin-utils": "^7.21.5", "regenerator-transform": "^0.15.1" }, "engines": { @@ -1503,8 +1571,9 @@ }, "node_modules/@babel/plugin-transform-reserved-words": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", + "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, @@ -1517,8 +1586,9 @@ }, "node_modules/@babel/plugin-transform-shorthand-properties": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", + "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, @@ -1531,8 +1601,9 @@ }, "node_modules/@babel/plugin-transform-spread": { "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.20.7.tgz", + "integrity": "sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0" @@ -1546,8 +1617,9 @@ }, "node_modules/@babel/plugin-transform-sticky-regex": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", + "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, @@ -1560,8 +1632,9 @@ }, "node_modules/@babel/plugin-transform-template-literals": { "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", + "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.9" }, @@ -1574,8 +1647,9 @@ }, "node_modules/@babel/plugin-transform-typeof-symbol": { "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", + "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.18.9" }, @@ -1587,10 +1661,12 @@ } }, "node_modules/@babel/plugin-transform-typescript": { - "version": "7.21.0", + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.21.3.tgz", + "integrity": "sha512-RQxPz6Iqt8T0uw/WsJNReuBpWpBqs/n7mNo18sKLoTbMp+UrEekhH+pKSVC7gWz+DNjo9gryfV8YzCiT45RgMw==", "dev": true, - "license": "MIT", "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-create-class-features-plugin": "^7.21.0", "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-typescript": "^7.20.0" @@ -1603,11 +1679,12 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.18.10", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.21.5.tgz", + "integrity": "sha512-LYm/gTOwZqsYohlvFUe/8Tujz75LqqVC2w+2qPHLR+WyWHGCZPN1KBpJCJn+4Bk4gOkQy/IXKIge6az5MqwlOg==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.21.5" }, "engines": { "node": ">=6.9.0" @@ -1618,8 +1695,9 @@ }, "node_modules/@babel/plugin-transform-unicode-regex": { "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", + "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -1632,30 +1710,31 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.20.2", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.21.5.tgz", + "integrity": "sha512-wH00QnTTldTbf/IefEVyChtRdw5RJvODT/Vb4Vcxq1AZvtXj6T0YeX0cAcXhI6/BdGuiP3GcNIL4OQbI2DVNxg==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.20.1", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-validator-option": "^7.18.6", + "@babel/compat-data": "^7.21.5", + "@babel/helper-compilation-targets": "^7.21.5", + "@babel/helper-plugin-utils": "^7.21.5", + "@babel/helper-validator-option": "^7.21.0", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", - "@babel/plugin-proposal-async-generator-functions": "^7.20.1", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.20.7", + "@babel/plugin-proposal-async-generator-functions": "^7.20.7", "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/plugin-proposal-class-static-block": "^7.18.6", + "@babel/plugin-proposal-class-static-block": "^7.21.0", "@babel/plugin-proposal-dynamic-import": "^7.18.6", "@babel/plugin-proposal-export-namespace-from": "^7.18.9", "@babel/plugin-proposal-json-strings": "^7.18.6", - "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", + "@babel/plugin-proposal-logical-assignment-operators": "^7.20.7", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", "@babel/plugin-proposal-numeric-separator": "^7.18.6", - "@babel/plugin-proposal-object-rest-spread": "^7.20.2", + "@babel/plugin-proposal-object-rest-spread": "^7.20.7", "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", - "@babel/plugin-proposal-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-optional-chaining": "^7.21.0", "@babel/plugin-proposal-private-methods": "^7.18.6", - "@babel/plugin-proposal-private-property-in-object": "^7.18.6", + "@babel/plugin-proposal-private-property-in-object": "^7.21.0", "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", @@ -1663,6 +1742,7 @@ "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", "@babel/plugin-syntax-import-assertions": "^7.20.0", + "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", @@ -1672,40 +1752,40 @@ "@babel/plugin-syntax-optional-chaining": "^7.8.3", "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.18.6", - "@babel/plugin-transform-async-to-generator": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.21.5", + "@babel/plugin-transform-async-to-generator": "^7.20.7", "@babel/plugin-transform-block-scoped-functions": "^7.18.6", - "@babel/plugin-transform-block-scoping": "^7.20.2", - "@babel/plugin-transform-classes": "^7.20.2", - "@babel/plugin-transform-computed-properties": "^7.18.9", - "@babel/plugin-transform-destructuring": "^7.20.2", + "@babel/plugin-transform-block-scoping": "^7.21.0", + "@babel/plugin-transform-classes": "^7.21.0", + "@babel/plugin-transform-computed-properties": "^7.21.5", + "@babel/plugin-transform-destructuring": "^7.21.3", "@babel/plugin-transform-dotall-regex": "^7.18.6", "@babel/plugin-transform-duplicate-keys": "^7.18.9", "@babel/plugin-transform-exponentiation-operator": "^7.18.6", - "@babel/plugin-transform-for-of": "^7.18.8", + "@babel/plugin-transform-for-of": "^7.21.5", "@babel/plugin-transform-function-name": "^7.18.9", "@babel/plugin-transform-literals": "^7.18.9", "@babel/plugin-transform-member-expression-literals": "^7.18.6", - "@babel/plugin-transform-modules-amd": "^7.19.6", - "@babel/plugin-transform-modules-commonjs": "^7.19.6", - "@babel/plugin-transform-modules-systemjs": "^7.19.6", + "@babel/plugin-transform-modules-amd": "^7.20.11", + "@babel/plugin-transform-modules-commonjs": "^7.21.5", + "@babel/plugin-transform-modules-systemjs": "^7.20.11", "@babel/plugin-transform-modules-umd": "^7.18.6", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.20.5", "@babel/plugin-transform-new-target": "^7.18.6", "@babel/plugin-transform-object-super": "^7.18.6", - "@babel/plugin-transform-parameters": "^7.20.1", + "@babel/plugin-transform-parameters": "^7.21.3", "@babel/plugin-transform-property-literals": "^7.18.6", - "@babel/plugin-transform-regenerator": "^7.18.6", + "@babel/plugin-transform-regenerator": "^7.21.5", "@babel/plugin-transform-reserved-words": "^7.18.6", "@babel/plugin-transform-shorthand-properties": "^7.18.6", - "@babel/plugin-transform-spread": "^7.19.0", + "@babel/plugin-transform-spread": "^7.20.7", "@babel/plugin-transform-sticky-regex": "^7.18.6", "@babel/plugin-transform-template-literals": "^7.18.9", "@babel/plugin-transform-typeof-symbol": "^7.18.9", - "@babel/plugin-transform-unicode-escapes": "^7.18.10", + "@babel/plugin-transform-unicode-escapes": "^7.21.5", "@babel/plugin-transform-unicode-regex": "^7.18.6", "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.20.2", + "@babel/types": "^7.21.5", "babel-plugin-polyfill-corejs2": "^0.3.3", "babel-plugin-polyfill-corejs3": "^0.6.0", "babel-plugin-polyfill-regenerator": "^0.4.1", @@ -1721,16 +1801,18 @@ }, "node_modules/@babel/preset-env/node_modules/semver": { "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/preset-modules": { "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", + "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", @@ -1762,13 +1844,16 @@ } }, "node_modules/@babel/preset-typescript": { - "version": "7.21.0", + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.21.5.tgz", + "integrity": "sha512-iqe3sETat5EOrORXiQ6rWfoOg2y68Cs75B9wNxdPW4kixJxh7aXQE1KPdWLDniC24T/6dSnguF33W9j/ZZQcmA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-plugin-utils": "^7.21.5", "@babel/helper-validator-option": "^7.21.0", - "@babel/plugin-transform-typescript": "^7.21.0" + "@babel/plugin-syntax-jsx": "^7.21.4", + "@babel/plugin-transform-modules-commonjs": "^7.21.5", + "@babel/plugin-transform-typescript": "^7.21.3" }, "engines": { "node": ">=6.9.0" @@ -1779,8 +1864,9 @@ }, "node_modules/@babel/regjsgen": { "version": "0.8.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", + "dev": true }, "node_modules/@babel/runtime": { "version": "7.21.0", @@ -1880,9 +1966,9 @@ "peer": true }, "node_modules/@esbuild/android-arm": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.18.tgz", - "integrity": "sha512-EmwL+vUBZJ7mhFCs5lA4ZimpUH3WMAoqvOIYhVQwdIgSpHC8ImHdsRyhHAVxpDYUSm0lWvd63z0XH1IlImS2Qw==", + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.19.tgz", + "integrity": "sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==", "cpu": [ "arm" ], @@ -1896,9 +1982,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.18.tgz", - "integrity": "sha512-/iq0aK0eeHgSC3z55ucMAHO05OIqmQehiGay8eP5l/5l+iEr4EIbh4/MI8xD9qRFjqzgkc0JkX0LculNC9mXBw==", + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz", + "integrity": "sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==", "cpu": [ "arm64" ], @@ -1912,9 +1998,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.18.tgz", - "integrity": "sha512-x+0efYNBF3NPW2Xc5bFOSFW7tTXdAcpfEg2nXmxegm4mJuVeS+i109m/7HMiOQ6M12aVGGFlqJX3RhNdYM2lWg==", + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.19.tgz", + "integrity": "sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==", "cpu": [ "x64" ], @@ -1928,9 +2014,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.18.tgz", - "integrity": "sha512-6tY+djEAdF48M1ONWnQb1C+6LiXrKjmqjzPNPWXhu/GzOHTHX2nh8Mo2ZAmBFg0kIodHhciEgUBtcYCAIjGbjQ==", + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz", + "integrity": "sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==", "cpu": [ "arm64" ], @@ -1944,9 +2030,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.18.tgz", - "integrity": "sha512-Qq84ykvLvya3dO49wVC9FFCNUfSrQJLbxhoQk/TE1r6MjHo3sFF2tlJCwMjhkBVq3/ahUisj7+EpRSz0/+8+9A==", + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz", + "integrity": "sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==", "cpu": [ "x64" ], @@ -1960,9 +2046,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.18.tgz", - "integrity": "sha512-fw/ZfxfAzuHfaQeMDhbzxp9mc+mHn1Y94VDHFHjGvt2Uxl10mT4CDavHm+/L9KG441t1QdABqkVYwakMUeyLRA==", + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz", + "integrity": "sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==", "cpu": [ "arm64" ], @@ -1976,9 +2062,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.18.tgz", - "integrity": "sha512-FQFbRtTaEi8ZBi/A6kxOC0V0E9B/97vPdYjY9NdawyLd4Qk5VD5g2pbWN2VR1c0xhzcJm74HWpObPszWC+qTew==", + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz", + "integrity": "sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==", "cpu": [ "x64" ], @@ -1992,9 +2078,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.18.tgz", - "integrity": "sha512-jW+UCM40LzHcouIaqv3e/oRs0JM76JfhHjCavPxMUti7VAPh8CaGSlS7cmyrdpzSk7A+8f0hiedHqr/LMnfijg==", + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz", + "integrity": "sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==", "cpu": [ "arm" ], @@ -2008,9 +2094,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.18.tgz", - "integrity": "sha512-R7pZvQZFOY2sxUG8P6A21eq6q+eBv7JPQYIybHVf1XkQYC+lT7nDBdC7wWKTrbvMXKRaGudp/dzZCwL/863mZQ==", + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz", + "integrity": "sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==", "cpu": [ "arm64" ], @@ -2024,9 +2110,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.18.tgz", - "integrity": "sha512-ygIMc3I7wxgXIxk6j3V00VlABIjq260i967Cp9BNAk5pOOpIXmd1RFQJQX9Io7KRsthDrQYrtcx7QCof4o3ZoQ==", + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz", + "integrity": "sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==", "cpu": [ "ia32" ], @@ -2040,9 +2126,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.18.tgz", - "integrity": "sha512-bvPG+MyFs5ZlwYclCG1D744oHk1Pv7j8psF5TfYx7otCVmcJsEXgFEhQkbhNW8otDHL1a2KDINW20cfCgnzgMQ==", + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz", + "integrity": "sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==", "cpu": [ "loong64" ], @@ -2056,9 +2142,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.18.tgz", - "integrity": "sha512-oVqckATOAGuiUOa6wr8TXaVPSa+6IwVJrGidmNZS1cZVx0HqkTMkqFGD2HIx9H1RvOwFeWYdaYbdY6B89KUMxA==", + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz", + "integrity": "sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==", "cpu": [ "mips64el" ], @@ -2072,9 +2158,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.18.tgz", - "integrity": "sha512-3dLlQO+b/LnQNxgH4l9rqa2/IwRJVN9u/bK63FhOPB4xqiRqlQAU0qDU3JJuf0BmaH0yytTBdoSBHrb2jqc5qQ==", + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz", + "integrity": "sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==", "cpu": [ "ppc64" ], @@ -2088,9 +2174,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.18.tgz", - "integrity": "sha512-/x7leOyDPjZV3TcsdfrSI107zItVnsX1q2nho7hbbQoKnmoeUWjs+08rKKt4AUXju7+3aRZSsKrJtaRmsdL1xA==", + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz", + "integrity": "sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==", "cpu": [ "riscv64" ], @@ -2104,9 +2190,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.18.tgz", - "integrity": "sha512-cX0I8Q9xQkL/6F5zWdYmVf5JSQt+ZfZD2bJudZrWD+4mnUvoZ3TDDXtDX2mUaq6upMFv9FlfIh4Gfun0tbGzuw==", + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz", + "integrity": "sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==", "cpu": [ "s390x" ], @@ -2120,9 +2206,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.18.tgz", - "integrity": "sha512-66RmRsPlYy4jFl0vG80GcNRdirx4nVWAzJmXkevgphP1qf4dsLQCpSKGM3DUQCojwU1hnepI63gNZdrr02wHUA==", + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz", + "integrity": "sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==", "cpu": [ "x64" ], @@ -2136,9 +2222,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.18.tgz", - "integrity": "sha512-95IRY7mI2yrkLlTLb1gpDxdC5WLC5mZDi+kA9dmM5XAGxCME0F8i4bYH4jZreaJ6lIZ0B8hTrweqG1fUyW7jbg==", + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz", + "integrity": "sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==", "cpu": [ "x64" ], @@ -2152,9 +2238,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.18.tgz", - "integrity": "sha512-WevVOgcng+8hSZ4Q3BKL3n1xTv5H6Nb53cBrtzzEjDbbnOmucEVcZeGCsCOi9bAOcDYEeBZbD2SJNBxlfP3qiA==", + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz", + "integrity": "sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==", "cpu": [ "x64" ], @@ -2168,9 +2254,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.18.tgz", - "integrity": "sha512-Rzf4QfQagnwhQXVBS3BYUlxmEbcV7MY+BH5vfDZekU5eYpcffHSyjU8T0xucKVuOcdCsMo+Ur5wmgQJH2GfNrg==", + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz", + "integrity": "sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==", "cpu": [ "x64" ], @@ -2184,9 +2270,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.18.tgz", - "integrity": "sha512-Kb3Ko/KKaWhjeAm2YoT/cNZaHaD1Yk/pa3FTsmqo9uFh1D1Rfco7BBLIPdDOozrObj2sahslFuAQGvWbgWldAg==", + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz", + "integrity": "sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==", "cpu": [ "arm64" ], @@ -2200,9 +2286,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.18.tgz", - "integrity": "sha512-0/xUMIdkVHwkvxfbd5+lfG7mHOf2FRrxNbPiKWg9C4fFrB8H0guClmaM3BFiRUYrznVoyxTIyC/Ou2B7QQSwmw==", + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz", + "integrity": "sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==", "cpu": [ "ia32" ], @@ -2216,9 +2302,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.18.tgz", - "integrity": "sha512-qU25Ma1I3NqTSHJUOKi9sAH1/Mzuvlke0ioMJRthLXKm7JiSKVwFghlGbDLOO2sARECGhja4xYfRAZNPAkooYg==", + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz", + "integrity": "sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==", "cpu": [ "x64" ], @@ -2268,14 +2354,14 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.2.tgz", - "integrity": "sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", + "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.5.1", + "espree": "^9.5.2", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -2306,9 +2392,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.39.0.tgz", - "integrity": "sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng==", + "version": "8.40.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz", + "integrity": "sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3336,22 +3422,22 @@ } }, "node_modules/@remix-run/dev": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/@remix-run/dev/-/dev-1.16.0.tgz", - "integrity": "sha512-mA5Wv8sOgN3pSZvjn22aEu+O+uz2/qkgRvB5RnXWncPtvOq8dMmGH7J9kvKO/iOF8btK5FaudymK+AjM6Yifag==", + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/@remix-run/dev/-/dev-1.16.1.tgz", + "integrity": "sha512-PrCIOa4qkZISW9l2tAX9+KMPSfO9QfMGfBZz6rd79v/GQ9N2bhWgKGWwzWhlGWJoVnnRZT5VRIy6YZsepa52/A==", "dev": true, "dependencies": { - "@babel/core": "^7.18.6", - "@babel/generator": "^7.18.6", - "@babel/parser": "^7.18.6", - "@babel/plugin-syntax-jsx": "^7.18.6", - "@babel/plugin-syntax-typescript": "^7.20.0", - "@babel/preset-env": "^7.18.6", - "@babel/preset-typescript": "^7.18.6", - "@babel/traverse": "^7.18.6", - "@babel/types": "^7.20.2", + "@babel/core": "^7.21.8", + "@babel/generator": "^7.21.5", + "@babel/parser": "^7.21.8", + "@babel/plugin-syntax-jsx": "^7.21.4", + "@babel/plugin-syntax-typescript": "^7.21.4", + "@babel/preset-env": "^7.21.5", + "@babel/preset-typescript": "^7.21.5", + "@babel/traverse": "^7.21.5", + "@babel/types": "^7.21.5", "@npmcli/package-json": "^2.0.0", - "@remix-run/server-runtime": "1.16.0", + "@remix-run/server-runtime": "1.16.1", "@vanilla-extract/integration": "^6.2.0", "arg": "^5.0.1", "cacache": "^15.0.5", @@ -3401,7 +3487,7 @@ "node": ">=14" }, "peerDependencies": { - "@remix-run/serve": "^1.16.0" + "@remix-run/serve": "^1.16.1" }, "peerDependenciesMeta": { "@remix-run/serve": { @@ -3914,13 +4000,13 @@ } }, "node_modules/@remix-run/eslint-config": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/@remix-run/eslint-config/-/eslint-config-1.16.0.tgz", - "integrity": "sha512-3jVSULYaNTwE+Ga/4hYfOFY0nVSM88PnDRU/eQHz/wlwsnvRbfxG1d3oY1qAEyqVfPqdmP07KjZrEqQYKIanLg==", + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/@remix-run/eslint-config/-/eslint-config-1.16.1.tgz", + "integrity": "sha512-oVkkpgVrTM3CcKaaw5ZOwVjV+yGi7DzgEnjD+BCnLVj4CHQNc9KsNOwVW1ub9JqW5mnBdly5MHDcocEft2LJBw==", "dev": true, "dependencies": { - "@babel/core": "^7.21.3", - "@babel/eslint-parser": "^7.21.3", + "@babel/core": "^7.21.8", + "@babel/eslint-parser": "^7.21.8", "@babel/preset-react": "^7.18.6", "@rushstack/eslint-patch": "^1.2.0", "@typescript-eslint/eslint-plugin": "^5.59.0", @@ -3951,12 +4037,12 @@ } }, "node_modules/@remix-run/express": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/@remix-run/express/-/express-1.16.0.tgz", - "integrity": "sha512-V6krwEHajFtpmp/Ds88Ml3HnVoZXrtBTgNaqIxnbiTKeIURKaVQbA0+BTIf3jwnFrL8jFTOFA0Dns3honKAHfw==", + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/@remix-run/express/-/express-1.16.1.tgz", + "integrity": "sha512-qBIuFiA0qiHCTT36RwnzxhoVaAEwUmg5bihxwSkhj6zIhjM98e1DQHeKJ4f0G9Zf/qxvdl+cRNjzvlauPmocqQ==", "dev": true, "dependencies": { - "@remix-run/node": "1.16.0" + "@remix-run/node": "1.16.1" }, "engines": { "node": ">=14" @@ -3966,12 +4052,12 @@ } }, "node_modules/@remix-run/node": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/@remix-run/node/-/node-1.16.0.tgz", - "integrity": "sha512-2JtU3sVWDkyLcZ2prLovSbp4/K/mjbei1r9Qv6D9+fKgJFu3YjCPKfPiSj+T4My5rCG7azuKs5KOtmnwKBavrA==", + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/@remix-run/node/-/node-1.16.1.tgz", + "integrity": "sha512-Qp9B2htm0bGG0iuxsqezDIl89uVSBZ8xfwq2aKWgRNm1FCa4/GRXzKmTo+sbBcacj7aYe+1r+0sIS6Q1sgaEnA==", "dev": true, "dependencies": { - "@remix-run/server-runtime": "1.16.0", + "@remix-run/server-runtime": "1.16.1", "@remix-run/web-fetch": "^4.3.4", "@remix-run/web-file": "^3.0.2", "@remix-run/web-stream": "^1.0.3", @@ -3986,13 +4072,13 @@ } }, "node_modules/@remix-run/react": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/@remix-run/react/-/react-1.16.0.tgz", - "integrity": "sha512-pFhlEuqnlk8xqpIkKJ/FLSG16NZ25g9/bQcol/zVW1zllgpL4NTXfy+xTGaCmuB3GsG5nVLLvUFlDsN+KBWfSw==", + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/@remix-run/react/-/react-1.16.1.tgz", + "integrity": "sha512-vmqDXL/cHDIg3iKObtH+FltNwG+rviK1lCYgXSHgY17/95fve07hXRQalOr/ctt1jrGvGgaR4o/nlwlW7QMmpQ==", "dev": true, "dependencies": { - "@remix-run/router": "1.6.0", - "react-router-dom": "6.11.0" + "@remix-run/router": "1.6.2", + "react-router-dom": "6.11.2" }, "engines": { "node": ">=14" @@ -4003,22 +4089,22 @@ } }, "node_modules/@remix-run/router": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.6.0.tgz", - "integrity": "sha512-N13NRw3T2+6Xi9J//3CGLsK2OqC8NMme3d/YX+nh05K9YHWGcv8DycHJrqGScSP4T75o8IN6nqIMhVFU8ohg8w==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.6.2.tgz", + "integrity": "sha512-LzqpSrMK/3JBAVBI9u3NWtOhWNw5AMQfrUFYB0+bDHTSw17z++WJLsPsxAuK+oSddsxk4d7F/JcdDPM1M5YAhA==", "dev": true, "engines": { "node": ">=14" } }, "node_modules/@remix-run/serve": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/@remix-run/serve/-/serve-1.16.0.tgz", - "integrity": "sha512-Q65NqQuqQosSZUnoHKgQkB9QN2Ed/uvtE9VV8D8ZPSZMV6asAs+BbZf5UUkMWX0+GlH+82j0a8emNnG6dlIQ0w==", + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/@remix-run/serve/-/serve-1.16.1.tgz", + "integrity": "sha512-wpYZcUH6rITI9fnUsHffLhOcq98l6DMQh9MFAiGjUjPpMta7X2c7C/l3xOsL3ioE45b1d7A+tS0F69aV71u+uQ==", "dev": true, "dependencies": { - "@remix-run/express": "1.16.0", - "@remix-run/node": "1.16.0", + "@remix-run/express": "1.16.1", + "@remix-run/node": "1.16.1", "compression": "^1.7.4", "express": "^4.17.1", "morgan": "^1.10.0" @@ -4031,12 +4117,12 @@ } }, "node_modules/@remix-run/server-runtime": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/@remix-run/server-runtime/-/server-runtime-1.16.0.tgz", - "integrity": "sha512-a8rfS2SJ2nWhyGikXo+uknOSl1gW1/maDYuiG4Ki2wbVmF0v5mhJhlyB+1l+BjvXw+ZTS9HIiSQkg6L6JWqEcQ==", + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/@remix-run/server-runtime/-/server-runtime-1.16.1.tgz", + "integrity": "sha512-HG+f3PGE9kzTTPe5i5Hv7UGrJLmFID1Ae4BMohP5e0xXOxbdlKDPj6NN6yGDgE7OqKFuDVliW2B5LlUdJZgUFw==", "dev": true, "dependencies": { - "@remix-run/router": "1.6.0", + "@remix-run/router": "1.6.2", "@web3-storage/multipart-parser": "^1.0.0", "cookie": "^0.4.1", "set-cookie-parser": "^2.4.8", @@ -4048,8 +4134,9 @@ }, "node_modules/@remix-run/web-blob": { "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@remix-run/web-blob/-/web-blob-3.0.4.tgz", + "integrity": "sha512-AfegzZvSSDc+LwnXV+SwROTrDtoLiPxeFW+jxgvtDAnkuCX1rrzmVJ6CzqZ1Ai0bVfmJadkG5GxtAfYclpPmgw==", "dev": true, - "license": "MIT", "dependencies": { "@remix-run/web-stream": "^1.0.0", "web-encoding": "1.1.5" @@ -4075,8 +4162,9 @@ }, "node_modules/@remix-run/web-file": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@remix-run/web-file/-/web-file-3.0.2.tgz", + "integrity": "sha512-eFC93Onh/rZ5kUNpCQersmBtxedGpaXK2/gsUl49BYSGK/DvuPu3l06vmquEDdcPaEuXcsdGP0L7zrmUqrqo4A==", "dev": true, - "license": "MIT", "dependencies": { "@remix-run/web-blob": "^3.0.3" } @@ -4092,8 +4180,9 @@ }, "node_modules/@remix-run/web-stream": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@remix-run/web-stream/-/web-stream-1.0.3.tgz", + "integrity": "sha512-wlezlJaA5NF6SsNMiwQnnAW6tnPzQ5I8qk0Y0pSohm0eHKa2FQ1QhEKLVVcDDu02TmkfHgnux0igNfeYhDOXiA==", "dev": true, - "license": "MIT", "dependencies": { "web-streams-polyfill": "^3.1.1" } @@ -4570,9 +4659,9 @@ "license": "MIT" }, "node_modules/@types/react": { - "version": "18.2.5", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.5.tgz", - "integrity": "sha512-RuoMedzJ5AOh23Dvws13LU9jpZHIc/k90AgmK7CecAYeWmSr3553L4u5rk4sWAPBuQosfT7HmTfG4Rg5o4nGEA==", + "version": "18.2.6", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.6.tgz", + "integrity": "sha512-wRZClXn//zxCFW+ye/D2qY65UsYP1Fpex2YXorHc8awoNamkMZSvBxwxdYVInsHOZZd2Ppq8isnSzJL5Mpf8OA==", "dev": true, "dependencies": { "@types/prop-types": "*", @@ -4603,9 +4692,10 @@ "license": "MIT" }, "node_modules/@types/semver": { - "version": "7.3.13", - "dev": true, - "license": "MIT" + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", + "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", + "dev": true }, "node_modules/@types/stack-utils": { "version": "2.0.1", @@ -4632,15 +4722,15 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.2.tgz", - "integrity": "sha512-yVrXupeHjRxLDcPKL10sGQ/QlVrA8J5IYOEWVqk0lJaSZP7X5DfnP7Ns3cc74/blmbipQ1htFNVGsHX6wsYm0A==", + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.6.tgz", + "integrity": "sha512-sXtOgJNEuRU5RLwPUb1jxtToZbgvq3M6FPpY4QENxoOggK+UpTxUBpj6tD8+Qh2g46Pi9We87E+eHnUw8YcGsw==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.59.2", - "@typescript-eslint/type-utils": "5.59.2", - "@typescript-eslint/utils": "5.59.2", + "@typescript-eslint/scope-manager": "5.59.6", + "@typescript-eslint/type-utils": "5.59.6", + "@typescript-eslint/utils": "5.59.6", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", @@ -4666,14 +4756,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.2.tgz", - "integrity": "sha512-uq0sKyw6ao1iFOZZGk9F8Nro/8+gfB5ezl1cA06SrqbgJAt0SRoFhb9pXaHvkrxUpZaoLxt8KlovHNk8Gp6/HQ==", + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.6.tgz", + "integrity": "sha512-7pCa6al03Pv1yf/dUg/s1pXz/yGMUBAw5EeWqNTFiSueKvRNonze3hma3lhdsOrQcaOXhbk5gKu2Fludiho9VA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.59.2", - "@typescript-eslint/types": "5.59.2", - "@typescript-eslint/typescript-estree": "5.59.2", + "@typescript-eslint/scope-manager": "5.59.6", + "@typescript-eslint/types": "5.59.6", + "@typescript-eslint/typescript-estree": "5.59.6", "debug": "^4.3.4" }, "engines": { @@ -4693,13 +4783,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.2.tgz", - "integrity": "sha512-dB1v7ROySwQWKqQ8rEWcdbTsFjh2G0vn8KUyvTXdPoyzSL6lLGkiXEV5CvpJsEe9xIdKV+8Zqb7wif2issoOFA==", + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.6.tgz", + "integrity": "sha512-gLbY3Le9Dxcb8KdpF0+SJr6EQ+hFGYFl6tVY8VxLPFDfUZC7BHFw+Vq7bM5lE9DwWPfx4vMWWTLGXgpc0mAYyQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.2", - "@typescript-eslint/visitor-keys": "5.59.2" + "@typescript-eslint/types": "5.59.6", + "@typescript-eslint/visitor-keys": "5.59.6" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4710,13 +4800,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.2.tgz", - "integrity": "sha512-b1LS2phBOsEy/T381bxkkywfQXkV1dWda/z0PhnIy3bC5+rQWQDS7fk9CSpcXBccPY27Z6vBEuaPBCKCgYezyQ==", + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.6.tgz", + "integrity": "sha512-A4tms2Mp5yNvLDlySF+kAThV9VTBPCvGf0Rp8nl/eoDX9Okun8byTKoj3fJ52IJitjWOk0fKPNQhXEB++eNozQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.59.2", - "@typescript-eslint/utils": "5.59.2", + "@typescript-eslint/typescript-estree": "5.59.6", + "@typescript-eslint/utils": "5.59.6", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -4737,9 +4827,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.2.tgz", - "integrity": "sha512-LbJ/HqoVs2XTGq5shkiKaNTuVv5tTejdHgfdjqRUGdYhjW1crm/M7og2jhVskMt8/4wS3T1+PfFvL1K3wqYj4w==", + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.6.tgz", + "integrity": "sha512-tH5lBXZI7T2MOUgOWFdVNUILsI02shyQvfzG9EJkoONWugCG77NDDa1EeDGw7oJ5IvsTAAGVV8I3Tk2PNu9QfA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4750,13 +4840,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.2.tgz", - "integrity": "sha512-+j4SmbwVmZsQ9jEyBMgpuBD0rKwi9RxRpjX71Brr73RsYnEr3Lt5QZ624Bxphp8HUkSKfqGnPJp1kA5nl0Sh7Q==", + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.6.tgz", + "integrity": "sha512-vW6JP3lMAs/Tq4KjdI/RiHaaJSO7IUsbkz17it/Rl9Q+WkQ77EOuOnlbaU8kKfVIOJxMhnRiBG+olE7f3M16DA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.2", - "@typescript-eslint/visitor-keys": "5.59.2", + "@typescript-eslint/types": "5.59.6", + "@typescript-eslint/visitor-keys": "5.59.6", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -4777,17 +4867,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.2.tgz", - "integrity": "sha512-kSuF6/77TZzyGPhGO4uVp+f0SBoYxCDf+lW3GKhtKru/L8k/Hd7NFQxyWUeY7Z/KGB2C6Fe3yf2vVi4V9TsCSQ==", + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.6.tgz", + "integrity": "sha512-vzaaD6EXbTS29cVH0JjXBdzMt6VBlv+hE31XktDRMX1j3462wZCJa7VzO2AxXEXcIl8GQqZPcOPuW/Z1tZVogg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.59.2", - "@typescript-eslint/types": "5.59.2", - "@typescript-eslint/typescript-estree": "5.59.2", + "@typescript-eslint/scope-manager": "5.59.6", + "@typescript-eslint/types": "5.59.6", + "@typescript-eslint/typescript-estree": "5.59.6", "eslint-scope": "^5.1.1", "semver": "^7.3.7" }, @@ -4803,12 +4893,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.59.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.2.tgz", - "integrity": "sha512-EEpsO8m3RASrKAHI9jpavNv9NlEUebV4qmF1OWxSTtKSFBpC1NCmWazDQHFivRf0O1DV11BA645yrLEVQ0/Lig==", + "version": "5.59.6", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.6.tgz", + "integrity": "sha512-zEfbFLzB9ETcEJ4HZEEsCR9HHeNku5/Qw1jSS5McYJv5BR+ftYXwFFAH5Al+xkGaZEqowMwl7uoJjQb1YSPF8Q==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.59.2", + "@typescript-eslint/types": "5.59.6", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -4820,9 +4910,9 @@ } }, "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", - "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", + "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -5385,8 +5475,9 @@ }, "node_modules/@zxing/text-encoding": { "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@zxing/text-encoding/-/text-encoding-0.9.0.tgz", + "integrity": "sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==", "dev": true, - "license": "(Unlicense OR Apache-2.0)", "optional": true }, "node_modules/abort-controller": { @@ -5864,8 +5955,9 @@ }, "node_modules/babel-plugin-polyfill-corejs2": { "version": "0.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", + "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", "dev": true, - "license": "MIT", "dependencies": { "@babel/compat-data": "^7.17.7", "@babel/helper-define-polyfill-provider": "^0.3.3", @@ -5877,16 +5969,18 @@ }, "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/babel-plugin-polyfill-corejs3": { "version": "0.6.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", + "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-define-polyfill-provider": "^0.3.3", "core-js-compat": "^3.25.1" @@ -5897,8 +5991,9 @@ }, "node_modules/babel-plugin-polyfill-regenerator": { "version": "0.4.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", + "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", "dev": true, - "license": "MIT", "dependencies": { "@babel/helper-define-polyfill-provider": "^0.3.3" }, @@ -6790,8 +6885,9 @@ }, "node_modules/cookie-signature": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.1.tgz", + "integrity": "sha512-78KWk9T26NhzXtuL26cIJ8/qNHANyJ/ZYrmEXFzUmhZdjpBv+DlWlOANRTGBt48YcyslsLrj0bMLFTmXvLRCOw==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.6.0" } @@ -6805,9 +6901,10 @@ } }, "node_modules/core-js-compat": { - "version": "3.28.0", + "version": "3.30.2", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.30.2.tgz", + "integrity": "sha512-nriW1nuJjUgvkEjIot1Spwakz52V9YkYHZAQG6A1eCgC8AA1p0zngrQEP9R0+V6hji5XilWKG1Bd0YRppmGimA==", "dev": true, - "license": "MIT", "dependencies": { "browserslist": "^4.21.5" }, @@ -7638,9 +7735,9 @@ } }, "node_modules/esbuild": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.18.tgz", - "integrity": "sha512-z1lix43jBs6UKjcZVKOw2xx69ffE2aG0PygLL5qJ9OS/gy0Ewd1gW/PUQIOIQGXBHWNywSc0floSKoMFF8aK2w==", + "version": "0.17.19", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz", + "integrity": "sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==", "dev": true, "hasInstallScript": true, "bin": { @@ -7650,28 +7747,28 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/android-arm": "0.17.18", - "@esbuild/android-arm64": "0.17.18", - "@esbuild/android-x64": "0.17.18", - "@esbuild/darwin-arm64": "0.17.18", - "@esbuild/darwin-x64": "0.17.18", - "@esbuild/freebsd-arm64": "0.17.18", - "@esbuild/freebsd-x64": "0.17.18", - "@esbuild/linux-arm": "0.17.18", - "@esbuild/linux-arm64": "0.17.18", - "@esbuild/linux-ia32": "0.17.18", - "@esbuild/linux-loong64": "0.17.18", - "@esbuild/linux-mips64el": "0.17.18", - "@esbuild/linux-ppc64": "0.17.18", - "@esbuild/linux-riscv64": "0.17.18", - "@esbuild/linux-s390x": "0.17.18", - "@esbuild/linux-x64": "0.17.18", - "@esbuild/netbsd-x64": "0.17.18", - "@esbuild/openbsd-x64": "0.17.18", - "@esbuild/sunos-x64": "0.17.18", - "@esbuild/win32-arm64": "0.17.18", - "@esbuild/win32-ia32": "0.17.18", - "@esbuild/win32-x64": "0.17.18" + "@esbuild/android-arm": "0.17.19", + "@esbuild/android-arm64": "0.17.19", + "@esbuild/android-x64": "0.17.19", + "@esbuild/darwin-arm64": "0.17.19", + "@esbuild/darwin-x64": "0.17.19", + "@esbuild/freebsd-arm64": "0.17.19", + "@esbuild/freebsd-x64": "0.17.19", + "@esbuild/linux-arm": "0.17.19", + "@esbuild/linux-arm64": "0.17.19", + "@esbuild/linux-ia32": "0.17.19", + "@esbuild/linux-loong64": "0.17.19", + "@esbuild/linux-mips64el": "0.17.19", + "@esbuild/linux-ppc64": "0.17.19", + "@esbuild/linux-riscv64": "0.17.19", + "@esbuild/linux-s390x": "0.17.19", + "@esbuild/linux-x64": "0.17.19", + "@esbuild/netbsd-x64": "0.17.19", + "@esbuild/openbsd-x64": "0.17.19", + "@esbuild/sunos-x64": "0.17.19", + "@esbuild/win32-arm64": "0.17.19", + "@esbuild/win32-ia32": "0.17.19", + "@esbuild/win32-x64": "0.17.19" } }, "node_modules/esbuild-plugin-polyfill-node": { @@ -7797,15 +7894,15 @@ } }, "node_modules/eslint": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.39.0.tgz", - "integrity": "sha512-mwiok6cy7KTW7rBpo05k6+p4YVZByLNjAZ/ACB9DRCu4YDRwjXI01tWHp6KAUWelsBetTxKK/2sHB0vdS8Z2Og==", + "version": "8.40.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.40.0.tgz", + "integrity": "sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.2", - "@eslint/js": "8.39.0", + "@eslint/eslintrc": "^2.0.3", + "@eslint/js": "8.40.0", "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -7816,8 +7913,8 @@ "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.2.0", - "eslint-visitor-keys": "^3.4.0", - "espree": "^9.5.1", + "eslint-visitor-keys": "^3.4.1", + "espree": "^9.5.2", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -8381,9 +8478,9 @@ } }, "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", - "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", + "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -8480,14 +8577,14 @@ } }, "node_modules/espree": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.1.tgz", - "integrity": "sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg==", + "version": "9.5.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", + "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", "dev": true, "dependencies": { "acorn": "^8.8.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.0" + "eslint-visitor-keys": "^3.4.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -8497,9 +8594,9 @@ } }, "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", - "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", + "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -10257,8 +10354,9 @@ }, "node_modules/is-generator-function": { "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", "dev": true, - "license": "MIT", "dependencies": { "has-tostringtag": "^1.0.0" }, @@ -12618,8 +12716,9 @@ }, "node_modules/lodash.debounce": { "version": "4.0.8", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true }, "node_modules/lodash.memoize": { "version": "4.1.2", @@ -15138,9 +15237,9 @@ } }, "node_modules/prettier-plugin-tailwindcss": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.2.8.tgz", - "integrity": "sha512-KgPcEnJeIijlMjsA6WwYgRs5rh3/q76oInqtMXBA/EMcamrcYJpyhtRhyX1ayT9hnHlHTuO8sIifHF10WuSDKg==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.3.0.tgz", + "integrity": "sha512-009/Xqdy7UmkcTBpwlq7jsViDqXAYSOMLDrHAdTMlVZOrKfM2o9Ci7EMWTMZ7SkKBFTG04UM9F9iM2+4i6boDA==", "dev": true, "engines": { "node": ">=12.17.0" @@ -15156,6 +15255,7 @@ "prettier-plugin-css-order": "*", "prettier-plugin-import-sort": "*", "prettier-plugin-jsdoc": "*", + "prettier-plugin-marko": "*", "prettier-plugin-organize-attributes": "*", "prettier-plugin-organize-imports": "*", "prettier-plugin-style-order": "*", @@ -15190,6 +15290,9 @@ "prettier-plugin-jsdoc": { "optional": true }, + "prettier-plugin-marko": { + "optional": true + }, "prettier-plugin-organize-attributes": { "optional": true }, @@ -15560,12 +15663,12 @@ } }, "node_modules/react-router": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.11.0.tgz", - "integrity": "sha512-hTm6KKNpj9SDG4syIWRjCU219O0RZY8RUPobCFt9p+PlF7nnkRgMoh2DieTKvw3F3Mw6zg565HGnSv8BuoY5oQ==", + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.11.2.tgz", + "integrity": "sha512-74z9xUSaSX07t3LM+pS6Un0T55ibUE/79CzfZpy5wsPDZaea1F8QkrsiyRnA2YQ7LwE/umaydzXZV80iDCPkMg==", "dev": true, "dependencies": { - "@remix-run/router": "1.6.0" + "@remix-run/router": "1.6.2" }, "engines": { "node": ">=14" @@ -15575,13 +15678,13 @@ } }, "node_modules/react-router-dom": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.11.0.tgz", - "integrity": "sha512-Q3mK1c/CYoF++J6ZINz7EZzwlgSOZK/kc7lxIA7PhtWhKju4KfF1WHqlx0kVCIFJAWztuYVpXZeljEbds8z4Og==", + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.11.2.tgz", + "integrity": "sha512-JNbKtAeh1VSJQnH6RvBDNhxNwemRj7KxCzc5jb7zvDSKRnPWIFj9pO+eXqjM69gQJ0r46hSz1x4l9y0651DKWw==", "dev": true, "dependencies": { - "@remix-run/router": "1.6.0", - "react-router": "6.11.0" + "@remix-run/router": "1.6.2", + "react-router": "6.11.2" }, "engines": { "node": ">=14" @@ -15713,13 +15816,15 @@ }, "node_modules/regenerate": { "version": "1.4.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true }, "node_modules/regenerate-unicode-properties": { "version": "10.1.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", + "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", "dev": true, - "license": "MIT", "dependencies": { "regenerate": "^1.4.2" }, @@ -15734,8 +15839,9 @@ }, "node_modules/regenerator-transform": { "version": "0.15.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz", + "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==", "dev": true, - "license": "MIT", "dependencies": { "@babel/runtime": "^7.8.4" } @@ -15769,9 +15875,10 @@ } }, "node_modules/regexpu-core": { - "version": "5.3.1", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/regjsgen": "^0.8.0", "regenerate": "^1.4.2", @@ -15811,8 +15918,9 @@ }, "node_modules/regjsparser": { "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "jsesc": "~0.5.0" }, @@ -15822,6 +15930,8 @@ }, "node_modules/regjsparser/node_modules/jsesc": { "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", "dev": true, "bin": { "jsesc": "bin/jsesc" @@ -16227,9 +16337,9 @@ } }, "node_modules/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", + "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -16637,8 +16747,9 @@ }, "node_modules/stream-slice": { "version": "0.1.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/stream-slice/-/stream-slice-0.1.2.tgz", + "integrity": "sha512-QzQxpoacatkreL6jsxnVb7X5R/pGw9OUv2qWTYWnmLpg4NdN31snPy/f3TdQE1ZUXaThRvj1Zw4/OGg0ZkaLMA==", + "dev": true }, "node_modules/string_decoder": { "version": "1.3.0", @@ -17496,16 +17607,18 @@ }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/unicode-match-property-ecmascript": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", "dev": true, - "license": "MIT", "dependencies": { "unicode-canonical-property-names-ecmascript": "^2.0.0", "unicode-property-aliases-ecmascript": "^2.0.0" @@ -17516,16 +17629,18 @@ }, "node_modules/unicode-match-property-value-ecmascript": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/unicode-property-aliases-ecmascript": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } @@ -17739,8 +17854,9 @@ }, "node_modules/util": { "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", "dev": true, - "license": "MIT", "dependencies": { "inherits": "^2.0.3", "is-arguments": "^1.0.4", @@ -17953,8 +18069,9 @@ }, "node_modules/web-encoding": { "version": "1.1.5", + "resolved": "https://registry.npmjs.org/web-encoding/-/web-encoding-1.1.5.tgz", + "integrity": "sha512-HYLeVCdJ0+lBYV2FvNZmv3HJ2Nt0QYXqZojk3d9FJOLkwnuhzM9tmamh8d7HPM8QqjKH8DeHkFTx+CFlWpZZDA==", "dev": true, - "license": "MIT", "dependencies": { "util": "^0.12.3" }, @@ -17964,8 +18081,9 @@ }, "node_modules/web-streams-polyfill": { "version": "3.2.1", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", + "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", "dev": true, - "license": "MIT", "engines": { "node": ">= 8" } diff --git a/package.json b/package.json index b9c834dbe..7f50cfdd3 100644 --- a/package.json +++ b/package.json @@ -32,11 +32,11 @@ "@mdi/js": "^7.2.96", "@mdi/react": "^1.6.1", "@react-spring/web": "^9.7.2", - "@remix-run/dev": "^1.16.0", - "@remix-run/eslint-config": "^1.16.0", - "@remix-run/node": "^1.16.0", - "@remix-run/react": "^1.16.0", - "@remix-run/serve": "^1.16.0", + "@remix-run/dev": "^1.16.1", + "@remix-run/eslint-config": "^1.16.1", + "@remix-run/node": "^1.16.1", + "@remix-run/react": "^1.16.1", + "@remix-run/serve": "^1.16.1", "@styled-icons/material": "^10.47.0", "@styled-icons/material-outlined": "^10.47.0", "@styled-icons/octicons": "^10.47.0", @@ -44,12 +44,12 @@ "@types/color-convert": "^2.0.0", "@types/d3-hierarchy": "^3.1.2", "@types/jest": "^29.5.1", - "@types/react": "^18.2.5", + "@types/react": "^18.2.6", "@types/react-dom": "^18.2.4", - "@types/semver": "^7.3.13", + "@types/semver": "^7.5.0", "@types/yargs": "^17.0.24", - "@typescript-eslint/eslint-plugin": "^5.59.2", - "@typescript-eslint/parser": "^5.59.2", + "@typescript-eslint/eslint-plugin": "^5.59.6", + "@typescript-eslint/parser": "^5.59.6", "autoprefixer": "^10.4.14", "byte-size": "^8.1.1", "clsx": "^1.2.1", @@ -58,8 +58,8 @@ "d3-hierarchy": "^3.1.2", "distinct-colors": "^3.0.0", "dotenv": "^16.0.3", - "esbuild": "^0.17.18", - "eslint": "^8.39.0", + "esbuild": "^0.17.19", + "eslint": "^8.40.0", "eslint-config-prettier": "^8.8.0", "eslint-plugin-prettier": "^4.2.1", "eslint-plugin-react": "^7.32.2", @@ -77,7 +77,7 @@ "nanospinner": "^1.1.0", "open": "^8.4.2", "postcss": "^8.4.23", - "prettier-plugin-tailwindcss": "^0.2.8", + "prettier-plugin-tailwindcss": "^0.3.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-konami-code": "^2.3.0", @@ -85,7 +85,7 @@ "react-use-size": "^3.0.1", "remix-typedjson": "^0.1.7", "rimraf": "^5.0.0", - "semver": "^7.5.0", + "semver": "^7.5.1", "tailwindcss": "^3.3.2", "tiny-invariant": "^1.3.1", "ts-jest": "^29.1.0", From 4b0c1dd7735ba126f78583c6b56fc26fb1352448 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B8ssum?= <1959615+joglr@users.noreply.github.com> Date: Wed, 17 May 2023 21:11:50 +0000 Subject: [PATCH 04/26] Add colored logging support --- package-lock.json | 49 ++++++++++++++++++++++++++++---------- package.json | 1 + src/analyzer/log.server.ts | 19 ++++++++++++++- 3 files changed, 56 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1e453cc85..054917e1c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,6 +33,7 @@ "@types/yargs": "^17.0.24", "@typescript-eslint/eslint-plugin": "^5.59.6", "@typescript-eslint/parser": "^5.59.6", + "ansi-colors": "^4.1.3", "autoprefixer": "^10.4.14", "byte-size": "^8.1.1", "clsx": "^1.2.1", @@ -5569,6 +5570,15 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/ansi-escapes": { "version": "4.3.2", "dev": true, @@ -6498,6 +6508,18 @@ "node": ">=0.8.0" } }, + "node_modules/chalk/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/char-regex": { "version": "1.0.2", "dev": true, @@ -9674,8 +9696,9 @@ }, "node_modules/has-flag": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } @@ -17020,6 +17043,19 @@ "react-is": ">= 16.8.0" } }, + "node_modules/styled-components/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/stylis": { "version": "4.1.2", "dev": true, @@ -17076,17 +17112,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/supports-color": { - "version": "5.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "dev": true, diff --git a/package.json b/package.json index 7f50cfdd3..e3efbb79e 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "@types/yargs": "^17.0.24", "@typescript-eslint/eslint-plugin": "^5.59.6", "@typescript-eslint/parser": "^5.59.6", + "ansi-colors": "^4.1.3", "autoprefixer": "^10.4.14", "byte-size": "^8.1.1", "clsx": "^1.2.1", diff --git a/src/analyzer/log.server.ts b/src/analyzer/log.server.ts index a7b3d56dd..b9bf7bc3c 100644 --- a/src/analyzer/log.server.ts +++ b/src/analyzer/log.server.ts @@ -1,3 +1,5 @@ +import c from "ansi-colors" + export enum LOG_LEVEL { SILENT, ERROR, @@ -82,7 +84,22 @@ export function raw(message: unknown) { } function prefix(label: LOG_LEVEL_LABEL): string { - return `[${label}] ` + const formatPrefix = (label: LOG_LEVEL_LABEL, colorFn = (s: string) => s) => + `${colorFn(` ${label} `)} ` + + if (process.env.COLOR === "0") return `[${label}] ` + switch (label) { + case LOG_LEVEL_LABEL.ERROR: + return formatPrefix(LOG_LEVEL_LABEL.ERROR, c.bgRedBright.black) + case LOG_LEVEL_LABEL.WARN: + return formatPrefix(LOG_LEVEL_LABEL.WARN, c.bgYellow.black) + case LOG_LEVEL_LABEL.INFO: + return formatPrefix(LOG_LEVEL_LABEL.INFO, c.bgBlueBright.black) + case LOG_LEVEL_LABEL.DEBUG: + return formatPrefix(LOG_LEVEL_LABEL.DEBUG, c.bgBlack.white) + default: + throw Error("Invalid log level") + } } export const log = { From 7587756db74e3a879d3721a1eaa235ed6d8fd9c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Glerup=20R=C3=B8ssum?= <1959615+joglr@users.noreply.github.com> Date: Wed, 17 May 2023 23:45:08 +0200 Subject: [PATCH 05/26] Add .env.example --- .env.example | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .env.example diff --git a/.env.example b/.env.example new file mode 100644 index 000000000..9d8dc4466 --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +LOG_LEVEL=debug +INVALIDATE_CACHE=true \ No newline at end of file From a5f7d445ea866c6c29cc234e0663fa19c88a98cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Glerup=20R=C3=B8ssum?= <1959615+joglr@users.noreply.github.com> Date: Wed, 17 May 2023 23:49:58 +0200 Subject: [PATCH 06/26] Add debug logging for setting initial log level --- src/analyzer/log.server.ts | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/analyzer/log.server.ts b/src/analyzer/log.server.ts index b9bf7bc3c..659112479 100644 --- a/src/analyzer/log.server.ts +++ b/src/analyzer/log.server.ts @@ -26,8 +26,18 @@ const stringToLevelMap: Record = { const { ERROR, WARN, INFO, DEBUG } = LOG_LEVEL_LABEL function setIntialLogLevel() { - if (typeof process.env.LOG_LEVEL === "string") return stringToLevelMap[process.env.LOG_LEVEL.toUpperCase()] - if (typeof process.env.LOG_LEVEL === "number") return process.env.LOG_LEVEL + if (typeof process.env.LOG_LEVEL === "string") { + setTimeout(() => { + log.debug(`Setting log level to ${process.env.LOG_LEVEL} from environment variable`) + }) + return stringToLevelMap[process.env.LOG_LEVEL.toUpperCase()] + } + if (typeof process.env.LOG_LEVEL === "number") { + setTimeout(() => { + log.debug(`Setting log level to ${process.env.LOG_LEVEL} from environment variable`) + }) + return process.env.LOG_LEVEL + } return null } @@ -85,18 +95,18 @@ export function raw(message: unknown) { function prefix(label: LOG_LEVEL_LABEL): string { const formatPrefix = (label: LOG_LEVEL_LABEL, colorFn = (s: string) => s) => - `${colorFn(` ${label} `)} ` + `${colorFn(` ${new Date().toLocaleTimeString()} ${label} `)} ` if (process.env.COLOR === "0") return `[${label}] ` switch (label) { case LOG_LEVEL_LABEL.ERROR: - return formatPrefix(LOG_LEVEL_LABEL.ERROR, c.bgRedBright.black) + return formatPrefix(LOG_LEVEL_LABEL.ERROR, c.bgRedBright.black.bold) case LOG_LEVEL_LABEL.WARN: - return formatPrefix(LOG_LEVEL_LABEL.WARN, c.bgYellow.black) + return formatPrefix(LOG_LEVEL_LABEL.WARN, c.bgYellow.black.bold) case LOG_LEVEL_LABEL.INFO: - return formatPrefix(LOG_LEVEL_LABEL.INFO, c.bgBlueBright.black) + return formatPrefix(LOG_LEVEL_LABEL.INFO, c.bgBlueBright.black.bold) case LOG_LEVEL_LABEL.DEBUG: - return formatPrefix(LOG_LEVEL_LABEL.DEBUG, c.bgBlack.white) + return formatPrefix(LOG_LEVEL_LABEL.DEBUG, c.bgWhite.bold) default: throw Error("Invalid log level") } From 10113416c2c349b1dba2e1a41de0d5b90534ca6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Glerup=20R=C3=B8ssum?= <1959615+joglr@users.noreply.github.com> Date: Thu, 18 May 2023 20:26:47 +0200 Subject: [PATCH 07/26] Fix logging of time in prod --- src/analyzer/analyze.server.ts | 56 +++++++++++++++++-------------- src/analyzer/git-caller.server.ts | 24 ++++++------- src/analyzer/util.server.ts | 20 +++++++---- src/cli.ts | 37 ++++++++++---------- 4 files changed, 75 insertions(+), 62 deletions(-) diff --git a/src/analyzer/analyze.server.ts b/src/analyzer/analyze.server.ts index ac0bbe16d..61c364bdf 100644 --- a/src/analyzer/analyze.server.ts +++ b/src/analyzer/analyze.server.ts @@ -208,12 +208,12 @@ export async function analyze(args: TruckConfig): Promise { const hiddenFiles = args.hiddenFiles const start = performance.now() - const [findBranchHeadResult, findBranchHeadError] = await describeAsyncJob( - () => git.findBranchHead(branch), - "Finding branch head", - "Found branch head", - "Error finding branch head" - ) + const [findBranchHeadResult, findBranchHeadError] = await describeAsyncJob({ + job: () => git.findBranchHead(branch), + beforeMsg: "Finding branch head", + afterMsg: "Found branch head", + errorMsg: "Error finding branch head", + }) const repoName = getDirName(repoDir) if (findBranchHeadError) throw findBranchHeadError @@ -253,21 +253,21 @@ export async function analyze(args: TruckConfig): Promise { await git.setGitSetting("diff.renameLimit", "1000000") const runDateEpoch = Date.now() - const [repoTree, repoTreeError] = await describeAsyncJob( - () => analyzeCommit(repoName, branchHead), - "Analyzing commit tree", - "Commit tree analyzed", - "Error analyzing commit tree" - ) + const [repoTree, repoTreeError] = await describeAsyncJob({ + job: () => analyzeCommit(repoName, branchHead), + beforeMsg: "Analyzing commit tree", + afterMsg: "Commit tree analyzed", + errorMsg: "Error analyzing commit tree", + }) if (repoTreeError) throw repoTreeError - const [hydrateResult, hydratedRepoTreeError] = await describeAsyncJob( - () => hydrateData(repoTree), - "Hydrating commit tree", - "Commit tree hydrated", - "Error hydrating commit tree" - ) + const [hydrateResult, hydratedRepoTreeError] = await describeAsyncJob({ + job: () => hydrateData(repoTree), + beforeMsg: "Hydrating commit tree", + afterMsg: "Commit tree hydrated", + errorMsg: "Error hydrating commit tree", + }) if (hydratedRepoTreeError) throw hydratedRepoTreeError @@ -297,16 +297,16 @@ export async function analyze(args: TruckConfig): Promise { commits, } - await describeAsyncJob( - () => + await describeAsyncJob({ + job: () => writeRepoToFile(outPath, { ...data, cached: true, } as AnalyzerData), - "Writing data to file", - `Wrote data to ${resolve(outPath)}`, - `Error writing data to file ${outPath}` - ) + beforeMsg: "Writing data to file", + afterMsg: `Wrote data to ${resolve(outPath)}`, + errorMsg: `Error writing data to file ${outPath}`, + }) } const truckignore = ignore().add(hiddenFiles) @@ -317,7 +317,13 @@ export async function analyze(args: TruckConfig): Promise { const stop = performance.now() - log.raw(`\nDone in ${formatMs(stop - start)}`) + await describeAsyncJob({ + job: () => Promise.resolve(), + beforeMsg: "", + afterMsg: `Ready in`, + errorMsg: "", + ms: stop - start, + }) return data } diff --git a/src/analyzer/git-caller.server.ts b/src/analyzer/git-caller.server.ts index 9a807034a..36e74963c 100644 --- a/src/analyzer/git-caller.server.ts +++ b/src/analyzer/git-caller.server.ts @@ -171,24 +171,24 @@ export class GitCaller { static async scanDirectoryForRepositories(argPath: string): Promise<[Repository | null, Repository[]]> { let userRepo: Repository | null = null - const [pathIsRepo] = await describeAsyncJob( - () => GitCaller.isGitRepo(argPath), - "Checking if path is a git repo...", - "Done checking if path is a git repo", - "Error checking if path is a git repo" - ) + const [pathIsRepo] = await describeAsyncJob({ + job: () => GitCaller.isGitRepo(argPath), + beforeMsg: "Checking if path is a git repo...", + afterMsg: "Done checking if path is a git repo", + errorMsg: "Error checking if path is a git repo", + }) const baseDir = resolve(pathIsRepo ? getBaseDirFromPath(argPath) : argPath) const entries = await fs.readdir(baseDir, { withFileTypes: true }) const dirs = entries.filter((entry) => entry.isDirectory()).map(({ name }) => name) - const [repoOrNull, repoOrNullError] = await describeAsyncJob( - () => Promise.all(dirs.map((repo) => GitCaller.getRepoMetadata(join(baseDir, repo)))), - "Scanning for repositories...", - "Done scanning for repositories", - "Error scanning for repositories" - ) + const [repoOrNull, repoOrNullError] = await describeAsyncJob({ + job: () => Promise.all(dirs.map((repo) => GitCaller.getRepoMetadata(join(baseDir, repo)))), + beforeMsg: "Scanning for repositories...", + afterMsg: "Done scanning for repositories", + errorMsg: "Error scanning for repositories", + }) if (repoOrNullError) { throw repoOrNullError diff --git a/src/analyzer/util.server.ts b/src/analyzer/util.server.ts index 8f0260c3e..bbdcead69 100644 --- a/src/analyzer/util.server.ts +++ b/src/analyzer/util.server.ts @@ -7,6 +7,7 @@ import { getLogLevel, log, LOG_LEVEL } from "./log.server" import type { GitBlobObject, GitTreeObject, AnalyzerData } from "./model" import { performance } from "perf_hooks" import { resolve as resolvePath } from "path" +import c from "ansi-colors" import pkg from "../../package.json" import getLatestVersion from "latest-version" @@ -118,12 +119,19 @@ export function createTruckSpinner() { let spinner: null | Spinner = null -export async function describeAsyncJob( - job: () => Promise, - beforeMsg: string, - afterMsg: string, +export async function describeAsyncJob({ + job = async () => null as T, + beforeMsg = "", + afterMsg = "", + errorMsg = "", + ms = null, +}: { + job: () => Promise + beforeMsg: string + afterMsg: string errorMsg: string -): Promise<[T, null] | [null, Error]> { + ms?: number | null +}): Promise<[T, null] | [null, Error]> { spinner = createTruckSpinner() const success = (text: string, final = false) => { if (getLogLevel() === LOG_LEVEL.SILENT) return @@ -148,7 +156,7 @@ export async function describeAsyncJob( const startTime = performance.now() const result = await job() const stopTime = performance.now() - const suffix = `[${formatMs(stopTime - startTime)}]` + const suffix = c.gray(`${formatMs(!ms ? stopTime - startTime : ms)}`) success(`${afterMsg} ${suffix}`, true) return [result, null] } catch (e) { diff --git a/src/cli.ts b/src/cli.ts index 37eb7350f..b89e88dea 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -66,8 +66,8 @@ for usage instructions.`) const onListen = async () => { const url = `http://localhost:${port}` - const [extension, extensionError] = await describeAsyncJob( - async () => { + const [extension, extensionError] = await describeAsyncJob({ + job: async () => { // If CWD or path argument is a git repo, go directly to that repo in the visualizer if (await GitCaller.isGitRepo(options.path)) { const repo = await GitCaller.getRepoMetadata(options.path) @@ -76,10 +76,10 @@ for usage instructions.`) } else return "" } }, - "Checking for git repo", - "Done checking for git repo", - "Failed to check for git repo" - ) + beforeMsg: "Checking for git repo", + afterMsg: "Done checking for git repo", + errorMsg: "Failed to check for git repo", + }) if (extensionError) { console.error(extensionError) @@ -91,19 +91,19 @@ for usage instructions.`) let err: Error | null = null if (!args.headless) { - [, err] = await describeAsyncJob( - () => open(openURL), - "Opening Git Truck in your browser", - `Succesfully opened Git Truck in your browser`, - `Failed to open Git Truck in your browser. To continue, open this link manually:\n\n${openURL}` - ) + ;[, err] = await describeAsyncJob({ + job: () => open(openURL), + beforeMsg: "Opening Git Truck in your browser", + afterMsg: `Succesfully opened Git Truck in your browser`, + errorMsg: `Failed to open Git Truck in your browser. To continue, open this link manually:\n\n${openURL}`, + }) } if (!err) console.log(`\nApplication available at ${url}`) } } - describeAsyncJob( - async () => { + describeAsyncJob({ + job: async () => { const app = createApp( path.join(__dirname, "build"), process.env.NODE_ENV ?? "production", @@ -112,15 +112,14 @@ for usage instructions.`) ) const server = process.env.HOST ? app.listen(port, process.env.HOST, onListen) : app.listen(port, onListen) - ;["SIGTERM", "SIGINT"].forEach((signal) => { process.once(signal, () => server?.close(console.error)) }) }, - "Starting Git Truck", - "Git Truck started", - "Failed to start Git Truck" - ) + beforeMsg: "Starting Git Truck", + afterMsg: "Git Truck started", + errorMsg: "Failed to start Git Truck", + }) } main() From 7fd14d1f4a417b84fb88eba7e0d985869eb3fca8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Glerup=20R=C3=B8ssum?= <1959615+joglr@users.noreply.github.com> Date: Sat, 20 May 2023 14:36:00 +0200 Subject: [PATCH 08/26] Make invalidateCache Disable writing to cache --- src/analyzer/analyze.server.ts | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/analyzer/analyze.server.ts b/src/analyzer/analyze.server.ts index 61c364bdf..c926cc977 100644 --- a/src/analyzer/analyze.server.ts +++ b/src/analyzer/analyze.server.ts @@ -297,16 +297,18 @@ export async function analyze(args: TruckConfig): Promise { commits, } - await describeAsyncJob({ - job: () => - writeRepoToFile(outPath, { - ...data, - cached: true, - } as AnalyzerData), - beforeMsg: "Writing data to file", - afterMsg: `Wrote data to ${resolve(outPath)}`, - errorMsg: `Error writing data to file ${outPath}`, - }) + if (!args.invalidateCache) { + await describeAsyncJob({ + job: () => + writeRepoToFile(outPath, { + ...data, + cached: true, + } as AnalyzerData), + beforeMsg: "Writing data to file", + afterMsg: `Wrote data to ${resolve(outPath)}`, + errorMsg: `Error writing data to file ${outPath}`, + }) + } } const truckignore = ignore().add(hiddenFiles) From ca527203eb339e95e53148293cae3ad67f2242b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Glerup=20R=C3=B8ssum?= <1959615+joglr@users.noreply.github.com> Date: Sat, 20 May 2023 15:02:14 +0200 Subject: [PATCH 09/26] Ignore cache on invalidate cache --- .env.example | 1 - src/analyzer/git-caller.server.ts | 53 ++++++++++++++++++++----------- src/cli.ts | 9 +++--- src/routes/$repo.$.tsx | 4 +-- src/routes/_index.tsx | 4 +-- 5 files changed, 44 insertions(+), 27 deletions(-) diff --git a/.env.example b/.env.example index 9d8dc4466..3adee3edd 100644 --- a/.env.example +++ b/.env.example @@ -1,2 +1 @@ LOG_LEVEL=debug -INVALIDATE_CACHE=true \ No newline at end of file diff --git a/src/analyzer/git-caller.server.ts b/src/analyzer/git-caller.server.ts index 36e74963c..0308caaad 100644 --- a/src/analyzer/git-caller.server.ts +++ b/src/analyzer/git-caller.server.ts @@ -114,10 +114,12 @@ export class GitCaller { return result.trim() } - static async getRepoMetadata(repoPath: string): Promise { + static async getRepoMetadata(repoPath: string, invalidateCache: boolean): Promise { const repoDir = getDirName(repoPath) - const [isRepo] = await promiseHelper(GitCaller.isGitRepo(repoPath)) - if (!isRepo) return null + const isRepo = await GitCaller.isGitRepo(repoPath) + if (!isRepo) { + return null + } const refs = GitCaller.parseRefs(await GitCaller._getRefs(repoPath)) const allHeads = new Set([...Object.entries(refs.Branches), ...Object.entries(refs.Tags)]).values() const headsWithCaches = await Promise.all( @@ -126,6 +128,7 @@ export class GitCaller { repo: getDirName(repoPath), branch: headName, branchHead: head, + invalidateCache, }) return { headName, @@ -159,6 +162,7 @@ export class GitCaller { repo: repoDir, branch, branchHead, + invalidateCache, }) repo.data = data repo.reasons = reasons @@ -169,7 +173,10 @@ export class GitCaller { return repo } - static async scanDirectoryForRepositories(argPath: string): Promise<[Repository | null, Repository[]]> { + static async scanDirectoryForRepositories( + argPath: string, + invalidateCache: boolean + ): Promise<[Repository | null, Repository[]]> { let userRepo: Repository | null = null const [pathIsRepo] = await describeAsyncJob({ job: () => GitCaller.isGitRepo(argPath), @@ -183,24 +190,29 @@ export class GitCaller { const entries = await fs.readdir(baseDir, { withFileTypes: true }) const dirs = entries.filter((entry) => entry.isDirectory()).map(({ name }) => name) - const [repoOrNull, repoOrNullError] = await describeAsyncJob({ - job: () => Promise.all(dirs.map((repo) => GitCaller.getRepoMetadata(join(baseDir, repo)))), + const [repoResults] = (await describeAsyncJob({ + job: () => + Promise.allSettled( + dirs.map(async (repo) => { + const result = await GitCaller.getRepoMetadata(join(baseDir, repo), invalidateCache) + if (!result) throw Error("Not a git repo") + return result + }) + ), beforeMsg: "Scanning for repositories...", afterMsg: "Done scanning for repositories", errorMsg: "Error scanning for repositories", - }) - - if (repoOrNullError) { - throw repoOrNullError - } + })) as [PromiseSettledResult[], null] - const onlyRepos: Repository[] = repoOrNull.filter((currentRepo) => { - if (currentRepo === null) return false - if (pathIsRepo && currentRepo.name === getDirName(argPath)) { - userRepo = currentRepo - } - return true - }) as Repository[] + const onlyRepos = ( + repoResults.filter((currentRepo) => { + if (currentRepo.status === "rejected") return false + if (pathIsRepo && currentRepo.value.name === getDirName(argPath)) { + userRepo = currentRepo.value + } + return true + }) as PromiseFulfilledResult[] + ).map((result) => result.value) return [userRepo, onlyRepos] } @@ -267,11 +279,16 @@ export class GitCaller { repo, branch, branchHead, + invalidateCache = false, }: { repo: string branch: string branchHead: string + invalidateCache: boolean }): Promise<[AnalyzerData | null, ANALYZER_CACHE_MISS_REASONS[]]> { + if (invalidateCache) { + return [null, [ANALYZER_CACHE_MISS_REASONS.NOT_CACHED]] + } const reasons = [] const cachedDataPath = GitCaller.getCachePath(repo, branch) if (!existsSync(cachedDataPath)) return [null, [ANALYZER_CACHE_MISS_REASONS.NOT_CACHED]] diff --git a/src/cli.ts b/src/cli.ts index b89e88dea..d4e9a125c 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -7,7 +7,7 @@ import { getArgsWithDefaults, parseArgs } from "./analyzer/args.server" import { getPathFromRepoAndHead } from "./util" import { createApp } from "@remix-run/serve" import { semverCompare } from "./util" -import { describeAsyncJob } from "./analyzer/util.server" +import { describeAsyncJob, getDirName } from "./analyzer/util.server" import { log, setLogLevel } from "./analyzer/log.server" async function main() { @@ -70,9 +70,10 @@ for usage instructions.`) job: async () => { // If CWD or path argument is a git repo, go directly to that repo in the visualizer if (await GitCaller.isGitRepo(options.path)) { - const repo = await GitCaller.getRepoMetadata(options.path) - if (repo) { - return `/${getPathFromRepoAndHead(repo.name, repo.currentHead)}` + const repoName = getDirName(options.path) + const currentHead = await GitCaller._getRepositoryHead(options.path) + if (repoName) { + return `/${getPathFromRepoAndHead(repoName, currentHead)}` } else return "" } }, diff --git a/src/routes/$repo.$.tsx b/src/routes/$repo.$.tsx index 407bf7c7f..a54aaeafd 100644 --- a/src/routes/$repo.$.tsx +++ b/src/routes/$repo.$.tsx @@ -10,7 +10,7 @@ import { analyze, openFile, updateTruckConfig } from "~/analyzer/analyze.server" import { getTruckConfigWithArgs } from "~/analyzer/args.server" import { GitCaller } from "~/analyzer/git-caller.server" import type { AnalyzerData, HydratedGitObject, Repository, TruckUserConfig } from "~/analyzer/model" -import { getGitTruckInfo } from "~/analyzer/util.server" +import { getGitTruckInfo, promiseHelper } from "~/analyzer/util.server" import { addAuthorUnion, makeDupeMap } from "~/authorUnionUtil.server" import { DetailsCard } from "~/components/DetailsCard" import { GlobalInfo } from "~/components/GlobalInfo" @@ -66,7 +66,7 @@ export const loader = async ({ params }: LoaderArgs) => { ) invalidateCache = false - const repo = await GitCaller.getRepoMetadata(options.path) + const repo = await GitCaller.getRepoMetadata(options.path, Boolean(options.invalidateCache)) if (!repo) { throw Error("Error loading repo") diff --git a/src/routes/_index.tsx b/src/routes/_index.tsx index 0639eaf6a..142242420 100644 --- a/src/routes/_index.tsx +++ b/src/routes/_index.tsx @@ -20,8 +20,8 @@ interface IndexData { } export const loader = async () => { - const args = await getArgsWithDefaults() - const [repo, repositories] = await GitCaller.scanDirectoryForRepositories(args.path) + const args = getArgsWithDefaults() + const [repo, repositories] = await GitCaller.scanDirectoryForRepositories(args.path, args.invalidateCache) const baseDir = resolve(repo ? getBaseDirFromPath(args.path) : args.path) const repositoriesResponse = json({ From 8d353bb84ecd3654a15e461bc2207cbe0da1361d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Glerup=20R=C3=B8ssum?= <1959615+joglr@users.noreply.github.com> Date: Sat, 20 May 2023 15:02:52 +0200 Subject: [PATCH 10/26] Only log non empty values in progress indicator --- src/analyzer/util.server.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/analyzer/util.server.ts b/src/analyzer/util.server.ts index bbdcead69..589dc811b 100644 --- a/src/analyzer/util.server.ts +++ b/src/analyzer/util.server.ts @@ -151,7 +151,9 @@ export async function describeAsyncJob({ const error = (text: string) => (spinner === null ? log.error(text) : spinner.error({ text })) - output(beforeMsg) + if (beforeMsg.length > 0) { + output(beforeMsg) + } try { const startTime = performance.now() const result = await job() From 10549fb23476768bde694fd764dee0de98d9deaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Glerup=20R=C3=B8ssum?= <1959615+joglr@users.noreply.github.com> Date: Sat, 20 May 2023 15:28:34 +0200 Subject: [PATCH 11/26] Small improvement --- src/cli.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cli.ts b/src/cli.ts index d4e9a125c..abbed418a 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -71,8 +71,8 @@ for usage instructions.`) // If CWD or path argument is a git repo, go directly to that repo in the visualizer if (await GitCaller.isGitRepo(options.path)) { const repoName = getDirName(options.path) - const currentHead = await GitCaller._getRepositoryHead(options.path) if (repoName) { + const currentHead = await GitCaller._getRepositoryHead(options.path) return `/${getPathFromRepoAndHead(repoName, currentHead)}` } else return "" } @@ -88,10 +88,10 @@ for usage instructions.`) if (process.env.NODE_ENV !== "development") { const openURL = url + (extension ?? "") - log.debug(`Opening ${openURL}`) let err: Error | null = null if (!args.headless) { + log.debug(`Opening ${openURL}`) ;[, err] = await describeAsyncJob({ job: () => open(openURL), beforeMsg: "Opening Git Truck in your browser", From a18eb997b251923501835f8bf6ad31529325ad7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Glerup=20R=C3=B8ssum?= <1959615+joglr@users.noreply.github.com> Date: Sat, 20 May 2023 15:56:02 +0200 Subject: [PATCH 12/26] Add e2e tests --- .github/workflows/playwright.yml | 29 ++++++++++ .github/workflows/test-and-build.yml | 2 +- .gitignore | 6 ++ .vscode/extensions.json | 7 ++- e2e/features/navigate-to-a-repository.spec.ts | 22 +++++++ e2e/features/see-more-repositories.spec.ts | 13 +++++ package-lock.json | 32 +++++++++++ package.json | 6 +- playwright.config.ts | 57 +++++++++++++++++++ src/analyzer/analyze.server.ts | 1 + 10 files changed, 172 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/playwright.yml create mode 100644 e2e/features/navigate-to-a-repository.spec.ts create mode 100644 e2e/features/see-more-repositories.spec.ts create mode 100644 playwright.config.ts diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml new file mode 100644 index 000000000..c77eba060 --- /dev/null +++ b/.github/workflows/playwright.yml @@ -0,0 +1,29 @@ +name: Playwright Tests +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] +jobs: + test: + timeout-minutes: 60 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Fetch main branch + run: git fetch origin main:main + - uses: actions/setup-node@v3 + with: + node-version: 16 + - name: Install dependencies + run: npm ci + - name: Install Playwright Browsers + run: npx playwright install --with-deps + - name: Run Playwright tests + run: npm run test:e2e + - uses: actions/upload-artifact@v3 + if: always() + with: + name: playwright-report + path: playwright-report/ + retention-days: 30 diff --git a/.github/workflows/test-and-build.yml b/.github/workflows/test-and-build.yml index 4acc006ca..1eb367440 100644 --- a/.github/workflows/test-and-build.yml +++ b/.github/workflows/test-and-build.yml @@ -30,7 +30,7 @@ jobs: cache: 'npm' - run: npm ci - - run: npm test + - run: npm run test:unit - run: npm run build - run: npm run tsc diff --git a/.gitignore b/.gitignore index b0463e993..51deec9d0 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,9 @@ data.json coverage .eslintcache cli.js +/test-results/ +/playwright-report/ +/playwright/.cache/ +/test-results/ +/playwright-report/ +/playwright/.cache/ diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 3e7aff705..17883dd86 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,3 +1,8 @@ { - "recommendations": ["esbenp.prettier-vscode", "bradlc.vscode-tailwindcss", "Orta.vscode-jest"] + "recommendations": [ + "esbenp.prettier-vscode", + "bradlc.vscode-tailwindcss", + "Orta.vscode-jest", + "ms-playwright.playwright" + ] } diff --git a/e2e/features/navigate-to-a-repository.spec.ts b/e2e/features/navigate-to-a-repository.spec.ts new file mode 100644 index 000000000..c28412e1d --- /dev/null +++ b/e2e/features/navigate-to-a-repository.spec.ts @@ -0,0 +1,22 @@ +import { test, expect } from "@playwright/test" + +test("navigate to a repository", async ({ page }) => { + await page.goto("/") + + // Expect a title "to contain" a substring. + await expect(page).toHaveTitle(/Git Truck/) + + const gitTruckCard = page.locator(".card", { has: page.locator("text=git-truck") }) + + // Select an option from a setMetricType(metric)} /> + + Size metric + + + } + enum={SizeMetric} + defaultValue={sizeMetric} + onChange={(sizeMetric: SizeMetricType) => setSizeMetricType(sizeMetric)} + /> diff --git a/src/components/Providers.tsx b/src/components/Providers.tsx index 0ea380041..83df8da66 100644 --- a/src/components/Providers.tsx +++ b/src/components/Providers.tsx @@ -11,6 +11,7 @@ import { SearchContext } from "../contexts/SearchContext" import type { AuthorshipType, MetricsData, MetricType } from "../metrics/metrics" import { createMetricData as createMetricsData } from "../metrics/metrics" import { OPTIONS_LOCAL_STORAGE_KEY } from "~/analyzer/constants" +import type { SizeMetricType } from "~/metrics/size-metric" interface ProvidersProps { children: React.ReactNode @@ -26,7 +27,7 @@ export function Providers({ children, data }: ProvidersProps) { const metricsData: MetricsData = useMemo(() => createMetricsData(data.analyzerData), [data]) - const optionsValue = useMemo( + const optionsValue = useMemo( () => ({ ...getDefaultOptionsContextValue(), ...options, @@ -45,6 +46,8 @@ export function Providers({ children, data }: ProvidersProps) { ...(prevOptions ?? getDefaultOptionsContextValue()), authorshipType, })), + setSizeMetricType: (sizeMetric: SizeMetricType) => + setOptions((prevOptions) => ({ ...(prevOptions ?? getDefaultOptionsContextValue()), sizeMetric })), setHoveredBlob: (blob: HydratedGitBlobObject | null) => setOptions((prevOptions) => ({ ...(prevOptions ?? getDefaultOptionsContextValue()), @@ -64,7 +67,7 @@ export function Providers({ children, data }: ProvidersProps) { setOptions((prevOptions) => ({ ...(prevOptions ?? getDefaultOptionsContextValue()), labelsVisible: visible, - })), + })) }), [options] ) @@ -86,7 +89,10 @@ export function Providers({ children, data }: ProvidersProps) { useEffect(() => { const savedOptions = localStorage.getItem(OPTIONS_LOCAL_STORAGE_KEY) if (savedOptions) { - setOptions(getDefaultOptionsContextValue(JSON.parse(savedOptions))) + setOptions({ + ...getDefaultOptionsContextValue(JSON.parse(savedOptions)), + hasLoadedSavedOptions: true, + }) } }, []) diff --git a/src/contexts/OptionsContext.ts b/src/contexts/OptionsContext.ts index cfe5444be..d2b79a62b 100644 --- a/src/contexts/OptionsContext.ts +++ b/src/contexts/OptionsContext.ts @@ -1,6 +1,8 @@ import { createContext, useContext } from "react" import type { AuthorshipType, MetricType } from "../metrics/metrics" import { Authorship, Metric } from "../metrics/metrics" +import type { SizeMetricType } from "~/metrics/size-metric" +import { SizeMetric } from "~/metrics/size-metric" export const Chart = { BUBBLE_CHART: "Bubble chart", @@ -10,8 +12,10 @@ export const Chart = { export type ChartType = keyof typeof Chart export type Options = { + hasLoadedSavedOptions: boolean metricType: MetricType chartType: ChartType + sizeMetric: SizeMetricType authorshipType: AuthorshipType transitionsEnabled: boolean labelsVisible: boolean @@ -20,6 +24,7 @@ export type Options = { export type OptionsContextType = Options & { setMetricType: (metricType: MetricType) => void setChartType: (chartType: ChartType) => void + setSizeMetricType: (sizeMetricType: SizeMetricType) => void setAuthorshipType: (authorshipType: AuthorshipType) => void setTransitionsEnabled: (transitionsEnabled: boolean) => void setLabelsVisible: (labelsVisible: boolean) => void @@ -36,8 +41,10 @@ export function useOptions() { } const defaultOptions: Options = { + hasLoadedSavedOptions: false, metricType: Object.keys(Metric)[0] as MetricType, chartType: Object.keys(Chart)[0] as ChartType, + sizeMetric: Object.keys(SizeMetric)[0] as SizeMetricType, authorshipType: Object.keys(Authorship)[0] as AuthorshipType, transitionsEnabled: true, labelsVisible: true, @@ -53,6 +60,9 @@ export function getDefaultOptionsContextValue(savedOptions: Partial = { setMetricType: () => { throw new Error("No metricTypeSetter provided") }, + setSizeMetricType: () => { + throw new Error("No sizeMetricTypeSetter provided") + }, setAuthorshipType: () => { throw new Error("No AuthorshipTypeSetter provided") }, @@ -61,6 +71,6 @@ export function getDefaultOptionsContextValue(savedOptions: Partial = { }, setLabelsVisible: () => { throw new Error("No labelsVisibleSetter provided") - }, + } } } diff --git a/src/metrics/size-metric.ts b/src/metrics/size-metric.ts new file mode 100644 index 000000000..830e53096 --- /dev/null +++ b/src/metrics/size-metric.ts @@ -0,0 +1,9 @@ +export const SizeMetric = { + FILE_SIZE: "File size", + MOST_COMMITS: "Number of commits", + NUMBER_OF_AUTHORS: "Number of authors", + EQUAL_SIZE: "Equal", + RANDOM: "Random", +} + +export type SizeMetricType = keyof typeof SizeMetric From 406b67b7b5e864c93bb935ba380e4550efba5d33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Glerup=20R=C3=B8ssum?= <1959615+joglr@users.noreply.github.com> Date: Sat, 20 May 2023 19:40:37 +0200 Subject: [PATCH 15/26] Make options icons dynamic --- src/components/Options.tsx | 47 ++++++++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/src/components/Options.tsx b/src/components/Options.tsx index e04d11e6d..c578b8324 100644 --- a/src/components/Options.tsx +++ b/src/components/Options.tsx @@ -6,7 +6,22 @@ import { Chart, useOptions } from "../contexts/OptionsContext" import { CheckboxWithLabel } from "./util" import { Icon } from "@mdi/react" import { memo } from "react" -import { mdiChartBubble, mdiDatabaseOutline, mdiImageSizeSelectSmall, mdiCogOutline } from "@mdi/js" +import { + mdiChartBubble, + mdiCogOutline, + mdiChartTree, + mdiPodiumGold, + mdiThermometer, + mdiFileCodeOutline, + mdiTruckFastOutline, + mdiUpdate, + mdiResize, + mdiSourceCommit, + mdiAccountGroupOutline, + mdiDice3Outline, + mdiScaleBalance, + mdiAccountAlertOutline, +} from "@mdi/js" import type { SizeMetricType } from "~/metrics/size-metric" import { SizeMetric } from "~/metrics/size-metric" @@ -33,6 +48,28 @@ export const Options = memo(function Options() { setSizeMetricType, } = useOptions() + const visualizationIcons: Record = { + FILE_TYPE: mdiFileCodeOutline, + LAST_CHANGED: mdiUpdate, + MOST_COMMITS: mdiThermometer, + SINGLE_AUTHOR: mdiAccountAlertOutline, + TOP_CONTRIBUTOR: mdiPodiumGold, + TRUCK_FACTOR: mdiTruckFastOutline, + } + + const sizeMetricIcons: Record = { + FILE_SIZE: mdiResize, + EQUAL_SIZE: mdiScaleBalance, + MOST_COMMITS: mdiSourceCommit, + NUMBER_OF_AUTHORS: mdiAccountGroupOutline, + RANDOM: mdiDice3Outline, + } + + const chartTypeIcons: Record = { + BUBBLE_CHART: mdiChartBubble, + TREE_MAP: mdiChartTree, + } + return (

@@ -43,7 +80,7 @@ export const Options = memo(function Options() { label={
Visualization - +
} enum={Metric} @@ -54,7 +91,7 @@ export const Options = memo(function Options() { label={
Size metric - +
} enum={SizeMetric} @@ -64,8 +101,8 @@ export const Options = memo(function Options() { - Layout - + Chart layout +

} enum={Chart} From 3da96a30257dcd20496da6491acf37c45614ed0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Glerup=20R=C3=B8ssum?= <1959615+joglr@users.noreply.github.com> Date: Sat, 20 May 2023 21:38:31 +0200 Subject: [PATCH 16/26] Rename some metrics --- src/components/Chart.tsx | 2 +- src/metrics/size-metric.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/Chart.tsx b/src/components/Chart.tsx index f52adcc5d..416dd5278 100644 --- a/src/components/Chart.tsx +++ b/src/components/Chart.tsx @@ -399,7 +399,7 @@ function createPartitionedHiearchy( return 1 case "RANDOM": return Math.random() * 100 - case "NUMBER_OF_AUTHORS": + case "TRUCK_FACTOR": return Object.keys(hydratedBlob.authors ?? {}).length } }) diff --git a/src/metrics/size-metric.ts b/src/metrics/size-metric.ts index 830e53096..a6a6fa033 100644 --- a/src/metrics/size-metric.ts +++ b/src/metrics/size-metric.ts @@ -1,8 +1,8 @@ export const SizeMetric = { + EQUAL_SIZE: "Equal", FILE_SIZE: "File size", MOST_COMMITS: "Number of commits", - NUMBER_OF_AUTHORS: "Number of authors", - EQUAL_SIZE: "Equal", + TRUCK_FACTOR: "Truck factor", RANDOM: "Random", } From f1f0517e5d683ca75546fe02787c98996c67e0e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Glerup=20R=C3=B8ssum?= <1959615+joglr@users.noreply.github.com> Date: Sat, 20 May 2023 22:34:06 +0200 Subject: [PATCH 17/26] Revamp options --- src/components/EnumSelect.tsx | 26 +++++++++++-- src/components/Options.tsx | 70 +++++++++++++++++++++++------------ src/components/util.tsx | 19 +++++----- src/metrics/size-metric.ts | 4 +- src/styles/vars.css | 2 +- src/tailwind.css | 6 +-- 6 files changed, 84 insertions(+), 43 deletions(-) diff --git a/src/components/EnumSelect.tsx b/src/components/EnumSelect.tsx index 0fcf97735..f7c90b9e0 100644 --- a/src/components/EnumSelect.tsx +++ b/src/components/EnumSelect.tsx @@ -1,3 +1,5 @@ +import Icon from "@mdi/react" +import clsx from "clsx" import type { ReactNode } from "react" import { useId } from "react" import { useOptions } from "~/contexts/OptionsContext" @@ -8,6 +10,7 @@ interface EnumSelectProps { defaultValue: T onChange: (metric: T) => void hidden?: boolean + iconMap: Record } export function EnumSelect(props: EnumSelectProps) { @@ -16,13 +19,13 @@ export function EnumSelect(props: EnumSelectProps) { const { hasLoadedSavedOptions } = useOptions() return ( -
+
- + */} +
+ {enumEntries.map(([key, value]) => ( + + ))} +
) } diff --git a/src/components/Options.tsx b/src/components/Options.tsx index c578b8324..6ec38ce20 100644 --- a/src/components/Options.tsx +++ b/src/components/Options.tsx @@ -5,15 +5,13 @@ import type { ChartType } from "../contexts/OptionsContext" import { Chart, useOptions } from "../contexts/OptionsContext" import { CheckboxWithLabel } from "./util" import { Icon } from "@mdi/react" -import { memo } from "react" +import { memo, useState } from "react" import { mdiChartBubble, mdiCogOutline, mdiChartTree, mdiPodiumGold, - mdiThermometer, mdiFileCodeOutline, - mdiTruckFastOutline, mdiUpdate, mdiResize, mdiSourceCommit, @@ -21,9 +19,13 @@ import { mdiDice3Outline, mdiScaleBalance, mdiAccountAlertOutline, + mdiTruckFastOutline, + mdiLink, + mdiLinkOff, } from "@mdi/js" import type { SizeMetricType } from "~/metrics/size-metric" import { SizeMetric } from "~/metrics/size-metric" +import { useLocalStorage } from "react-use" function isMetricWithHistoricalOption(metric: MetricType) { switch (metric) { @@ -48,10 +50,15 @@ export const Options = memo(function Options() { setSizeMetricType, } = useOptions() + const [linkMetricAndSizeMetric, setLinkMetricAndSizeMetric] = useLocalStorage( + "LINK_METRIC_AND_SIZE_METRIC", + true + ) + const visualizationIcons: Record = { FILE_TYPE: mdiFileCodeOutline, LAST_CHANGED: mdiUpdate, - MOST_COMMITS: mdiThermometer, + MOST_COMMITS: mdiSourceCommit, SINGLE_AUTHOR: mdiAccountAlertOutline, TOP_CONTRIBUTOR: mdiPodiumGold, TRUCK_FACTOR: mdiTruckFastOutline, @@ -61,7 +68,7 @@ export const Options = memo(function Options() { FILE_SIZE: mdiResize, EQUAL_SIZE: mdiScaleBalance, MOST_COMMITS: mdiSourceCommit, - NUMBER_OF_AUTHORS: mdiAccountGroupOutline, + TRUCK_FACTOR: mdiAccountGroupOutline, RANDOM: mdiDice3Outline, } @@ -70,6 +77,15 @@ export const Options = memo(function Options() { TREE_MAP: mdiChartTree, } + const relatedSizeMetric: Partial> = { + FILE_TYPE: "FILE_SIZE", + TRUCK_FACTOR: "TRUCK_FACTOR", + TOP_CONTRIBUTOR: "TRUCK_FACTOR", + MOST_COMMITS: "MOST_COMMITS", + SINGLE_AUTHOR: "TRUCK_FACTOR", + LAST_CHANGED: "EQUAL_SIZE", + } + return (

@@ -77,37 +93,43 @@ export const Options = memo(function Options() {

- Visualization - -
- } + label={
Color
} enum={Metric} defaultValue={metricType} - onChange={(metric: MetricType) => setMetricType(metric)} + onChange={(metric: MetricType) => { + setMetricType(metric) + if (!linkMetricAndSizeMetric) { + return + } + const relatedSizeMetricType = relatedSizeMetric[metric] + if (relatedSizeMetricType) { + setSizeMetricType(relatedSizeMetricType) + } + }} + iconMap={visualizationIcons} /> + setLinkMetricAndSizeMetric(e.target.checked)} + checkedIcon={mdiLink} + uncheckedIcon={mdiLinkOff} + > + Link size metric to color metric + - Size metric - -
- } + label={
Size
} enum={SizeMetric} defaultValue={sizeMetric} onChange={(sizeMetric: SizeMetricType) => setSizeMetricType(sizeMetric)} + iconMap={sizeMetricIcons} /> - Chart layout - - - } + label={
Chart layout
} enum={Chart} defaultValue={chartType} onChange={(chartType: ChartType) => setChartType(chartType)} + iconMap={chartTypeIcons} /> {/* ) => void -} & Omit, "onChange" | "checked">) { - const id = useId() + checkedIcon?: string + uncheckedIcon?: string +} & Omit, "onChange" | "checked">) { return ( -
- -
+ ) } diff --git a/src/metrics/size-metric.ts b/src/metrics/size-metric.ts index a6a6fa033..dee094800 100644 --- a/src/metrics/size-metric.ts +++ b/src/metrics/size-metric.ts @@ -1,8 +1,8 @@ export const SizeMetric = { - EQUAL_SIZE: "Equal", FILE_SIZE: "File size", - MOST_COMMITS: "Number of commits", TRUCK_FACTOR: "Truck factor", + MOST_COMMITS: "Number of commits", + EQUAL_SIZE: "Equal", RANDOM: "Random", } diff --git a/src/styles/vars.css b/src/styles/vars.css index 32177c84d..5932392e1 100644 --- a/src/styles/vars.css +++ b/src/styles/vars.css @@ -1,7 +1,7 @@ :root { --unit: 8px; --global-bg-color: hsl(210, 38%, 95%); - --side-panel-width-units: 40; + --side-panel-width-units: 48; --side-panel-width: calc(var(--side-panel-width-units) * var(--unit)); --title-color: hsl(200, 5%, 30%); --text-color: hsl(200, 5%, 25%); diff --git a/src/tailwind.css b/src/tailwind.css index bb46ad5c4..0dc5b1973 100644 --- a/src/tailwind.css +++ b/src/tailwind.css @@ -29,7 +29,7 @@ /* Inputs */ .btn { - @apply grid h-8 cursor-pointer grid-flow-col items-center justify-center gap-2 rounded-md bg-gray-200 px-3 text-sm font-bold text-gray-600 transition-all hover:opacity-70 disabled:cursor-not-allowed disabled:opacity-50; + @apply border grid h-8 cursor-pointer grid-flow-col items-center justify-center gap-2 rounded-md bg-gray-200 px-3 text-sm font-bold text-gray-600 transition-all hover:opacity-70 disabled:cursor-not-allowed disabled:opacity-50; } .btn > svg, @@ -42,11 +42,11 @@ } .btn--outlined { - @apply border border-current bg-transparent text-black/50 hover:bg-transparent hover:text-black/80; + @apply border-current bg-transparent text-black/50 hover:bg-transparent hover:text-black/80; } .btn--outlined--light { - @apply border border-current bg-transparent text-white/80 hover:bg-transparent hover:text-white/100; + @apply border-current bg-transparent text-white/80 hover:bg-transparent hover:text-white/100; } .btn--primary { From fbb9c42a75ac6cce757461302c7dd0e20465d49e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Glerup=20R=C3=B8ssum?= <1959615+joglr@users.noreply.github.com> Date: Sun, 21 May 2023 17:55:38 +0200 Subject: [PATCH 18/26] Make close button inherit parent text color --- src/components/util.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/util.tsx b/src/components/util.tsx index b9e2318f9..136072cfe 100644 --- a/src/components/util.tsx +++ b/src/components/util.tsx @@ -6,7 +6,7 @@ import clsx from "clsx" export const CloseButton = ({ className = "", ...props }: HTMLAttributes) => ( - - {clickedObject.name.includes(".") ? ( -
- +
+
+

+ + + {clickedObject.name} + + setClickedObject(null)} /> +

+
+ {isBlob ? ( + <> + + + + + ) : ( + + )} + +
+
+ {isBlob ? ( + + ) : ( + + )} +
+ +
+ +
+
+
+ {isBlob ? ( + <> + + - ) : null} -
- - -
- - ) : ( -
- - -
- )} -
- {isBlob ? ( - <> - - - + {clickedObject.name.includes(".") ? ( +
+ + +
+ ) : null} ) : ( - + <> +
+ + +
+ )} -
- {isBlob ? ( - - ) : ( - - )} - -
) } @@ -206,14 +258,30 @@ function LastchangedEntry(props: { clickedBlob: HydratedGitBlobObject }) { } function PathEntry(props: { path: string }) { + const { state } = useNavigation() + const { clickedObject } = useClickedObject() + if (!clickedObject) return null return ( <>
Located at
-

- {props.path} -

+
+

+ {props.path} +

+
+ + +
+
) } diff --git a/src/components/EnumSelect.tsx b/src/components/EnumSelect.tsx index f7c90b9e0..1b9d99793 100644 --- a/src/components/EnumSelect.tsx +++ b/src/components/EnumSelect.tsx @@ -5,7 +5,6 @@ import { useId } from "react" import { useOptions } from "~/contexts/OptionsContext" interface EnumSelectProps { - label: ReactNode enum: Record defaultValue: T onChange: (metric: T) => void @@ -14,43 +13,23 @@ interface EnumSelectProps { } export function EnumSelect(props: EnumSelectProps) { - const id = useId() const enumEntries = Object.entries(props.enum) as [T, string][] - const { hasLoadedSavedOptions } = useOptions() return ( -
- - {/* */} -
- {enumEntries.map(([key, value]) => ( - - ))} -
+
+ {enumEntries.map(([key, value]) => ( + + ))}
) } diff --git a/src/components/FeedbackCard.tsx b/src/components/FeedbackCard.tsx index 0840d7bbf..7c2f33696 100644 --- a/src/components/FeedbackCard.tsx +++ b/src/components/FeedbackCard.tsx @@ -6,7 +6,7 @@ export const FeedbackCard = memo(function FeedbackCard() { return (
-

Help improve Git Truck

+

Help improve Git Truck

{commit.message} diff --git a/src/components/GlobalInfo.tsx b/src/components/GlobalInfo.tsx index 316a7a918..49107c326 100644 --- a/src/components/GlobalInfo.tsx +++ b/src/components/GlobalInfo.tsx @@ -3,10 +3,11 @@ import { dateTimeFormatShort } from "~/util" import { useData } from "../contexts/DataContext" import { memo, useEffect, useState } from "react" import { RevisionSelect } from "./RevisionSelect" -import { mdiFolder, mdiRefresh, mdiArrowTopLeft } from "@mdi/js" -import { Code } from "./util" +import { mdiRefresh, mdiArrowTopLeft, mdiInformation } from "@mdi/js" +import { CloseButton, Code } from "./util" import { Icon } from "@mdi/react" import { useClient } from "~/hooks" +import clsx from "clsx" const title = "Git Truck" const analyzingTitle = "Analyzing | Git Truck" @@ -20,6 +21,7 @@ export const GlobalInfo = memo(function GlobalInfo() { const navigate = useNavigate() const [isAnalyzing, setIsAnalyzing] = useState(false) + const [analysisDetailsVisible, setAnalysisDetailsVisible] = useState(false) useEffect(() => { document.title = isAnalyzing ? analyzingTitle : title @@ -37,53 +39,71 @@ export const GlobalInfo = memo(function GlobalInfo() { const isoString = new Date(analyzerData.lastRunEpoch).toISOString() return ( -
-
- - -

See more repositories

- -
-
-

- - {repo.name} -

-
{ - setIsAnalyzing(true) - }} - > - - -
-
- switchBranch(e.target.value)} - defaultValue={analyzerData.branch} - headGroups={repo.refs} - analyzedHeads={repo.analyzedHeads} - /> -
- Analyzed - +
+
+
+
+ +
+

Analysis details

+ setAnalysisDetailsVisible(false)} /> +
+ Analyzed + - As of commit - - #{analyzerData.commit.hash.slice(0, 7)} - + As of commit + + #{analyzerData.commit.hash.slice(0, 7)} + - Files analyzed - {analyzerData.commit.fileCount ?? 0} + Files analyzed + {analyzerData.commit.fileCount ?? 0} +
+
+
+

+ {repo.name} +

+
+
+ + +

See more repositories

+ +
{ + setIsAnalyzing(true) + }} + > + + +
+
+ switchBranch(e.target.value)} + defaultValue={analyzerData.branch} + headGroups={repo.refs} + analyzedHeads={repo.analyzedHeads} + />
) diff --git a/src/components/HiddenFiles.tsx b/src/components/HiddenFiles.tsx index ffc3703ed..a3b0d6617 100644 --- a/src/components/HiddenFiles.tsx +++ b/src/components/HiddenFiles.tsx @@ -21,16 +21,14 @@ export const HiddenFiles = memo(function HiddenFiles() { return (
-

- - setExpanded(!expanded)} - /> +

setExpanded(!expanded)} + role="button" + > + + Hidden files ({analyzerData.hiddenFiles.length}) +

{expanded ? (
diff --git a/src/components/Options.tsx b/src/components/Options.tsx index 6ec38ce20..fc69a9f81 100644 --- a/src/components/Options.tsx +++ b/src/components/Options.tsx @@ -5,23 +5,25 @@ import type { ChartType } from "../contexts/OptionsContext" import { Chart, useOptions } from "../contexts/OptionsContext" import { CheckboxWithLabel } from "./util" import { Icon } from "@mdi/react" -import { memo, useState } from "react" +import { memo } from "react" import { mdiChartBubble, - mdiCogOutline, mdiChartTree, mdiPodiumGold, mdiFileCodeOutline, mdiUpdate, mdiResize, mdiSourceCommit, - mdiAccountGroupOutline, - mdiDice3Outline, mdiScaleBalance, mdiAccountAlertOutline, mdiTruckFastOutline, mdiLink, - mdiLinkOff, + mdiTransition, + mdiLabel, + mdiPalette, + mdiImageSizeSelectSmall, + mdiPuzzle, + mdiCog, } from "@mdi/js" import type { SizeMetricType } from "~/metrics/size-metric" import { SizeMetric } from "~/metrics/size-metric" @@ -68,8 +70,8 @@ export const Options = memo(function Options() { FILE_SIZE: mdiResize, EQUAL_SIZE: mdiScaleBalance, MOST_COMMITS: mdiSourceCommit, - TRUCK_FACTOR: mdiAccountGroupOutline, - RANDOM: mdiDice3Outline, + TRUCK_FACTOR: mdiTruckFastOutline, + LAST_CHANGED: mdiUpdate, } const chartTypeIcons: Record = { @@ -77,82 +79,125 @@ export const Options = memo(function Options() { TREE_MAP: mdiChartTree, } - const relatedSizeMetric: Partial> = { + const relatedSizeMetric: Record = { FILE_TYPE: "FILE_SIZE", TRUCK_FACTOR: "TRUCK_FACTOR", TOP_CONTRIBUTOR: "TRUCK_FACTOR", MOST_COMMITS: "MOST_COMMITS", SINGLE_AUTHOR: "TRUCK_FACTOR", - LAST_CHANGED: "EQUAL_SIZE", + LAST_CHANGED: "LAST_CHANGED", } return ( -
-

+ <> + {/*

Options -

- Color
} - enum={Metric} - defaultValue={metricType} - onChange={(metric: MetricType) => { - setMetricType(metric) - if (!linkMetricAndSizeMetric) { - return - } - const relatedSizeMetricType = relatedSizeMetric[metric] - if (relatedSizeMetricType) { - setSizeMetricType(relatedSizeMetricType) - } - }} - iconMap={visualizationIcons} - /> - setLinkMetricAndSizeMetric(e.target.checked)} - checkedIcon={mdiLink} - uncheckedIcon={mdiLinkOff} - > - Link size metric to color metric - - Size
} - enum={SizeMetric} - defaultValue={sizeMetric} - onChange={(sizeMetric: SizeMetricType) => setSizeMetricType(sizeMetric)} - iconMap={sizeMetricIcons} - /> +

*/} +
+
+ + + Layout + + setChartType(chartType)} + iconMap={chartTypeIcons} + /> +
+ {/*
*/} +
+ + + Color + + { + setMetricType(metric) + if (!linkMetricAndSizeMetric) { + return + } + const relatedSizeMetricType = relatedSizeMetric[metric] + if (relatedSizeMetricType) { + setSizeMetricType(relatedSizeMetricType) + } + }} + iconMap={visualizationIcons} + /> +
+ {/*
*/} +
+ + + Size + + setSizeMetricType(sizeMetric)} + iconMap={sizeMetricIcons} + /> +
+ {/*
*/} + + {/* +
+ {props.label} Chart layout
} - enum={Chart} - defaultValue={chartType} - onChange={(chartType: ChartType) => setChartType(chartType)} - iconMap={chartTypeIcons} - /> - {/* setAuthorshipType(baseData)} hidden={!isMetricWithHistoricalOption(metricType)} - />*/} - setTransitionsEnabled(e.target.checked)} - title="Disable to improve performance when zooming" - > - Transitions - - setLabelsVisible(e.target.checked)} - title="Disable to improve performance" - > - Labels - -
+ /> +
+ */} + + {/*
*/} +
+ + + Settings + + { + setLinkMetricAndSizeMetric(e.target.checked) + if (e.target.checked) { + setSizeMetricType(relatedSizeMetric[metricType]) + } + }} + // checkedIcon={mdiLink} + // uncheckedIcon={mdiLinkOff} + title="Enable to sync size metric with color metric" + > + + Link size and color option + + setTransitionsEnabled(e.target.checked)} + title="Disable to improve performance when zooming" + > + + Transitions + + setLabelsVisible(e.target.checked)} + title="Disable to improve performance" + > + + Labels + +
+
+ ) }) diff --git a/src/components/SearchCard.tsx b/src/components/SearchCard.tsx index be647ea4a..b6a1eaa10 100644 --- a/src/components/SearchCard.tsx +++ b/src/components/SearchCard.tsx @@ -7,7 +7,7 @@ import { usePath } from "~/contexts/PathContext" import { useClickedObject } from "~/contexts/ClickedContext" import { allExceptLast, getSeparator } from "~/util" import { Icon } from "@mdi/react" -import { mdiFolder, mdiFileSearchOutline, mdiFileOutline } from "@mdi/js" +import { mdiFolder, mdiFileOutline, mdiMagnify } from "@mdi/js" function findSearchResults(tree: HydratedGitTreeObject, searchString: string) { const searchResults: HydratedGitObject[] = [] @@ -49,24 +49,39 @@ export const SearchCard = memo(function SearchCard() { return ( <>
-

+

+ Search -

- { - const value = event.target.value - startTransition(() => { - setSearchText(value) - setSearchResults(findSearchResults(analyzerData.commit.tree, value)) - }) - }} - /> +
+ { + const value = event.target.value + startTransition(() => { + setSearchText(value) + setSearchResults(findSearchResults(analyzerData.commit.tree, value)) + }) + }} + /> + +
{isTransitioning || searchText.length > 0 ? (

{isTransitioning ? "Searching..." : searchText.length > 0 ? `${searchResults.length} results` : null} diff --git a/src/components/Tooltip.tsx b/src/components/Tooltip.tsx index 534c23479..46e66d26a 100644 --- a/src/components/Tooltip.tsx +++ b/src/components/Tooltip.tsx @@ -51,7 +51,7 @@ export const Tooltip = memo(function Tooltip({ hoveredObject, x, y }: TooltipPro ) : ( )} - + {hoveredObject && isBlob(hoveredObject) ? hoveredObject?.name : allExceptFirst(hoveredObject?.path.split("/") ?? []).map((segment, index, segments) => ( diff --git a/src/components/util.tsx b/src/components/util.tsx index 80b9c0319..1b43d9297 100644 --- a/src/components/util.tsx +++ b/src/components/util.tsx @@ -3,9 +3,15 @@ import { Icon } from "@mdi/react" import { mdiCheckboxOutline, mdiCheckboxBlankOutline, mdiMenuUp, mdiClose } from "@mdi/js" import clsx from "clsx" -export const CloseButton = ({ className = "", ...props }: HTMLAttributes) => ( +export const CloseButton = ({ + className = "", + absolute = true, + ...props +}: HTMLAttributes & { absolute?: boolean }) => (

{isTransitioning || searchText.length > 0 ? (

- {isTransitioning ? "Searching..." : searchText.length > 0 ? `${searchResults.length} results` : null} + {isTransitioning ? "Searching..." : searchText.length > 0 ? `${searchResultsArray.length} results` : null}

) : null}
- {searchResults.length > 0 ? : null} + {searchResultsArray.length > 0 ? : null} ) }) -const SearchResults = memo(function SearchResults() { +const SearchResultsList = memo(function SearchResults() { const { setPath } = usePath() const { setClickedObject } = useClickedObject() const { searchResults } = useSearch() @@ -110,7 +115,7 @@ const SearchResults = memo(function SearchResults() { return (
- {searchResults.map((result) => ( + {Object.values(searchResults).map((result) => ( ))}
diff --git a/src/contexts/OptionsContext.ts b/src/contexts/OptionsContext.ts index d2b79a62b..41516d69e 100644 --- a/src/contexts/OptionsContext.ts +++ b/src/contexts/OptionsContext.ts @@ -35,7 +35,7 @@ export const OptionsContext = createContext(unde export function useOptions() { const context = useContext(OptionsContext) if (!context) { - throw new Error("useSearch must be used within a SearchProvider") + throw new Error("useOptions must be used within a SearchProvider") } return context } @@ -71,6 +71,6 @@ export function getDefaultOptionsContextValue(savedOptions: Partial = { }, setLabelsVisible: () => { throw new Error("No labelsVisibleSetter provided") - } + }, } } diff --git a/src/contexts/PathContext.ts b/src/contexts/PathContext.ts index ac91ff853..8e90af72a 100644 --- a/src/contexts/PathContext.ts +++ b/src/contexts/PathContext.ts @@ -11,7 +11,7 @@ export const PathContext = createContext(undefined) export function usePath() { const context = useContext(PathContext) if (!context) { - throw new Error("useSearch must be used within a PathProvider") + throw new Error("useOptions must be used within a PathProvider") } return context } diff --git a/src/contexts/SearchContext.ts b/src/contexts/SearchContext.ts index 0cb371819..00630e2e3 100644 --- a/src/contexts/SearchContext.ts +++ b/src/contexts/SearchContext.ts @@ -2,11 +2,11 @@ import type { Dispatch, SetStateAction } from "react" import { createContext, useContext } from "react" import type { HydratedGitObject } from "~/analyzer/model" +export type SearchResults = Record + type Search = { - searchText: string - setSearchText: Dispatch> - searchResults: HydratedGitObject[] - setSearchResults: Dispatch> + searchResults: SearchResults + setSearchResults: Dispatch> } export const SearchContext = createContext(undefined) diff --git a/src/styles/vars.css b/src/styles/vars.css index 71c054c62..e10781490 100644 --- a/src/styles/vars.css +++ b/src/styles/vars.css @@ -1,7 +1,7 @@ :root { --unit: 4px; --global-bg-color: hsl(210, 38%, 95%); - --side-panel-width-units: 90; + --side-panel-width-units: 94; --side-panel-width: calc(var(--side-panel-width-units) * var(--unit)); --title-color: hsl(200, 5%, 30%); --text-color: hsl(200, 5%, 25%); From ded4512b4311742c5b03a2dad88684fe46ce9374 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Glerup=20R=C3=B8ssum?= <1959615+joglr@users.noreply.github.com> Date: Sun, 28 May 2023 15:31:01 +0200 Subject: [PATCH 26/26] 1.5.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7bcee0cfb..d87e5b8a7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "git-truck", - "version": "1.4.5", + "version": "1.5.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "git-truck", - "version": "1.4.5", + "version": "1.5.0", "license": "MIT", "bin": { "git-truck": "cli.js" diff --git a/package.json b/package.json index 3911e5732..2e8798442 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-truck", - "version": "1.4.5", + "version": "1.5.0", "private": false, "description": "Visualizing a Git repository", "license": "MIT",