From c39f9006d93efe8c8579f2564aa3cf7448cf6717 Mon Sep 17 00:00:00 2001 From: Alexander Harding <2166114+aeharding@users.noreply.github.com> Date: Wed, 21 Jun 2023 17:55:25 -0500 Subject: [PATCH] Add reorganized file structure, add lint and CI --- .eslintrc | 59 ++ .eslintrc.js | 17 - .github/workflows/ci.yml | 36 + capacitor.config.ts | 12 - cypress.config.ts | 10 - cypress/e2e/test.cy.ts | 6 - cypress/fixtures/example.json | 5 - cypress/support/commands.ts | 37 - cypress/support/e2e.ts | 20 - index.html | 2 +- ionic.config.json | 7 - package.json | 25 +- server.mjs | 5 +- src/ActorRedirect.tsx | 3 +- src/App.test.tsx | 7 +- src/App.tsx | 30 +- src/Auth.tsx | 10 +- src/Router.tsx | 24 + src/{Tabs.tsx => TabbedRoutes.tsx} | 26 +- src/ThemeColorUpdater.tsx | 44 - src/components/PersonLabel.tsx | 64 -- src/components/PostFilter.tsx | 33 - src/features/auth/AppContext.tsx | 2 +- src/features/auth/Login.tsx | 7 +- src/features/auth/authSlice.ts | 4 +- .../comment}/Comment.tsx | 30 +- .../comment}/CommentContent.tsx | 12 +- .../comment}/CommentHr.tsx | 2 +- .../comment}/CommentTree.tsx | 9 +- .../comment}/Comments.tsx | 34 +- src/features/comment/commentSlice.ts | 4 +- .../comment/{ => reply}/CommentReply.tsx | 28 +- .../comment/{ => reply}/ItemReplyingTo.tsx | 8 +- .../community/MoreActions.tsx | 4 +- .../community/communitySlice.ts | 14 +- src/{components => features/labels}/Ago.tsx | 1 - src/features/labels/Handle.tsx | 24 + src/{components => features/labels}/Nsfw.tsx | 2 +- src/{components => features/labels}/Vote.tsx | 13 +- src/features/labels/img/CommunityIcon.tsx | 67 ++ src/features/labels/links/CommunityLink.tsx | 33 + src/features/labels/links/PersonLink.tsx | 62 ++ src/features/labels/links/shared.ts | 8 + .../post/actions/ActionButton.tsx | 0 .../post/actions}/PostActions.tsx | 4 +- .../post/detail}/Img.tsx | 5 +- .../post/detail}/PostDetail.tsx | 94 +- .../post/detail}/Stats.tsx | 6 +- .../post/detail}/ViewAllComments.tsx | 2 +- .../post/inFeed}/EndPost.tsx | 7 +- .../post/inFeed}/Post.tsx | 98 +- .../post/inFeed}/PostSort.tsx | 4 +- .../post/inFeed}/Posts.tsx | 25 +- .../post/inFeed}/PreviewStats.tsx | 8 +- src/features/post/postSlice.ts | 7 +- .../post/shared}/Embed.tsx | 0 .../post/{item => shared}/MoreActions.tsx | 37 +- .../post/shared}/VoteButton.tsx | 12 +- .../shared}/AppBackButton.tsx | 4 +- .../shared}/AppContent.tsx | 1 + .../shared}/DraggingVote.tsx | 3 +- .../shared}/InlineMarkdown.tsx | 0 .../shared}/Markdown.tsx | 6 +- .../{profile => user}/PostContext.tsx | 8 +- src/features/{profile => user}/Profile.tsx | 28 +- src/features/{profile => user}/Scores.tsx | 2 +- src/features/{profile => user}/incognito.svg | 0 src/features/user/userSlice.tsx | 2 +- src/{main.css => index.css} | 2 +- src/{main.tsx => index.tsx} | 4 +- .../{Communities.tsx => CommunitiesPage.tsx} | 62 +- .../{Community.tsx => CommunityPage.tsx} | 15 +- src/pages/ProfilePage.tsx | 19 +- src/pages/SettingsPage.tsx | 4 +- src/pages/SpecialFeedPage.tsx | 4 +- src/pages/UserPage.tsx | 10 +- src/pages/settings/InstallAppPage.tsx | 6 +- src/services/lemmy.ts | 2 +- src/setupTests.ts | 21 +- src/store.ts | 2 +- vite.config.ts | 8 +- yarn.lock | 989 ++++-------------- 82 files changed, 849 insertions(+), 1512 deletions(-) create mode 100644 .eslintrc delete mode 100644 .eslintrc.js create mode 100644 .github/workflows/ci.yml delete mode 100644 capacitor.config.ts delete mode 100644 cypress.config.ts delete mode 100644 cypress/e2e/test.cy.ts delete mode 100644 cypress/fixtures/example.json delete mode 100644 cypress/support/commands.ts delete mode 100644 cypress/support/e2e.ts delete mode 100644 ionic.config.json create mode 100644 src/Router.tsx rename src/{Tabs.tsx => TabbedRoutes.tsx} (91%) delete mode 100644 src/ThemeColorUpdater.tsx delete mode 100644 src/components/PersonLabel.tsx delete mode 100644 src/components/PostFilter.tsx rename src/{components => features/comment}/Comment.tsx (89%) rename src/{components => features/comment}/CommentContent.tsx (69%) rename src/{components => features/comment}/CommentHr.tsx (93%) rename src/{components => features/comment}/CommentTree.tsx (84%) rename src/{components => features/comment}/Comments.tsx (85%) rename src/features/comment/{ => reply}/CommentReply.tsx (84%) rename src/features/comment/{ => reply}/ItemReplyingTo.tsx (86%) rename src/{components => features}/community/MoreActions.tsx (96%) rename src/{components => features}/community/communitySlice.ts (88%) rename src/{components => features/labels}/Ago.tsx (97%) create mode 100644 src/features/labels/Handle.tsx rename src/{components => features/labels}/Nsfw.tsx (91%) rename src/{components => features/labels}/Vote.tsx (82%) create mode 100644 src/features/labels/img/CommunityIcon.tsx create mode 100644 src/features/labels/links/CommunityLink.tsx create mode 100644 src/features/labels/links/PersonLink.tsx create mode 100644 src/features/labels/links/shared.ts rename src/{components => features}/post/actions/ActionButton.tsx (100%) rename src/{components => features/post/actions}/PostActions.tsx (92%) rename src/{components => features/post/detail}/Img.tsx (92%) rename src/{components => features/post/detail}/PostDetail.tsx (73%) rename src/{components => features/post/detail}/Stats.tsx (87%) rename src/{components => features/post/detail}/ViewAllComments.tsx (95%) rename src/{components => features/post/inFeed}/EndPost.tsx (90%) rename src/{components => features/post/inFeed}/Post.tsx (75%) rename src/{components => features/post/inFeed}/PostSort.tsx (94%) rename src/{components => features/post/inFeed}/Posts.tsx (87%) rename src/{components => features/post/inFeed}/PreviewStats.tsx (78%) rename src/{components => features/post/shared}/Embed.tsx (100%) rename src/features/post/{item => shared}/MoreActions.tsx (78%) rename src/{components => features/post/shared}/VoteButton.tsx (86%) rename src/{components => features/shared}/AppBackButton.tsx (92%) rename src/{components => features/shared}/AppContent.tsx (95%) rename src/{components => features/shared}/DraggingVote.tsx (96%) rename src/{components => features/shared}/InlineMarkdown.tsx (100%) rename src/{components => features/shared}/Markdown.tsx (84%) rename src/features/{profile => user}/PostContext.tsx (84%) rename src/features/{profile => user}/Profile.tsx (80%) rename src/features/{profile => user}/Scores.tsx (96%) rename src/features/{profile => user}/incognito.svg (100%) rename src/{main.css => index.css} (94%) rename src/{main.tsx => index.tsx} (75%) rename src/pages/{Communities.tsx => CommunitiesPage.tsx} (72%) rename src/pages/{Community.tsx => CommunityPage.tsx} (76%) diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000000..fd25ec19d4 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,59 @@ +{ + "root": true, + "env": { + "browser": true, + "es2022": true + }, + "extends": [ + "plugin:@typescript-eslint/recommended", + "plugin:react/recommended", + "plugin:react-hooks/recommended", + "plugin:prettier/recommended" + ], + "plugins": ["react", "@typescript-eslint", "@emotion"], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaFeatures": { + "jsx": true + }, + "sourceType": "module", + "ecmaVersion": 2022 + }, + "rules": { + "react/react-in-jsx-scope": "off", + "no-console": ["warn", { "allow": ["warn", "error", "info"] }], + "linebreak-style": ["warn", "unix"], + "react/jsx-fragments": ["warn", "syntax"], + "no-undef": 1, + "@typescript-eslint/no-empty-function": 0, + "@typescript-eslint/no-empty-interface": 0, + "react/jsx-curly-brace-presence": ["warn", "never"], + "eqeqeq": ["warn", "smart"], + "react/no-unknown-property": ["error", { "ignore": ["css"] }], + "@emotion/no-vanilla": "error", + "@emotion/import-from-emotion": "error", + "@emotion/styled-import": "error", + "@emotion/syntax-preference": [2, "string"], + "@typescript-eslint/no-unused-vars": [ + "warn", + { "destructuredArrayIgnorePattern": "^_" } + ] + }, + "overrides": [ + { + "files": ["**/*.test.ts", "**/*.test.tsx"], + "globals": { + "global": "writable" + }, + "env": { + "jest": true + } + }, + { + "files": ["server.mjs"], + "env": { + "node": true + } + } + ] +} diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index af472a1f7d..0000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,17 +0,0 @@ -module.exports = { - root: true, - env: { - node: true - }, - 'extends': [ - 'plugin:react/recommended', - 'eslint:recommended' - ], - parserOptions: { - ecmaVersion: 2020 - }, - rules: { - 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', - 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', - } -} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000000..4adec4d4ce --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,36 @@ +name: ci + +permissions: {} + +on: + push: + branches: + - main + pull_request: + branches: + - main + workflow_dispatch: {} + +jobs: + ci: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - run: corepack enable + - uses: actions/setup-node@v3 + with: + node-version: 18 + cache: yarn + + - name: ๐Ÿ“ฆ Install dependencies + run: yarn --frozen-lockfile + + - name: ๐Ÿงช Test project + run: yarn test + + - name: ๐Ÿ“ Lint + run: yarn lint + + - name: ๐Ÿ’ช Type check + run: yarn test:typecheck diff --git a/capacitor.config.ts b/capacitor.config.ts deleted file mode 100644 index 3fd0a52f40..0000000000 --- a/capacitor.config.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { CapacitorConfig } from '@capacitor/cli'; - -const config: CapacitorConfig = { - appId: 'io.ionic.starter', - appName: 'wefwef', - webDir: 'dist', - server: { - androidScheme: 'https' - } -}; - -export default config; diff --git a/cypress.config.ts b/cypress.config.ts deleted file mode 100644 index 5d58e7ab1f..0000000000 --- a/cypress.config.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { defineConfig } from "cypress"; - -export default defineConfig({ - e2e: { - baseUrl: "http://localhost:5173", - setupNodeEvents(on, config) { - // implement node event listeners here - }, - }, -}); \ No newline at end of file diff --git a/cypress/e2e/test.cy.ts b/cypress/e2e/test.cy.ts deleted file mode 100644 index f6b655f3b1..0000000000 --- a/cypress/e2e/test.cy.ts +++ /dev/null @@ -1,6 +0,0 @@ -describe('My First Test', () => { - it('Visits the app root url', () => { - cy.visit('/') - cy.contains('ion-content', 'Tab 1 page') - }) -}) \ No newline at end of file diff --git a/cypress/fixtures/example.json b/cypress/fixtures/example.json deleted file mode 100644 index 02e4254378..0000000000 --- a/cypress/fixtures/example.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "Using fixtures to represent data", - "email": "hello@cypress.io", - "body": "Fixtures are a great way to mock data for responses to routes" -} diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts deleted file mode 100644 index 698b01a42c..0000000000 --- a/cypress/support/commands.ts +++ /dev/null @@ -1,37 +0,0 @@ -/// -// *********************************************** -// This example commands.ts shows you how to -// create various custom commands and overwrite -// existing commands. -// -// For more comprehensive examples of custom -// commands please read more here: -// https://on.cypress.io/custom-commands -// *********************************************** -// -// -// -- This is a parent command -- -// Cypress.Commands.add('login', (email, password) => { ... }) -// -// -// -- This is a child command -- -// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) -// -// -// -- This is a dual command -- -// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) -// -// -// -- This will overwrite an existing command -- -// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) -// -// declare global { -// namespace Cypress { -// interface Chainable { -// login(email: string, password: string): Chainable -// drag(subject: string, options?: Partial): Chainable -// dismiss(subject: string, options?: Partial): Chainable -// visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable -// } -// } -// } \ No newline at end of file diff --git a/cypress/support/e2e.ts b/cypress/support/e2e.ts deleted file mode 100644 index f80f74f8e1..0000000000 --- a/cypress/support/e2e.ts +++ /dev/null @@ -1,20 +0,0 @@ -// *********************************************************** -// This example support/e2e.ts is processed and -// loaded automatically before your test files. -// -// This is a great place to put global configuration and -// behavior that modifies Cypress. -// -// You can change the location of this file or turn off -// automatically serving support files with the -// 'supportFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/configuration -// *********************************************************** - -// Import commands.js using ES2015 syntax: -import './commands' - -// Alternatively you can use CommonJS syntax: -// require('./commands') \ No newline at end of file diff --git a/index.html b/index.html index ad74b59a03..5a3ab170dc 100644 --- a/index.html +++ b/index.html @@ -28,6 +28,6 @@
- + diff --git a/ionic.config.json b/ionic.config.json deleted file mode 100644 index d0e2a9f63c..0000000000 --- a/ionic.config.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "wefwef", - "integrations": { - "capacitor": {} - }, - "type": "react-vite" -} diff --git a/package.json b/package.json index 5b6dce5ce2..aaf3d1cd92 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ "build": "vite build", "preview": "vite preview", "test": "vitest", - "lint": "eslint" + "test:typecheck": "tsc", + "lint": "eslint src" }, "dependencies": { "express": "^4.18.2", @@ -19,49 +20,55 @@ "devDependencies": { "@emotion/babel-plugin": "^11.11.0", "@emotion/css": "^11.11.2", + "@emotion/eslint-plugin": "^11.11.0", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", "@ionic/core": "^7.0.14", - "@ionic/react-router": "^7.0.0", "@ionic/react": "^7.0.14", + "@ionic/react-router": "^7.0.0", "@reduxjs/toolkit": "^1.9.5", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^14.0.0", "@testing-library/user-event": "^14.4.3", "@types/js-cookie": "^3.0.3", "@types/lodash": "^4.14.195", + "@types/react": "^18.2.13", "@types/react-dom": "^18.2.6", - "@types/react-router-dom": "^5.3.3", "@types/react-router": "^5.1.20", - "@types/react": "^18.2.13", + "@types/react-router-dom": "^5.3.3", "@types/ua-parser-js": "^0.7.36", + "@typescript-eslint/eslint-plugin": "^5.60.0", + "@typescript-eslint/parser": "^5.60.0", "@vitejs/plugin-react": "^4.0.1", - "cypress": "^12.15.0", "date-fns": "^2.30.0", - "eslint-plugin-react": "^7.32.2", "eslint": "^8.43.0", + "eslint-config-prettier": "^8.8.0", + "eslint-plugin-prettier": "^4.2.1", + "eslint-plugin-react": "^7.32.2", + "eslint-plugin-react-hooks": "^4.6.0", "ionicons": "^7.1.2", "js-cookie": "^3.0.5", "jsdom": "^22.1.0", "lemmy-js-client": "0.18.0-rc.1", "lodash": "^4.17.21", "photoswipe": "^5.3.7", + "prettier": "^2.8.8", + "react": "^18.2.0", "react-animate-height": "^3.1.1", "react-dom": "^18.2.0", "react-markdown": "^8.0.7", "react-photoswipe-gallery": "^2.2.7", "react-redux": "^8.1.0", - "react-router-dom": "^5.3.4", "react-router": "^5.3.4", + "react-router-dom": "^5.3.4", "react-virtuoso": "^4.3.10", - "react": "^18.2.0", "remark-gfm": "^3.0.1", "terser": "^5.18.1", "typescript": "^5.1.3", "ua-parser-js": "^1.0.35", + "vite": "^4.3.9", "vite-plugin-pwa": "^0.16.4", "vite-plugin-svgr": "^3.2.0", - "vite": "^4.3.9", "vitest": "^0.32.0" } } diff --git a/server.mjs b/server.mjs index 60046c14b2..83f2fc5f8c 100644 --- a/server.mjs +++ b/server.mjs @@ -105,8 +105,9 @@ app.use( }) ); -const PORT = process.env.PORT || 3000; +const PORT = process.env.PORT || 5173; ViteExpress.listen(app, PORT, () => - console.log(`Server is listening on port ${PORT}...`) + // eslint-disable-next-line no-console + console.log(`Server is on http://localhost:${PORT}`) ); diff --git a/src/ActorRedirect.tsx b/src/ActorRedirect.tsx index 2ad4149445..1083b13b3f 100644 --- a/src/ActorRedirect.tsx +++ b/src/ActorRedirect.tsx @@ -1,6 +1,7 @@ import { Redirect, useLocation, useParams } from "react-router"; import { useAppSelector } from "./store"; import { jwtIssSelector } from "./features/auth/authSlice"; +import React from "react"; interface ActorRedirectProps { children?: React.ReactNode; @@ -14,7 +15,7 @@ export default function ActorRedirect({ children }: ActorRedirectProps) { if (!iss || !actor) return <>{children}; if (iss === actor) return <>{children}; - const [first, second, wrongActor, ...rest] = location.pathname.split("/"); + const [first, second, _wrongActor, ...rest] = location.pathname.split("/"); return ; } diff --git a/src/App.test.tsx b/src/App.test.tsx index 8c927a8d7a..8efaeadab9 100644 --- a/src/App.test.tsx +++ b/src/App.test.tsx @@ -1,8 +1,7 @@ -import React from 'react'; -import { render } from '@testing-library/react'; -import App from './App'; +import { render } from "@testing-library/react"; +import App from "./App"; -test('renders without crashing', () => { +test("renders without crashing", () => { const { baseElement } = render(); expect(baseElement).toBeDefined(); }); diff --git a/src/App.tsx b/src/App.tsx index c727f76fc1..b94e4eb167 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,5 +1,4 @@ import { IonApp, setupIonicReact } from "@ionic/react"; -import { createMemoryHistory } from "history"; /* Core CSS required for Ionic components to work properly */ import "@ionic/react/css/core.css"; @@ -21,13 +20,11 @@ import "@ionic/react/css/display.css"; import "./theme/variables.css"; import { Provider } from "react-redux"; import store from "./store"; -import ThemeColorUpdater from "./ThemeColorUpdater"; import { isInstalled } from "./helpers/device"; -import React, { useEffect } from "react"; -import Tabs from "./Tabs"; +import TabbedRoutes from "./TabbedRoutes"; import Auth from "./Auth"; import { AppContextProvider } from "./features/auth/AppContext"; -import { IonReactMemoryRouter, IonReactRouter } from "@ionic/react-router"; +import Router from "./Router"; setupIonicReact({ rippleEffect: false, @@ -35,35 +32,14 @@ setupIonicReact({ swipeBackEnabled: isInstalled(), }); -function Router({ children }: { children: React.ReactNode }) { - const history = createMemoryHistory(); - - useEffect(() => { - const unListen = history.listen(() => { - window.scrollTo(0, 0); - }); - return () => { - unListen(); - }; - }, []); - - if (isInstalled()) - return ( - {children} - ); - - return {children}; -} - export default function App() { return ( - - + diff --git a/src/Auth.tsx b/src/Auth.tsx index 910509c018..7ba5c4c0f7 100644 --- a/src/Auth.tsx +++ b/src/Auth.tsx @@ -1,12 +1,12 @@ -import { useEffect } from "react"; +import React, { useEffect } from "react"; import { useAppDispatch, useAppSelector } from "./store"; import { - getSelf, + getSite, jwtIssSelector, updateConnectedInstance, } from "./features/auth/authSlice"; import { useLocation } from "react-router"; -import { DEFAULT_ACTOR } from "./Tabs"; +import { DEFAULT_ACTOR } from "./TabbedRoutes"; interface AuthProps { children: React.ReactNode; @@ -34,10 +34,12 @@ export default function Auth({ children }: AuthProps) { if (potentialConnectedInstance) dispatch(updateConnectedInstance(potentialConnectedInstance)); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [location.pathname]); useEffect(() => { - dispatch(getSelf()); + dispatch(getSite()); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [jwt]); if (!connectedInstance) return; diff --git a/src/Router.tsx b/src/Router.tsx new file mode 100644 index 0000000000..33b3389d11 --- /dev/null +++ b/src/Router.tsx @@ -0,0 +1,24 @@ +import { IonReactMemoryRouter, IonReactRouter } from "@ionic/react-router"; +import { createMemoryHistory } from "history"; +import React, { useEffect } from "react"; +import { isInstalled } from "./helpers/device"; + +export default function Router({ children }: { children: React.ReactNode }) { + const history = createMemoryHistory(); + + useEffect(() => { + const unListen = history.listen(() => { + window.scrollTo(0, 0); + }); + return () => { + unListen(); + }; + }, [history]); + + if (isInstalled()) + return ( + {children} + ); + + return {children}; +} diff --git a/src/Tabs.tsx b/src/TabbedRoutes.tsx similarity index 91% rename from src/Tabs.tsx rename to src/TabbedRoutes.tsx index 8a43fdcb07..b45698ede6 100644 --- a/src/Tabs.tsx +++ b/src/TabbedRoutes.tsx @@ -9,21 +9,15 @@ import { IonTabs, useIonRouter, } from "@ionic/react"; -import { - settings, - telescopeSharp, - personCircleOutline, - cog, -} from "ionicons/icons"; -import PostDetail from "./components/PostDetail"; -import Communities from "./pages/Communities"; -import Community from "./pages/Community"; +import { telescopeSharp, personCircleOutline, cog } from "ionicons/icons"; +import PostDetail from "./features/post/detail/PostDetail"; +import CommunitiesPage from "./pages/CommunitiesPage"; +import CommunityPage from "./pages/CommunityPage"; import { useAppSelector } from "./store"; import { jwtIssSelector } from "./features/auth/authSlice"; import { POPULAR_SERVERS } from "./helpers/lemmy"; import ActorRedirect from "./ActorRedirect"; import SpecialFeedPage from "./pages/SpecialFeedPage"; -import { ListingType } from "lemmy-js-client"; import styled from "@emotion/styled"; import ProfilePage from "./pages/ProfilePage"; import SettingsPage from "./pages/SettingsPage"; @@ -41,7 +35,7 @@ const Interceptor = styled.div` export const DEFAULT_ACTOR = POPULAR_SERVERS[0]; -export default function Tabs() { +export default function TabbedRoutes() { const { activePage } = useContext(AppContext); const location = useLocation(); const router = useIonRouter(); @@ -128,16 +122,19 @@ export default function Tabs() { function buildGeneralBrowseRoutes(tab: string) { return [ + // eslint-disable-next-line react/jsx-key - + , + // eslint-disable-next-line react/jsx-key , + // eslint-disable-next-line react/jsx-key , + // eslint-disable-next-line react/jsx-key @@ -178,9 +176,9 @@ export default function Tabs() { - + - + {...buildGeneralBrowseRoutes("posts")} diff --git a/src/ThemeColorUpdater.tsx b/src/ThemeColorUpdater.tsx deleted file mode 100644 index 9ab8701778..0000000000 --- a/src/ThemeColorUpdater.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import React, { useEffect, useState } from "react"; - -const ThemeColorUpdater = () => { - const lightThemeColor = "#f7f7f7f7"; - const darkThemeColor = "#000000"; - - const [themeColor, setThemeColor] = useState(lightThemeColor); // Default light theme color - - useEffect(() => { - const handleThemeChange = (event: MediaQueryListEvent) => { - const newThemeColor = event.matches ? darkThemeColor : lightThemeColor; - setThemeColor(newThemeColor); - }; - - const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)"); - mediaQuery.addEventListener("change", handleThemeChange); - - // Update theme color when component mounts - setThemeColor(mediaQuery.matches ? darkThemeColor : lightThemeColor); - - // Create and inject the tag if it doesn't exist - let metaThemeColor = document.querySelector('meta[name="theme-color"]'); - if (!metaThemeColor) { - metaThemeColor = document.createElement("meta"); - metaThemeColor.setAttribute("name", "theme-color"); - document.head.appendChild(metaThemeColor); - } - - return () => { - mediaQuery.removeEventListener("change", handleThemeChange); - }; - }, []); - - useEffect(() => { - const metaThemeColor = document.querySelector('meta[name="theme-color"]'); - if (metaThemeColor) { - metaThemeColor.setAttribute("content", themeColor); - } - }, [themeColor]); - - return null; -}; - -export default ThemeColorUpdater; diff --git a/src/components/PersonLabel.tsx b/src/components/PersonLabel.tsx deleted file mode 100644 index 4dcceac8fa..0000000000 --- a/src/components/PersonLabel.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import { css } from "@emotion/react"; -import { Link } from "react-router-dom"; -import { getHandle, getItemActorName } from "../helpers/lemmy"; -import styled from "@emotion/styled"; -import { useBuildGeneralBrowseLink } from "../helpers/routes"; -import { Person } from "lemmy-js-client"; - -const StyledLink = styled(Link)` - text-decoration: none; -`; - -interface PersonLabelProps { - person: Person; - opId?: number; - distinguished?: boolean; - showAtInstanceWhenRemote?: boolean; - - className?: string; -} - -export default function PersonLabel({ - person, - opId, - distinguished, - className, - showAtInstanceWhenRemote, -}: PersonLabelProps) { - const buildGeneralBrowseLink = useBuildGeneralBrowseLink(); - - let color: string | undefined; - - if (distinguished) { - if (person.admin) color = "#ff0000"; - else color = "#00e600"; - } else if (opId && person.id === opId) color = "var(--ion-color-primary)"; - - return ( - e.stopPropagation()} - className={className} - css={ - color - ? css` - && { - color: ${color}; - } - ` - : css` - color: inherit; - ` - } - > - {showAtInstanceWhenRemote ? ( - <> - {person.name} - {!person.local && } - - ) : ( - person.name - )} - - ); -} diff --git a/src/components/PostFilter.tsx b/src/components/PostFilter.tsx deleted file mode 100644 index fc0ffd7880..0000000000 --- a/src/components/PostFilter.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { IonActionSheet, IonButton, IonIcon } from "@ionic/react"; -import { peopleCircleOutline, planetOutline } from "ionicons/icons"; -import { useState } from "react"; - -export default function PostFilter() { - const [open, setOpen] = useState(false); - - return ( - <> - setOpen(true)}> - - - setOpen(false)} - header="Show..." - buttons={[ - { - text: "Federated", - role: "all", - icon: planetOutline, - }, - { - text: "Local Only", - role: "local", - icon: peopleCircleOutline, - }, - ]} - /> - - ); -} diff --git a/src/features/auth/AppContext.tsx b/src/features/auth/AppContext.tsx index dfa4f5d7ad..5fe5f4b259 100644 --- a/src/features/auth/AppContext.tsx +++ b/src/features/auth/AppContext.tsx @@ -1,4 +1,4 @@ -import { RefObject, createContext, useState } from "react"; +import React, { RefObject, createContext, useState } from "react"; import { VirtuosoHandle } from "react-virtuoso"; interface IAppContext { diff --git a/src/features/auth/Login.tsx b/src/features/auth/Login.tsx index 0b9d4975ed..210c5849fc 100644 --- a/src/features/auth/Login.tsx +++ b/src/features/auth/Login.tsx @@ -22,6 +22,7 @@ import { useAppDispatch } from "../../store"; import { login } from "./authSlice"; import { LemmyHttp } from "lemmy-js-client"; import { getClient } from "../../services/lemmy"; +import { IonInputCustomEvent } from "@ionic/core"; export const Spinner = styled(IonSpinner)` width: 1.5rem; @@ -51,7 +52,7 @@ export default function Login({ const [serverConfirmed, setServerConfirmed] = useState(false); const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); - const usernameRef = useRef(null); + const usernameRef = useRef["target"]>(null); const [loading, setLoading] = useState(false); const customServerHostname = (() => { @@ -211,7 +212,7 @@ export default function Login({ {!serverConfirmed && ( <> - Choose your account's server + Choose your account's server setServer(e.target.value)} @@ -263,7 +264,7 @@ export default function Login({ target="_blank" rel="noopener noreferrer" > - Don't have an account? + Don't have an account? diff --git a/src/features/auth/authSlice.ts b/src/features/auth/authSlice.ts index 2b70d1dc80..61d1971e22 100644 --- a/src/features/auth/authSlice.ts +++ b/src/features/auth/authSlice.ts @@ -95,13 +95,13 @@ export const login = dispatch(updateToken(res.jwt)); }; -export const getSelf = +export const getSite = () => async (dispatch: AppDispatch, getState: () => RootState) => { const jwtPayload = jwtPayloadSelector(getState()); if (!jwtPayload) return; - const { iss, sub } = jwtPayload; + const { iss } = jwtPayload; const details = await new LemmyHttp(`/api/${iss}`).getSite({ auth: getState().auth.jwt, diff --git a/src/components/Comment.tsx b/src/features/comment/Comment.tsx similarity index 89% rename from src/components/Comment.tsx rename to src/features/comment/Comment.tsx index 901e837879..2f0f88d54e 100644 --- a/src/components/Comment.tsx +++ b/src/features/comment/Comment.tsx @@ -3,22 +3,22 @@ import { IonIcon, IonItem, useIonModal } from "@ionic/react"; import { chevronDownOutline } from "ionicons/icons"; import { CommentView } from "lemmy-js-client"; import { css } from "@emotion/react"; -import { useContext } from "react"; -import Ago from "./Ago"; -import { maxWidthCss } from "./AppContent"; -import PersonLabel from "./PersonLabel"; -import { ignoreSsrFlag } from "../helpers/emotion"; -import DraggingVote from "./DraggingVote"; -import { useAppDispatch, useAppSelector } from "../store"; -import Login from "../features/auth/Login"; -import { PageContext } from "../features/auth/PageContext"; -import { voteOnComment } from "../features/comment/commentSlice"; -import Vote from "./Vote"; +import React, { useContext } from "react"; +import Ago from "../labels/Ago"; +import { maxWidthCss } from "../shared/AppContent"; +import PersonLink from "../labels/links/PersonLink"; +import { ignoreSsrFlag } from "../../helpers/emotion"; +import DraggingVote from "../shared/DraggingVote"; +import { useAppDispatch, useAppSelector } from "../../store"; +import Login from "../auth/Login"; +import { PageContext } from "../auth/PageContext"; +import { voteOnComment } from "./commentSlice"; +import Vote from "../labels/Vote"; import AnimateHeight from "react-animate-height"; -import CommentReply from "../features/comment/CommentReply"; +import CommentReply from "./reply/CommentReply"; import CommentContent from "./CommentContent"; -import { PostContext } from "../features/post/detail/PostContext"; -import useKeyPressed from "../helpers/useKeyPressed"; +import { PostContext } from "../post/detail/PostContext"; +import useKeyPressed from "../../helpers/useKeyPressed"; const rainbowColors = [ "#FF0000", // Red @@ -105,7 +105,7 @@ const Header = styled.div` color: var(--ion-color-medium); `; -const StyledPersonLabel = styled(PersonLabel)` +const StyledPersonLabel = styled(PersonLink)` color: var(--ion-text-color); `; diff --git a/src/components/CommentContent.tsx b/src/features/comment/CommentContent.tsx similarity index 69% rename from src/components/CommentContent.tsx rename to src/features/comment/CommentContent.tsx index 656653b60c..b3478f03e4 100644 --- a/src/components/CommentContent.tsx +++ b/src/features/comment/CommentContent.tsx @@ -1,5 +1,5 @@ -import { Comment, CommentView, Post } from "lemmy-js-client"; -import Markdown from "./Markdown"; +import { Comment, Post } from "lemmy-js-client"; +import Markdown from "../shared/Markdown"; import { useMemo } from "react"; interface CommentContentProps { @@ -7,14 +7,14 @@ interface CommentContentProps { } export default function CommentContent({ item }: CommentContentProps) { - if (item.deleted) return deleted by creator; - if (item.removed) return removed by mod; - const content = useMemo(() => { + if (item.deleted) return deleted by creator; + if (item.removed) return removed by mod; + return ( ( + img: (props) => ( {props.alt || "Image"} diff --git a/src/components/CommentHr.tsx b/src/features/comment/CommentHr.tsx similarity index 93% rename from src/components/CommentHr.tsx rename to src/features/comment/CommentHr.tsx index cd868d1573..5f50f38182 100644 --- a/src/components/CommentHr.tsx +++ b/src/features/comment/CommentHr.tsx @@ -1,5 +1,5 @@ import styled from "@emotion/styled"; -import { maxWidthCss } from "./AppContent"; +import { maxWidthCss } from "../shared/AppContent"; import { css } from "@emotion/react"; const HrContainer = styled.div<{ depth: number }>` diff --git a/src/components/CommentTree.tsx b/src/features/comment/CommentTree.tsx similarity index 84% rename from src/components/CommentTree.tsx rename to src/features/comment/CommentTree.tsx index ac6a89e2a7..ef9ee2bc49 100644 --- a/src/components/CommentTree.tsx +++ b/src/features/comment/CommentTree.tsx @@ -1,10 +1,9 @@ -import styled from "@emotion/styled"; -import { CommentNodeI, getFlattenedChildren } from "../helpers/lemmy"; +import { CommentNodeI, getFlattenedChildren } from "../../helpers/lemmy"; import Comment from "./Comment"; -import React, { useMemo, useState } from "react"; +import React, { useMemo } from "react"; import CommentHr from "./CommentHr"; -import { useAppDispatch, useAppSelector } from "../store"; -import { updateCommentCollapseState } from "../features/comment/commentSlice"; +import { useAppDispatch, useAppSelector } from "../../store"; +import { updateCommentCollapseState } from "./commentSlice"; import { Person } from "lemmy-js-client"; interface CommentTreeProps { diff --git a/src/components/Comments.tsx b/src/features/comment/Comments.tsx similarity index 85% rename from src/components/Comments.tsx rename to src/features/comment/Comments.tsx index cb5316e7f0..ef150cc0e1 100644 --- a/src/components/Comments.tsx +++ b/src/features/comment/Comments.tsx @@ -1,9 +1,7 @@ -import { useContext, useEffect, useMemo, useRef, useState } from "react"; -import { LIMIT, getClient } from "../services/lemmy"; -import { CommentNodeI, buildCommentsTree } from "../helpers/lemmy"; +import React, { useContext, useEffect, useMemo, useRef, useState } from "react"; +import { buildCommentsTree } from "../../helpers/lemmy"; import CommentTree from "./CommentTree"; import { - IonLoading, IonRefresher, IonRefresherContent, IonSpinner, @@ -12,17 +10,16 @@ import { } from "@ionic/react"; import styled from "@emotion/styled"; import { css } from "@emotion/react"; -import { CommentView, ListingType, Person } from "lemmy-js-client"; +import { CommentView, Person } from "lemmy-js-client"; import { pullAllBy, uniqBy } from "lodash"; -import { useLocation } from "react-router"; import { Virtuoso, VirtuosoHandle } from "react-virtuoso"; -import { useAppDispatch, useAppSelector } from "../store"; -import { receivedComments } from "../features/comment/commentSlice"; +import { useAppDispatch, useAppSelector } from "../../store"; +import { receivedComments } from "./commentSlice"; import { RefresherCustomEvent } from "@ionic/core"; -import { getPost } from "../features/post/postSlice"; -import useClient from "../helpers/useClient"; -import { AppContext } from "../features/auth/AppContext"; -import { PostContext } from "../features/post/detail/PostContext"; +import { getPost } from "../post/postSlice"; +import useClient from "../../helpers/useClient"; +import { AppContext } from "../auth/AppContext"; +import { PostContext } from "../post/detail/PostContext"; const centerCss = css` position: relative; @@ -71,14 +68,15 @@ export default function Comments({ const [comments, setComments] = useState([]); const commentTree = useMemo( () => (comments.length ? buildCommentsTree(comments, !!commentPath) : []), - [comments] + [commentPath, comments] ); const client = useClient(); const [isListAtTop, setIsListAtTop] = useState(true); const [present] = useIonToast(); const highlightedCommentId = commentPath - ? +commentPath.split(".").pop()! + ? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + +commentPath.split(".").pop()! : undefined; const commentId = commentPath ? +commentPath.split(".")[1] : undefined; @@ -91,6 +89,7 @@ export default function Comments({ useEffect(() => { fetchComments(true); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [postId, commentId]); async function fetchComments(refresh = false) { @@ -180,13 +179,14 @@ export default function Comments({ } const allComments = (() => { - if (loading && !comments.length) return []; + if (loading && !comments.length) + return []; if (!comments.length) return [ - +
No Comments
- +
, ]; diff --git a/src/features/comment/commentSlice.ts b/src/features/comment/commentSlice.ts index 1451670f0d..95cda7daa7 100644 --- a/src/features/comment/commentSlice.ts +++ b/src/features/comment/commentSlice.ts @@ -62,11 +62,13 @@ export const voteOnComment = const jwt = getState().auth.jwt; + if (!jwt) throw new Error("Not authorized"); + try { await clientSelector(getState())?.likeComment({ comment_id: commentId, score: vote, - auth: jwt!, + auth: jwt, }); } catch (error) { dispatch(updateCommentVote({ commentId, vote: oldVote })); diff --git a/src/features/comment/CommentReply.tsx b/src/features/comment/reply/CommentReply.tsx similarity index 84% rename from src/features/comment/CommentReply.tsx rename to src/features/comment/reply/CommentReply.tsx index ce152f2668..59edb5b16c 100644 --- a/src/features/comment/CommentReply.tsx +++ b/src/features/comment/reply/CommentReply.tsx @@ -13,10 +13,10 @@ import { import { CommentView, PostView } from "lemmy-js-client"; import { useState } from "react"; import ItemReplyingTo from "./ItemReplyingTo"; -import useClient from "../../helpers/useClient"; -import { useAppSelector } from "../../store"; -import { Centered, Spinner } from "../auth/Login"; -import { handleSelector } from "../auth/authSlice"; +import useClient from "../../../helpers/useClient"; +import { useAppSelector } from "../../../store"; +import { Centered, Spinner } from "../../auth/Login"; +import { handleSelector } from "../../auth/authSlice"; const Container = styled.div` position: absolute; @@ -46,15 +46,17 @@ const TitleContainer = styled.div` line-height: 1; `; +type CommentReplyProps = { + onDismiss: (data?: string, role?: string) => void; +} & ({ comment: CommentView } | { post: PostView }); + export default function CommentReply({ onDismiss, - comment, - post, -}: { - onDismiss: (data?: string, role?: string) => void; - comment?: CommentView; - post?: PostView; -}) { + ...rest +}: CommentReplyProps) { + const item = "comment" in rest ? rest.comment : rest.post; + const comment = "comment" in rest ? rest.comment : undefined; + const [replyContent, setReplyContent] = useState(""); const client = useClient(); const jwt = useAppSelector((state) => state.auth.jwt); @@ -71,7 +73,7 @@ export default function CommentReply({ await client.createComment({ content: replyContent, parent_id: comment?.comment.id, - post_id: (comment?.post.id ?? post?.post.id)!, + post_id: item.post.id, auth: jwt, }); } catch (error) { @@ -135,7 +137,7 @@ export default function CommentReply({ onChange={(e) => setReplyContent(e.target.value)} autoFocus /> - +
diff --git a/src/features/comment/ItemReplyingTo.tsx b/src/features/comment/reply/ItemReplyingTo.tsx similarity index 86% rename from src/features/comment/ItemReplyingTo.tsx rename to src/features/comment/reply/ItemReplyingTo.tsx index d7d2352138..1b5e9f3fb2 100644 --- a/src/features/comment/ItemReplyingTo.tsx +++ b/src/features/comment/reply/ItemReplyingTo.tsx @@ -2,10 +2,10 @@ import styled from "@emotion/styled"; import { IonIcon } from "@ionic/react"; import { returnDownForwardSharp } from "ionicons/icons"; import { CommentView, PostView } from "lemmy-js-client"; -import { getHandle } from "../../helpers/lemmy"; -import Vote from "../../components/Vote"; -import Ago from "../../components/Ago"; -import CommentContent from "../../components/CommentContent"; +import { getHandle } from "../../../helpers/lemmy"; +import Vote from "../../labels/Vote"; +import Ago from "../../labels/Ago"; +import CommentContent from "../CommentContent"; const Container = styled.div` padding: 1rem; diff --git a/src/components/community/MoreActions.tsx b/src/features/community/MoreActions.tsx similarity index 96% rename from src/components/community/MoreActions.tsx rename to src/features/community/MoreActions.tsx index 705a4f807b..5804ca074b 100644 --- a/src/components/community/MoreActions.tsx +++ b/src/features/community/MoreActions.tsx @@ -9,8 +9,8 @@ import { ellipsisHorizontal, heart, heartDislike } from "ionicons/icons"; import { useContext, useState } from "react"; import { useAppDispatch, useAppSelector } from "../../store"; import { followCommunity } from "./communitySlice"; -import { PageContext } from "../../features/auth/PageContext"; -import Login from "../../features/auth/Login"; +import { PageContext } from "../auth/PageContext"; +import Login from "../auth/Login"; interface MoreActionsProps { community: string; diff --git a/src/components/community/communitySlice.ts b/src/features/community/communitySlice.ts similarity index 88% rename from src/components/community/communitySlice.ts rename to src/features/community/communitySlice.ts index 70e3d74d2d..092f686b0c 100644 --- a/src/components/community/communitySlice.ts +++ b/src/features/community/communitySlice.ts @@ -1,12 +1,7 @@ import { Dictionary, PayloadAction, createSlice } from "@reduxjs/toolkit"; import { AppDispatch, RootState } from "../../store"; -import { clientSelector } from "../../features/auth/authSlice"; -import { - CommentView, - CommunityResponse, - CommunityView, - PostView, -} from "lemmy-js-client"; +import { clientSelector } from "../auth/authSlice"; +import { CommunityResponse } from "lemmy-js-client"; import { getHandle } from "../../helpers/lemmy"; interface CommentState { @@ -41,7 +36,7 @@ export const getCommunity = const community = await clientSelector(getState())?.getCommunity({ name: handle, - auth: jwt!, + auth: jwt, }); if (community) dispatch(receivedCommunity(community)); }; @@ -56,11 +51,12 @@ export const followCommunity = .id; if (!id) return; + if (!jwt) throw new Error("Not authorized"); const community = await clientSelector(getState())?.followCommunity({ community_id: id, follow, - auth: jwt!, + auth: jwt, }); if (community) dispatch(receivedCommunity(community)); diff --git a/src/components/Ago.tsx b/src/features/labels/Ago.tsx similarity index 97% rename from src/components/Ago.tsx rename to src/features/labels/Ago.tsx index 2afd47c798..dc0067946b 100644 --- a/src/components/Ago.tsx +++ b/src/features/labels/Ago.tsx @@ -1,4 +1,3 @@ -import React from "react"; import { formatDistanceToNowStrict } from "date-fns"; interface AgoProps { diff --git a/src/features/labels/Handle.tsx b/src/features/labels/Handle.tsx new file mode 100644 index 0000000000..b80d744b72 --- /dev/null +++ b/src/features/labels/Handle.tsx @@ -0,0 +1,24 @@ +const Aside = styled.aside` + display: inline; + opacity: 0.7; +`; + +import { Person } from "lemmy-js-client"; +import { getItemActorName } from "../../helpers/lemmy"; +import styled from "@emotion/styled"; + +interface HandleProps { + showInstanceWhenRemote?: boolean; + item: Pick; +} + +export default function Handle({ showInstanceWhenRemote, item }: HandleProps) { + return showInstanceWhenRemote ? ( + <> + {item.name} + {!item.local && } + + ) : ( + item.name + ); +} diff --git a/src/components/Nsfw.tsx b/src/features/labels/Nsfw.tsx similarity index 91% rename from src/components/Nsfw.tsx rename to src/features/labels/Nsfw.tsx index 47b09a2cb9..b1a874bc04 100644 --- a/src/components/Nsfw.tsx +++ b/src/features/labels/Nsfw.tsx @@ -1,6 +1,6 @@ import styled from "@emotion/styled"; import { PostView } from "lemmy-js-client"; -import { getItemActorName } from "../helpers/lemmy"; +import { getItemActorName } from "../../helpers/lemmy"; const Container = styled.span` font-size: 0.8em; diff --git a/src/components/Vote.tsx b/src/features/labels/Vote.tsx similarity index 82% rename from src/components/Vote.tsx rename to src/features/labels/Vote.tsx index b2053fb3af..7cbaa76d22 100644 --- a/src/components/Vote.tsx +++ b/src/features/labels/Vote.tsx @@ -1,14 +1,13 @@ -import { CommentAggregates, PostAggregates } from "lemmy-js-client"; -import { useAppDispatch, useAppSelector } from "../store"; +import { useAppDispatch, useAppSelector } from "../../store"; import { IonIcon, useIonModal, useIonToast } from "@ionic/react"; import { arrowDownSharp, arrowUpSharp } from "ionicons/icons"; import styled from "@emotion/styled"; -import { voteOnPost } from "../features/post/postSlice"; -import Login from "../features/auth/Login"; +import { voteOnPost } from "../post/postSlice"; +import Login from "../auth/Login"; import { useContext } from "react"; -import { PageContext } from "../features/auth/PageContext"; -import { voteOnComment } from "../features/comment/commentSlice"; -import { voteError } from "../helpers/toastMessages"; +import { PageContext } from "../auth/PageContext"; +import { voteOnComment } from "../comment/commentSlice"; +import { voteError } from "../../helpers/toastMessages"; const Container = styled.div<{ vote: 1 | -1 | 0 | undefined }>` display: flex; diff --git a/src/features/labels/img/CommunityIcon.tsx b/src/features/labels/img/CommunityIcon.tsx new file mode 100644 index 0000000000..4fd871478f --- /dev/null +++ b/src/features/labels/img/CommunityIcon.tsx @@ -0,0 +1,67 @@ +import styled from "@emotion/styled"; +import { Community } from "lemmy-js-client"; + +const SubImgIcon = styled.img<{ size: number }>` + width: ${({ size }) => `${size}px`}; + height: ${({ size }) => `${size}px`}; + border-radius: 50%; +`; + +const FakeIcon = styled.div<{ bg: string; size: number }>` + width: ${({ size }) => `${size}px`}; + height: ${({ size }) => `${size}px`}; + border-radius: 50%; + + display: flex; + align-items: center; + justify-content: center; + + background-color: ${({ bg }) => bg}; + color: white; +`; + +interface CommunityIconProps { + community: Community; + size?: number; +} + +export default function CommunityIcon({ community, size }: CommunityIconProps) { + size = size ?? 28; + + if (community.icon) return ; + + return ( + + {community.name.slice(0, 1).toUpperCase()} + + ); +} + +function generateRandomColor(seed: string | number): string { + // Convert seed to a numeric value + let num: number; + if (typeof seed === "number") { + num = seed; + } else { + num = 0; + for (let i = 0; i < seed.length; i++) { + num += seed.charCodeAt(i); + } + } + + // Generate random RGB values + const random = (num: number) => { + const x = Math.sin(num) * 10000; + return Math.floor((x - Math.floor(x)) * 256); + }; + + const red = random(num); + const green = random(num + 1); + const blue = random(num + 2); + + // Format RGB values into hexadecimal color + const rgb = (red << 16) | (green << 8) | blue; + const hexColor = `#${(rgb | 0x1000000).toString(16).substring(1)}`; + + return hexColor; +} diff --git a/src/features/labels/links/CommunityLink.tsx b/src/features/labels/links/CommunityLink.tsx new file mode 100644 index 0000000000..ce0a16818e --- /dev/null +++ b/src/features/labels/links/CommunityLink.tsx @@ -0,0 +1,33 @@ +import { getHandle } from "../../../helpers/lemmy"; +import { useBuildGeneralBrowseLink } from "../../../helpers/routes"; +import { Community } from "lemmy-js-client"; +import Handle from "../Handle"; +import { StyledLink } from "./shared"; + +interface CommunityLinkProps { + community: Community; + showInstanceWhenRemote?: boolean; + + className?: string; +} + +export default function CommunityLink({ + community, + className, + showInstanceWhenRemote, +}: CommunityLinkProps) { + const buildGeneralBrowseLink = useBuildGeneralBrowseLink(); + + return ( + e.stopPropagation()} + className={className} + > + + + ); +} diff --git a/src/features/labels/links/PersonLink.tsx b/src/features/labels/links/PersonLink.tsx new file mode 100644 index 0000000000..e13762e598 --- /dev/null +++ b/src/features/labels/links/PersonLink.tsx @@ -0,0 +1,62 @@ +import { css } from "@emotion/react"; +import { getHandle } from "../../../helpers/lemmy"; +import styled from "@emotion/styled"; +import { useBuildGeneralBrowseLink } from "../../../helpers/routes"; +import { Person } from "lemmy-js-client"; +import Handle from "../Handle"; +import { StyledLink } from "./shared"; + +const Prefix = styled.span` + font-weight: normal; +`; + +interface PersonLinkProps { + person: Person; + opId?: number; + distinguished?: boolean; + showInstanceWhenRemote?: boolean; + prefix?: string; + + className?: string; +} + +export default function PersonLink({ + person, + opId, + distinguished, + className, + showInstanceWhenRemote, + prefix, +}: PersonLinkProps) { + const buildGeneralBrowseLink = useBuildGeneralBrowseLink(); + + let color: string | undefined; + + if (person.admin) color = "var(--ion-color-danger)"; + else if (distinguished) color = "var(--ion-color-success)"; + else if (opId && person.id === opId) color = "var(--ion-color-primary)"; + + return ( + e.stopPropagation()} + className={className} + css={ + color + ? css` + && { + color: ${color}; + } + ` + : undefined + } + > + {prefix ? ( + <> + {prefix}{" "} + + ) : undefined} + + + ); +} diff --git a/src/features/labels/links/shared.ts b/src/features/labels/links/shared.ts new file mode 100644 index 0000000000..ac0f73661d --- /dev/null +++ b/src/features/labels/links/shared.ts @@ -0,0 +1,8 @@ +import styled from "@emotion/styled"; +import { Link } from "react-router-dom"; + +export const StyledLink = styled(Link)` + text-decoration: none; + color: inherit; + font-weight: 500; +`; diff --git a/src/components/post/actions/ActionButton.tsx b/src/features/post/actions/ActionButton.tsx similarity index 100% rename from src/components/post/actions/ActionButton.tsx rename to src/features/post/actions/ActionButton.tsx diff --git a/src/components/PostActions.tsx b/src/features/post/actions/PostActions.tsx similarity index 92% rename from src/components/PostActions.tsx rename to src/features/post/actions/PostActions.tsx index 38eb808494..962c667da6 100644 --- a/src/components/PostActions.tsx +++ b/src/features/post/actions/PostActions.tsx @@ -7,8 +7,8 @@ import { shareOutline, } from "ionicons/icons"; import { PostView } from "lemmy-js-client"; -import { VoteButton } from "./VoteButton"; -import { ActionButton } from "./post/actions/ActionButton"; +import { VoteButton } from "../shared/VoteButton"; +import { ActionButton } from "./ActionButton"; const Container = styled.div` display: flex; diff --git a/src/components/Img.tsx b/src/features/post/detail/Img.tsx similarity index 92% rename from src/components/Img.tsx rename to src/features/post/detail/Img.tsx index 02d5888857..01770c6d86 100644 --- a/src/components/Img.tsx +++ b/src/features/post/detail/Img.tsx @@ -1,11 +1,10 @@ -import styled from "@emotion/styled"; -import { useState } from "react"; +import React, { useState } from "react"; import { Gallery, Item } from "react-photoswipe-gallery"; import "photoswipe/dist/photoswipe.css"; interface ImgProps { - src: string; + src?: string; alt?: string; className?: string; onClick?: React.MouseEventHandler; diff --git a/src/components/PostDetail.tsx b/src/features/post/detail/PostDetail.tsx similarity index 73% rename from src/components/PostDetail.tsx rename to src/features/post/detail/PostDetail.tsx index 77c1f9b7af..7d257fca6d 100644 --- a/src/components/PostDetail.tsx +++ b/src/features/post/detail/PostDetail.tsx @@ -1,43 +1,41 @@ import { - IonBackButton, IonButtons, IonContent, IonHeader, + IonIcon, IonItem, IonPage, - IonRefresher, - IonRefresherContent, - IonRouterLink, IonSpinner, IonTitle, IonToolbar, useIonModal, } from "@ionic/react"; -import { useAppDispatch, useAppSelector } from "../store"; -import { useLocation, useParams } from "react-router"; +import { useAppDispatch, useAppSelector } from "../../../store"; +import { useParams } from "react-router"; import Stats from "./Stats"; import styled from "@emotion/styled"; -import Embed from "./Embed"; -import Comments from "./Comments"; -import Markdown from "./Markdown"; -import PostActions from "./PostActions"; -import { useContext, useEffect, useMemo, useRef, useState } from "react"; -import { findLoneImage } from "../helpers/markdown"; -import { getPost, receivedPosts } from "../features/post/postSlice"; -import { getHandle, getItemActorName, isUrlImage } from "../helpers/lemmy"; -import AppBackButton from "./AppBackButton"; +import Embed from "../shared/Embed"; +import Comments from "../../comment/Comments"; +import Markdown from "../../shared/Markdown"; +import PostActions from "../actions/PostActions"; +import { useEffect, useMemo, useRef, useState } from "react"; +import { findLoneImage } from "../../../helpers/markdown"; +import { getPost } from "../postSlice"; +import { isUrlImage } from "../../../helpers/lemmy"; +import AppBackButton from "../../shared/AppBackButton"; import Img from "./Img"; -import { Link } from "react-router-dom"; -import { PageContext } from "../features/auth/PageContext"; -import { maxWidthCss } from "./AppContent"; -import { getClient } from "../services/lemmy"; -import PersonLabel from "./PersonLabel"; +import { PageContext } from "../../auth/PageContext"; +import { maxWidthCss } from "../../shared/AppContent"; +import PersonLink from "../../labels/links/PersonLink"; import { PostView } from "lemmy-js-client"; -import { useBuildGeneralBrowseLink } from "../helpers/routes"; +import { useBuildGeneralBrowseLink } from "../../../helpers/routes"; import ViewAllComments from "./ViewAllComments"; -import CommentReply from "../features/comment/CommentReply"; -import Login from "../features/auth/Login"; -import InlineMarkdown from "./InlineMarkdown"; +import CommentReply from "../../comment/reply/CommentReply"; +import Login from "../../auth/Login"; +import InlineMarkdown from "../../shared/InlineMarkdown"; +import { megaphone } from "ionicons/icons"; +import CommunityIcon from "../../labels/img/CommunityIcon"; +import CommunityLink from "../../labels/links/CommunityLink"; const BorderlessIonItem = styled(IonItem)` --padding-start: 0; @@ -65,7 +63,7 @@ const LightboxImg = styled(Img)` background: var(--lightroom-bg); `; -const StyledMarkdown = styled(Markdown as any)` +const StyledMarkdown = styled(Markdown)` img { display: block; max-width: 100%; @@ -100,20 +98,17 @@ const Title = styled.div` `; const By = styled.div` + display: flex; + align-items: center; + gap: 0.5rem; + color: var(--ion-color-medium); margin: 0 0 0.5rem; - - strong, - a { - font-weight: 500; - color: inherit; - text-decoration: none; - } `; -const Aside = styled.div` - display: inline; - opacity: 0.7; +export const AnnouncementIcon = styled(IonIcon)` + font-size: 1.1rem; + color: var(--ion-color-success); `; export default function PostDetail() { @@ -147,16 +142,16 @@ export default function PostDetail() { onDismiss: (data: string, role: string) => onDismissLogin(data, role), }); - const pageContext = useContext(PageContext); - useEffect(() => { if (post) return; dispatch(getPost(+id)); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [post]); useEffect(() => { dispatch(getPost(+id)); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [jwt]); useEffect(() => { @@ -215,17 +210,20 @@ export default function PostDetail() { {!collapsed && renderText()} - in{" "} - e.stopPropagation()} - > - {post.community.name} - {!post.community.local && ( - - )} - {" "} - by + {post.counts.featured_community || + post.counts.featured_local ? ( + + ) : undefined} + + + +
+ {" "} + +
span { + max-width: 14rem; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } aside { display: inline; @@ -274,10 +267,14 @@ export default function Post({ post, communityMode, className }: PostProps) { {communityMode ? ( - by{" "} - + ) : undefined} + @@ -289,15 +286,12 @@ export default function Post({ post, communityMode, className }: PostProps) { onClick={(e) => e.stopPropagation()} > - {post.community.icon && ( - - )} - - {post.community.name} - {!post.community.local && ( - - )} - + + + )} diff --git a/src/components/PostSort.tsx b/src/features/post/inFeed/PostSort.tsx similarity index 94% rename from src/components/PostSort.tsx rename to src/features/post/inFeed/PostSort.tsx index a80c64cca8..78815fc4c8 100644 --- a/src/components/PostSort.tsx +++ b/src/features/post/inFeed/PostSort.tsx @@ -14,8 +14,8 @@ import { helpCircleOutline, timeOutline, } from "ionicons/icons"; -import { useAppDispatch, useAppSelector } from "../store"; -import { updateSortType } from "../features/post/postSlice"; +import { useAppDispatch, useAppSelector } from "../../../store"; +import { updateSortType } from "../postSlice"; import { useState } from "react"; import { startCase } from "lodash"; import { SortType } from "lemmy-js-client"; diff --git a/src/components/Posts.tsx b/src/features/post/inFeed/Posts.tsx similarity index 87% rename from src/components/Posts.tsx rename to src/features/post/inFeed/Posts.tsx index 35c500df57..1d15df365f 100644 --- a/src/components/Posts.tsx +++ b/src/features/post/inFeed/Posts.tsx @@ -1,30 +1,24 @@ import { useContext, useEffect, useMemo, useRef, useState } from "react"; - -interface ContainerProps { - name: string; -} - -import { LemmyHttp, ListingType, PostView } from "lemmy-js-client"; +import { ListingType, PostView } from "lemmy-js-client"; import Post from "./Post"; import { Virtuoso, VirtuosoHandle } from "react-virtuoso"; -import { useAppDispatch, useAppSelector } from "../store"; -import { receivedPosts } from "../features/post/postSlice"; +import { useAppDispatch, useAppSelector } from "../../../store"; +import { receivedPosts } from "../postSlice"; import { IonRefresher, IonRefresherContent, RefresherCustomEvent, useIonToast, useIonViewDidEnter, - useIonViewWillEnter, } from "@ionic/react"; -import { LIMIT, getClient } from "../services/lemmy"; -import { CenteredSpinner } from "./PostDetail"; +import { LIMIT } from "../../../services/lemmy"; +import { CenteredSpinner } from "../detail/PostDetail"; import EndPost from "./EndPost"; import { pullAllBy } from "lodash"; -import { notEmpty } from "../helpers/array"; +import { notEmpty } from "../../../helpers/array"; import { useParams } from "react-router"; -import useClient from "../helpers/useClient"; -import { AppContext } from "../features/auth/AppContext"; +import useClient from "../../../helpers/useClient"; +import { AppContext } from "../../auth/AppContext"; interface PostsProps { communityName?: string; @@ -59,11 +53,12 @@ export default function Posts({ communityName, type }: PostsProps) { [...posts, atEnd ? ({ type: "AT_END " } as EndItem) : undefined].filter( notEmpty ), - [posts, notEmpty] + [posts, atEnd] ); useEffect(() => { fetchMore(true); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [communityName, actor, sort, jwt]); async function fetchMore(refresh = false) { diff --git a/src/components/PreviewStats.tsx b/src/features/post/inFeed/PreviewStats.tsx similarity index 78% rename from src/components/PreviewStats.tsx rename to src/features/post/inFeed/PreviewStats.tsx index 66695594d8..ad53a527f9 100644 --- a/src/components/PreviewStats.tsx +++ b/src/features/post/inFeed/PreviewStats.tsx @@ -1,11 +1,9 @@ import styled from "@emotion/styled"; import { IonIcon } from "@ionic/react"; -import { arrowUpSharp, chatbubbleOutline, timeOutline } from "ionicons/icons"; +import { chatbubbleOutline, timeOutline } from "ionicons/icons"; import { PostAggregates } from "lemmy-js-client"; -import Ago from "./Ago"; -import { useAppSelector } from "../store"; -import { css } from "@emotion/react"; -import Vote from "./Vote"; +import Ago from "../../labels/Ago"; +import Vote from "../../labels/Vote"; const Container = styled.div` display: flex; diff --git a/src/features/post/postSlice.ts b/src/features/post/postSlice.ts index 0d6b28b971..7a090ffa5b 100644 --- a/src/features/post/postSlice.ts +++ b/src/features/post/postSlice.ts @@ -2,8 +2,7 @@ import { Dictionary, PayloadAction, createSlice } from "@reduxjs/toolkit"; import { PostView, SortType } from "lemmy-js-client"; import { AppDispatch, RootState } from "../../store"; import { clientSelector } from "../auth/authSlice"; -import { POST_SORTS } from "../../components/PostSort"; -import { getClient } from "../../services/lemmy"; +import { POST_SORTS } from "./inFeed/PostSort"; const POST_SORT_KEY = "post-sort"; @@ -61,11 +60,13 @@ export const voteOnPost = const jwt = getState().auth.jwt; + if (!jwt) throw new Error("Not authorized"); + try { await clientSelector(getState())?.likePost({ post_id: postId, score: vote, - auth: jwt!, + auth: jwt, }); } catch (error) { dispatch(updatePostVote({ postId, vote: oldVote })); diff --git a/src/components/Embed.tsx b/src/features/post/shared/Embed.tsx similarity index 100% rename from src/components/Embed.tsx rename to src/features/post/shared/Embed.tsx diff --git a/src/features/post/item/MoreActions.tsx b/src/features/post/shared/MoreActions.tsx similarity index 78% rename from src/features/post/item/MoreActions.tsx rename to src/features/post/shared/MoreActions.tsx index 0539e13a7c..30fefce669 100644 --- a/src/features/post/item/MoreActions.tsx +++ b/src/features/post/shared/MoreActions.tsx @@ -1,10 +1,8 @@ import { IonActionSheet, - IonButton, IonIcon, useIonModal, useIonRouter, - useIonToast, } from "@ionic/react"; import { arrowDown, @@ -12,8 +10,6 @@ import { arrowUp, bookmarkOutline, ellipsisHorizontal, - heart, - heartDislike, peopleOutline, personOutline, shareOutline, @@ -26,7 +22,7 @@ import { PostView } from "lemmy-js-client"; import { voteOnPost } from "../postSlice"; import { getHandle } from "../../../helpers/lemmy"; import { useBuildGeneralBrowseLink } from "../../../helpers/routes"; -import CommentReply from "../../comment/CommentReply"; +import CommentReply from "../../comment/reply/CommentReply"; interface MoreActionsProps { post: PostView; @@ -34,7 +30,6 @@ interface MoreActionsProps { export default function MoreActions({ post }: MoreActionsProps) { const buildGeneralBrowseLink = useBuildGeneralBrowseLink(); - const [present] = useIonToast(); const dispatch = useAppDispatch(); const [open, setOpen] = useState(false); const jwt = useAppSelector((state) => state.auth.jwt); @@ -134,6 +129,7 @@ export default function MoreActions({ post }: MoreActionsProps) { router.push( buildGeneralBrowseLink(`/u/${getHandle(post.creator)}`) ); + break; } case "community": { @@ -145,37 +141,10 @@ export default function MoreActions({ post }: MoreActionsProps) { } case "share": { navigator.share({ url: post.post.url ?? post.post.ap_id }); - // TODO + break; } } - - // if (e.detail.role === "subscribe") { - // if (!jwt) return login({ presentingElement: pageContext.page }); - - // try { - // // await dispatch(followCommunity(!isSubscribed, community)); - // } catch (error) { - // present({ - // message: `Problem ${ - // isSubscribed ? "unsubscribing from" : "subscribing to" - // } c/${community}. Please try again.`, - // duration: 3500, - // position: "bottom", - // color: "danger", - // }); - // throw error; - // } - - // present({ - // message: `${ - // isSubscribed ? "Unsubscribed from" : "Subscribed to" - // } c/${community}.`, - // duration: 3500, - // position: "bottom", - // color: "success", - // }); - // } }} /> diff --git a/src/components/VoteButton.tsx b/src/features/post/shared/VoteButton.tsx similarity index 86% rename from src/components/VoteButton.tsx rename to src/features/post/shared/VoteButton.tsx index 433244f112..14016b85b9 100644 --- a/src/components/VoteButton.tsx +++ b/src/features/post/shared/VoteButton.tsx @@ -1,14 +1,14 @@ import styled from "@emotion/styled"; import { IonIcon, useIonModal, useIonToast } from "@ionic/react"; -import Login from "../features/auth/Login"; +import Login from "../../auth/Login"; import { useContext } from "react"; -import { PageContext } from "../features/auth/PageContext"; -import { useAppDispatch, useAppSelector } from "../store"; -import { voteOnPost } from "../features/post/postSlice"; +import { PageContext } from "../../auth/PageContext"; +import { useAppDispatch, useAppSelector } from "../../../store"; +import { voteOnPost } from "../postSlice"; import { css } from "@emotion/react"; import { arrowDownSharp, arrowUpSharp } from "ionicons/icons"; -import { ActionButton } from "./post/actions/ActionButton"; -import { voteError } from "../helpers/toastMessages"; +import { ActionButton } from "../actions/ActionButton"; +import { voteError } from "../../../helpers/toastMessages"; export const Item = styled(ActionButton, { shouldForwardProp: (prop) => prop !== "on" && prop !== "activeColor", diff --git a/src/components/AppBackButton.tsx b/src/features/shared/AppBackButton.tsx similarity index 92% rename from src/components/AppBackButton.tsx rename to src/features/shared/AppBackButton.tsx index cb5a351fcd..dba7b71714 100644 --- a/src/components/AppBackButton.tsx +++ b/src/features/shared/AppBackButton.tsx @@ -1,5 +1,5 @@ import { IonBackButton } from "@ionic/react"; -import { useState } from "react"; +// import { useState } from "react"; interface AppBackButtonProps { defaultText?: string; @@ -7,7 +7,7 @@ interface AppBackButtonProps { } export default function AppBackButton({ - defaultText, + // defaultText, defaultHref, }: AppBackButtonProps) { // Totally a hack, but I haven't found a better solution diff --git a/src/components/AppContent.tsx b/src/features/shared/AppContent.tsx similarity index 95% rename from src/components/AppContent.tsx rename to src/features/shared/AppContent.tsx index a921776e7a..276fc60d07 100644 --- a/src/components/AppContent.tsx +++ b/src/features/shared/AppContent.tsx @@ -1,6 +1,7 @@ import { css } from "@emotion/react"; import styled from "@emotion/styled"; import { IonContent } from "@ionic/react"; +import React from "react"; export const maxWidthCss = css` width: 100%; diff --git a/src/components/DraggingVote.tsx b/src/features/shared/DraggingVote.tsx similarity index 96% rename from src/components/DraggingVote.tsx rename to src/features/shared/DraggingVote.tsx index 107a563dbf..d433dc34b3 100644 --- a/src/components/DraggingVote.tsx +++ b/src/features/shared/DraggingVote.tsx @@ -8,7 +8,7 @@ import { IonItemSliding, } from "@ionic/react"; import { arrowDownSharp, arrowUndo, arrowUpSharp } from "ionicons/icons"; -import { useEffect, useRef, useState } from "react"; +import React, { useEffect, useRef, useState } from "react"; const Action = styled(IonIcon)<{ active: boolean }>` display: flex; @@ -77,6 +77,7 @@ export default function DraggingVote({ useEffect(() => { setStaleCurrentVote(currentVote); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [ratio]); async function onVoteDragStop() { diff --git a/src/components/InlineMarkdown.tsx b/src/features/shared/InlineMarkdown.tsx similarity index 100% rename from src/components/InlineMarkdown.tsx rename to src/features/shared/InlineMarkdown.tsx diff --git a/src/components/Markdown.tsx b/src/features/shared/Markdown.tsx similarity index 84% rename from src/components/Markdown.tsx rename to src/features/shared/Markdown.tsx index f0f068ef75..61c2d2def4 100644 --- a/src/components/Markdown.tsx +++ b/src/features/shared/Markdown.tsx @@ -2,7 +2,7 @@ import { ReactMarkdown, ReactMarkdownOptions, } from "react-markdown/lib/react-markdown"; -import Img from "./Img"; +import Img from "../post/detail/Img"; import styled from "@emotion/styled"; import remarkGfm from "remark-gfm"; @@ -22,9 +22,7 @@ export default function Markdown(props: ReactMarkdownOptions) { linkTarget="_blank" {...props} components={{ - img: (props: any) => ( - e.stopPropagation()} /> - ), + img: (props) => e.stopPropagation()} />, blockquote: (props) =>
, code: (props) => , ...props.components, diff --git a/src/features/profile/PostContext.tsx b/src/features/user/PostContext.tsx similarity index 84% rename from src/features/profile/PostContext.tsx rename to src/features/user/PostContext.tsx index 1581e9cdd0..27478e5d7c 100644 --- a/src/features/profile/PostContext.tsx +++ b/src/features/user/PostContext.tsx @@ -1,8 +1,7 @@ import styled from "@emotion/styled"; -import { CommunitySafe, Post } from "lemmy-js-client"; +import { Community, Post } from "lemmy-js-client"; import { getHandle } from "../../helpers/lemmy"; import { Link } from "react-router-dom"; -import { useAppSelector } from "../../store"; import { useBuildGeneralBrowseLink } from "../../helpers/routes"; const ContainerLink = styled(Link)` @@ -34,13 +33,10 @@ const CommunityName = styled.div` interface PostContextProps { post: Post; - community: CommunitySafe; + community: Community; } export default function PostContext({ post, community }: PostContextProps) { - const connectedInstance = useAppSelector( - (state) => state.auth.connectedInstance - ); const buildGeneralBrowseLink = useBuildGeneralBrowseLink(); return ( diff --git a/src/features/profile/Profile.tsx b/src/features/user/Profile.tsx similarity index 80% rename from src/features/profile/Profile.tsx rename to src/features/user/Profile.tsx index aaa1cbb762..fa3fc8eb73 100644 --- a/src/features/profile/Profile.tsx +++ b/src/features/user/Profile.tsx @@ -1,31 +1,19 @@ -import { - IonIcon, - IonLabel, - IonList, - IonRouterLink, - IonSpinner, - IonItem, -} from "@ionic/react"; -import { useAppSelector } from "../../store"; +import React from "react"; +import { IonIcon, IonLabel, IonList, IonItem } from "@ionic/react"; import styled from "@emotion/styled"; import Scores from "./Scores"; import { albumsOutline, - bookmark, bookmarkOutline, - chatbubble, chatbubbleOutline, - chevronForward, } from "ionicons/icons"; -import { GetPersonDetailsResponse, PersonViewSafe } from "lemmy-js-client"; -import Comment from "../../components/Comment"; -import CommentHr from "../../components/CommentHr"; +import { GetPersonDetailsResponse } from "lemmy-js-client"; +import Comment from "../comment/Comment"; +import CommentHr from "../comment/CommentHr"; import PostContext from "./PostContext"; -import React from "react"; -import { Link } from "react-router-dom"; import { useBuildGeneralBrowseLink } from "../../helpers/routes"; import { getHandle } from "../../helpers/lemmy"; -import { MaxWidthContainer } from "../../components/AppContent"; +import { MaxWidthContainer } from "../shared/AppContent"; export const InsetIonItem = styled(IonItem)` --background: var(--ion-tab-bar-background, var(--ion-color-step-50, #fff)); @@ -35,10 +23,6 @@ export const SettingLabel = styled(IonLabel)` margin-left: 1rem; `; -const StyledLink = styled(Link)` - text-decoration: none; -`; - interface ProfileProps { person: GetPersonDetailsResponse; } diff --git a/src/features/profile/Scores.tsx b/src/features/user/Scores.tsx similarity index 96% rename from src/features/profile/Scores.tsx rename to src/features/user/Scores.tsx index 00ae41f687..0bb9c4fcca 100644 --- a/src/features/profile/Scores.tsx +++ b/src/features/user/Scores.tsx @@ -1,7 +1,7 @@ import styled from "@emotion/styled"; import { PersonAggregates } from "lemmy-js-client"; import { formatNumber } from "../../helpers/number"; -import Ago from "../../components/Ago"; +import Ago from "../labels/Ago"; const Container = styled.div` display: flex; diff --git a/src/features/profile/incognito.svg b/src/features/user/incognito.svg similarity index 100% rename from src/features/profile/incognito.svg rename to src/features/user/incognito.svg diff --git a/src/features/user/userSlice.tsx b/src/features/user/userSlice.tsx index 58e0755bc7..a7d616e954 100644 --- a/src/features/user/userSlice.tsx +++ b/src/features/user/userSlice.tsx @@ -40,7 +40,7 @@ export const getUser = const personResponse = await clientSelector(getState())?.getPersonDetails({ username: handle, - auth: jwt!, + auth: jwt, limit: LIMIT, sort: "New", }); diff --git a/src/main.css b/src/index.css similarity index 94% rename from src/main.css rename to src/index.css index 215b16c641..53b5cce38e 100644 --- a/src/main.css +++ b/src/index.css @@ -22,7 +22,7 @@ ion-tab-button { .ios .grey-bg { --ion-background-color: var(--ion-color-step-50, #f2f2f7); } - .ios body:has(.grey-bg) { + .ios body:has(.grey-bg:not([aria-hidden="true"])) { --ion-background-color: var(--ion-color-step-50, #f2f2f7); } .ios .grey-bg ion-header { diff --git a/src/main.tsx b/src/index.tsx similarity index 75% rename from src/main.tsx rename to src/index.tsx index 9f4d15e3ad..a2f489d9f5 100644 --- a/src/main.tsx +++ b/src/index.tsx @@ -1,10 +1,10 @@ import React from "react"; import { createRoot } from "react-dom/client"; import App from "./App"; -import "./main.css"; +import "./index.css"; const container = document.getElementById("root"); -const root = createRoot(container!); +const root = createRoot(container as HTMLElement); root.render( diff --git a/src/pages/Communities.tsx b/src/pages/CommunitiesPage.tsx similarity index 72% rename from src/pages/Communities.tsx rename to src/pages/CommunitiesPage.tsx index db4e0a43b4..f320493488 100644 --- a/src/pages/Communities.tsx +++ b/src/pages/CommunitiesPage.tsx @@ -11,17 +11,18 @@ import { IonToolbar, useIonViewWillEnter, } from "@ionic/react"; -import AppContent from "../components/AppContent"; +import AppContent from "../features/shared/AppContent"; import { useParams } from "react-router"; import { useAppSelector } from "../store"; import { getHandle } from "../helpers/lemmy"; import { home, library, people } from "ionicons/icons"; import styled from "@emotion/styled"; -import { pull, pullAll, pullAllBy, sortBy, uniqBy } from "lodash"; +import { pullAllBy, sortBy, uniqBy } from "lodash"; import { notEmpty } from "../helpers/array"; import { useContext, useMemo, useRef } from "react"; import { AppContext } from "../features/auth/AppContext"; import { useBuildGeneralBrowseLink } from "../helpers/routes"; +import CommunityIcon from "../features/labels/img/CommunityIcon"; const SubIcon = styled(IonIcon)<{ color: string }>` border-radius: 50%; @@ -33,25 +34,6 @@ const SubIcon = styled(IonIcon)<{ color: string }>` --ion-color-base: white; `; -const SubImgIcon = styled.img` - width: 28px; - height: 28px; - border-radius: 50%; -`; - -const FakeIcon = styled.div<{ bg: string }>` - width: 28px; - height: 28px; - border-radius: 50%; - - display: flex; - align-items: center; - justify-content: center; - - background-color: ${({ bg }) => bg}; - color: white; -`; - const Content = styled.div` margin: 0.7rem 0; @@ -66,7 +48,7 @@ const Content = styled.div` } `; -export default function Communities() { +export default function CommunitiesPage() { const buildGeneralBrowseLink = useBuildGeneralBrowseLink(); const { setActivePage } = useContext(AppContext); const { actor } = useParams<{ actor: string }>(); @@ -158,13 +140,7 @@ export default function Communities() { routerLink={buildGeneralBrowseLink(`/c/${getHandle(community)}`)} > - {community.icon ? ( - - ) : ( - - {community.name.slice(0, 1).toUpperCase()} - - )} + {getHandle(community)} @@ -174,31 +150,3 @@ export default function Communities() { ); } -function generateRandomColor(seed: string | number): string { - // Convert seed to a numeric value - let num: number; - if (typeof seed === "number") { - num = seed; - } else { - num = 0; - for (let i = 0; i < seed.length; i++) { - num += seed.charCodeAt(i); - } - } - - // Generate random RGB values - const random = (num: number) => { - const x = Math.sin(num) * 10000; - return Math.floor((x - Math.floor(x)) * 256); - }; - - const red = random(num); - const green = random(num + 1); - const blue = random(num + 2); - - // Format RGB values into hexadecimal color - const rgb = (red << 16) | (green << 8) | blue; - const hexColor = `#${(rgb | 0x1000000).toString(16).substring(1)}`; - - return hexColor; -} diff --git a/src/pages/Community.tsx b/src/pages/CommunityPage.tsx similarity index 76% rename from src/pages/Community.tsx rename to src/pages/CommunityPage.tsx index 11801dcf6b..d5623941cd 100644 --- a/src/pages/Community.tsx +++ b/src/pages/CommunityPage.tsx @@ -1,24 +1,22 @@ import { - IonButton, IonButtons, IonContent, IonHeader, - IonIcon, IonPage, IonTitle, IonToolbar, } from "@ionic/react"; -import Posts from "../components/Posts"; +import Posts from "../features/post/inFeed/Posts"; import { useParams } from "react-router"; -import AppBackButton from "../components/AppBackButton"; -import PostSort from "../components/PostSort"; -import MoreActions from "../components/community/MoreActions"; +import AppBackButton from "../features/shared/AppBackButton"; +import PostSort from "../features/post/inFeed/PostSort"; +import MoreActions from "../features/community/MoreActions"; import { useAppDispatch, useAppSelector } from "../store"; import { useEffect } from "react"; -import { getCommunity } from "../components/community/communitySlice"; +import { getCommunity } from "../features/community/communitySlice"; import { useBuildGeneralBrowseLink } from "../helpers/routes"; -export default function Community() { +export default function CommunityPage() { const buildGeneralBrowseLink = useBuildGeneralBrowseLink(); const dispatch = useAppDispatch(); const { community } = useParams<{ @@ -33,6 +31,7 @@ export default function Community() { if (communityByHandle[community]) return; dispatch(getCommunity(community)); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [community]); return ( diff --git a/src/pages/ProfilePage.tsx b/src/pages/ProfilePage.tsx index 1aa3e40450..9c2962fbff 100644 --- a/src/pages/ProfilePage.tsx +++ b/src/pages/ProfilePage.tsx @@ -3,8 +3,6 @@ import { IonButtons, IonHeader, IonIcon, - IonItem, - IonLabel, IonList, IonPage, IonPicker, @@ -14,7 +12,7 @@ import { useIonModal, useIonViewWillEnter, } from "@ionic/react"; -import AppContent from "../components/AppContent"; +import AppContent from "../features/shared/AppContent"; import { handleSelector, logout, @@ -23,19 +21,12 @@ import { import { useAppDispatch, useAppSelector } from "../store"; import Login from "../features/auth/Login"; import { useContext, useRef, useState } from "react"; -import Profile, { - InsetIonItem, - SettingLabel, -} from "../features/profile/Profile"; -import { ReactComponent as IncognitoSvg } from "../features/profile/incognito.svg"; +import { InsetIonItem, SettingLabel } from "../features/user/Profile"; +import { ReactComponent as IncognitoSvg } from "../features/user/incognito.svg"; import styled from "@emotion/styled"; import UserPage from "./UserPage"; import { AppContext } from "../features/auth/AppContext"; -import { - serverOutline, - swapHorizontalOutline, - wifiOutline, -} from "ionicons/icons"; +import { swapHorizontalOutline } from "ionicons/icons"; import { css } from "@emotion/react"; const Incognito = styled(IncognitoSvg)` @@ -100,7 +91,7 @@ export default function ProfilePage() { padding: 1rem; `} > - Change the instance you're currently connected to below. + Change the instance you're currently connected to below. Alternatively, click login to join your instance with your account.

diff --git a/src/pages/SettingsPage.tsx b/src/pages/SettingsPage.tsx index 9a4855af5a..f4318e0f4b 100644 --- a/src/pages/SettingsPage.tsx +++ b/src/pages/SettingsPage.tsx @@ -7,8 +7,8 @@ import { IonTitle, IonToolbar, } from "@ionic/react"; -import AppContent from "../components/AppContent"; -import { InsetIonItem, SettingLabel } from "../features/profile/Profile"; +import AppContent from "../features/shared/AppContent"; +import { InsetIonItem, SettingLabel } from "../features/user/Profile"; import { apps } from "ionicons/icons"; import { isInstalled } from "../helpers/device"; diff --git a/src/pages/SpecialFeedPage.tsx b/src/pages/SpecialFeedPage.tsx index 463041c0fe..fe48619a2d 100644 --- a/src/pages/SpecialFeedPage.tsx +++ b/src/pages/SpecialFeedPage.tsx @@ -7,10 +7,10 @@ import { IonTitle, IonToolbar, } from "@ionic/react"; -import Posts from "../components/Posts"; +import Posts from "../features/post/inFeed/Posts"; import { PageContext } from "../features/auth/PageContext"; import { useRef } from "react"; -import PostSort from "../components/PostSort"; +import PostSort from "../features/post/inFeed/PostSort"; import { ListingType } from "lemmy-js-client"; import { useBuildGeneralBrowseLink } from "../helpers/routes"; diff --git a/src/pages/UserPage.tsx b/src/pages/UserPage.tsx index b542dd1bba..69b46b8d35 100644 --- a/src/pages/UserPage.tsx +++ b/src/pages/UserPage.tsx @@ -1,6 +1,6 @@ +import React from "react"; import { IonBackButton, - IonButton, IonButtons, IonContent, IonHeader, @@ -8,22 +8,19 @@ import { IonRefresher, IonRefresherContent, IonSpinner, - IonText, IonTitle, IonToolbar, - useIonModal, useIonViewWillEnter, } from "@ionic/react"; import { useContext, useEffect, useRef, useState } from "react"; -import Profile from "../features/profile/Profile"; +import Profile from "../features/user/Profile"; import { useParams } from "react-router"; import { PageContext } from "../features/auth/PageContext"; -import { GetPersonDetailsResponse, PersonViewSafe } from "lemmy-js-client"; +import { GetPersonDetailsResponse } from "lemmy-js-client"; import styled from "@emotion/styled"; import { useAppDispatch } from "../store"; import { getUser } from "../features/user/userSlice"; import { AppContext } from "../features/auth/AppContext"; -import { useBuildGeneralBrowseLink } from "../helpers/routes"; const PageContentIonSpinner = styled(IonSpinner)` position: relative; @@ -48,6 +45,7 @@ export default function UserPage(props: UserPageProps) { useEffect(() => { if (handle) load(); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [handle]); useIonViewWillEnter(() => { diff --git a/src/pages/settings/InstallAppPage.tsx b/src/pages/settings/InstallAppPage.tsx index 2a77c07f5f..a1f2a99755 100644 --- a/src/pages/settings/InstallAppPage.tsx +++ b/src/pages/settings/InstallAppPage.tsx @@ -1,10 +1,8 @@ import { IonBackButton, - IonBadge, IonButtons, IonHeader, IonIcon, - IonList, IonPage, IonText, IonTitle, @@ -15,7 +13,7 @@ import { checkmarkCircleOutline, shareOutline, } from "ionicons/icons"; -import AppContent from "../../components/AppContent"; +import AppContent from "../../features/shared/AppContent"; import styled from "@emotion/styled"; import { isInstalled } from "../../helpers/device"; @@ -92,7 +90,7 @@ export default function InstallAppPage() { Installed -

Congrats, you're browsing from the app!

+

Congrats, you're browsing from the app!

)} diff --git a/src/services/lemmy.ts b/src/services/lemmy.ts index 7ea93af453..bdefe519da 100644 --- a/src/services/lemmy.ts +++ b/src/services/lemmy.ts @@ -1,7 +1,7 @@ import { LemmyHttp } from "lemmy-js-client"; export function getClient(url: string): LemmyHttp { - let baseUrl = `/api/${url}`; + const baseUrl = `${location.origin}/api/${url}`; return new LemmyHttp(baseUrl); } diff --git a/src/setupTests.ts b/src/setupTests.ts index 87988d6bde..b06c239ace 100644 --- a/src/setupTests.ts +++ b/src/setupTests.ts @@ -2,13 +2,24 @@ // allows you to do things like: // expect(element).toHaveTextContent(/react/i) // learn more: https://github.com/testing-library/jest-dom -import '@testing-library/jest-dom/extend-expect'; +import "@testing-library/jest-dom/extend-expect"; // Mock matchmedia -window.matchMedia = window.matchMedia || function() { - return { +window.matchMedia = + window.matchMedia || + function () { + return { matches: false, - addListener: function() {}, - removeListener: function() {} + addListener: function () {}, + removeListener: function () {}, + }; }; + +window.localStorage = window.localStorage || { + setItem(key, item) { + this.state[key] = item; + }, + getItem(key) { + return this.state[key]; + }, }; diff --git a/src/store.ts b/src/store.ts index 5398ef496a..74a0a78a5b 100644 --- a/src/store.ts +++ b/src/store.ts @@ -3,7 +3,7 @@ import postSlice from "./features/post/postSlice"; import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux"; import authSlice from "./features/auth/authSlice"; import commentSlice from "./features/comment/commentSlice"; -import communitySlice from "./components/community/communitySlice"; +import communitySlice from "./features/community/communitySlice"; import userSlice from "./features/user/userSlice"; const store = configureStore({ diff --git a/vite.config.ts b/vite.config.ts index e4600f897a..15652546ed 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,6 +1,5 @@ import react from "@vitejs/plugin-react"; -import { defineConfig } from "vite"; -import _ from "lodash"; +import { defineConfig } from "vitest/config"; import { VitePWA } from "vite-plugin-pwa"; import svgr from "vite-plugin-svgr"; @@ -16,4 +15,9 @@ export default defineConfig({ svgr(), VitePWA({ registerType: "autoUpdate" }), ], + test: { + globals: true, + environment: "jsdom", + setupFiles: "./src/setupTests.ts", + }, }); diff --git a/yarn.lock b/yarn.lock index 173c412d46..26ba0795e4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -980,43 +980,6 @@ "@babel/helper-validator-identifier" "^7.22.5" to-fast-properties "^2.0.0" -"@colors/colors@1.5.0": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" - integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== - -"@cypress/request@^2.88.10": - version "2.88.11" - resolved "https://registry.yarnpkg.com/@cypress/request/-/request-2.88.11.tgz#5a4c7399bc2d7e7ed56e92ce5acb620c8b187047" - integrity sha512-M83/wfQ1EkspjkE2lNWNV5ui2Cv7UCv1swW1DqljahbzLVWltcsexQh8jYtuS/vzFXP+HySntGM83ZXA9fn17w== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - http-signature "~1.3.6" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - performance-now "^2.1.0" - qs "~6.10.3" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^8.3.2" - -"@cypress/xvfb@^1.2.4": - version "1.2.4" - resolved "https://registry.yarnpkg.com/@cypress/xvfb/-/xvfb-1.2.4.tgz#2daf42e8275b39f4aa53c14214e557bd14e7748a" - integrity sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q== - dependencies: - debug "^3.1.0" - lodash.once "^4.1.1" - "@emotion/babel-plugin@^11.11.0": version "11.11.0" resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz#c2d872b6a7767a9d176d007f5b31f7d504bb5d6c" @@ -1056,6 +1019,11 @@ "@emotion/sheet" "^1.2.2" "@emotion/utils" "^1.2.1" +"@emotion/eslint-plugin@^11.11.0": + version "11.11.0" + resolved "https://registry.yarnpkg.com/@emotion/eslint-plugin/-/eslint-plugin-11.11.0.tgz#9f19ecf64ba67c4472576c4c82f6bd4df646be61" + integrity sha512-jCOYqU/0Sqm+g+6D7QuIlG99q8YAF0T7BP98zQF/MPZKfbcm46z5mizXn0YlhZ9AYZfNtZ1DeODXdncYxZzR4Q== + "@emotion/hash@^0.9.1": version "0.9.1" resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.1.tgz#4ffb0055f7ef676ebc3a5a91fb621393294e2f43" @@ -1718,6 +1686,11 @@ resolved "https://registry.yarnpkg.com/@types/js-cookie/-/js-cookie-3.0.3.tgz#d6bfbbdd0c187354ca555213d1962f6d0691ff4e" integrity sha512-Xe7IImK09HP1sv2M/aI+48a20VX+TdRJucfq4vfRVy6nWN8PYPOEnlMRSgxJAgYQIXJVL8dZ4/ilAM7dWNaOww== +"@types/json-schema@^7.0.9": + version "7.0.12" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb" + integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== + "@types/lodash@^4.14.195": version "4.14.195" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.195.tgz#bafc975b252eb6cea78882ce8a7b6bf22a6de632" @@ -1740,11 +1713,6 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-20.3.1.tgz#e8a83f1aa8b649377bb1fb5d7bac5cb90e784dfe" integrity sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg== -"@types/node@^14.14.31": - version "14.18.51" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.51.tgz#cb90935b89c641201c3d07a595c3e22d1cfaa417" - integrity sha512-P9bsdGFPpVtofEKlhWMVS2qqx1A/rt9QBfihWlklfHHpUpjtYse5AzFz6j4DWrARLYh6gRnw9+5+DJcrq3KvBA== - "@types/parse-json@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" @@ -1800,15 +1768,10 @@ resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.3.tgz#cef09e3ec9af1d63d2a6cc5b383a737e24e6dcf5" integrity sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ== -"@types/sinonjs__fake-timers@8.1.1": - version "8.1.1" - resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz#b49c2c70150141a15e0fa7e79cf1f92a72934ce3" - integrity sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g== - -"@types/sizzle@^2.3.2": - version "2.3.3" - resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.3.tgz#ff5e2f1902969d305225a047c8a0fd5c915cebef" - integrity sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ== +"@types/semver@^7.3.12": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.0.tgz#591c1ce3a702c45ee15f47a42ade72c2fd78978a" + integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== "@types/stack-utils@^2.0.0": version "2.0.1" @@ -1854,12 +1817,89 @@ dependencies: "@types/yargs-parser" "*" -"@types/yauzl@^2.9.1": - version "2.10.0" - resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.10.0.tgz#b3248295276cf8c6f153ebe6a9aba0c988cb2599" - integrity sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw== +"@typescript-eslint/eslint-plugin@^5.60.0": + version "5.60.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.60.0.tgz#2f4bea6a3718bed2ba52905358d0f45cd3620d31" + integrity sha512-78B+anHLF1TI8Jn/cD0Q00TBYdMgjdOn980JfAVa9yw5sop8nyTfVOQAv6LWywkOGLclDBtv5z3oxN4w7jxyNg== dependencies: - "@types/node" "*" + "@eslint-community/regexpp" "^4.4.0" + "@typescript-eslint/scope-manager" "5.60.0" + "@typescript-eslint/type-utils" "5.60.0" + "@typescript-eslint/utils" "5.60.0" + debug "^4.3.4" + grapheme-splitter "^1.0.4" + ignore "^5.2.0" + natural-compare-lite "^1.4.0" + semver "^7.3.7" + tsutils "^3.21.0" + +"@typescript-eslint/parser@^5.60.0": + version "5.60.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.60.0.tgz#08f4daf5fc6548784513524f4f2f359cebb4068a" + integrity sha512-jBONcBsDJ9UoTWrARkRRCgDz6wUggmH5RpQVlt7BimSwaTkTjwypGzKORXbR4/2Hqjk9hgwlon2rVQAjWNpkyQ== + dependencies: + "@typescript-eslint/scope-manager" "5.60.0" + "@typescript-eslint/types" "5.60.0" + "@typescript-eslint/typescript-estree" "5.60.0" + debug "^4.3.4" + +"@typescript-eslint/scope-manager@5.60.0": + version "5.60.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.60.0.tgz#ae511967b4bd84f1d5e179bb2c82857334941c1c" + integrity sha512-hakuzcxPwXi2ihf9WQu1BbRj1e/Pd8ZZwVTG9kfbxAMZstKz8/9OoexIwnmLzShtsdap5U/CoQGRCWlSuPbYxQ== + dependencies: + "@typescript-eslint/types" "5.60.0" + "@typescript-eslint/visitor-keys" "5.60.0" + +"@typescript-eslint/type-utils@5.60.0": + version "5.60.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.60.0.tgz#69b09087eb12d7513d5b07747e7d47f5533aa228" + integrity sha512-X7NsRQddORMYRFH7FWo6sA9Y/zbJ8s1x1RIAtnlj6YprbToTiQnM6vxcMu7iYhdunmoC0rUWlca13D5DVHkK2g== + dependencies: + "@typescript-eslint/typescript-estree" "5.60.0" + "@typescript-eslint/utils" "5.60.0" + debug "^4.3.4" + tsutils "^3.21.0" + +"@typescript-eslint/types@5.60.0": + version "5.60.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.60.0.tgz#3179962b28b4790de70e2344465ec97582ce2558" + integrity sha512-ascOuoCpNZBccFVNJRSC6rPq4EmJ2NkuoKnd6LDNyAQmdDnziAtxbCGWCbefG1CNzmDvd05zO36AmB7H8RzKPA== + +"@typescript-eslint/typescript-estree@5.60.0": + version "5.60.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.0.tgz#4ddf1a81d32a850de66642d9b3ad1e3254fb1600" + integrity sha512-R43thAuwarC99SnvrBmh26tc7F6sPa2B3evkXp/8q954kYL6Ro56AwASYWtEEi+4j09GbiNAHqYwNNZuNlARGQ== + dependencies: + "@typescript-eslint/types" "5.60.0" + "@typescript-eslint/visitor-keys" "5.60.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.3.7" + tsutils "^3.21.0" + +"@typescript-eslint/utils@5.60.0": + version "5.60.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.60.0.tgz#4667c5aece82f9d4f24a667602f0f300864b554c" + integrity sha512-ba51uMqDtfLQ5+xHtwlO84vkdjrqNzOnqrnwbMHMRY8Tqeme8C2Q8Fc7LajfGR+e3/4LoYiWXUM6BpIIbHJ4hQ== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@types/json-schema" "^7.0.9" + "@types/semver" "^7.3.12" + "@typescript-eslint/scope-manager" "5.60.0" + "@typescript-eslint/types" "5.60.0" + "@typescript-eslint/typescript-estree" "5.60.0" + eslint-scope "^5.1.1" + semver "^7.3.7" + +"@typescript-eslint/visitor-keys@5.60.0": + version "5.60.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.0.tgz#b48b29da3f5f31dd1656281727004589d2722a66" + integrity sha512-wm9Uz71SbCyhUKgcaPRauBdTegUyY/ZWl8gLwD/i/ybJqscrrdVSFImpvUz16BLPChIeKBK5Fa9s6KDQjsjyWw== + dependencies: + "@typescript-eslint/types" "5.60.0" + eslint-visitor-keys "^3.3.0" "@vitejs/plugin-react@^4.0.1": version "4.0.1" @@ -1950,14 +1990,6 @@ agent-base@6: dependencies: debug "4" -aggregate-error@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" - integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== - dependencies: - clean-stack "^2.0.0" - indent-string "^4.0.0" - ajv@^6.10.0, ajv@^6.12.4: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" @@ -1978,18 +2010,6 @@ ajv@^8.6.0: require-from-string "^2.0.2" uri-js "^4.2.2" -ansi-colors@^4.1.1: - version "4.1.3" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" - integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== - -ansi-escapes@^4.3.0: - version "4.3.2" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" - integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== - dependencies: - type-fest "^0.21.3" - ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" @@ -2002,7 +2022,7 @@ ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" -ansi-styles@^4.0.0, ansi-styles@^4.1.0: +ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== @@ -2014,11 +2034,6 @@ ansi-styles@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== -arch@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11" - integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ== - argparse@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" @@ -2062,6 +2077,11 @@ array-includes@^3.1.5, array-includes@^3.1.6: get-intrinsic "^1.1.3" is-string "^1.0.7" +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + array.prototype.flatmap@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz#1aae7903c2100433cb8261cd4ed310aab5c4a183" @@ -2083,29 +2103,12 @@ array.prototype.tosorted@^1.1.1: es-shim-unscopables "^1.0.0" get-intrinsic "^1.1.3" -asn1@~0.2.3: - version "0.2.6" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" - integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== - assertion-error@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== -astral-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" - integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== - -async@^3.2.0, async@^3.2.3: +async@^3.2.3: version "3.2.4" resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== @@ -2125,16 +2128,6 @@ available-typed-arrays@^1.0.5: resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA== - -aws4@^1.8.0: - version "1.12.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.12.0.tgz#ce1c9d143389679e253b314241ea9aa5cec980d3" - integrity sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg== - babel-plugin-macros@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz#9ef6dc74deb934b4db344dc973ee851d148c50c1" @@ -2178,28 +2171,6 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== - dependencies: - tweetnacl "^0.14.3" - -blob-util@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/blob-util/-/blob-util-2.0.2.tgz#3b4e3c281111bb7f11128518006cdc60b403a1eb" - integrity sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ== - -bluebird@^3.7.2: - version "3.7.2" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" - integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== - blueimp-md5@^2.10.0: version "2.19.0" resolved "https://registry.yarnpkg.com/blueimp-md5/-/blueimp-md5-2.19.0.tgz#b53feea5498dcb53dc6ec4b823adb84b729c4af0" @@ -2255,24 +2226,11 @@ browserslist@^4.21.3, browserslist@^4.21.5: node-releases "^2.0.12" update-browserslist-db "^1.0.11" -buffer-crc32@~0.2.3: - version "0.2.13" - resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" - integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== - buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== -buffer@^5.6.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" - integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.1.13" - builtin-modules@^3.1.0: version "3.3.0" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" @@ -2288,11 +2246,6 @@ cac@^6.7.14: resolved "https://registry.yarnpkg.com/cac/-/cac-6.7.14.tgz#804e1e6f506ee363cb0e3ccbb09cad5dd9870959" integrity sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ== -cachedir@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.3.0.tgz#0c75892a052198f0b21c7c1804d8331edfcae0e8" - integrity sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw== - call-bind@^1.0.0, call-bind@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" @@ -2316,11 +2269,6 @@ caniuse-lite@^1.0.30001503: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001505.tgz#10a343e49d31cbbfdae298ef73cb0a9f46670dc5" integrity sha512-jaAOR5zVtxHfL0NjZyflVTtXm3D3J9P15zSJ7HmQF8dSKGA6tqzQq+0ZI3xkjyQj46I4/M0K2GbMpcAFOcbr3A== -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== - ccount@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/ccount/-/ccount-2.0.1.tgz#17a3bf82302e0870d6da43a01311a8bc02a3ecf5" @@ -2374,45 +2322,11 @@ check-error@^1.0.2: resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" integrity sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA== -check-more-types@^2.24.0: - version "2.24.0" - resolved "https://registry.yarnpkg.com/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600" - integrity sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA== - ci-info@^3.2.0: version "3.8.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.8.0.tgz#81408265a5380c929f0bc665d62256628ce9ef91" integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== -clean-stack@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" - integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== - -cli-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" - integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== - dependencies: - restore-cursor "^3.1.0" - -cli-table3@~0.6.1: - version "0.6.3" - resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.3.tgz#61ab765aac156b52f222954ffc607a6f01dbeeb2" - integrity sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg== - dependencies: - string-width "^4.2.0" - optionalDependencies: - "@colors/colors" "1.5.0" - -cli-truncate@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" - integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== - dependencies: - slice-ansi "^3.0.0" - string-width "^4.2.0" - color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -2437,12 +2351,7 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -colorette@^2.0.16: - version "2.0.20" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" - integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== - -combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: +combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -2459,11 +2368,6 @@ commander@^2.20.0: resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== -commander@^6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" - integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== - common-tags@^1.8.0: version "1.8.2" resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.2.tgz#94ebb3c076d26032745fd54face7f688ef5ac9c6" @@ -2522,11 +2426,6 @@ core-js-compat@^3.30.1, core-js-compat@^3.30.2: dependencies: browserslist "^4.21.5" -core-util-is@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== - cosmiconfig@^7.0.0: version "7.1.0" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6" @@ -2555,7 +2454,7 @@ cross-fetch@^3.1.5: dependencies: node-fetch "^2.6.11" -cross-spawn@^7.0.0, cross-spawn@^7.0.2: +cross-spawn@^7.0.2: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -2586,61 +2485,6 @@ csstype@^3.0.2: resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== -cypress@^12.15.0: - version "12.15.0" - resolved "https://registry.yarnpkg.com/cypress/-/cypress-12.15.0.tgz#06103529583c41f39712c6cfa6d9d09a01731760" - integrity sha512-FqGbxsH+QgjStuTO9onXMIeF44eOrgVwPvlcvuzLIaePQMkl72YgBvpuHlBGRcrw3Q4SvqKfajN8iV5XWShAiQ== - dependencies: - "@cypress/request" "^2.88.10" - "@cypress/xvfb" "^1.2.4" - "@types/node" "^14.14.31" - "@types/sinonjs__fake-timers" "8.1.1" - "@types/sizzle" "^2.3.2" - arch "^2.2.0" - blob-util "^2.0.2" - bluebird "^3.7.2" - buffer "^5.6.0" - cachedir "^2.3.0" - chalk "^4.1.0" - check-more-types "^2.24.0" - cli-cursor "^3.1.0" - cli-table3 "~0.6.1" - commander "^6.2.1" - common-tags "^1.8.0" - dayjs "^1.10.4" - debug "^4.3.4" - enquirer "^2.3.6" - eventemitter2 "6.4.7" - execa "4.1.0" - executable "^4.1.1" - extract-zip "2.0.1" - figures "^3.2.0" - fs-extra "^9.1.0" - getos "^3.2.1" - is-ci "^3.0.0" - is-installed-globally "~0.4.0" - lazy-ass "^1.6.0" - listr2 "^3.8.3" - lodash "^4.17.21" - log-symbols "^4.0.0" - minimist "^1.2.8" - ospath "^1.2.2" - pretty-bytes "^5.6.0" - proxy-from-env "1.0.0" - request-progress "^3.0.0" - semver "^7.3.2" - supports-color "^8.1.1" - tmp "~0.2.1" - untildify "^4.0.0" - yauzl "^2.10.0" - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g== - dependencies: - assert-plus "^1.0.0" - data-urls@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-4.0.0.tgz#333a454eca6f9a5b7b0f1013ff89074c3f522dd4" @@ -2664,11 +2508,6 @@ date-time@^3.1.0: dependencies: time-zone "^1.0.0" -dayjs@^1.10.4: - version "1.11.8" - resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.8.tgz#4282f139c8c19dd6d0c7bd571e30c2d0ba7698ea" - integrity sha512-LcgxzFoWMEPO7ggRv1Y2N31hUf2R0Vj7fuy/m+Bg1K8rr+KAs1AEy4y9jd5DXe8pbHgX+srkHNS7TH6Q6ZhYeQ== - debug@2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -2683,13 +2522,6 @@ debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: dependencies: ms "2.1.2" -debug@^3.1.0: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - decimal.js@^10.4.3: version "10.4.3" resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" @@ -2781,6 +2613,13 @@ diff@^5.0.0: resolved "https://registry.yarnpkg.com/diff/-/diff-5.1.0.tgz#bc52d298c5ea8df9194800224445ed43ffc87e40" integrity sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw== +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + doctrine@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" @@ -2807,14 +2646,6 @@ domexception@^4.0.0: dependencies: webidl-conversions "^7.0.0" -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw== - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -2832,30 +2663,11 @@ electron-to-chromium@^1.4.431: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.435.tgz#761c34300603b9f1234f0b6155870d3002435db6" integrity sha512-B0CBWVFhvoQCW/XtjRzgrmqcgVWg6RXOEM/dK59+wFV93BFGR6AeNKc4OyhM+T3IhJaOOG8o/V+33Y2mwJWtzw== -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== -end-of-stream@^1.1.0: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - -enquirer@^2.3.6: - version "2.3.6" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" - integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== - dependencies: - ansi-colors "^4.1.1" - entities@^4.4.0: version "4.5.0" resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" @@ -3006,6 +2818,23 @@ escape-string-regexp@^5.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz#4683126b500b61762f2dbebace1806e8be31b1c8" integrity sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw== +eslint-config-prettier@^8.8.0: + version "8.8.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz#bfda738d412adc917fd7b038857110efe98c9348" + integrity sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA== + +eslint-plugin-prettier@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz#651cbb88b1dab98bfd42f017a12fa6b2d993f94b" + integrity sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ== + dependencies: + prettier-linter-helpers "^1.0.0" + +eslint-plugin-react-hooks@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz#4c3e697ad95b77e93f8646aaa1630c1ba607edd3" + integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g== + eslint-plugin-react@^7.32.2: version "7.32.2" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.32.2.tgz#e71f21c7c265ebce01bcbc9d0955170c55571f10" @@ -3027,6 +2856,14 @@ eslint-plugin-react@^7.32.2: semver "^6.3.0" string.prototype.matchall "^4.0.8" +eslint-scope@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + eslint-scope@^7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.0.tgz#f21ebdafda02352f103634b96dd47d9f81ca117b" @@ -3108,6 +2945,11 @@ esrecurse@^4.3.0: dependencies: estraverse "^5.2.0" +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" @@ -3133,38 +2975,11 @@ etag@~1.8.1: resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== -eventemitter2@6.4.7: - version "6.4.7" - resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-6.4.7.tgz#a7f6c4d7abf28a14c1ef3442f21cb306a054271d" - integrity sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg== - eventemitter3@^4.0.0: version "4.0.7" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== -execa@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" - integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== - dependencies: - cross-spawn "^7.0.0" - get-stream "^5.0.0" - human-signals "^1.1.1" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.0" - onetime "^5.1.0" - signal-exit "^3.0.2" - strip-final-newline "^2.0.0" - -executable@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/executable/-/executable-4.1.1.tgz#41532bff361d3e57af4d763b70582db18f5d133c" - integrity sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg== - dependencies: - pify "^2.2.0" - expect@^29.0.0: version "29.5.0" resolved "https://registry.yarnpkg.com/expect/-/expect-29.5.0.tgz#68c0509156cb2a0adb8865d413b137eeaae682f7" @@ -3213,43 +3028,22 @@ express@^4.18.2: utils-merge "1.0.1" vary "~1.1.2" -extend@^3.0.0, extend@~3.0.2: +extend@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== -extract-zip@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a" - integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg== - dependencies: - debug "^4.1.1" - get-stream "^5.1.0" - yauzl "^2.10.0" - optionalDependencies: - "@types/yauzl" "^2.9.1" - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g== - -extsprintf@^1.2.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" - integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== - fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-diff@^1.2.0: +fast-diff@^1.1.2, fast-diff@^1.2.0: version "1.3.0" resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== -fast-glob@^3.2.12: +fast-glob@^3.2.12, fast-glob@^3.2.9: version "3.2.12" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== @@ -3277,20 +3071,6 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" -fd-slicer@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" - integrity sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g== - dependencies: - pend "~1.2.0" - -figures@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" - integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== - dependencies: - escape-string-regexp "^1.0.5" - file-entry-cache@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" @@ -3363,11 +3143,6 @@ for-each@^0.3.3: dependencies: is-callable "^1.1.3" -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== - form-data@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" @@ -3377,15 +3152,6 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - forwarded@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" @@ -3396,7 +3162,7 @@ fresh@0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== -fs-extra@^9.0.1, fs-extra@^9.1.0: +fs-extra@^9.0.1: version "9.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== @@ -3461,13 +3227,6 @@ get-own-enumerable-property-symbols@^3.0.0: resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== -get-stream@^5.0.0, get-stream@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" - integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== - dependencies: - pump "^3.0.0" - get-symbol-description@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" @@ -3476,20 +3235,6 @@ get-symbol-description@^1.0.0: call-bind "^1.0.2" get-intrinsic "^1.1.1" -getos@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/getos/-/getos-3.2.1.tgz#0134d1f4e00eb46144c5a9c0ac4dc087cbb27dc5" - integrity sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q== - dependencies: - async "^3.2.0" - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng== - dependencies: - assert-plus "^1.0.0" - glob-parent@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -3516,13 +3261,6 @@ glob@^7.1.3, glob@^7.1.6: once "^1.3.0" path-is-absolute "^1.0.0" -global-dirs@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.1.tgz#0c488971f066baceda21447aecb1a8b911d22485" - integrity sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA== - dependencies: - ini "2.0.0" - globals@^11.1.0: version "11.12.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" @@ -3542,6 +3280,18 @@ globalthis@^1.0.3: dependencies: define-properties "^1.1.3" +globby@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + gopd@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" @@ -3554,6 +3304,11 @@ graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.9: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== +grapheme-splitter@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" + integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== + graphemer@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" @@ -3676,15 +3431,6 @@ http-proxy@^1.18.1: follow-redirects "^1.0.0" requires-port "^1.0.0" -http-signature@~1.3.6: - version "1.3.6" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.3.6.tgz#cb6fbfdf86d1c974f343be94e87f7fc128662cf9" - integrity sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw== - dependencies: - assert-plus "^1.0.0" - jsprim "^2.0.2" - sshpk "^1.14.1" - https-proxy-agent@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" @@ -3693,11 +3439,6 @@ https-proxy-agent@^5.0.1: agent-base "6" debug "4" -human-signals@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" - integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== - iconv-lite@0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -3717,11 +3458,6 @@ idb@^7.0.1: resolved "https://registry.yarnpkg.com/idb/-/idb-7.1.1.tgz#d910ded866d32c7ced9befc5bfdf36f572ced72b" integrity sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ== -ieee754@^1.1.13: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - ignore@^5.2.0: version "5.2.4" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" @@ -3763,11 +3499,6 @@ inherits@2, inherits@2.0.4: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -ini@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" - integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== - inline-style-parser@0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz#ec8a3b429274e9c0a1f1c4ffa9453a7fef72cea1" @@ -3841,13 +3572,6 @@ is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== -is-ci@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.1.tgz#db6ecbed1bd659c43dac0f45661e7674103d1867" - integrity sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ== - dependencies: - ci-info "^3.2.0" - is-core-module@^2.11.0, is-core-module@^2.9.0: version "2.12.1" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.1.tgz#0c0b6885b6f80011c71541ce15c8d66cf5a4f9fd" @@ -3867,11 +3591,6 @@ is-extglob@^2.1.1: resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" @@ -3879,14 +3598,6 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: dependencies: is-extglob "^2.1.1" -is-installed-globally@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520" - integrity sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ== - dependencies: - global-dirs "^3.0.0" - is-path-inside "^3.0.2" - is-map@^2.0.1, is-map@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" @@ -3919,7 +3630,7 @@ is-obj@^1.0.1: resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" integrity sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg== -is-path-inside@^3.0.2, is-path-inside@^3.0.3: +is-path-inside@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== @@ -3994,16 +3705,6 @@ is-typed-array@^1.1.10, is-typed-array@^1.1.9: gopd "^1.0.1" has-tostringtag "^1.0.0" -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== - -is-unicode-supported@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" - integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== - is-weakmap@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2" @@ -4039,11 +3740,6 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== - jake@^10.8.5: version "10.8.7" resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.7.tgz#63a32821177940c33f356e0ba44ff9d34e1c7d8f" @@ -4137,11 +3833,6 @@ js-yaml@^4.1.0: dependencies: argparse "^2.0.1" -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== - jsdom@^22.1.0: version "22.1.0" resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-22.1.0.tgz#0fca6d1a37fbeb7f4aac93d1090d782c56b611c8" @@ -4196,7 +3887,7 @@ json-schema-traverse@^1.0.0: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== -json-schema@0.4.0, json-schema@^0.4.0: +json-schema@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== @@ -4206,11 +3897,6 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== - json5@^2.2.0, json5@^2.2.2: version "2.2.3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" @@ -4235,16 +3921,6 @@ jsonpointer@^5.0.0: resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-5.0.1.tgz#2110e0af0900fd37467b5907ecd13a7884a1b559" integrity sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ== -jsprim@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-2.0.2.tgz#77ca23dbcd4135cd364800d22ff82c2185803d4d" - integrity sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ== - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.4.0" - verror "1.10.0" - "jsx-ast-utils@^2.4.1 || ^3.0.0": version "3.3.3" resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz#76b3e6e6cece5c69d49a5792c3d01bd1a0cdc7ea" @@ -4258,11 +3934,6 @@ kleur@^4.0.3: resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.5.tgz#95106101795f7050c6c650f350c683febddb1780" integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ== -lazy-ass@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/lazy-ass/-/lazy-ass-1.6.0.tgz#7999655e8646c17f089fdd187d150d3324d54513" - integrity sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw== - lemmy-js-client@0.18.0-rc.1: version "0.18.0-rc.1" resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-0.18.0-rc.1.tgz#fd0c88810572d90413696011ebaed19e3b8162d8" @@ -4289,20 +3960,6 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== -listr2@^3.8.3: - version "3.14.0" - resolved "https://registry.yarnpkg.com/listr2/-/listr2-3.14.0.tgz#23101cc62e1375fd5836b248276d1d2b51fdbe9e" - integrity sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g== - dependencies: - cli-truncate "^2.1.0" - colorette "^2.0.16" - log-update "^4.0.0" - p-map "^4.0.0" - rfdc "^1.3.0" - rxjs "^7.5.1" - through "^2.3.8" - wrap-ansi "^7.0.0" - local-pkg@^0.4.3: version "0.4.3" resolved "https://registry.yarnpkg.com/local-pkg/-/local-pkg-0.4.3.tgz#0ff361ab3ae7f1c19113d9bb97b98b905dbc4963" @@ -4325,11 +3982,6 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== -lodash.once@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" - integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== - lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" @@ -4340,24 +3992,6 @@ lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -log-symbols@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" - integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== - dependencies: - chalk "^4.1.0" - is-unicode-supported "^0.1.0" - -log-update@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1" - integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== - dependencies: - ansi-escapes "^4.3.0" - cli-cursor "^3.1.0" - slice-ansi "^4.0.0" - wrap-ansi "^6.2.0" - longest-streak@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-3.1.0.tgz#62fa67cd958742a1574af9f39866364102d90cd4" @@ -4575,7 +4209,7 @@ merge-stream@^2.0.0: resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -merge2@^1.3.0: +merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== @@ -4871,7 +4505,7 @@ mime-db@1.52.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34: +mime-types@^2.1.12, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== @@ -4883,11 +4517,6 @@ mime@1.6.0: resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - min-indent@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" @@ -4907,11 +4536,6 @@ minimatch@^5.0.1: dependencies: brace-expansion "^2.0.1" -minimist@^1.2.8: - version "1.2.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" - integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== - mlly@^1.2.0: version "1.4.0" resolved "https://registry.yarnpkg.com/mlly/-/mlly-1.4.0.tgz#830c10d63f1f97bd8785377b24dc2a15d972832b" @@ -4937,7 +4561,7 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@2.1.3, ms@^2.1.1: +ms@2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -4947,6 +4571,11 @@ nanoid@^3.3.6: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== +natural-compare-lite@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" + integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -4969,13 +4598,6 @@ node-releases@^2.0.12: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.12.tgz#35627cc224a23bfb06fb3380f2b3afaaa7eb1039" integrity sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ== -npm-run-path@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== - dependencies: - path-key "^3.0.0" - nwsapi@^2.2.4: version "2.2.5" resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.5.tgz#a52744c61b3889dd44b0a158687add39b8d935e2" @@ -5056,20 +4678,13 @@ on-finished@2.4.1: dependencies: ee-first "1.1.1" -once@^1.3.0, once@^1.3.1, once@^1.4.0: +once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== dependencies: wrappy "1" -onetime@^5.1.0: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - optionator@^0.9.1: version "0.9.1" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" @@ -5082,11 +4697,6 @@ optionator@^0.9.1: type-check "^0.4.0" word-wrap "^1.2.3" -ospath@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/ospath/-/ospath-1.2.2.tgz#1276639774a3f8ef2572f7fe4280e0ea4550c07b" - integrity sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA== - p-limit@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" @@ -5108,13 +4718,6 @@ p-locate@^5.0.0: dependencies: p-limit "^3.0.2" -p-map@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" - integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== - dependencies: - aggregate-error "^3.0.0" - parent-module@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" @@ -5154,7 +4757,7 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== -path-key@^3.0.0, path-key@^3.1.0: +path-key@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== @@ -5191,16 +4794,6 @@ pathval@^1.1.1: resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== -pend@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" - integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg== - -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== - photoswipe@^5.3.7: version "5.3.7" resolved "https://registry.yarnpkg.com/photoswipe/-/photoswipe-5.3.7.tgz#c67df67aaddb5705bcf8ff265bd2086f57805756" @@ -5216,11 +4809,6 @@ picomatch@^2.2.2, picomatch@^2.2.3, picomatch@^2.3.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -pify@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== - pkg-types@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-1.0.3.tgz#988b42ab19254c01614d13f4f65a2cfc7880f868" @@ -5244,7 +4832,19 @@ prelude-ls@^1.2.1: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== -pretty-bytes@^5.3.0, pretty-bytes@^5.6.0: +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + +prettier@^2.8.8: + version "2.8.8" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" + integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== + +pretty-bytes@^5.3.0: version "5.6.0" resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== @@ -5294,24 +4894,11 @@ proxy-addr@~2.0.7: forwarded "0.2.0" ipaddr.js "1.9.1" -proxy-from-env@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.0.0.tgz#33c50398f70ea7eb96d21f7b817630a55791c7ee" - integrity sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A== - -psl@^1.1.28, psl@^1.1.33: +psl@^1.1.33: version "1.9.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - punycode@^2.1.0, punycode@^2.1.1, punycode@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" @@ -5324,13 +4911,6 @@ qs@6.11.0: dependencies: side-channel "^1.0.4" -qs@~6.10.3: - version "6.10.5" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.5.tgz#974715920a80ff6a262264acd2c7e6c2a53282b4" - integrity sha512-O5RlPh0VFtR78y79rgcgKK4wbAI0C5zGVLztOIdpWX6ep368q5Hv6XRxDvXuZ9q3C6v+e3n8UfZZJw7IIG27eQ== - dependencies: - side-channel "^1.0.4" - querystringify@^2.1.1: version "2.2.0" resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" @@ -5575,13 +5155,6 @@ remark-rehype@^10.0.0: mdast-util-to-hast "^12.1.0" unified "^10.0.0" -request-progress@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/request-progress/-/request-progress-3.0.0.tgz#4ca754081c7fec63f505e4faa825aa06cd669dbe" - integrity sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg== - dependencies: - throttleit "^1.0.0" - require-from-string@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" @@ -5625,25 +5198,12 @@ resolve@^2.0.0-next.4: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -restore-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" - integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== - dependencies: - onetime "^5.1.0" - signal-exit "^3.0.2" - reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rfdc@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" - integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== - -rimraf@^3.0.0, rimraf@^3.0.2: +rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== @@ -5686,13 +5246,6 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -rxjs@^7.5.1: - version "7.8.1" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" - integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== - dependencies: - tslib "^2.1.0" - sade@^1.7.3: version "1.8.1" resolved "https://registry.yarnpkg.com/sade/-/sade-1.8.1.tgz#0a78e81d658d394887be57d2a409bf703a3b2701" @@ -5700,7 +5253,7 @@ sade@^1.7.3: dependencies: mri "^1.1.0" -safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2: +safe-buffer@5.2.1, safe-buffer@^5.1.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -5714,7 +5267,7 @@ safe-regex-test@^1.0.0: get-intrinsic "^1.1.3" is-regex "^1.1.4" -"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -5738,7 +5291,7 @@ semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.3.2: +semver@^7.3.2, semver@^7.3.7: version "7.5.2" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.2.tgz#5b851e66d1be07c1cdaf37dfc856f543325a2beb" integrity sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ== @@ -5812,34 +5365,11 @@ siginfo@^2.0.0: resolved "https://registry.yarnpkg.com/siginfo/-/siginfo-2.0.0.tgz#32e76c70b79724e3bb567cb9d543eb858ccfaf30" integrity sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g== -signal-exit@^3.0.2: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -slice-ansi@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" - integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== - dependencies: - ansi-styles "^4.0.0" - astral-regex "^2.0.0" - is-fullwidth-code-point "^3.0.0" - -slice-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" - integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== - dependencies: - ansi-styles "^4.0.0" - astral-regex "^2.0.0" - is-fullwidth-code-point "^3.0.0" - source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" @@ -5880,21 +5410,6 @@ space-separated-tokens@^2.0.0: resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz#1ecd9d2350a3844572c3f4a312bceb018348859f" integrity sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q== -sshpk@^1.14.1: - version "1.17.0" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5" - integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - stack-utils@^2.0.3: version "2.0.6" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" @@ -5924,15 +5439,6 @@ stop-iteration-iterator@^1.0.0: dependencies: internal-slot "^1.0.4" -string-width@^4.1.0, string-width@^4.2.0: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - string.prototype.matchall@^4.0.6, string.prototype.matchall@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz#3bf85722021816dcd1bf38bb714915887ca79fd3" @@ -5983,7 +5489,7 @@ stringify-object@^3.3.0: is-obj "^1.0.1" is-regexp "^1.0.0" -strip-ansi@^6.0.0, strip-ansi@^6.0.1: +strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -5995,11 +5501,6 @@ strip-comments@^2.0.1: resolved "https://registry.yarnpkg.com/strip-comments/-/strip-comments-2.0.1.tgz#4ad11c3fbcac177a67a40ac224ca339ca1c1ba9b" integrity sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw== -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== - strip-indent@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" @@ -6045,13 +5546,6 @@ supports-color@^7.0.0, supports-color@^7.1.0: dependencies: has-flag "^4.0.0" -supports-color@^8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" @@ -6097,16 +5591,6 @@ text-table@^0.2.0: resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== -throttleit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c" - integrity sha512-rkTVqu6IjfQ/6+uNuuc3sZek4CEYxTJom3IktzgdSxcZqdARuebbA/f4QmAxMQIxqq9ZLEUkSYqvuk1I6VKq4g== - -through@^2.3.8: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== - time-zone@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/time-zone/-/time-zone-1.0.0.tgz#99c5bf55958966af6d06d83bdf3800dc82faec5d" @@ -6137,13 +5621,6 @@ tinyspy@^2.1.0: resolved "https://registry.yarnpkg.com/tinyspy/-/tinyspy-2.1.1.tgz#9e6371b00c259e5c5b301917ca18c01d40ae558c" integrity sha512-XPJL2uSzcOyBMky6OFrusqWlzfFrXtE0hPuMgW8A2HmaqrPo4ZQHRN/V0QXN3FSjKxpsbRrFc5LI7KOwBsT1/w== -tmp@~0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" - integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== - dependencies: - rimraf "^3.0.0" - to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" @@ -6171,14 +5648,6 @@ tough-cookie@^4.1.2: universalify "^0.2.0" url-parse "^1.5.3" -tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - tr46@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" @@ -6213,17 +5682,17 @@ tslib@*, tslib@^2.1.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.3.tgz#24944ba2d990940e6e982c4bea147aba80209913" integrity sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w== -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== - dependencies: - safe-buffer "^5.0.1" +tslib@^1.8.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== +tsutils@^3.21.0: + version "3.21.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== + dependencies: + tslib "^1.8.1" type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" @@ -6247,11 +5716,6 @@ type-fest@^0.20.2: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== -type-fest@^0.21.3: - version "0.21.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" - integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== - type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -6395,11 +5859,6 @@ unpipe@1.0.0, unpipe@~1.0.0: resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== -untildify@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" - integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== - upath@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" @@ -6438,11 +5897,6 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== -uuid@^8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" - integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== - uvu@^0.5.0: version "0.5.6" resolved "https://registry.yarnpkg.com/uvu/-/uvu-0.5.6.tgz#2754ca20bcb0bb59b64e9985e84d2e81058502df" @@ -6463,15 +5917,6 @@ vary@~1.1.2: resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw== - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - vfile-message@^3.0.0: version "3.1.4" resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-3.1.4.tgz#15a50816ae7d7c2d1fa87090a7f9f96612b59dea" @@ -6846,24 +6291,6 @@ workbox-window@7.0.0, workbox-window@^7.0.0: "@types/trusted-types" "^2.0.2" workbox-core "7.0.0" -wrap-ansi@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" - integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" @@ -6899,14 +6326,6 @@ yaml@^1.10.0: resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== -yauzl@^2.10.0: - version "2.10.0" - resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" - integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g== - dependencies: - buffer-crc32 "~0.2.3" - fd-slicer "~1.1.0" - yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"