Browse Source

fix conflict

cyhhao 2 years ago
parent
commit
efd3310711

+ 21 - 17
.github/workflows/sync.yml

@@ -1,29 +1,33 @@
 name: Upstream Sync
 
+permissions:
+  contents: write
+
 on:
   schedule:
-    - cron: '0 */12 * * *' # every 12 hours
-  workflow_dispatch: # on button click
+    - cron: "0 */6 * * *" # every 6 hours
+  workflow_dispatch:
 
 jobs:
   sync_latest_from_upstream:
     name: Sync latest commits from upstream repo
     runs-on: ubuntu-latest
+    if: ${{ github.event.repository.fork }}
 
     steps:
-    # Step 1: run a standard checkout action, provided by github
-    - name: Checkout target repo
-      uses: actions/checkout@v3
+      # Step 1: run a standard checkout action
+      - name: Checkout target repo
+        uses: actions/checkout@v3
+
+      # Step 2: run the sync action
+      - name: Sync upstream changes
+        id: sync
+        uses: aormsby/Fork-Sync-With-Upstream-action@v3.4
+        with:
+          upstream_sync_repo: Yidadaa/ChatGPT-Next-Web
+          upstream_sync_branch: main
+          target_sync_branch: main
+          target_repo_token: ${{ secrets.GITHUB_TOKEN }} # automatically generated, no need to set
 
-    # Step 2: run the sync action
-    - name: Sync upstream changes
-      id: sync
-      uses: aormsby/Fork-Sync-With-Upstream-action@v3.4
-      with:
-        upstream_sync_repo: Yidadaa/ChatGPT-Next-Web
-        upstream_sync_branch: main
-        target_sync_branch: main
-        target_repo_token: ${{ secrets.GITHUB_TOKEN }} # automatically generated, no need to set
-        
-        # Set test_mode true to run tests instead of the true action!!
-        test_mode: false
+          # Set test_mode true to run tests instead of the true action!!
+          test_mode: false

+ 6 - 3
README.md

@@ -74,7 +74,9 @@ One-Click to deploy your own ChatGPT web UI.
 - 前往 vercel 控制台,删除掉原先的 project,然后新建 project,选择你刚刚 fork 出来的项目重新进行部署即可;
 - 在重新部署的过程中,请手动添加名为 `OPENAI_API_KEY` 的环境变量,并填入你的 api key 作为值。
 
-本项目会持续更新,如果你想让代码库总是保持更新,可以查看 [Github 的文档](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork) 了解如何让 fork 的项目与上游代码同步,建议定期进行同步操作以获得新功能。
+本项目会持续更新,当你 Fork 项目之后,默认会每天自动同步上游代码,无需额外操作。
+
+如果你想让手动立即更新,可以查看 [Github 的文档](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork) 了解如何让 fork 的项目与上游代码同步。
 
 你可以 star/watch 本项目或者 follow 作者来及时获得新功能更新通知。
 
@@ -87,7 +89,9 @@ We recommend that you follow the steps below to re-deploy:
 - Go to the Vercel dashboard, delete the original project, then create a new project and select the project you just forked to redeploy;
 - Please manually add an environment variable named `OPENAI_API_KEY` and enter your API key as the value during the redeploy process.
 
-This project will be continuously maintained. If you want to keep the code repository up to date, you can check out the [Github documentation](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork) to learn how to synchronize a forked project with upstream code. It is recommended to perform synchronization operations regularly.
+This project will be continuously updated, and after forking the project, the upstream code will be automatically synchronized every day without additional operations.
+
+If you want to update instantly, you can check out the [Github documentation](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork) to learn how to synchronize a forked project with upstream code. 
 
 You can star or watch this project or follow author to get release notifictions in time.
 
@@ -184,7 +188,6 @@ docker run -d -p 3000:3000 -e OPENAI_API_KEY="" -e CODE="" yidadaa/chatgpt-next-
 
 
 ## 鸣谢 Special Thanks
