Compare commits

..

40 Commits

Author SHA1 Message Date
bbig 8420085fb1 update BreakIcon to ClearIcon 2023-06-22 14:31:23 +08:00
bbig 5caaa440a4 Merge branch 'main' b0c6f6d 20230616 into pro 2023-06-22 13:20:21 +08:00
Yifei Zhang b0c6f6d4d3 Update tauri.conf.json 2023-06-16 00:53:10 +08:00
Yidadaa 473061b4d5 fixup: add TAURI_KEY_PASSWORD secrets 2023-06-16 00:18:54 +08:00
Yifei Zhang c4921f3da7 Merge pull request #1990 from Yidadaa/bugfix-0615
fix: #1982 should not fullscreen on standlone build
2023-06-16 00:02:17 +08:00
Yidadaa 91b871ef3b feat: try to add auto updater 2023-06-15 23:55:18 +08:00
Yidadaa 698be6671c feat: enable drag area for tauri apps 2023-06-15 23:20:14 +08:00
Yidadaa 47c546fafa fix: #1982 should not fullscreen on standlone build 2023-06-15 22:34:50 +08:00
Yifei Zhang 9d1a84858c Merge pull request #1973 from Jiacheng787/patch-1
fix: updating the array using push in zustand does not actually trigger component updates
2023-06-15 14:42:33 +08:00
Jiacheng Dong 4dd5bf71ea Update chat.ts 2023-06-15 13:59:38 +08:00
Yidadaa ea253e3bae fixup: tauri app name 2023-06-15 11:01:37 +08:00
Jiacheng Dong 1d42e955fc fix: updating the array using push in zustand does not actually trigger component updates 2023-06-15 10:55:25 +08:00
Jiacheng Dong e636d486f5 fix: updating the array using push in zustand does not actually trigger component updates 2023-06-15 10:23:01 +08:00
Yifei Zhang 818cc545eb Merge pull request #1970 from Yidadaa/app
feat: update app release workflow
2023-06-15 03:32:18 +08:00
Yidadaa e7858495e6 feat: update app release workflow 2023-06-15 03:28:53 +08:00
Yifei Zhang af3a273a56 Merge pull request #1969 from Yidadaa/app
feat: ready to release desktop app
2023-06-15 02:53:42 +08:00
Yidadaa 6264c02543 feat: add app logo and
release workflow
2023-06-15 02:49:08 +08:00
Yidadaa 80d5bfd7c0 feat: add app dev mode 2023-06-15 01:48:56 +08:00
Yifei Zhang 3fa8b0ad14 Merge pull request #1968 from Yidadaa/bugfix-0614
fix: #1954 lazy render bugs
2023-06-15 01:40:51 +08:00
Yidadaa 184a0b9481 fix: #1954 lazy render bugs 2023-06-15 01:34:21 +08:00
Yifei Zhang 4e80096ee4 Merge pull request #1967 from Yidadaa/bugfix-0614
fix: #1931 try to fix cors issues
2023-06-15 00:31:00 +08:00
Yidadaa 0fb775d71a fix: #1931 try to fix cors issues 2023-06-15 00:28:47 +08:00
Yidadaa 76fdd047e7 feat: new token count function 2023-06-15 00:14:38 +08:00
Yidadaa 8590750e4c feat: close #1960 add gpt-3.5-turbo-16k-0613 2023-06-14 23:22:59 +08:00
Yifei Zhang 590bd8e4bb Merge pull request #1946 from cesaryuan/fix-selection
fix: remove selection range when user blured
2023-06-14 15:42:24 +08:00
Cesaryuan b4cb8c3d75 chore: translate comment to english 2023-06-14 14:40:51 +08:00
Cesaryuan 21aa015a79 fix: remove slection range when user blured 2023-06-14 14:30:08 +08:00
Yifei Zhang dd5b9d420b Merge pull request #1928 from samelamin/fix_chat_time
fix date time bug on chat lists
2023-06-14 11:31:00 +08:00
Yifei Zhang 2593de5872 Merge pull request #1929 from suhipek/main
add new models
2023-06-14 10:29:00 +08:00
suhipek d2ae740d5f add new models 2023-06-14 01:51:37 +08:00
samelamin c56c6074e9 fix date time bug 2023-06-13 18:32:51 +01:00
Yifei Zhang 426ce7fd35 Merge pull request #1927 from Yidadaa/bugfix-0613
feat: #1000 ready to support client-side only
2023-06-14 00:48:32 +08:00
Yidadaa 2a191aacb7 fixup 2023-06-14 00:46:52 +08:00
Yidadaa 50cd33dbb2 feat: #1000 ready to support client-side only 2023-06-14 00:37:42 +08:00
Yifei Zhang e6b49a60c0 Merge pull request #1921 from Yidadaa/bugfix-0612
fixup: #1762 optimize style on mobile screen
2023-06-13 03:04:38 +08:00
Yidadaa a7e9356c16 fixup: #1762 optimize style on mobile screen 2023-06-13 03:04:09 +08:00
Yifei Zhang 58cc1c8482 Merge pull request #1919 from Yidadaa/bugfix-0612
feat: close #1762 add hover text for chat input actions
2023-06-13 02:29:56 +08:00
Yidadaa 88df4a2223 feat: close #1762 add hover text for chat input actions 2023-06-13 02:27:39 +08:00
Yifei Zhang d046100875 Merge pull request #1917 from Yidadaa/bugfix-0612
feat: white url list for openai security
2023-06-13 00:49:15 +08:00
Yidadaa 0d4611052e feat: white url list for openai security 2023-06-13 00:39:29 +08:00
31 changed files with 794 additions and 735 deletions
+88
View File
@@ -0,0 +1,88 @@
name: Release App
on:
workflow_dispatch:
release:
types: [published]
jobs:
create-release:
permissions:
contents: write
runs-on: ubuntu-20.04
outputs:
release_id: ${{ steps.create-release.outputs.result }}
steps:
- uses: actions/checkout@v3
- name: setup node
uses: actions/setup-node@v3
with:
node-version: 16
- name: get version
run: echo "PACKAGE_VERSION=$(node -p "require('./src-tauri/tauri.conf.json').package.version")" >> $GITHUB_ENV
- name: create release
id: create-release
uses: actions/github-script@v6
with:
script: |
const { data } = await github.rest.repos.getLatestRelease({
owner: context.repo.owner,
repo: context.repo.repo,
})
return data.id
build-tauri:
needs: create-release
permissions:
contents: write
strategy:
fail-fast: false
matrix:
platform: [macos-latest, ubuntu-20.04, windows-latest]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v3
- name: setup node
uses: actions/setup-node@v3
with:
node-version: 16
- name: install Rust stable
uses: dtolnay/rust-toolchain@stable
- name: install dependencies (ubuntu only)
if: matrix.platform == 'ubuntu-20.04'
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf
- name: install frontend dependencies
run: yarn install # change this to npm or pnpm depending on which one you use
- uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
with:
releaseId: ${{ needs.create-release.outputs.release_id }}
publish-release:
permissions:
contents: write
runs-on: ubuntu-20.04
needs: [create-release, build-tauri]
steps:
- name: publish release
id: publish-release
uses: actions/github-script@v6
env:
release_id: ${{ needs.create-release.outputs.release_id }}
with:
script: |
github.rest.repos.updateRelease({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: process.env.release_id,
draft: false,
prerelease: false
})
+2 -2
View File
@@ -35,6 +35,6 @@ jobs:
- name: Sync check - name: Sync check
if: failure() if: failure()
run: | run: |
echo "::error::由于权限不足,导致同步失败(这是预期的行为),请前往仓库首页手动执行[Sync fork]。" echo "[Error] 由于上游仓库的 workflow 文件变更,导致 GitHub 自动暂停了本次自动更新,你需要手动 Sync Fork 一次,详细教程请查看:https://github.com/Yidadaa/ChatGPT-Next-Web/blob/main/README_CN.md#%E6%89%93%E5%BC%80%E8%87%AA%E5%8A%A8%E6%9B%B4%E6%96%B0"
echo "::error::Due to insufficient permissions, synchronization failed (as expected). Please go to the repository homepage and manually perform [Sync fork]." echo "[Error] Due to a change in the workflow file of the upstream repository, GitHub has automatically suspended the scheduled automatic update. You need to manually sync your fork. Please refer to the detailed tutorial for instructions: https://github.com/Yidadaa/ChatGPT-Next-Web#enable-automatic-updates"
exit 1 exit 1
+6
View File
@@ -42,4 +42,10 @@ dev
# docker-compose env files # docker-compose env files
.env .env
*.key
*.key.pub
.dev-env .dev-env
*.key
*.key.pub
-1
View File
@@ -2,7 +2,6 @@ import { NextRequest } from "next/server";
import { getServerSideConfig } from "../config/server"; import { getServerSideConfig } from "../config/server";
import md5 from "spark-md5"; import md5 from "spark-md5";
import { ACCESS_CODE_PREFIX } from "../constant"; import { ACCESS_CODE_PREFIX } from "../constant";
import { OPENAI_URL } from "./common";
function getIP(req: NextRequest) { function getIP(req: NextRequest) {
let ip = req.ip ?? req.headers.get("x-real-ip"); let ip = req.ip ?? req.headers.get("x-real-ip");
+22
View File
@@ -1,14 +1,36 @@
import { OpenaiPath } from "@/app/constant";
import { prettyObject } from "@/app/utils/format"; import { prettyObject } from "@/app/utils/format";
import { NextRequest, NextResponse } from "next/server"; import { NextRequest, NextResponse } from "next/server";
import { auth } from "../../auth"; import { auth } from "../../auth";
import { requestOpenai } from "../../common"; import { requestOpenai } from "../../common";
const ALLOWD_PATH = new Set(Object.values(OpenaiPath));
async function handle( async function handle(
req: NextRequest, req: NextRequest,
{ params }: { params: { path: string[] } }, { params }: { params: { path: string[] } },
) { ) {
console.log("[OpenAI Route] params ", params); console.log("[OpenAI Route] params ", params);
if (req.method === "OPTIONS") {
return NextResponse.json({ body: "OK" }, { status: 200 });
}
const subpath = params.path.join("/");
if (!ALLOWD_PATH.has(subpath)) {
console.log("[OpenAI Route] forbidden path ", subpath);
return NextResponse.json(
{
error: true,
msg: "you are not allowed to request " + subpath,
},
{
status: 403,
},
);
}
const authResult = auth(req); const authResult = auth(req);
if (authResult.error) { if (authResult.error) {
return NextResponse.json(authResult, { return NextResponse.json(authResult, {
+23 -1
View File
@@ -1,5 +1,6 @@
import { getClientConfig } from "../config/client";
import { ACCESS_CODE_PREFIX } from "../constant"; import { ACCESS_CODE_PREFIX } from "../constant";
import { ChatMessage, ModelConfig, ModelType, useAccessStore } from "../store"; import { ChatMessage, ModelType, useAccessStore } from "../store";
import { ChatGPTApi } from "./platforms/openai"; import { ChatGPTApi } from "./platforms/openai";
export const ROLES = ["system", "user", "assistant"] as const; export const ROLES = ["system", "user", "assistant"] as const;
@@ -42,6 +43,27 @@ export abstract class LLMApi {
abstract usage(): Promise<LLMUsage>; abstract usage(): Promise<LLMUsage>;
} }
type ProviderName = "openai" | "azure" | "claude" | "palm";
interface Model {
name: string;
provider: ProviderName;
ctxlen: number;
}
interface ChatProvider {
name: ProviderName;
apiConfig: {
baseUrl: string;
apiKey: string;
summaryModel: Model;
};
models: Model[];
chat: () => void;
usage: () => void;
}
export class ClientApi { export class ClientApi {
public llm: LLMApi; public llm: LLMApi;
+5 -8
View File
@@ -1,4 +1,4 @@
import { REQUEST_TIMEOUT_MS } from "@/app/constant"; import { OpenaiPath, REQUEST_TIMEOUT_MS } from "@/app/constant";
import { useAccessStore, useAppConfig, useChatStore } from "@/app/store"; import { useAccessStore, useAppConfig, useChatStore } from "@/app/store";
import { ChatOptions, getHeaders, LLMApi, LLMUsage } from "../api"; import { ChatOptions, getHeaders, LLMApi, LLMUsage } from "../api";
@@ -10,10 +10,6 @@ import {
import { prettyObject } from "@/app/utils/format"; import { prettyObject } from "@/app/utils/format";
export class ChatGPTApi implements LLMApi { export class ChatGPTApi implements LLMApi {
public ChatPath = "v1/chat/completions";
public UsagePath = "dashboard/billing/usage";
public SubsPath = "dashboard/billing/subscription";
path(path: string): string { path(path: string): string {
let openaiUrl = useAccessStore.getState().openaiUrl; let openaiUrl = useAccessStore.getState().openaiUrl;
if (openaiUrl.endsWith("/")) { if (openaiUrl.endsWith("/")) {
@@ -55,7 +51,7 @@ export class ChatGPTApi implements LLMApi {
options.onController?.(controller); options.onController?.(controller);
try { try {
const chatPath = this.path(this.ChatPath); const chatPath = this.path(OpenaiPath.ChatPath);
const chatPayload = { const chatPayload = {
method: "POST", method: "POST",
body: JSON.stringify(requestPayload), body: JSON.stringify(requestPayload),
@@ -177,14 +173,14 @@ export class ChatGPTApi implements LLMApi {
const [used, subs] = await Promise.all([ const [used, subs] = await Promise.all([
fetch( fetch(
this.path( this.path(
`${this.UsagePath}?start_date=${startDate}&end_date=${endDate}`, `${OpenaiPath.UsagePath}?start_date=${startDate}&end_date=${endDate}`,
), ),
{ {
method: "GET", method: "GET",
headers: getHeaders(), headers: getHeaders(),
}, },
), ),
fetch(this.path(this.SubsPath), { fetch(this.path(OpenaiPath.SubsPath), {
method: "GET", method: "GET",
headers: getHeaders(), headers: getHeaders(),
}), }),
@@ -228,3 +224,4 @@ export class ChatGPTApi implements LLMApi {
} as LLMUsage; } as LLMUsage;
} }
} }
export { OpenaiPath };
+1 -3
View File
@@ -72,9 +72,7 @@ export function ChatItem(props: {
<div className={styles["chat-item-count"]}> <div className={styles["chat-item-count"]}>
{Locale.ChatItem.ChatItemCount(props.count)} {Locale.ChatItem.ChatItemCount(props.count)}
</div> </div>
<div className={styles["chat-item-date"]}> <div className={styles["chat-item-date"]}>{props.time}</div>
{new Date(props.time).toLocaleString()}
</div>
</div> </div>
</> </>
)} )}
+28
View File
@@ -17,10 +17,38 @@
transition: all ease 0.3s; transition: all ease 0.3s;
margin-bottom: 10px; margin-bottom: 10px;
align-items: center; align-items: center;
height: 16px;
width: var(--icon-width);
&:not(:last-child) { &:not(:last-child) {
margin-right: 5px; margin-right: 5px;
} }
.text {
white-space: nowrap;
padding-left: 5px;
opacity: 0;
transform: translateX(-5px);
transition: all ease 0.3s;
transition-delay: 0.1s;
pointer-events: none;
}
&:hover {
width: var(--full-width);
.text {
opacity: 1;
transform: translate(0);
}
}
.text,
.icon {
display: flex;
align-items: center;
justify-content: center;
}
} }
} }
+102 -43
View File
@@ -1,5 +1,11 @@
import { useDebouncedCallback } from "use-debounce"; import { useDebouncedCallback } from "use-debounce";
import { useState, useRef, useEffect, useLayoutEffect } from "react"; import React, {
useState,
useRef,
useEffect,
useLayoutEffect,
useMemo,
} from "react";
import SendWhiteIcon from "../icons/send-white.svg"; import SendWhiteIcon from "../icons/send-white.svg";
import BrainIcon from "../icons/brain.svg"; import BrainIcon from "../icons/brain.svg";
@@ -61,6 +67,7 @@ import { useMaskStore } from "../store/mask";
import { useCommand } from "../command"; import { useCommand } from "../command";
import { prettyObject } from "../utils/format"; import { prettyObject } from "../utils/format";
import { ExportMessageModal } from "./exporter"; import { ExportMessageModal } from "./exporter";
import { getClientConfig } from "../config/client";
const Markdown = dynamic(async () => (await import("./markdown")).Markdown, { const Markdown = dynamic(async () => (await import("./markdown")).Markdown, {
loading: () => <LoadingIcon />, loading: () => <LoadingIcon />,
@@ -279,6 +286,57 @@ function ClearContextDivider() {
); );
} }
function ChatAction(props: {
text: string;
icon: JSX.Element;
onClick: () => void;
}) {
const iconRef = useRef<HTMLDivElement>(null);
const textRef = useRef<HTMLDivElement>(null);
const [width, setWidth] = useState({
full: 20,
icon: 20,
});
function updateWidth() {
if (!iconRef.current || !textRef.current) return;
const getWidth = (dom: HTMLDivElement) => dom.getBoundingClientRect().width;
const textWidth = getWidth(textRef.current);
const iconWidth = getWidth(iconRef.current);
setWidth({
full: textWidth + iconWidth,
icon: iconWidth,
});
}
useEffect(() => {
updateWidth();
}, []);
return (
<div
className={`${chatStyle["chat-input-action"]} clickable`}
onClick={() => {
props.onClick();
setTimeout(updateWidth, 1);
}}
style={
{
"--icon-width": `${width.icon}px`,
"--full-width": `${width.full}px`,
} as React.CSSProperties
}
>
<div ref={iconRef} className={chatStyle["icon"]}>
{props.icon}
</div>
<div className={chatStyle["text"]} ref={textRef}>
{props.text}
</div>
</div>
);
}
function useScrollToBottom() { function useScrollToBottom() {
// for auto-scroll // for auto-scroll
const scrollRef = useRef<HTMLDivElement>(null); const scrollRef = useRef<HTMLDivElement>(null);
@@ -330,61 +388,60 @@ export function ChatActions(props: {
return ( return (
<div className={chatStyle["chat-input-actions"]}> <div className={chatStyle["chat-input-actions"]}>
{couldStop && ( {couldStop && (
<div <ChatAction
className={`${chatStyle["chat-input-action"]} clickable`}
onClick={stopAll} onClick={stopAll}
> text={Locale.Chat.InputActions.Stop}
<StopIcon /> icon={<StopIcon />}
</div> />
)} )}
{!props.hitBottom && ( {!props.hitBottom && (
<div <ChatAction
className={`${chatStyle["chat-input-action"]} clickable`}
onClick={props.scrollToBottom} onClick={props.scrollToBottom}
> text={Locale.Chat.InputActions.ToBottom}
<BottomIcon /> icon={<BottomIcon />}
</div> />
)} )}
{props.hitBottom && ( {props.hitBottom && (
<div <ChatAction
className={`${chatStyle["chat-input-action"]} clickable`}
onClick={props.showPromptModal} onClick={props.showPromptModal}
> text={Locale.Chat.InputActions.Settings}
<SettingsIcon /> icon={<SettingsIcon />}
</div> />
)} )}
<div <ChatAction
className={`${chatStyle["chat-input-action"]} clickable`}
onClick={nextTheme} onClick={nextTheme}
> text={Locale.Chat.InputActions.Theme[theme]}
{theme === Theme.Auto ? ( icon={
<AutoIcon /> <>
) : theme === Theme.Light ? ( {theme === Theme.Auto ? (
<LightIcon /> <AutoIcon />
) : theme === Theme.Dark ? ( ) : theme === Theme.Light ? (
<DarkIcon /> <LightIcon />
) : null} ) : theme === Theme.Dark ? (
</div> <DarkIcon />
) : null}
</>
}
/>
<div <ChatAction
className={`${chatStyle["chat-input-action"]} clickable`}
onClick={props.showPromptHints} onClick={props.showPromptHints}
> text={Locale.Chat.InputActions.Prompt}
<PromptIcon /> icon={<PromptIcon />}
</div> />
<div <ChatAction
className={`${chatStyle["chat-input-action"]} clickable`}
onClick={() => { onClick={() => {
navigate(Path.Masks); navigate(Path.Masks);
}} }}
> text={Locale.Chat.InputActions.Masks}
<MaskIcon /> icon={<MaskIcon />}
</div> />
<div <ChatAction
className={`${chatStyle["chat-input-action"]} clickable`} text={Locale.Chat.InputActions.Clear}
icon={<ClearIcon />}
onClick={() => { onClick={() => {
chatStore.updateCurrentSession((session) => { chatStore.updateCurrentSession((session) => {
if (session.clearContextIndex === session.messages.length) { if (session.clearContextIndex === session.messages.length) {
@@ -395,9 +452,7 @@ export function ChatActions(props: {
} }
}); });
}} }}
> />
<ClearIcon />
</div>
</div> </div>
); );
} }
@@ -656,9 +711,13 @@ export function Chat() {
} }
}; };
const clientConfig = useMemo(() => getClientConfig(), []);
const location = useLocation(); const location = useLocation();
const isChat = location.pathname === Path.Chat; const isChat = location.pathname === Path.Chat;
const autoFocus = !isMobileScreen || isChat; // only focus in chat page const autoFocus = !isMobileScreen || isChat; // only focus in chat page
const showMaxIcon = !isMobileScreen && !clientConfig?.isApp;
useCommand({ useCommand({
fill: setUserInput, fill: setUserInput,
@@ -707,7 +766,7 @@ export function Chat() {
}} }}
/> />
</div> </div>
{!isMobileScreen && ( {showMaxIcon && (
<div className="window-action-button"> <div className="window-action-button">
<IconButton <IconButton
icon={config.tightBorder ? <MinIcon /> : <MaxIcon />} icon={config.tightBorder ? <MinIcon /> : <MaxIcon />}
+11 -1
View File
@@ -24,6 +24,7 @@ import {
import { SideBar } from "./sidebar"; import { SideBar } from "./sidebar";
import { useAppConfig } from "../store/config"; import { useAppConfig } from "../store/config";
import { AuthPage } from "./auth"; import { AuthPage } from "./auth";
import { getClientConfig } from "../config/client";
export function Loading(props: { noLogo?: boolean }) { export function Loading(props: { noLogo?: boolean }) {
return ( return (
@@ -93,9 +94,14 @@ const useHasHydrated = () => {
const loadAsyncGoogleFont = () => { const loadAsyncGoogleFont = () => {
const linkEl = document.createElement("link"); const linkEl = document.createElement("link");
const proxyFontUrl = "/google-fonts";
const remoteFontUrl = "https://fonts.googleapis.com";
const googleFontUrl =
getClientConfig()?.buildMode === "export" ? remoteFontUrl : proxyFontUrl;
linkEl.rel = "stylesheet"; linkEl.rel = "stylesheet";
linkEl.href = linkEl.href =
"/google-fonts/css2?family=Noto+Sans+SC:wght@300;400;700;900&display=swap"; googleFontUrl +
"/css2?family=Noto+Sans+SC:wght@300;400;700;900&display=swap";
document.head.appendChild(linkEl); document.head.appendChild(linkEl);
}; };
@@ -147,6 +153,10 @@ function Screen() {
export function Home() { export function Home() {
useSwitchTheme(); useSwitchTheme();
useEffect(() => {
console.log("[Config] got config from build time", getClientConfig());
}, []);
if (!useHasHydrated()) { if (!useHasHydrated()) {
return <Loading />; return <Loading />;
} }
+42 -27
View File
@@ -11,6 +11,7 @@ import mermaid from "mermaid";
import LoadingIcon from "../icons/three-dots.svg"; import LoadingIcon from "../icons/three-dots.svg";
import React from "react"; import React from "react";
import { useThrottledCallback } from "use-debounce";
export function Mermaid(props: { code: string; onError: () => void }) { export function Mermaid(props: { code: string; onError: () => void }) {
const ref = useRef<HTMLDivElement>(null); const ref = useRef<HTMLDivElement>(null);
@@ -127,43 +128,57 @@ export function Markdown(
) { ) {
const mdRef = useRef<HTMLDivElement>(null); const mdRef = useRef<HTMLDivElement>(null);
const renderedHeight = useRef(0); const renderedHeight = useRef(0);
const renderedWidth = useRef(0);
const inView = useRef(!!props.defaultShow); const inView = useRef(!!props.defaultShow);
const [_, triggerRender] = useState(0);
const checkInView = useThrottledCallback(
() => {
const parent = props.parentRef?.current;
const md = mdRef.current;
if (parent && md && !props.defaultShow) {
const parentBounds = parent.getBoundingClientRect();
const twoScreenHeight = Math.max(500, parentBounds.height * 2);
const mdBounds = md.getBoundingClientRect();
const parentTop = parentBounds.top - twoScreenHeight;
const parentBottom = parentBounds.bottom + twoScreenHeight;
const isOverlap =
Math.max(parentTop, mdBounds.top) <=
Math.min(parentBottom, mdBounds.bottom);
inView.current = isOverlap;
triggerRender(Date.now());
}
const parent = props.parentRef?.current; if (inView.current && md) {
const md = mdRef.current; const rect = md.getBoundingClientRect();
renderedHeight.current = Math.max(renderedHeight.current, rect.height);
renderedWidth.current = Math.max(renderedWidth.current, rect.width);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
},
300,
{
leading: true,
trailing: true,
},
);
const checkInView = () => { useEffect(() => {
if (parent && md) { props.parentRef?.current?.addEventListener("scroll", checkInView);
const parentBounds = parent.getBoundingClientRect(); checkInView();
const twoScreenHeight = Math.max(500, parentBounds.height * 2); return () =>
const mdBounds = md.getBoundingClientRect(); props.parentRef?.current?.removeEventListener("scroll", checkInView);
const parentTop = parentBounds.top - twoScreenHeight; // eslint-disable-next-line react-hooks/exhaustive-deps
const parentBottom = parentBounds.bottom + twoScreenHeight; }, []);
const isOverlap =
Math.max(parentTop, mdBounds.top) <=
Math.min(parentBottom, mdBounds.bottom);
inView.current = isOverlap;
}
if (inView.current && md) { const getSize = (x: number) => (!inView.current && x > 0 ? x : "auto");
renderedHeight.current = Math.max(
renderedHeight.current,
md.getBoundingClientRect().height,
);
}
};
setTimeout(() => checkInView(), 1);
return ( return (
<div <div
className="markdown-body" className="markdown-body"
style={{ style={{
fontSize: `${props.fontSize ?? 14}px`, fontSize: `${props.fontSize ?? 14}px`,
height: height: getSize(renderedHeight.current),
!inView.current && renderedHeight.current > 0 width: getSize(renderedWidth.current),
? renderedHeight.current
: "auto",
}} }}
ref={mdRef} ref={mdRef}
onContextMenu={props.onContextMenu} onContextMenu={props.onContextMenu}
+6 -1
View File
@@ -185,7 +185,12 @@ function ContextPromptItem(props: {
className={chatStyle["context-content"]} className={chatStyle["context-content"]}
rows={focusingInput ? 5 : 1} rows={focusingInput ? 5 : 1}
onFocus={() => setFocusingInput(true)} onFocus={() => setFocusingInput(true)}
onBlur={() => setFocusingInput(false)} onBlur={() => {
setFocusingInput(false);
// If the selection is not removed when the user loses focus, some
// extensions like "Translate" will always display a floating bar
window?.getSelection()?.removeAllRanges();
}}
onInput={(e) => onInput={(e) =>
props.update({ props.update({
...props.prompt, ...props.prompt,
-595
View File
@@ -1,596 +1 @@
export {}; export {};
// import { useState, useEffect, useMemo, HTMLProps, useRef } from "react";
// import styles from "./settings.module.scss";
// import ResetIcon from "../icons/reload.svg";
// import AddIcon from "../icons/add.svg";
// import CloseIcon from "../icons/close.svg";
// import CopyIcon from "../icons/copy.svg";
// import ClearIcon from "../icons/clear.svg";
// import LoadingIcon from "../icons/three-dots.svg";
// import EditIcon from "../icons/edit.svg";
// import EyeIcon from "../icons/eye.svg";
// import {
// Input,
// List,
// ListItem,
// Modal,
// PasswordInput,
// Popover,
// Select,
// } from "./ui-lib";
// import { ModelConfigList } from "./model-config";
// import { IconButton } from "./button";
// import {
// SubmitKey,
// useChatStore,
// Theme,
// useUpdateStore,
// useAccessStore,
// useAppConfig,
// } from "../store";
// import Locale, {
// AllLangs,
// ALL_LANG_OPTIONS,
// changeLang,
// getLang,
// } from "../locales";
// import { copyToClipboard } from "../utils";
// import Link from "next/link";
// import { Path, UPDATE_URL } from "../constant";
// import { Prompt, SearchService, usePromptStore } from "../store/prompt";
// import { ErrorBoundary } from "./error";
// import { InputRange } from "./input-range";
// import { useNavigate } from "react-router-dom";
// import { Avatar, AvatarPicker } from "./emoji";
// function EditPromptModal(props: { id: number; onClose: () => void }) {
// const promptStore = usePromptStore();
// const prompt = promptStore.get(props.id);
// return prompt ? (
// <div className="modal-mask">
// <Modal
// title={Locale.Settings.Prompt.EditModal.Title}
// onClose={props.onClose}
// actions={[
// <IconButton
// key=""
// onClick={props.onClose}
// text={Locale.UI.Confirm}
// bordered
// />,
// ]}
// >
// <div className={styles["edit-prompt-modal"]}>
// <input
// type="text"
// value={prompt.title}
// readOnly={!prompt.isUser}
// className={styles["edit-prompt-title"]}
// onInput={(e) =>
// promptStore.update(
// props.id,
// (prompt) => (prompt.title = e.currentTarget.value),
// )
// }
// ></input>
// <Input
// value={prompt.content}
// readOnly={!prompt.isUser}
// className={styles["edit-prompt-content"]}
// rows={10}
// onInput={(e) =>
// promptStore.update(
// props.id,
// (prompt) => (prompt.content = e.currentTarget.value),
// )
// }
// ></Input>
// </div>
// </Modal>
// </div>
// ) : null;
// }
// function UserPromptModal(props: { onClose?: () => void }) {
// const promptStore = usePromptStore();
// const userPrompts = promptStore.getUserPrompts();
// const builtinPrompts = SearchService.builtinPrompts;
// const allPrompts = userPrompts.concat(builtinPrompts);
// const [searchInput, setSearchInput] = useState("");
// const [searchPrompts, setSearchPrompts] = useState<Prompt[]>([]);
// const prompts = searchInput.length > 0 ? searchPrompts : allPrompts;
// const [editingPromptId, setEditingPromptId] = useState<number>();
// useEffect(() => {
// if (searchInput.length > 0) {
// const searchResult = SearchService.search(searchInput);
// setSearchPrompts(searchResult);
// } else {
// setSearchPrompts([]);
// }
// }, [searchInput]);
// return (
// <div className="modal-mask">
// <Modal
// title={Locale.Settings.Prompt.Modal.Title}
// onClose={() => props.onClose?.()}
// actions={[
// <IconButton
// key="add"
// onClick={() =>
// promptStore.add({
// title: "Empty Prompt",
// content: "Empty Prompt Content",
// })
// }
// icon={<AddIcon />}
// bordered
// text={Locale.Settings.Prompt.Modal.Add}
// />,
// ]}
// >
// <div className={styles["user-prompt-modal"]}>
// <input
// type="text"
// className={styles["user-prompt-search"]}
// placeholder={Locale.Settings.Prompt.Modal.Search}
// value={searchInput}
// onInput={(e) => setSearchInput(e.currentTarget.value)}
// ></input>
// <div className={styles["user-prompt-list"]}>
// {prompts.map((v, _) => (
// <div className={styles["user-prompt-item"]} key={v.id ?? v.title}>
// <div className={styles["user-prompt-header"]}>
// <div className={styles["user-prompt-title"]}>{v.title}</div>
// <div className={styles["user-prompt-content"] + " one-line"}>
// {v.content}
// </div>
// </div>
// <div className={styles["user-prompt-buttons"]}>
// {v.isUser && (
// <IconButton
// icon={<ClearIcon />}
// className={styles["user-prompt-button"]}
// onClick={() => promptStore.remove(v.id!)}
// />
// )}
// {v.isUser ? (
// <IconButton
// icon={<EditIcon />}
// className={styles["user-prompt-button"]}
// onClick={() => setEditingPromptId(v.id)}
// />
// ) : (
// <IconButton
// icon={<EyeIcon />}
// className={styles["user-prompt-button"]}
// onClick={() => setEditingPromptId(v.id)}
// />
// )}
// <IconButton
// icon={<CopyIcon />}
// className={styles["user-prompt-button"]}
// onClick={() => copyToClipboard(v.content)}
// />
// </div>
// </div>
// ))}
// </div>
// </div>
// </Modal>
// {editingPromptId !== undefined && (
// <EditPromptModal
// id={editingPromptId!}
// onClose={() => setEditingPromptId(undefined)}
// />
// )}
// </div>
// );
// }
// function formatVersionDate(t: string) {
// const d = new Date(+t);
// const year = d.getUTCFullYear();
// const month = d.getUTCMonth() + 1;
// const day = d.getUTCDate();
// return [
// year.toString(),
// month.toString().padStart(2, "0"),
// day.toString().padStart(2, "0"),
// ].join("");
// }
// export function Settings() {
// const navigate = useNavigate();
// const [showEmojiPicker, setShowEmojiPicker] = useState(false);
// const config = useAppConfig();
// const updateConfig = config.update;
// const resetConfig = config.reset;
// const chatStore = useChatStore();
// const updateStore = useUpdateStore();
// const [checkingUpdate, setCheckingUpdate] = useState(false);
// const currentVersion = formatVersionDate(updateStore.version);
// const remoteId = formatVersionDate(updateStore.remoteVersion);
// const hasNewVersion = currentVersion !== remoteId;
// function checkUpdate(force = false) {
// setCheckingUpdate(true);
// updateStore.getLatestVersion(force).then(() => {
// setCheckingUpdate(false);
// });
// console.log(
// "[Update] local version ",
// new Date(+updateStore.version).toLocaleString(),
// );
// console.log(
// "[Update] remote version ",
// new Date(+updateStore.remoteVersion).toLocaleString(),
// );
// }
// const usage = {
// used: updateStore.used,
// subscription: updateStore.subscription,
// };
// const [loadingUsage, setLoadingUsage] = useState(false);
// function checkUsage(force = false) {
// setLoadingUsage(true);
// updateStore.updateUsage(force).finally(() => {
// setLoadingUsage(false);
// });
// }
// const accessStore = useAccessStore();
// const enabledAccessControl = useMemo(
// () => accessStore.enabledAccessControl(),
// // eslint-disable-next-line react-hooks/exhaustive-deps
// [],
// );
// const promptStore = usePromptStore();
// const builtinCount = SearchService.count.builtin;
// const customCount = promptStore.getUserPrompts().length ?? 0;
// const [shouldShowPromptModal, setShowPromptModal] = useState(false);
// const showUsage = accessStore.isAuthorized();
// useEffect(() => {
// // checks per minutes
// checkUpdate();
// showUsage && checkUsage();
// // eslint-disable-next-line react-hooks/exhaustive-deps
// }, []);
// useEffect(() => {
// const keydownEvent = (e: KeyboardEvent) => {
// if (e.key === "Escape") {
// navigate(Path.Home);
// }
// };
// document.addEventListener("keydown", keydownEvent);
// return () => {
// document.removeEventListener("keydown", keydownEvent);
// };
// // eslint-disable-next-line react-hooks/exhaustive-deps
// }, []);
// return (
// <ErrorBoundary>
// <div className="window-header">
// <div className="window-header-title">
// <div className="window-header-main-title">
// {Locale.Settings.Title}
// </div>
// <div className="window-header-sub-title">
// {Locale.Settings.SubTitle}
// </div>
// </div>
// <div className="window-actions">
// <div className="window-action-button">
// <IconButton
// icon={<ClearIcon />}
// onClick={() => {
// if (confirm(Locale.Settings.Actions.ConfirmClearAll)) {
// chatStore.clearAllData();
// }
// }}
// bordered
// title={Locale.Settings.Actions.ClearAll}
// />
// </div>
// <div className="window-action-button">
// <IconButton
// icon={<ResetIcon />}
// onClick={() => {
// if (confirm(Locale.Settings.Actions.ConfirmResetAll)) {
// resetConfig();
// }
// }}
// bordered
// title={Locale.Settings.Actions.ResetAll}
// />
// </div>
// <div className="window-action-button">
// <IconButton
// icon={<CloseIcon />}
// onClick={() => navigate(Path.Home)}
// bordered
// title={Locale.Settings.Actions.Close}
// />
// </div>
// </div>
// </div>
// <div className={styles["settings"]}>
// <List>
// <ListItem title={Locale.Settings.Avatar}>
// <Popover
// onClose={() => setShowEmojiPicker(false)}
// content={
// <AvatarPicker
// onEmojiClick={(avatar: string) => {
// updateConfig((config) => (config.avatar = avatar));
// setShowEmojiPicker(false);
// }}
// />
// }
// open={showEmojiPicker}
// >
// <div
// className={styles.avatar}
// onClick={() => setShowEmojiPicker(true)}
// >
// <Avatar avatar={config.avatar} />
// </div>
// </Popover>
// </ListItem>
// <ListItem
// title={Locale.Settings.Update.Version(currentVersion ?? "unknown")}
// subTitle={
// checkingUpdate
// ? Locale.Settings.Update.IsChecking
// : hasNewVersion
// ? Locale.Settings.Update.FoundUpdate(remoteId ?? "ERROR")
// : Locale.Settings.Update.IsLatest
// }
// >
// {checkingUpdate ? (
// <LoadingIcon />
// ) : hasNewVersion ? (
// <Link href={UPDATE_URL} target="_blank" className="link">
// {Locale.Settings.Update.GoToUpdate}
// </Link>
// ) : (
// <IconButton
// icon={<ResetIcon></ResetIcon>}
// text={Locale.Settings.Update.CheckUpdate}
// onClick={() => checkUpdate(true)}
// />
// )}
// </ListItem>
// <ListItem title={Locale.Settings.SendKey}>
// <Select
// value={config.submitKey}
// onChange={(e) => {
// updateConfig(
// (config) =>
// (config.submitKey = e.target.value as any as SubmitKey),
// );
// }}
// >
// {Object.values(SubmitKey).map((v) => (
// <option value={v} key={v}>
// {v}
// </option>
// ))}
// </Select>
// </ListItem>
// <ListItem title={Locale.Settings.Theme}>
// <Select
// value={config.theme}
// onChange={(e) => {
// updateConfig(
// (config) => (config.theme = e.target.value as any as Theme),
// );
// }}
// >
// {Object.values(Theme).map((v) => (
// <option value={v} key={v}>
// {v}
// </option>
// ))}
// </Select>
// </ListItem>
// <ListItem title={Locale.Settings.Lang.Name}>
// <Select
// value={getLang()}
// onChange={(e) => {
// changeLang(e.target.value as any);
// }}
// >
// {AllLangs.map((lang) => (
// <option value={lang} key={lang}>
// {ALL_LANG_OPTIONS[lang]}
// </option>
// ))}
// </Select>
// </ListItem>
// <ListItem
// title={Locale.Settings.FontSize.Title}
// subTitle={Locale.Settings.FontSize.SubTitle}
// >
// <InputRange
// title={`${config.fontSize ?? 14}px`}
// value={config.fontSize}
// min="12"
// max="18"
// step="1"
// onChange={(e) =>
// updateConfig(
// (config) =>
// (config.fontSize = Number.parseInt(e.currentTarget.value)),
// )
// }
// ></InputRange>
// </ListItem>
// <ListItem
// title={Locale.Settings.SendPreviewBubble.Title}
// subTitle={Locale.Settings.SendPreviewBubble.SubTitle}
// >
// <input
// type="checkbox"
// checked={config.sendPreviewBubble}
// onChange={(e) =>
// updateConfig(
// (config) =>
// (config.sendPreviewBubble = e.currentTarget.checked),
// )
// }
// ></input>
// </ListItem>
// <ListItem
// title={Locale.Settings.Mask.Title}
// subTitle={Locale.Settings.Mask.SubTitle}
// >
// <input
// type="checkbox"
// checked={!config.dontShowMaskSplashScreen}
// onChange={(e) =>
// updateConfig(
// (config) =>
// (config.dontShowMaskSplashScreen =
// !e.currentTarget.checked),
// )
// }
// ></input>
// </ListItem>
// </List>
// <List>
// {enabledAccessControl ? (
// <ListItem
// title={Locale.Settings.AccessCode.Title}
// subTitle={Locale.Settings.AccessCode.SubTitle}
// >
// <PasswordInput
// value={accessStore.accessCode}
// type="text"
// placeholder={Locale.Settings.AccessCode.Placeholder}
// onChange={(e) => {
// accessStore.updateCode(e.currentTarget.value);
// }}
// />
// </ListItem>
// ) : (
// <></>
// )}
// {!accessStore.hideUserApiKey ? (
// <ListItem
// title={Locale.Settings.Token.Title}
// subTitle={Locale.Settings.Token.SubTitle}
// >
// <PasswordInput
// value={accessStore.token}
// type="text"
// placeholder={Locale.Settings.Token.Placeholder}
// onChange={(e) => {
// accessStore.updateToken(e.currentTarget.value);
// }}
// />
// </ListItem>
// ) : null}
// <ListItem
// title={Locale.Settings.Usage.Title}
// subTitle={
// showUsage
// ? loadingUsage
// ? Locale.Settings.Usage.IsChecking
// : Locale.Settings.Usage.SubTitle(
// usage?.used ?? "[?]",
// usage?.subscription ?? "[?]",
// )
// : Locale.Settings.Usage.NoAccess
// }
// >
// {!showUsage || loadingUsage ? (
// <div />
// ) : (
// <IconButton
// icon={<ResetIcon></ResetIcon>}
// text={Locale.Settings.Usage.Check}
// onClick={() => checkUsage(true)}
// />
// )}
// </ListItem>
// </List>
// <List>
// <ListItem
// title={Locale.Settings.Prompt.Disable.Title}
// subTitle={Locale.Settings.Prompt.Disable.SubTitle}
// >
// <input
// type="checkbox"
// checked={config.disablePromptHint}
// onChange={(e) =>
// updateConfig(
// (config) =>
// (config.disablePromptHint = e.currentTarget.checked),
// )
// }
// ></input>
// </ListItem>
// <ListItem
// title={Locale.Settings.Prompt.List}
// subTitle={Locale.Settings.Prompt.ListCount(
// builtinCount,
// customCount,
// )}
// >
// <IconButton
// icon={<EditIcon />}
// text={Locale.Settings.Prompt.Edit}
// onClick={() => setShowPromptModal(true)}
// />
// </ListItem>
// </List>
// <List>
// <ModelConfigList
// modelConfig={config.modelConfig}
// updateConfig={(updater) => {
// const modelConfig = { ...config.modelConfig };
// updater(modelConfig);
// config.update((config) => (config.modelConfig = modelConfig));
// }}
// />
// </List>
// {shouldShowPromptModal && (
// <UserPromptModal onClose={() => setShowPromptModal(false)} />
// )}
// </div>
// </ErrorBoundary>
// );
// }
+17 -13
View File
@@ -1,16 +1,3 @@
const COMMIT_ID: string = (() => {
try {
const childProcess = require("child_process");
return childProcess
.execSync('git log -1 --format="%at000" --date=unix')
.toString()
.trim();
} catch (e) {
console.error("[Build Config] No git or not from git repo.");
return "unknown";
}
})();
export const getBuildConfig = () => { export const getBuildConfig = () => {
if (typeof process === "undefined") { if (typeof process === "undefined") {
throw Error( throw Error(
@@ -18,7 +5,24 @@ export const getBuildConfig = () => {
); );
} }
const COMMIT_ID: string = (() => {
try {
const childProcess = require("child_process");
return childProcess
.execSync('git log -1 --format="%at000" --date=unix')
.toString()
.trim();
} catch (e) {
console.error("[Build Config] No git or not from git repo.");
return "unknown";
}
})();
return { return {
commitId: COMMIT_ID, commitId: COMMIT_ID,
buildMode: process.env.BUILD_MODE ?? "standalone",
isApp: !!process.env.BUILD_APP,
}; };
}; };
export type BuildConfig = ReturnType<typeof getBuildConfig>;
+27
View File
@@ -0,0 +1,27 @@
import { BuildConfig, getBuildConfig } from "./build";
export function getClientConfig() {
if (typeof document !== "undefined") {
// client side
return JSON.parse(queryMeta("config")) as BuildConfig;
}
if (typeof process !== "undefined") {
// server side
return getBuildConfig();
}
}
function queryMeta(key: string, defaultValue?: string): string {
let ret: string;
if (document) {
const meta = document.head.querySelector(
`meta[name='${key}']`,
) as HTMLMetaElement;
ret = meta?.content ?? "";
} else {
ret = defaultValue ?? "";
}
return ret;
}
+2
View File
@@ -10,6 +10,8 @@ declare global {
VERCEL?: string; VERCEL?: string;
HIDE_USER_API_KEY?: string; // disable user's api key input HIDE_USER_API_KEY?: string; // disable user's api key input
DISABLE_GPT4?: string; // allow user to use gpt-4 or not DISABLE_GPT4?: string; // allow user to use gpt-4 or not
BUILD_MODE?: "standalone" | "export";
BUILD_APP?: string; // is building desktop app
} }
} }
} }
+8
View File
@@ -1,3 +1,5 @@
export const DEFAULT_API_HOST = "https://api.openai.com/";
export enum Path { export enum Path {
Home = "/", Home = "/",
Chat = "/chat", Chat = "/chat",
@@ -36,3 +38,9 @@ export const LAST_INPUT_KEY = "last-input";
export const REQUEST_TIMEOUT_MS = 60000; export const REQUEST_TIMEOUT_MS = 60000;
export const EXPORT_MESSAGE_CLASS_NAME = "export-markdown"; export const EXPORT_MESSAGE_CLASS_NAME = "export-markdown";
export const OpenaiPath = {
ChatPath: "v1/chat/completions",
UsagePath: "dashboard/billing/usage",
SubsPath: "dashboard/billing/subscription",
};
+2 -4
View File
@@ -2,9 +2,7 @@
import "./styles/globals.scss"; import "./styles/globals.scss";
import "./styles/markdown.scss"; import "./styles/markdown.scss";
import "./styles/highlight.scss"; import "./styles/highlight.scss";
import { getBuildConfig } from "./config/build"; import { getClientConfig } from "./config/client";
const buildConfig = getBuildConfig();
export const metadata = { export const metadata = {
title: "ChatGPT Pro", title: "ChatGPT Pro",
@@ -32,7 +30,7 @@ export default function RootLayout({
return ( return (
<html lang="en"> <html lang="en">
<head> <head>
<meta name="version" content={buildConfig.commitId} /> <meta name="config" content={JSON.stringify(getClientConfig())} />
<link rel="manifest" href="/site.webmanifest"></link> <link rel="manifest" href="/site.webmanifest"></link>
<script src="/serviceWorkerRegister.js" defer></script> <script src="/serviceWorkerRegister.js" defer></script>
</head> </head>
+17
View File
@@ -27,6 +27,19 @@ const cn = {
Retry: "重试", Retry: "重试",
Delete: "删除", Delete: "删除",
}, },
InputActions: {
Stop: "停止响应",
ToBottom: "滚到最新",
Theme: {
auto: "自动主题",
light: "亮色模式",
dark: "深色模式",
},
Prompt: "快捷指令",
Masks: "所有面具",
Clear: "清除聊天",
Settings: "对话设置",
},
Rename: "重命名对话", Rename: "重命名对话",
Typing: "正在输入…", Typing: "正在输入…",
Input: (submitKey: string) => { Input: (submitKey: string) => {
@@ -166,6 +179,10 @@ const cn = {
SubTitle: "管理员已开启加密访问", SubTitle: "管理员已开启加密访问",
Placeholder: "请输入访问密码", Placeholder: "请输入访问密码",
}, },
Endpoint: {
Title: "接口地址",
SubTitle: "除默认地址外,必须包含 http(s)://",
},
Model: "模型 (model)", Model: "模型 (model)",
Temperature: { Temperature: {
Title: "随机性 (temperature)", Title: "随机性 (temperature)",
+17
View File
@@ -28,6 +28,19 @@ const en: RequiredLocaleType = {
Retry: "Retry", Retry: "Retry",
Delete: "Delete", Delete: "Delete",
}, },
InputActions: {
Stop: "Stop",
ToBottom: "To Latest",
Theme: {
auto: "Auto",
light: "Light Theme",
dark: "Dark Theme",
},
Prompt: "Prompts",
Masks: "Masks",
Clear: "Clear Context",
Settings: "Settings",
},
Rename: "Rename Chat", Rename: "Rename Chat",
Typing: "Typing…", Typing: "Typing…",
Input: (submitKey: string) => { Input: (submitKey: string) => {
@@ -167,6 +180,10 @@ const en: RequiredLocaleType = {
SubTitle: "Access control enabled", SubTitle: "Access control enabled",
Placeholder: "Need Access Code", Placeholder: "Need Access Code",
}, },
Endpoint: {
Title: "Endpoint",
SubTitle: "Custom endpoint must start with http(s)://",
},
Model: "Model", Model: "Model",
Temperature: { Temperature: {
Title: "Temperature", Title: "Temperature",
-1
View File
@@ -69,7 +69,6 @@ function getLanguage() {
try { try {
return navigator.language.toLowerCase(); return navigator.language.toLowerCase();
} catch { } catch {
console.log("[Lang] failed to detect user lang.");
return DEFAULT_LANG; return DEFAULT_LANG;
} }
} }
+12 -3
View File
@@ -1,9 +1,10 @@
import { create } from "zustand"; import { create } from "zustand";
import { persist } from "zustand/middleware"; import { persist } from "zustand/middleware";
import { StoreKey } from "../constant"; import { DEFAULT_API_HOST, StoreKey } from "../constant";
import { getHeaders } from "../client/api"; import { getHeaders } from "../client/api";
import { BOT_HELLO } from "./chat"; import { BOT_HELLO } from "./chat";
import { ALL_MODELS } from "./config"; import { ALL_MODELS } from "./config";
import { getClientConfig } from "../config/client";
export interface AccessControlStore { export interface AccessControlStore {
accessCode: string; accessCode: string;
@@ -15,6 +16,7 @@ export interface AccessControlStore {
updateToken: (_: string) => void; updateToken: (_: string) => void;
updateCode: (_: string) => void; updateCode: (_: string) => void;
updateOpenAiUrl: (_: string) => void;
enabledAccessControl: () => boolean; enabledAccessControl: () => boolean;
isAuthorized: () => boolean; isAuthorized: () => boolean;
fetch: () => void; fetch: () => void;
@@ -22,6 +24,10 @@ export interface AccessControlStore {
let fetchState = 0; // 0 not fetch, 1 fetching, 2 done let fetchState = 0; // 0 not fetch, 1 fetching, 2 done
const DEFAULT_OPENAI_URL =
getClientConfig()?.buildMode === "export" ? DEFAULT_API_HOST : "/api/openai/";
console.log("[API] default openai url", DEFAULT_OPENAI_URL);
export const useAccessStore = create<AccessControlStore>()( export const useAccessStore = create<AccessControlStore>()(
persist( persist(
(set, get) => ({ (set, get) => ({
@@ -29,7 +35,7 @@ export const useAccessStore = create<AccessControlStore>()(
accessCode: "", accessCode: "",
needCode: true, needCode: true,
hideUserApiKey: false, hideUserApiKey: false,
openaiUrl: "/api/openai/", openaiUrl: DEFAULT_OPENAI_URL,
enabledAccessControl() { enabledAccessControl() {
get().fetch(); get().fetch();
@@ -42,6 +48,9 @@ export const useAccessStore = create<AccessControlStore>()(
updateToken(token: string) { updateToken(token: string) {
set(() => ({ token })); set(() => ({ token }));
}, },
updateOpenAiUrl(url: string) {
set(() => ({ openaiUrl: url }));
},
isAuthorized() { isAuthorized() {
get().fetch(); get().fetch();
@@ -51,7 +60,7 @@ export const useAccessStore = create<AccessControlStore>()(
); );
}, },
fetch() { fetch() {
if (fetchState > 0) return; if (fetchState > 0 || getClientConfig()?.buildMode === "export") return;
fetchState = 1; fetchState = 1;
fetch("/api/config", { fetch("/api/config", {
method: "post", method: "post",
+10 -7
View File
@@ -11,6 +11,7 @@ import { StoreKey } from "../constant";
import { api, RequestMessage } from "../client/api"; import { api, RequestMessage } from "../client/api";
import { ChatControllerPool } from "../client/controller"; import { ChatControllerPool } from "../client/controller";
import { prettyObject } from "../utils/format"; import { prettyObject } from "../utils/format";
import { estimateTokenLength } from "../utils/token";
export type ChatMessage = RequestMessage & { export type ChatMessage = RequestMessage & {
date: string; date: string;
@@ -102,7 +103,7 @@ interface ChatStore {
} }
function countMessages(msgs: ChatMessage[]) { function countMessages(msgs: ChatMessage[]) {
return msgs.reduce((pre, cur) => pre + cur.content.length, 0); return msgs.reduce((pre, cur) => pre + estimateTokenLength(cur.content), 0);
} }
export const useChatStore = create<ChatStore>()( export const useChatStore = create<ChatStore>()(
@@ -226,6 +227,7 @@ export const useChatStore = create<ChatStore>()(
onNewMessage(message) { onNewMessage(message) {
get().updateCurrentSession((session) => { get().updateCurrentSession((session) => {
session.messages = session.messages.concat();
session.lastUpdate = Date.now(); session.lastUpdate = Date.now();
}); });
get().updateStat(message); get().updateStat(message);
@@ -272,8 +274,7 @@ export const useChatStore = create<ChatStore>()(
// save user's and bot's message // save user's and bot's message
get().updateCurrentSession((session) => { get().updateCurrentSession((session) => {
session.messages.push(userMessage); session.messages = session.messages.concat([userMessage, botMessage]);
session.messages.push(botMessage);
}); });
// make request // make request
@@ -286,7 +287,9 @@ export const useChatStore = create<ChatStore>()(
if (message) { if (message) {
botMessage.content = message; botMessage.content = message;
} }
set(() => ({})); get().updateCurrentSession((session) => {
session.messages = session.messages.concat();
});
}, },
onFinish(message) { onFinish(message) {
botMessage.streaming = false; botMessage.streaming = false;
@@ -298,7 +301,6 @@ export const useChatStore = create<ChatStore>()(
sessionIndex, sessionIndex,
botMessage.id ?? messageIndex, botMessage.id ?? messageIndex,
); );
set(() => ({}));
}, },
onError(error) { onError(error) {
const isAborted = error.message.includes("aborted"); const isAborted = error.message.includes("aborted");
@@ -311,8 +313,9 @@ export const useChatStore = create<ChatStore>()(
botMessage.streaming = false; botMessage.streaming = false;
userMessage.isError = !isAborted; userMessage.isError = !isAborted;
botMessage.isError = !isAborted; botMessage.isError = !isAborted;
get().updateCurrentSession((session) => {
set(() => ({})); session.messages = session.messages.concat();
});
ChatControllerPool.remove( ChatControllerPool.remove(
sessionIndex, sessionIndex,
botMessage.id ?? messageIndex, botMessage.id ?? messageIndex,
+23 -2
View File
@@ -1,5 +1,6 @@
import { create } from "zustand"; import { create } from "zustand";
import { persist } from "zustand/middleware"; import { persist } from "zustand/middleware";
import { getClientConfig } from "../config/client";
import { StoreKey } from "../constant"; import { StoreKey } from "../constant";
export enum SubmitKey { export enum SubmitKey {
@@ -22,7 +23,7 @@ export const DEFAULT_CONFIG = {
avatar: "1f603", avatar: "1f603",
fontSize: 14, fontSize: 14,
theme: Theme.Auto as Theme, theme: Theme.Auto as Theme,
tightBorder: false, tightBorder: !!getClientConfig()?.isApp,
sendPreviewBubble: true, sendPreviewBubble: true,
sidebarWidth: 300, sidebarWidth: 300,
@@ -61,6 +62,10 @@ export const ALL_MODELS = [
name: "gpt-4-0314", name: "gpt-4-0314",
available: ENABLE_GPT4, available: ENABLE_GPT4,
}, },
{
name: "gpt-4-0613",
available: ENABLE_GPT4,
},
{ {
name: "gpt-4-32k", name: "gpt-4-32k",
available: ENABLE_GPT4, available: ENABLE_GPT4,
@@ -69,6 +74,10 @@ export const ALL_MODELS = [
name: "gpt-4-32k-0314", name: "gpt-4-32k-0314",
available: ENABLE_GPT4, available: ENABLE_GPT4,
}, },
{
name: "gpt-4-32k-0613",
available: ENABLE_GPT4,
},
{ {
name: "gpt-3.5-turbo", name: "gpt-3.5-turbo",
available: true, available: true,
@@ -77,6 +86,18 @@ export const ALL_MODELS = [
name: "gpt-3.5-turbo-0301", name: "gpt-3.5-turbo-0301",
available: true, available: true,
}, },
{
name: "gpt-3.5-turbo-0613",
available: true,
},
{
name: "gpt-3.5-turbo-16k",
available: true,
},
{
name: "gpt-3.5-turbo-16k-0613",
available: true,
},
{ {
name: "qwen-v1", // 通义千问 name: "qwen-v1", // 通义千问
available: false, available: false,
@@ -117,7 +138,7 @@ export function limitNumber(
export function limitModel(name: string) { export function limitModel(name: string) {
return ALL_MODELS.some((m) => m.name === name && m.available) return ALL_MODELS.some((m) => m.name === name && m.available)
? name ? name
: ALL_MODELS[4].name; : "gpt-3.5-turbo";
} }
export const ModalConfigValidator = { export const ModalConfigValidator = {
+2 -16
View File
@@ -3,7 +3,7 @@ export {};
// import { persist } from "zustand/middleware"; // import { persist } from "zustand/middleware";
// import { FETCH_COMMIT_URL, StoreKey } from "../constant"; // import { FETCH_COMMIT_URL, StoreKey } from "../constant";
// import { api } from "../client/api"; // import { api } from "../client/api";
// import { showToast } from "../components/ui-lib"; // import { getClientConfig } from "../config/client";
// export interface UpdateStore { // export interface UpdateStore {
// lastUpdate: number; // lastUpdate: number;
@@ -18,20 +18,6 @@ export {};
// updateUsage: (force?: boolean) => Promise<void>; // updateUsage: (force?: boolean) => Promise<void>;
// } // }
// function queryMeta(key: string, defaultValue?: string): string {
// let ret: string;
// if (document) {
// const meta = document.head.querySelector(
// `meta[name='${key}']`,
// ) as HTMLMetaElement;
// ret = meta?.content ?? "";
// } else {
// ret = defaultValue ?? "";
// }
// return ret;
// }
// const ONE_MINUTE = 60 * 1000; // const ONE_MINUTE = 60 * 1000;
// export const useUpdateStore = create<UpdateStore>()( // export const useUpdateStore = create<UpdateStore>()(
@@ -45,7 +31,7 @@ export {};
// version: "unknown", // version: "unknown",
// async getLatestVersion(force = false) { // async getLatestVersion(force = false) {
// set(() => ({ version: queryMeta("version") ?? "unknown" })); // set(() => ({ version: getClientConfig()?.commitId ?? "unknown" }));
// const overTenMins = Date.now() - get().lastUpdate > 10 * ONE_MINUTE; // const overTenMins = Date.now() - get().lastUpdate > 10 * ONE_MINUTE;
// if (!force && !overTenMins) return; // if (!force && !overTenMins) return;
+1 -1
View File
@@ -1116,4 +1116,4 @@
.markdown-body ::-webkit-calendar-picker-indicator { .markdown-body ::-webkit-calendar-picker-indicator {
filter: invert(50%); filter: invert(50%);
} }
+22
View File
@@ -0,0 +1,22 @@
export function estimateTokenLength(input: string): number {
let tokenLength = 0;
for (let i = 0; i < input.length; i++) {
const charCode = input.charCodeAt(i);
if (charCode < 128) {
// ASCII character
if (charCode <= 122 && charCode >= 65) {
// a-Z
tokenLength += 0.25;
} else {
tokenLength += 0.5;
}
} else {
// Unicode character
tokenLength += 1.5;
}
}
return tokenLength;
}
+27
View File
@@ -12,9 +12,36 @@ const nextConfig = {
return config; return config;
}, },
output: mode, output: mode,
images: {
unoptimized: mode === "export",
},
}; };
if (mode !== "export") { if (mode !== "export") {
nextConfig.headers = async () => {
return [
{
source: "/api/:path*",
headers: [
{ key: "Access-Control-Allow-Credentials", value: "true" },
{ key: "Access-Control-Allow-Origin", value: "*" },
{
key: "Access-Control-Allow-Methods",
value: "*",
},
{
key: "Access-Control-Allow-Headers",
value: "*",
},
{
key: "Access-Control-Max-Age",
value: "86400",
},
],
},
];
};
nextConfig.rewrites = async () => { nextConfig.rewrites = async () => {
const ret = [ const ret = [
{ {
+6 -2
View File
@@ -8,6 +8,10 @@
"build": "next build", "build": "next build",
"start": "next start", "start": "next start",
"lint": "next lint", "lint": "next lint",
"export": "cross-env BUILD_MODE=export BUILD_APP=1 yarn build",
"export:dev": "cross-env BUILD_MODE=export BUILD_APP=1 yarn dev",
"app:dev": "yarn tauri dev",
"app:build": "yarn tauri build",
"prompts": "node ./scripts/fetch-prompts.mjs", "prompts": "node ./scripts/fetch-prompts.mjs",
"prepare": "husky install", "prepare": "husky install",
"proxy-dev": "sh ./scripts/init-proxy.sh && proxychains -f ./scripts/proxychains.conf yarn dev" "proxy-dev": "sh ./scripts/init-proxy.sh && proxychains -f ./scripts/proxychains.conf yarn dev"
@@ -38,6 +42,7 @@
"zustand": "^4.3.6" "zustand": "^4.3.6"
}, },
"devDependencies": { "devDependencies": {
"@tauri-apps/cli": "^1.3.1",
"@types/node": "^18.14.6", "@types/node": "^18.14.6",
"@types/react": "^18.0.28", "@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11", "@types/react-dom": "^18.0.11",
@@ -51,7 +56,6 @@
"husky": "^8.0.0", "husky": "^8.0.0",
"lint-staged": "^13.2.0", "lint-staged": "^13.2.0",
"prettier": "^2.8.7", "prettier": "^2.8.7",
"typescript": "4.9.5", "typescript": "4.9.5"
"@tauri-apps/cli": "^1.3.1"
} }
} }
+265 -4
View File
@@ -1754,11 +1754,25 @@ balanced-match@^1.0.0:
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
base64-js@^1.3.1:
version "1.5.1"
resolved "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
binary-extensions@^2.0.0: binary-extensions@^2.0.0:
version "2.2.0" version "2.2.0"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
bl@^4.0.3:
version "4.1.0"
resolved "https://registry.npmmirror.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a"
integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==
dependencies:
buffer "^5.5.0"
inherits "^2.0.4"
readable-stream "^3.4.0"
boolbase@^1.0.0: boolbase@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
@@ -1789,6 +1803,14 @@ browserslist@^4.21.3, browserslist@^4.21.5:
node-releases "^2.0.8" node-releases "^2.0.8"
update-browserslist-db "^1.0.10" update-browserslist-db "^1.0.10"
buffer@^5.5.0:
version "5.7.1"
resolved "https://registry.npmmirror.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==
dependencies:
base64-js "^1.3.1"
ieee754 "^1.1.13"
busboy@1.6.0: busboy@1.6.0:
version "1.6.0" version "1.6.0"
resolved "https://registry.npmmirror.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" resolved "https://registry.npmmirror.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893"
@@ -1866,6 +1888,11 @@ character-entities@^2.0.0:
optionalDependencies: optionalDependencies:
fsevents "~2.3.2" fsevents "~2.3.2"
chownr@^1.1.1:
version "1.1.4"
resolved "https://registry.npmmirror.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==
clean-stack@^2.0.0: clean-stack@^2.0.0:
version "2.2.0" version "2.2.0"
resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b"
@@ -1923,11 +1950,27 @@ color-name@1.1.3:
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==
color-name@~1.1.4: color-name@^1.0.0, color-name@~1.1.4:
version "1.1.4" version "1.1.4"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
color-string@^1.9.0:
version "1.9.1"
resolved "https://registry.npmmirror.com/color-string/-/color-string-1.9.1.tgz#4467f9146f036f855b764dfb5bf8582bf342c7a4"
integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==
dependencies:
color-name "^1.0.0"
simple-swizzle "^0.2.2"
color@^4.2.3:
version "4.2.3"
resolved "https://registry.npmmirror.com/color/-/color-4.2.3.tgz#d781ecb5e57224ee43ea9627560107c0e0c6463a"
integrity sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==
dependencies:
color-convert "^2.0.1"
color-string "^1.9.0"
colorette@^2.0.19: colorette@^2.0.19:
version "2.0.19" version "2.0.19"
resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798"
@@ -2364,6 +2407,13 @@ decode-named-character-reference@^1.0.0:
dependencies: dependencies:
character-entities "^2.0.0" character-entities "^2.0.0"
decompress-response@^6.0.0:
version "6.0.0"
resolved "https://registry.npmmirror.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc"
integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==
dependencies:
mimic-response "^3.1.0"
deep-equal@^2.0.5: deep-equal@^2.0.5:
version "2.2.0" version "2.2.0"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.2.0.tgz#5caeace9c781028b9ff459f33b779346637c43e6" resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.2.0.tgz#5caeace9c781028b9ff459f33b779346637c43e6"
@@ -2387,6 +2437,11 @@ deep-equal@^2.0.5:
which-collection "^1.0.1" which-collection "^1.0.1"
which-typed-array "^1.1.9" which-typed-array "^1.1.9"
deep-extend@^0.6.0:
version "0.6.0"
resolved "https://registry.npmmirror.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==
deep-is@^0.1.3: deep-is@^0.1.3:
version "0.1.4" version "0.1.4"
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
@@ -2422,6 +2477,11 @@ dequal@^2.0.0:
resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be"
integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==
detect-libc@^2.0.0, detect-libc@^2.0.1:
version "2.0.1"
resolved "https://registry.npmmirror.com/detect-libc/-/detect-libc-2.0.1.tgz#e1897aa88fa6ad197862937fbc0441ef352ee0cd"
integrity sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==
diff@^5.0.0: diff@^5.0.0:
version "5.1.0" version "5.1.0"
resolved "https://registry.yarnpkg.com/diff/-/diff-5.1.0.tgz#bc52d298c5ea8df9194800224445ed43ffc87e40" resolved "https://registry.yarnpkg.com/diff/-/diff-5.1.0.tgz#bc52d298c5ea8df9194800224445ed43ffc87e40"
@@ -2515,6 +2575,13 @@ emoji-regex@^9.2.2:
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72"
integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==
end-of-stream@^1.1.0, end-of-stream@^1.4.1:
version "1.4.4"
resolved "https://registry.npmmirror.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"
enhanced-resolve@^5.12.0: enhanced-resolve@^5.12.0:
version "5.12.0" version "5.12.0"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz#300e1c90228f5b570c4d35babf263f6da7155634" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz#300e1c90228f5b570c4d35babf263f6da7155634"
@@ -2872,6 +2939,11 @@ execa@^7.0.0:
signal-exit "^3.0.7" signal-exit "^3.0.7"
strip-final-newline "^3.0.0" strip-final-newline "^3.0.0"
expand-template@^2.0.3:
version "2.0.3"
resolved "https://registry.npmmirror.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c"
integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==
extend@^3.0.0: extend@^3.0.0:
version "3.0.2" version "3.0.2"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
@@ -2984,6 +3056,11 @@ formdata-polyfill@^4.0.10:
dependencies: dependencies:
fetch-blob "^3.1.2" fetch-blob "^3.1.2"
fs-constants@^1.0.0:
version "1.0.0"
resolved "https://registry.npmmirror.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
fs.realpath@^1.0.0: fs.realpath@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
@@ -3051,6 +3128,11 @@ get-tsconfig@^4.5.0:
resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.5.0.tgz#6d52d1c7b299bd3ee9cd7638561653399ac77b0f" resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.5.0.tgz#6d52d1c7b299bd3ee9cd7638561653399ac77b0f"
integrity sha512-MjhiaIWCJ1sAU4pIQ5i5OfOuHHxVo1oYeNsWTON7jxYkod8pHocXeh+SSbmu5OZZZK73B6cbJ2XADzXehLyovQ== integrity sha512-MjhiaIWCJ1sAU4pIQ5i5OfOuHHxVo1oYeNsWTON7jxYkod8pHocXeh+SSbmu5OZZZK73B6cbJ2XADzXehLyovQ==
github-from-package@0.0.0:
version "0.0.0"
resolved "https://registry.npmmirror.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce"
integrity sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==
glob-parent@^5.1.2, glob-parent@~5.1.2: glob-parent@^5.1.2, glob-parent@~5.1.2:
version "5.1.2" version "5.1.2"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
@@ -3297,6 +3379,11 @@ iconv-lite@0.6:
dependencies: dependencies:
safer-buffer ">= 2.1.2 < 3.0.0" safer-buffer ">= 2.1.2 < 3.0.0"
ieee754@^1.1.13:
version "1.2.1"
resolved "https://registry.npmmirror.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
ignore@^5.2.0: ignore@^5.2.0:
version "5.2.4" version "5.2.4"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324"
@@ -3333,11 +3420,16 @@ inflight@^1.0.4:
once "^1.3.0" once "^1.3.0"
wrappy "1" wrappy "1"
inherits@2: inherits@2, inherits@^2.0.3, inherits@^2.0.4:
version "2.0.4" version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
ini@~1.3.0:
version "1.3.8"
resolved "https://registry.npmmirror.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
inline-style-parser@0.1.1: inline-style-parser@0.1.1:
version "0.1.1" version "0.1.1"
resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz#ec8a3b429274e9c0a1f1c4ffa9453a7fef72cea1" resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz#ec8a3b429274e9c0a1f1c4ffa9453a7fef72cea1"
@@ -3379,6 +3471,11 @@ is-arrayish@^0.2.1:
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==
is-arrayish@^0.3.1:
version "0.3.2"
resolved "https://registry.npmmirror.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03"
integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==
is-bigint@^1.0.1: is-bigint@^1.0.1:
version "1.0.4" version "1.0.4"
resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3"
@@ -4303,6 +4400,11 @@ mimic-fn@^4.0.0:
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc"
integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==
mimic-response@^3.1.0:
version "3.1.0"
resolved "https://registry.npmmirror.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9"
integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==
minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
version "3.1.2" version "3.1.2"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
@@ -4310,11 +4412,16 @@ minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
dependencies: dependencies:
brace-expansion "^1.1.7" brace-expansion "^1.1.7"
minimist@^1.2.0, minimist@^1.2.6: minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.6:
version "1.2.8" version "1.2.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3:
version "0.5.3"
resolved "https://registry.npmmirror.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113"
integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==
mri@^1.1.0: mri@^1.1.0:
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b" resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b"
@@ -4335,6 +4442,11 @@ nanoid@^3.3.4:
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c"
integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==
napi-build-utils@^1.0.1:
version "1.0.2"
resolved "https://registry.npmmirror.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806"
integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==
natural-compare@^1.4.0: natural-compare@^1.4.0:
version "1.4.0" version "1.4.0"
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
@@ -4363,6 +4475,18 @@ next@^13.4.3:
"@next/swc-win32-ia32-msvc" "13.4.3" "@next/swc-win32-ia32-msvc" "13.4.3"
"@next/swc-win32-x64-msvc" "13.4.3" "@next/swc-win32-x64-msvc" "13.4.3"
node-abi@^3.3.0:
version "3.45.0"
resolved "https://registry.npmmirror.com/node-abi/-/node-abi-3.45.0.tgz#f568f163a3bfca5aacfce1fbeee1fa2cc98441f5"
integrity sha512-iwXuFrMAcFVi/ZoZiqq8BzAdsLw9kxDfTC0HMyjXfSL/6CSDAGD5UmR7azrAgWV1zKYq7dUUMj4owusBWKLsiQ==
dependencies:
semver "^7.3.5"
node-addon-api@^6.1.0:
version "6.1.0"
resolved "https://registry.npmmirror.com/node-addon-api/-/node-addon-api-6.1.0.tgz#ac8470034e58e67d0c6f1204a18ae6995d9c0d76"
integrity sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==
node-domexception@^1.0.0: node-domexception@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5"
@@ -4474,7 +4598,7 @@ object.values@^1.1.6:
define-properties "^1.1.4" define-properties "^1.1.4"
es-abstract "^1.20.4" es-abstract "^1.20.4"
once@^1.3.0: once@^1.3.0, once@^1.3.1, once@^1.4.0:
version "1.4.0" version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
@@ -4613,6 +4737,24 @@ postcss@8.4.14:
picocolors "^1.0.0" picocolors "^1.0.0"
source-map-js "^1.0.2" source-map-js "^1.0.2"
prebuild-install@^7.1.1:
version "7.1.1"
resolved "https://registry.npmmirror.com/prebuild-install/-/prebuild-install-7.1.1.tgz#de97d5b34a70a0c81334fd24641f2a1702352e45"
integrity sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==
dependencies:
detect-libc "^2.0.0"
expand-template "^2.0.3"
github-from-package "0.0.0"
minimist "^1.2.3"
mkdirp-classic "^0.5.3"
napi-build-utils "^1.0.1"
node-abi "^3.3.0"
pump "^3.0.0"
rc "^1.2.7"
simple-get "^4.0.0"
tar-fs "^2.0.0"
tunnel-agent "^0.6.0"
prelude-ls@^1.2.1: prelude-ls@^1.2.1:
version "1.2.1" version "1.2.1"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
@@ -4644,6 +4786,14 @@ property-information@^6.0.0:
resolved "https://registry.yarnpkg.com/property-information/-/property-information-6.2.0.tgz#b74f522c31c097b5149e3c3cb8d7f3defd986a1d" resolved "https://registry.yarnpkg.com/property-information/-/property-information-6.2.0.tgz#b74f522c31c097b5149e3c3cb8d7f3defd986a1d"
integrity sha512-kma4U7AFCTwpqq5twzC1YVIDXSqg6qQK6JN0smOw8fgRy1OkMi0CYSzFmsy6dnqSenamAtj0CyXMUJ1Mf6oROg== integrity sha512-kma4U7AFCTwpqq5twzC1YVIDXSqg6qQK6JN0smOw8fgRy1OkMi0CYSzFmsy6dnqSenamAtj0CyXMUJ1Mf6oROg==
pump@^3.0.0:
version "3.0.0"
resolved "https://registry.npmmirror.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.0:
version "2.3.0" version "2.3.0"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f"
@@ -4659,6 +4809,16 @@ raf-schd@^4.0.3:
resolved "https://registry.npmmirror.com/raf-schd/-/raf-schd-4.0.3.tgz#5d6c34ef46f8b2a0e880a8fcdb743efc5bfdbc1a" resolved "https://registry.npmmirror.com/raf-schd/-/raf-schd-4.0.3.tgz#5d6c34ef46f8b2a0e880a8fcdb743efc5bfdbc1a"
integrity sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ== integrity sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==
rc@^1.2.7:
version "1.2.8"
resolved "https://registry.npmmirror.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==
dependencies:
deep-extend "^0.6.0"
ini "~1.3.0"
minimist "^1.2.0"
strip-json-comments "~2.0.1"
react-dom@^18.2.0: react-dom@^18.2.0:
version "18.2.0" version "18.2.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d"
@@ -4732,6 +4892,15 @@ react@^18.2.0:
dependencies: dependencies:
loose-envify "^1.1.0" loose-envify "^1.1.0"
readable-stream@^3.1.1, readable-stream@^3.4.0:
version "3.6.2"
resolved "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967"
integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==
dependencies:
inherits "^2.0.3"
string_decoder "^1.1.1"
util-deprecate "^1.0.1"
readdirp@~3.6.0: readdirp@~3.6.0:
version "3.6.0" version "3.6.0"
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
@@ -4960,6 +5129,11 @@ sade@^1.7.3:
dependencies: dependencies:
mri "^1.1.0" mri "^1.1.0"
safe-buffer@^5.0.1, safe-buffer@~5.2.0:
version "5.2.1"
resolved "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
safe-regex-test@^1.0.0: safe-regex-test@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295"
@@ -4995,6 +5169,13 @@ semver@^6.1.1, semver@^6.1.2, semver@^6.3.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
semver@^7.3.5, semver@^7.5.0:
version "7.5.1"
resolved "https://registry.npmmirror.com/semver/-/semver-7.5.1.tgz#c90c4d631cf74720e46b21c1d37ea07edfab91ec"
integrity sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==
dependencies:
lru-cache "^6.0.0"
semver@^7.3.7: semver@^7.3.7:
version "7.3.8" version "7.3.8"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798"
@@ -5002,6 +5183,20 @@ semver@^7.3.7:
dependencies: dependencies:
lru-cache "^6.0.0" lru-cache "^6.0.0"
sharp@^0.32.1:
version "0.32.1"
resolved "https://registry.npmmirror.com/sharp/-/sharp-0.32.1.tgz#41aa0d0b2048b2e0ee453d9fcb14ec1f408390fe"
integrity sha512-kQTFtj7ldpUqSe8kDxoGLZc1rnMFU0AO2pqbX6pLy3b7Oj8ivJIdoKNwxHVQG2HN6XpHPJqCSM2nsma2gOXvOg==
dependencies:
color "^4.2.3"
detect-libc "^2.0.1"
node-addon-api "^6.1.0"
prebuild-install "^7.1.1"
semver "^7.5.0"
simple-get "^4.0.1"
tar-fs "^2.1.1"
tunnel-agent "^0.6.0"
shebang-command@^2.0.0: shebang-command@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
@@ -5028,6 +5223,27 @@ signal-exit@^3.0.2, signal-exit@^3.0.7:
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
simple-concat@^1.0.0:
version "1.0.1"
resolved "https://registry.npmmirror.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f"
integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==
simple-get@^4.0.0, simple-get@^4.0.1:
version "4.0.1"
resolved "https://registry.npmmirror.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543"
integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==
dependencies:
decompress-response "^6.0.0"
once "^1.3.1"
simple-concat "^1.0.0"
simple-swizzle@^0.2.2:
version "0.2.2"
resolved "https://registry.npmmirror.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a"
integrity sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==
dependencies:
is-arrayish "^0.3.1"
slash@^3.0.0: slash@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
@@ -5165,6 +5381,13 @@ string.prototype.trimstart@^1.0.6:
define-properties "^1.1.4" define-properties "^1.1.4"
es-abstract "^1.20.4" es-abstract "^1.20.4"
string_decoder@^1.1.1:
version "1.3.0"
resolved "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
dependencies:
safe-buffer "~5.2.0"
strip-ansi@^6.0.0, strip-ansi@^6.0.1: strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1" version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
@@ -5194,6 +5417,11 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
strip-json-comments@~2.0.1:
version "2.0.1"
resolved "https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==
style-to-object@^0.4.0: style-to-object@^0.4.0:
version "0.4.1" version "0.4.1"
resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.4.1.tgz#53cf856f7cf7f172d72939d9679556469ba5de37" resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.4.1.tgz#53cf856f7cf7f172d72939d9679556469ba5de37"
@@ -5263,6 +5491,27 @@ tapable@^2.2.0:
resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0"
integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==
tar-fs@^2.0.0, tar-fs@^2.1.1:
version "2.1.1"
resolved "https://registry.npmmirror.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784"
integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==
dependencies:
chownr "^1.1.1"
mkdirp-classic "^0.5.2"
pump "^3.0.0"
tar-stream "^2.1.4"
tar-stream@^2.1.4:
version "2.2.0"
resolved "https://registry.npmmirror.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287"
integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==
dependencies:
bl "^4.0.3"
end-of-stream "^1.4.1"
fs-constants "^1.0.0"
inherits "^2.0.3"
readable-stream "^3.1.1"
text-table@^0.2.0: text-table@^0.2.0:
version "0.2.0" version "0.2.0"
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
@@ -5340,6 +5589,13 @@ tsutils@^3.21.0:
dependencies: dependencies:
tslib "^1.8.1" tslib "^1.8.1"
tunnel-agent@^0.6.0:
version "0.6.0"
resolved "https://registry.npmmirror.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==
dependencies:
safe-buffer "^5.0.1"
type-check@^0.4.0, type-check@~0.4.0: type-check@^0.4.0, type-check@~0.4.0:
version "0.4.0" version "0.4.0"
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"
@@ -5506,6 +5762,11 @@ use-sync-external-store@1.2.0, use-sync-external-store@^1.0.0:
resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a"
integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==
util-deprecate@^1.0.1:
version "1.0.2"
resolved "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
uuid@^9.0.0: uuid@^9.0.0:
version "9.0.0" version "9.0.0"
resolved "https://registry.npmmirror.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5" resolved "https://registry.npmmirror.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5"