-
 ### 捐赠者 Sponsor
 
 [@mushan0x0](https://github.com/mushan0x0)

+ 6 - 8
app/components/chat.tsx

@@ -12,14 +12,7 @@ import BotIcon from "../icons/bot.svg";
 import AddIcon from "../icons/add.svg";
 import DeleteIcon from "../icons/delete.svg";
 
-import {
-  Message,
-  SubmitKey,
-  useChatStore,
-  ChatSession,
-  BOT_HELLO,
-  ROLES,
-} from "../store";
+import { Message, SubmitKey, useChatStore, BOT_HELLO, ROLES } from "../store";
 
 import {
   copyToClipboard,
@@ -462,6 +455,7 @@ export function Chat(props: {
 
   // Auto focus
   useEffect(() => {
+    if (props.sideBarShowing && isMobileScreen()) return;
     inputRef.current?.focus();
   }, []);
 
@@ -599,6 +593,7 @@ export function Chat(props: {
                         if (!isMobileScreen()) return;
                         setUserInput(message.content);
                       }}
+                      onMouseOver={() => inputRef.current?.blur()}
                     >
                       <Markdown content={message.content} />
                     </div>
@@ -633,6 +628,9 @@ export function Chat(props: {
               setAutoScroll(false);
               setTimeout(() => setPromptHints([]), 500);
             }}
+            onMouseOver={() => {
+              inputRef.current?.focus();
+            }}
             autoFocus={!props?.sideBarShowing}
           />
           <IconButton

+ 47 - 0
app/components/error.tsx

@@ -0,0 +1,47 @@
+import React from "react";
+import { IconButton } from "./button";
+import GithubIcon from "../icons/github.svg";
+import { ISSUE_URL } from "../constant";
+
+interface IErrorBoundaryState {
+  hasError: boolean;
+  error: Error | null;
+  info: React.ErrorInfo | null;
+}
+
+export class ErrorBoundary extends React.Component<any, IErrorBoundaryState> {
+  constructor(props: any) {
+    super(props);
+    this.state = { hasError: false, error: null, info: null };
+  }
+
+  componentDidCatch(error: Error, info: React.ErrorInfo) {
+    // Update state with error details
+    this.setState({ hasError: true, error, info });
+  }
+
+  render() {
+    if (this.state.hasError) {
+      // Render error message
+      return (
+        <div className="error">
+          <h2>Oops, something went wrong!</h2>
+          <pre>
+            <code>{this.state.error?.toString()}</code>
+            <code>{this.state.info?.componentStack}</code>
+          </pre>
+
+          <a href={ISSUE_URL} className="report">
+            <IconButton
+              text="Report This Error"
+              icon={<GithubIcon />}
+              bordered
+            />
+          </a>
+        </div>
+      );
+    }
+    // if no error occurred, render children
+    return this.props.children;
+  }
+}

+ 15 - 15
app/components/home.tsx

@@ -1,6 +1,8 @@
 "use client";
 
-import { useState, useRef, useEffect, useLayoutEffect } from "react";
+require("../polyfill");
+
+import { useState, useEffect } from "react";
 
 import { IconButton } from "./button";
 import styles from "./home.module.scss";
@@ -14,25 +16,15 @@ import AddIcon from "../icons/add.svg";
 import LoadingIcon from "../icons/three-dots.svg";
 import CloseIcon from "../icons/close.svg";
 
-import {
-  Message,
-  SubmitKey,
-  useChatStore,
-  ChatSession,
-  BOT_HELLO,
-} from "../store";
-import {
-  copyToClipboard,
-  downloadAs,
-  isMobileScreen,
-  selectOrCopy,
-} from "../utils";
+import { useChatStore } from "../store";
+import { isMobileScreen } from "../utils";
 import Locale from "../locales";
 import { ChatList } from "./chat-list";
 import { Chat } from "./chat";
 
 import dynamic from "next/dynamic";
 import { REPO_URL } from "../constant";
+import { ErrorBoundary } from "./error";
 
 export function Loading(props: { noLogo?: boolean }) {
   return (
@@ -78,7 +70,7 @@ const useHasHydrated = () => {
   return hasHydrated;
 };
 
-export function Home() {
+function _Home() {
   const [createNewSession, currentIndex, removeSession] = useChatStore(
     (state) => [
       state.newSession,
@@ -191,3 +183,11 @@ export function Home() {
     </div>
   );
 }
+
+export function Home() {
+  return (
+    <ErrorBoundary>
+      <_Home></_Home>
+    </ErrorBoundary>
+  );
+}

+ 1 - 0
app/constant.ts

@@ -1,6 +1,7 @@
 export const OWNER = "Yidadaa";
 export const REPO = "ChatGPT-Next-Web";
 export const REPO_URL = `https://github.com/${OWNER}/${REPO}`;
+export const ISSUE_URL = `https://github.com/${OWNER}/${REPO}/issues`;
 export const UPDATE_URL = `${REPO_URL}#%E4%BF%9D%E6%8C%81%E6%9B%B4%E6%96%B0-keep-updated`;
 export const FETCH_COMMIT_URL = `https://api.github.com/repos/${OWNER}/${REPO}/commits?per_page=1`;
 export const FETCH_TAG_URL = `https://api.github.com/repos/${OWNER}/${REPO}/tags?per_page=1`;

+ 1 - 0
app/locales/cn.ts

@@ -58,6 +58,7 @@ const cn = {
         en: "English",
         tw: "繁體中文",
         es: "Español",
+        it: "Italiano",
       },
     },
     Avatar: "头像",

+ 1 - 0
app/locales/en.ts

@@ -60,6 +60,7 @@ const en: LocaleType = {
         en: "English",
         tw: "繁體中文",
         es: "Español",
+        it: "Italiano",
       },
     },
     Avatar: "Avatar",

+ 1 - 0
app/locales/es.ts

@@ -60,6 +60,7 @@ const es: LocaleType = {
         en: "Inglés",
         tw: "繁體中文",
         es: "Español",
+        it: "Italiano",
       },
     },
     Avatar: "Avatar",

+ 5 - 2
app/locales/index.ts

@@ -2,10 +2,11 @@ import CN from "./cn";
 import EN from "./en";
 import TW from "./tw";
 import ES from "./es";
+import IT from "./it";
 
 export type { LocaleType } from "./cn";
 
-export const AllLangs = ["cn", "tw", "en", "es"] as const;
+export const AllLangs = ["en", "cn", "tw", "es", "it"] as const;
 type Lang = (typeof AllLangs)[number];
 
 const LANG_KEY = "lang";
@@ -47,6 +48,8 @@ export function getLang(): Lang {
     return "tw";
   } else if (lang.includes("es")) {
     return "es";
+  } else if (lang.includes("it")) {
+    return "it";
   } else {
     return "en";
   }
@@ -57,4 +60,4 @@ export function changeLang(lang: Lang) {
   location.reload();
 }
 
-export default { en: EN, cn: CN, tw: TW, es: ES }[getLang()];
+export default { en: EN, cn: CN, tw: TW, es: ES, it: IT }[getLang()];

+ 164 - 0
app/locales/it.ts

@@ -0,0 +1,164 @@
+import { SubmitKey } from "../store/app";
+import type { LocaleType } from "./index";
+
+const it: LocaleType = {
+  WIP: "Work in progress...",
+  Error: {
+    Unauthorized:
+      "Accesso non autorizzato, inserire il codice di accesso nella pagina delle impostazioni.",
+  },
+  ChatItem: {
+    ChatItemCount: (count: number) => `${count} messaggi`,
+  },
+  Chat: {
+    SubTitle: (count: number) => `${count} messaggi con ChatGPT`,
+    Actions: {
+      ChatList: "Vai alla Chat List",
+      CompressedHistory: "Prompt di memoria della cronologia compressa",
+      Export: "Esportazione di tutti i messaggi come Markdown",
+      Copy: "Copia",
+      Stop: "Stop",
+      Retry: "Riprova",
+    },
+    Rename: "Rinomina Chat",
+    Typing: "Typing…",
+    Input: (submitKey: string) => {
+      var inputHints = `Scrivi qualcosa e premi ${submitKey} per inviare`;
+      if (submitKey === String(SubmitKey.Enter)) {
+        inputHints += ", premi Shift + Enter per andare a capo";
+      }
+      return inputHints;
+    },
+    Send: "Invia",
+  },
+  Export: {
+    Title: "Tutti i messaggi",
+    Copy: "Copia tutto",
+    Download: "Scarica",
+  },
+  Memory: {
+    Title: "Prompt di memoria",
+    EmptyContent: "Vuoto.",
+    Copy: "Copia tutto",
+  },
+  Home: {
+    NewChat: "Nuova Chat",
+    DeleteChat: "Confermare la cancellazione della conversazione selezionata?",
+  },
+  Settings: {
+    Title: "Impostazioni",
+    SubTitle: "Tutte le impostazioni",
+    Actions: {
+      ClearAll: "Cancella tutti i dati",
+      ResetAll: "Resetta tutte le impostazioni",
+      Close: "Chiudi",
+    },
+    Lang: {
+      Name: "Lingue",
+      Options: {
+        cn: "简体中文",
+        en: "English",
+        tw: "繁體中文",
+        es: "Español",
+        it: "Italiano",
+      },
+    },
+    Avatar: "Avatar",
+    FontSize: {
+      Title: "Dimensione carattere",
+      SubTitle: "Regolare la dimensione dei caratteri del contenuto della chat",
+    },
+    Update: {
+      Version: (x: string) => `Versione: ${x}`,
+      IsLatest: "Ultima versione",
+      CheckUpdate: "Controlla aggiornamenti",
+      IsChecking: "Sto controllando gli aggiornamenti...",
+      FoundUpdate: (x: string) => `Trovata nuova versione: ${x}`,
+      GoToUpdate: "Aggiorna",
+    },
+    SendKey: "Tasto invia",
+    Theme: "tema",
+    TightBorder: "Bordi stretti",
+    SendPreviewBubble: "Invia l'anteprima della bolla",
+    Prompt: {
+      Disable: {
+        Title: "Disabilita l'auto completamento",
+        SubTitle: "Input / per attivare il completamento automatico",
+      },
+      List: "Elenco dei suggerimenti",
+      ListCount: (builtin: number, custom: number) =>
+        `${builtin} built-in, ${custom} user-defined`,
+      Edit: "Modifica",
+    },
+    HistoryCount: {
+      Title: "Conteggio dei messaggi allegati",
+      SubTitle: "Numero di messaggi inviati allegati per richiesta",
+    },
+    CompressThreshold: {
+      Title: "Soglia di compressione della cronologia",
+      SubTitle:
+        "Comprimerà se la lunghezza dei messaggi non compressi supera il valore",
+    },
+    Token: {
+      Title: "Chiave API",
+      SubTitle:
+        "Utilizzare la chiave per ignorare il limite del codice di accesso",
+      Placeholder: "OpenAI API Key",
+    },
+    Usage: {
+      Title: "Bilancio Account",
+      SubTitle(used: any) {
+        return `Usato in questo mese $${used}`;
+      },
+      IsChecking: "Controllando...",
+      Check: "Controlla ancora",
+    },
+    AccessCode: {
+      Title: "Codice d'accesso",
+      SubTitle: "Controllo d'accesso abilitato",
+      Placeholder: "Inserisci il codice d'accesso",
+    },
+    Model: "Modello GPT",
+    Temperature: {
+      Title: "Temperature",
+      SubTitle: "Un valore maggiore rende l'output più casuale",
+    },
+    MaxTokens: {
+      Title: "Token massimi",
+      SubTitle: "Lunghezza massima dei token in ingresso e dei token generati",
+    },
+    PresencePenlty: {
+      Title: "Penalità di presenza",
+      SubTitle:
+        "Un valore maggiore aumenta la probabilità di parlare di nuovi argomenti",
+    },
+  },
+  Store: {
+    DefaultTopic: "Nuova conversazione",
+    BotHello: "Ciao, come posso aiutarti oggi?",
+    Error: "Qualcosa è andato storto, riprova più tardi.",
+    Prompt: {
+      History: (content: string) =>
+        "Questo è un riassunto della cronologia delle chat tra l'IA e l'utente:" +
+        content,
+      Topic:
+        "Si prega di generare un titolo di quattro o cinque parole che riassuma la nostra conversazione senza alcuna traccia, punteggiatura, virgolette, punti, simboli o testo aggiuntivo. Rimuovere le virgolette",
+      Summarize:
+        "Riassumi brevemente la nostra discussione in 200 caratteri o meno per usarla come spunto per una futura conversazione.",
+    },
+    ConfirmClearAll:
+      "Confermi la cancellazione di tutti i dati della chat e delle impostazioni?",
+  },
+  Copy: {
+    Success: "Copiato sugli appunti",
+    Failed:
+      "Copia fallita, concedere l'autorizzazione all'accesso agli appunti",
+  },
+  Context: {
+    Toast: (x: any) => `Con ${x} prompts contestuali`,
+    Edit: "Prompt contestuali e di memoria",
+    Add: "Aggiungi altro",
+  },
+};
+
+export default it;

+ 1 - 0
app/locales/tw.ts

@@ -59,6 +59,7 @@ const tw: LocaleType = {
         en: "English",
         tw: "繁體中文",
         es: "Español",
+        it: "Italiano",
       },
     },
     Avatar: "大頭貼",

+ 0 - 2
app/page.tsx

@@ -1,7 +1,5 @@
 import { Analytics } from "@vercel/analytics/react";
 
-import "array.prototype.at";
-
 import { Home } from "./components/home";
 
 export default function App() {

+ 27 - 0
app/polyfill.ts

@@ -0,0 +1,27 @@
+declare global {
+  interface Array<T> {
+    at(index: number): T | undefined;
+  }
+}
+
+if (!Array.prototype.at) {
+  Array.prototype.at = function (index: number) {
+    // Get the length of the array
+    const length = this.length;
+
+    // Convert negative index to a positive index
+    if (index < 0) {
+      index = length + index;
+    }
+
+    // Return undefined if the index is out of range
+    if (index < 0 || index >= length) {
+      return undefined;
+    }
+
+    // Use Array.prototype.slice method to get value at the specified index
+    return Array.prototype.slice.call(this, index, index + 1)[0];
+  };
+}
+
+export {};

+ 1 - 1
app/store/app.ts

@@ -103,7 +103,7 @@ export function filterConfig(oldConfig: ModelConfig): Partial<ModelConfig> {
       return isValidModel(x as string);
     },
     max_tokens(x) {
-      return isValidNumber(x as number, 100, 4000);
+      return isValidNumber(x as number, 100, 32000);
     },
     presence_penalty(x) {
       return isValidNumber(x as number, -2, 2);

+ 15 - 0
app/styles/globals.scss

@@ -268,3 +268,18 @@ pre {
     filter: brightness(0.9);
   }
 }
+
+.error {
+  width: 80%;
+  border-radius: 20px;
+  border: var(--border-in-light);
+  box-shadow: var(--card-shadow);
+  padding: 20px;
+  overflow: auto;
+  background-color: var(--white);
+  color: var(--black);
+
+  pre {
+    overflow: auto;
+  }
+}

+ 8 - 7
app/styles/highlight.scss

@@ -8,16 +8,22 @@
     font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace;
   }
 
-  pre code.hljs {
+  pre code {
     display: block;
     overflow-x: auto;
     padding: 1em;
   }
 
-  code.hljs {
+  code {
     padding: 3px 5px;
   }
 
+  .hljs,
+  pre {
+    background: #1a1b26;
+    color: #cbd2ea;
+  }
+
   /*!
   Theme: Tokyo-night-Dark
   origin: https://github.com/enkia/tokyo-night-vscode-theme
@@ -99,11 +105,6 @@
     color: #c0caf5;
   }
 
-  .hljs {
-    background: #1a1b26;
-    color: #9aa5ce;
-  }
-
   .hljs-emphasis {
     font-style: italic;
   }

+ 13 - 9
app/utils.ts

@@ -5,15 +5,19 @@ export function trimTopic(topic: string) {
   return topic.replace(/[,。!?、,.!?]*$/, "");
 }
 
-export function copyToClipboard(text: string) {
-  navigator.clipboard
-    .writeText(text)
-    .then((res) => {
-      showToast(Locale.Copy.Success);
-    })
-    .catch((err) => {
-      showToast(Locale.Copy.Failed);
-    });
+export async function copyToClipboard(text: string) {
+  try {
+    await navigator.clipboard.writeText(text);
+  } catch (error) {
+    const textarea = document.createElement("textarea");
+    textarea.value = text;
+    document.body.appendChild(textarea);
+    textarea.select();
+    document.execCommand("copy");
+    document.body.removeChild(textarea);
+  } finally {
+    showToast(Locale.Copy.Success);
+  }
 }
 
 export function downloadAs(text: string, filename: string) {

+ 0 - 1
package.json

@@ -14,7 +14,6 @@
   "dependencies": {
     "@svgr/webpack": "^6.5.1",
     "@vercel/analytics": "^0.1.11",
-    "array.prototype.at": "^1.1.1",
     "emoji-picker-react": "^4.4.7",
     "eventsource-parser": "^0.1.0",
     "fuse.js": "^6.6.2",

+ 1 - 106
yarn.lock

@@ -1365,11 +1365,6 @@
   resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
   integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==
 
-"@types/prismjs@^1.0.0":
-  version "1.26.0"
-  resolved "https://registry.yarnpkg.com/@types/prismjs/-/prismjs-1.26.0.tgz#a1c3809b0ad61c62cac6d4e0c56d610c910b7654"
-  integrity sha512-ZTaqn/qSqUuAq1YwvOFQfVW1AR/oQJlLSZVustdjwI+GZ8kr0MSHBj0tsXPW1EqHubx50gtBEjbPGsdZwQwCjQ==
-
 "@types/prop-types@*", "@types/prop-types@^15.0.0":
   version "15.7.5"
   resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf"
@@ -1570,16 +1565,6 @@ array-union@^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.at@^1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/array.prototype.at/-/array.prototype.at-1.1.1.tgz#6deda3cd3c704afa16361387ea344e0b8d8831b5"
-  integrity sha512-n/wYNLJy/fVEU9EGPt2ww920hy1XX3XB2yTREFy1QsxctBgQV/tZIwg1G8jVxELna4pLCzg/xvvS/DDXtI4NNg==
-  dependencies:
-    call-bind "^1.0.2"
-    define-properties "^1.1.4"
-    es-abstract "^1.20.4"
-    es-shim-unscopables "^1.0.0"
-
 array.prototype.flat@^1.3.1:
   version "1.3.1"
   resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz#ffc6576a7ca3efc2f46a143b9d1dda9b4b3cf5e2"
@@ -1769,21 +1754,11 @@ chalk@^4.0.0:
     ansi-styles "^4.1.0"
     supports-color "^7.1.0"
 
-character-entities-legacy@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz#76bc83a90738901d7bc223a9e93759fdd560125b"
-  integrity sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==
-
 character-entities@^2.0.0:
   version "2.0.2"
   resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-2.0.2.tgz#2d09c2e72cd9523076ccb21157dff66ad43fcc22"
   integrity sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==
 
-character-reference-invalid@^2.0.0:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz#85c66b041e43b47210faf401278abf808ac45cb9"
-  integrity sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==
-
 "chokidar@>=3.0.0 <4.0.0":
   version "3.5.3"
   resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
@@ -2879,13 +2854,6 @@ hast-util-parse-selector@^3.0.0:
   dependencies:
     "@types/hast" "^2.0.0"
 
-hast-util-to-string@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/hast-util-to-string/-/hast-util-to-string-2.0.0.tgz#b008b0a4ea472bf34dd390b7eea1018726ae152a"
-  integrity sha512-02AQ3vLhuH3FisaMM+i/9sm4OXGSq1UhOOCpTLLQtHdL3tZt7qil69r8M8iDkZYyC0HCFylcYoP+8IO7ddta1A==
-  dependencies:
-    "@types/hast" "^2.0.0"
-
 hast-util-to-text@^3.0.0, hast-util-to-text@^3.1.0:
   version "3.1.2"
   resolved "https://registry.yarnpkg.com/hast-util-to-text/-/hast-util-to-text-3.1.2.tgz#ecf30c47141f41e91a5d32d0b1e1859fd2ac04f2"
@@ -2982,19 +2950,6 @@ internal-slot@^1.0.3, internal-slot@^1.0.4, internal-slot@^1.0.5:
     has "^1.0.3"
     side-channel "^1.0.4"
 
-is-alphabetical@^2.0.0:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-2.0.1.tgz#01072053ea7c1036df3c7d19a6daaec7f19e789b"
-  integrity sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==
-
-is-alphanumerical@^2.0.0:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz#7c03fbe96e3e931113e57f964b0a368cc2dfd875"
-  integrity sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==
-  dependencies:
-    is-alphabetical "^2.0.0"
-    is-decimal "^2.0.0"
-
 is-arguments@^1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b"
@@ -3063,11 +3018,6 @@ is-date-object@^1.0.1, is-date-object@^1.0.5:
   dependencies:
     has-tostringtag "^1.0.0"
 
-is-decimal@^2.0.0:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-2.0.1.tgz#9469d2dc190d0214fd87d78b78caecc0cc14eef7"
-  integrity sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==
-
 is-docker@^2.0.0, is-docker@^2.1.1:
   version "2.2.1"
   resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa"
@@ -3095,11 +3045,6 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1:
   dependencies:
     is-extglob "^2.1.1"
 
-is-hexadecimal@^2.0.0:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz#86b5bf668fca307498d319dfc03289d781a90027"
-  integrity sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==
-
 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"
@@ -4156,20 +4101,6 @@ parent-module@^1.0.0:
   dependencies:
     callsites "^3.0.0"
 
-parse-entities@^4.0.0:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-4.0.1.tgz#4e2a01111fb1c986549b944af39eeda258fc9e4e"
-  integrity sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==
-  dependencies:
-    "@types/unist" "^2.0.0"
-    character-entities "^2.0.0"
-    character-entities-legacy "^3.0.0"
-    character-reference-invalid "^2.0.0"
-    decode-named-character-reference "^1.0.0"
-    is-alphanumerical "^2.0.0"
-    is-decimal "^2.0.0"
-    is-hexadecimal "^2.0.0"
-
 parse-json@^5.0.0:
   version "5.2.0"
   resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd"
@@ -4180,11 +4111,6 @@ parse-json@^5.0.0:
     json-parse-even-better-errors "^2.3.0"
     lines-and-columns "^1.1.6"
 
-parse-numeric-range@^1.3.0:
-  version "1.3.0"
-  resolved "https://registry.yarnpkg.com/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz#7c63b61190d61e4d53a1197f0c83c47bb670ffa3"
-  integrity sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==
-
 parse5@^6.0.0:
   version "6.0.1"
   resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b"
@@ -4338,16 +4264,6 @@ readdirp@~3.6.0:
   dependencies:
     picomatch "^2.2.1"
 
-refractor@^4.7.0:
-  version "4.8.1"
-  resolved "https://registry.yarnpkg.com/refractor/-/refractor-4.8.1.tgz#fbdd889333a3d86c9c864479622855c9b38e9d42"
-  integrity sha512-/fk5sI0iTgFYlmVGYVew90AoYnNMP6pooClx/XKqyeeCQXrL0Kvgn8V0VEht5ccdljbzzF1i3Q213gcntkRExg==
-  dependencies:
-    "@types/hast" "^2.0.0"
-    "@types/prismjs" "^1.0.0"
-    hastscript "^7.0.0"
-    parse-entities "^4.0.0"
-
 regenerate-unicode-properties@^10.1.0:
   version "10.1.0"
   resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz#7c3192cab6dd24e21cb4461e5ddd7dd24fa8374c"
@@ -4425,7 +4341,7 @@ rehype-katex@^6.0.2:
     unist-util-remove-position "^4.0.0"
     unist-util-visit "^4.0.0"
 
-rehype-parse@^8.0.0, rehype-parse@^8.0.2:
+rehype-parse@^8.0.0:
   version "8.0.4"
   resolved "https://registry.yarnpkg.com/rehype-parse/-/rehype-parse-8.0.4.tgz#3d17c9ff16ddfef6bbcc8e6a25a99467b482d688"
   integrity sha512-MJJKONunHjoTh4kc3dsM1v3C9kGrrxvA3U8PxZlP2SjH8RNUSrb+lF7Y0KVaUDnGH2QZ5vAn7ulkiajM9ifuqg==
@@ -4435,18 +4351,6 @@ rehype-parse@^8.0.0, rehype-parse@^8.0.2:
     parse5 "^6.0.0"
     unified "^10.0.0"
 
-rehype-prism-plus@^1.5.1:
-  version "1.5.1"
-  resolved "https://registry.yarnpkg.com/rehype-prism-plus/-/rehype-prism-plus-1.5.1.tgz#b5f4eb3c789a13ffe874c81039665e144bcb1cae"
-  integrity sha512-mowYefSfrIkMMxkb0fwuEXlvc5nA9b1vQ6mzujM81Qx28RI0mo7jCHsBZ2tJ4eIJKXdFn+EdPkZZBGB10K02vg==
-  dependencies:
-    hast-util-to-string "^2.0.0"
-    parse-numeric-range "^1.3.0"
-    refractor "^4.7.0"
-    rehype-parse "^8.0.2"
-    unist-util-filter "^4.0.0"
-    unist-util-visit "^4.0.0"
-
 remark-breaks@^3.0.2:
   version "3.0.2"
   resolved "https://registry.yarnpkg.com/remark-breaks/-/remark-breaks-3.0.2.tgz#f466b9d3474d7323146c0149fc1496dabadd908e"
@@ -4996,15 +4900,6 @@ unified@^10.0.0:
     trough "^2.0.0"
     vfile "^5.0.0"
 
-unist-util-filter@^4.0.0:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/unist-util-filter/-/unist-util-filter-4.0.1.tgz#fd885dd48adaad345de5f5dc706ec4ff44a8d074"
-  integrity sha512-RynicUM/vbOSTSiUK+BnaK9XMfmQUh6gyi7L6taNgc7FIf84GukXVV3ucGzEN/PhUUkdP5hb1MmXc+3cvPUm5Q==
-  dependencies:
-    "@types/unist" "^2.0.0"
-    unist-util-is "^5.0.0"
-    unist-util-visit-parents "^5.0.0"
-
 unist-util-find-after@^4.0.0:
   version "4.0.1"
   resolved "https://registry.yarnpkg.com/unist-util-find-after/-/unist-util-find-after-4.0.1.tgz#80c69c92b0504033638ce11973f4135f2c822e2d"