mirror of
https://github.com/PinkSheep27/SBU-Hackathon.git
synced 2026-10-10 23:50:26 -04:00
added a exit button on the chat bot and make sure it still working
This commit is contained in:
@@ -17,7 +17,7 @@ export async function POST(request: Request) {
|
|||||||
catch(error){
|
catch(error){
|
||||||
console.error(error);
|
console.error(error);
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{error: "Error with the model response "},
|
{error: "Error with the model response " + String(error)},
|
||||||
{status : 500}
|
{status : 500}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-3
@@ -1,20 +1,22 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useState, useEffect, useRef, useCallback } from "react";
|
import { useState, useEffect, useRef, useCallback } from "react";
|
||||||
import { useSearchParams } from "next/navigation";
|
import { useSearchParams, useRouter } from "next/navigation";
|
||||||
import ChatInput from "../utils/component/ui/ChatInput";
|
import ChatInput from "../utils/component/ui/ChatInput";
|
||||||
import MessageWindow from "../utils/component/ui/MessageWindow";
|
import MessageWindow from "../utils/component/ui/MessageWindow";
|
||||||
import { ChatHistory, ChatSetting, Message , MessageRole } from "@/app/exportType/types";
|
import { ChatHistory, ChatSetting, Message , MessageRole } from "@/app/exportType/types";
|
||||||
|
|
||||||
export default function Home(){
|
export default function Home(){
|
||||||
const [history, setHistory] = useState<ChatHistory>([])
|
const [history, setHistory] = useState<ChatHistory>([])
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
const historyRef = useRef<ChatHistory>([]); // Create a ref for history
|
const historyRef = useRef<ChatHistory>([]); // Create a ref for history
|
||||||
const [settings] = useState<ChatSetting>({
|
const [settings] = useState<ChatSetting>({
|
||||||
temperature:1,
|
temperature:1,
|
||||||
model:"gemini-2.5-pro",
|
model:"gemini-2.5-pro",
|
||||||
sysTemInstructions:"you are a ai helper. Your goal is to expand the project idea and interact with the user on any problem or question they have with the project. You are not allow to code the project for them and stray away from your job"
|
systemInstruction:"you are a ai helper. Your goal is to expand the project idea and interact with the user on any problem or question they have with the project. You are not allow to code the project for them and stray away from your job"
|
||||||
|
|
||||||
});
|
});
|
||||||
|
const router = useRouter();
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
const initialMessageSent = useRef(false);
|
const initialMessageSent = useRef(false);
|
||||||
|
|
||||||
@@ -32,6 +34,7 @@ export default function Home(){
|
|||||||
const currentHistory = [...prevHistory, newUserMessage];
|
const currentHistory = [...prevHistory, newUserMessage];
|
||||||
|
|
||||||
const sendApiRequest = async () => {
|
const sendApiRequest = async () => {
|
||||||
|
setLoading(true);
|
||||||
try{
|
try{
|
||||||
const response = await fetch("/api/chat", {
|
const response = await fetch("/api/chat", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
@@ -49,6 +52,7 @@ export default function Home(){
|
|||||||
|
|
||||||
if (data.error) {
|
if (data.error) {
|
||||||
console.error("AI Error:", data.error);
|
console.error("AI Error:", data.error);
|
||||||
|
setLoading(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,6 +67,7 @@ export default function Home(){
|
|||||||
catch (error) {
|
catch (error) {
|
||||||
console.error("Request Failed:", error);
|
console.error("Request Failed:", error);
|
||||||
}
|
}
|
||||||
|
setLoading(false);
|
||||||
};
|
};
|
||||||
sendApiRequest();
|
sendApiRequest();
|
||||||
|
|
||||||
@@ -88,6 +93,7 @@ export default function Home(){
|
|||||||
}, 0);
|
}, 0);
|
||||||
|
|
||||||
const sendInitialApiRequest = async () => {
|
const sendInitialApiRequest = async () => {
|
||||||
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
const response = await fetch("/api/chat", {
|
const response = await fetch("/api/chat", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
@@ -105,6 +111,7 @@ export default function Home(){
|
|||||||
|
|
||||||
if (data.error) {
|
if (data.error) {
|
||||||
console.error("AI Error:", data.error);
|
console.error("AI Error:", data.error);
|
||||||
|
setLoading(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,6 +124,7 @@ export default function Home(){
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Request Failed:", error);
|
console.error("Request Failed:", error);
|
||||||
}
|
}
|
||||||
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
sendInitialApiRequest();
|
sendInitialApiRequest();
|
||||||
@@ -128,7 +136,13 @@ export default function Home(){
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col py-32">
|
<div className="flex flex-col py-32">
|
||||||
<MessageWindow history={history} />
|
<button
|
||||||
|
onClick={() => router.push('/Dashboard')}
|
||||||
|
className="absolute top-4 right-4 bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded"
|
||||||
|
>
|
||||||
|
Exit
|
||||||
|
</button>
|
||||||
|
<MessageWindow history={history} isLoading={loading} />
|
||||||
<ChatInput onSend={handleSend} onOpenSettings={() => {}} />
|
<ChatInput onSend={handleSend} onOpenSettings={() => {}} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export interface GenerateConfig{
|
|||||||
export interface ChatSetting{
|
export interface ChatSetting{
|
||||||
temperature :number;
|
temperature :number;
|
||||||
model: string;
|
model: string;
|
||||||
sysTemInstructions: string;
|
systemInstruction: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CardData {
|
export interface CardData {
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ export default function Home() {
|
|||||||
const [settings] = useState<ChatSetting>({
|
const [settings] = useState<ChatSetting>({
|
||||||
temperature: 1,
|
temperature: 1,
|
||||||
model: "gemini-2.5-flash-lite",
|
model: "gemini-2.5-flash-lite",
|
||||||
sysTemInstructions: `You are an elite hackathon idea generator. Your task is to choose at lease two track and generate five different creative, feasible, and relevant project idea.
|
systemInstruction: `You are an elite hackathon idea generator. Your task is to choose at lease two track and generate five different creative, feasible, and relevant project idea.
|
||||||
The output MUST be in Markdown format and strictly follow this structure:
|
The output MUST be in Markdown format and strictly follow this structure:
|
||||||
### Project Idea Title
|
### Project Idea Title
|
||||||
**Track** [print out the track you used]
|
**Track** [print out the track you used]
|
||||||
|
|||||||
+5
-3
@@ -5,11 +5,13 @@ import { useRouter } from 'next/navigation';
|
|||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import ProtectedNavButton from "../components/ProtectedNavButton";
|
import ProtectedNavButton from "../components/ProtectedNavButton";
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
import { style } from 'framer-motion/client';
|
||||||
|
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
return (
|
return (
|
||||||
<div className="flex min-h-screen items-center justify-center bg-zinc-50 font-sans dark:bg-black">
|
<div className="flex min-h-screen items-center justify-center bg-zinc-50 font-sans dark:bg-black">
|
||||||
<header className="absolute top-6 left-8 right-8 flex items-center justify-between text-sm font-medium text-zinc-700 dark:text-zinc-300">
|
<header className="absolute top-6 left-8 right-8 flex items-center justify-between text-sm font-medium text-zinc-700 dark:text-zinc-300 background-blue-300">
|
||||||
<Image
|
<Image
|
||||||
className=""
|
className=""
|
||||||
src="/logo.svg"
|
src="/logo.svg"
|
||||||
@@ -19,10 +21,10 @@ export default function Page() {
|
|||||||
priority
|
priority
|
||||||
/>
|
/>
|
||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
<Link href = "/auth/login" className="hover:text-blue-600 dark:hover:text-blue-400 transition-colors">
|
<Link href = "/auth/login" className="hover:text-blue-600 dark:hover:text-blue-400 transition-colors container">
|
||||||
Sign in
|
Sign in
|
||||||
</Link>
|
</Link>
|
||||||
<Link href = "/auth/logout" className="hover:text-blue-600 dark:hover:text-blue-400 transition-colors">
|
<Link href = "/auth/logout" className="hover:text-blue-600 dark:hover:text-blue-400 transition-colors container">
|
||||||
Log out
|
Log out
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,11 +4,12 @@ import { ChatHistory } from "@/app/exportType/types";
|
|||||||
import {User, Bot} from "lucide-react"
|
import {User, Bot} from "lucide-react"
|
||||||
|
|
||||||
interface MessageWindowProps{
|
interface MessageWindowProps{
|
||||||
history :ChatHistory
|
history :ChatHistory;
|
||||||
|
isLoading: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function MessageWindow({history}:MessageWindowProps){
|
export default function MessageWindow({history, isLoading}:MessageWindowProps){
|
||||||
const messageEndRef = useRef<HTMLDivElement>(null);
|
const messageEndRef = useRef<HTMLDivVElement>(null);
|
||||||
|
|
||||||
useEffect(() =>{
|
useEffect(() =>{
|
||||||
messageEndRef.current?.scrollIntoView({behavior:"smooth"});
|
messageEndRef.current?.scrollIntoView({behavior:"smooth"});
|
||||||
@@ -52,6 +53,20 @@ export default function MessageWindow({history}:MessageWindowProps){
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
||||||
|
{isLoading && (
|
||||||
|
<div className="flex justify-start">
|
||||||
|
<div className="mr-2">
|
||||||
|
<div className="flex items-center justify-center w-8 h-8 rounded-full bg-gray">
|
||||||
|
<Bot size={15} className="text-gray-700" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="px-4 py-2 shadow-sm rounded-lg bg-white text-gray-800 rounded-bl-none max-w-xs sm:max-w-md">
|
||||||
|
<div className="whitespace-pre-wrap break-words">
|
||||||
|
<span>Loading...</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
{/* Invisible element to help scroll to bottom */}
|
{/* Invisible element to help scroll to bottom */}
|
||||||
<div ref={messageEndRef} />
|
<div ref={messageEndRef} />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export async function chatToGemini(
|
|||||||
):Promise<string>{
|
):Promise<string>{
|
||||||
const model = genAI.getGenerativeModel({
|
const model = genAI.getGenerativeModel({
|
||||||
model:settings.model || "gemini-2.5-flash",
|
model:settings.model || "gemini-2.5-flash",
|
||||||
systemInstruction: settings.sysTemInstructions || "you are going to create a project idea, explain it in summery first before going to detail",
|
systemInstruction: settings.systemInstruction || "you are going to create a project idea, explain it in summery first before going to detail",
|
||||||
});
|
});
|
||||||
|
|
||||||
const generationConfig:GenerateConfig = {
|
const generationConfig:GenerateConfig = {
|
||||||
|
|||||||
Generated
+12
@@ -66,6 +66,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz",
|
||||||
"integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
|
"integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/code-frame": "^7.27.1",
|
"@babel/code-frame": "^7.27.1",
|
||||||
"@babel/generator": "^7.28.5",
|
"@babel/generator": "^7.28.5",
|
||||||
@@ -1470,6 +1471,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz",
|
||||||
"integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==",
|
"integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"csstype": "^3.0.2"
|
"csstype": "^3.0.2"
|
||||||
}
|
}
|
||||||
@@ -1526,6 +1528,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.3.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.3.tgz",
|
||||||
"integrity": "sha512-6m1I5RmHBGTnUGS113G04DMu3CpSdxCAU/UvtjNWL4Nuf3MW9tQhiJqRlHzChIkhy6kZSAQmc+I1bcGjE3yNKg==",
|
"integrity": "sha512-6m1I5RmHBGTnUGS113G04DMu3CpSdxCAU/UvtjNWL4Nuf3MW9tQhiJqRlHzChIkhy6kZSAQmc+I1bcGjE3yNKg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/scope-manager": "8.46.3",
|
"@typescript-eslint/scope-manager": "8.46.3",
|
||||||
"@typescript-eslint/types": "8.46.3",
|
"@typescript-eslint/types": "8.46.3",
|
||||||
@@ -2023,6 +2026,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
|
||||||
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"acorn": "bin/acorn"
|
"acorn": "bin/acorn"
|
||||||
},
|
},
|
||||||
@@ -2341,6 +2345,7 @@
|
|||||||
"url": "https://github.com/sponsors/ai"
|
"url": "https://github.com/sponsors/ai"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"baseline-browser-mapping": "^2.8.19",
|
"baseline-browser-mapping": "^2.8.19",
|
||||||
"caniuse-lite": "^1.0.30001751",
|
"caniuse-lite": "^1.0.30001751",
|
||||||
@@ -2870,6 +2875,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.1.tgz",
|
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.1.tgz",
|
||||||
"integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==",
|
"integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/eslint-utils": "^4.8.0",
|
"@eslint-community/eslint-utils": "^4.8.0",
|
||||||
"@eslint-community/regexpp": "^4.12.1",
|
"@eslint-community/regexpp": "^4.12.1",
|
||||||
@@ -3047,6 +3053,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz",
|
||||||
"integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==",
|
"integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@rtsao/scc": "^1.1.0",
|
"@rtsao/scc": "^1.1.0",
|
||||||
"array-includes": "^3.1.9",
|
"array-includes": "^3.1.9",
|
||||||
@@ -5123,6 +5130,7 @@
|
|||||||
"version": "19.2.0",
|
"version": "19.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz",
|
||||||
"integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==",
|
"integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
@@ -5131,6 +5139,7 @@
|
|||||||
"version": "19.2.0",
|
"version": "19.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz",
|
||||||
"integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==",
|
"integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"scheduler": "^0.27.0"
|
"scheduler": "^0.27.0"
|
||||||
},
|
},
|
||||||
@@ -5776,6 +5785,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
|
||||||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
},
|
},
|
||||||
@@ -5927,6 +5937,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
||||||
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsc": "bin/tsc",
|
"tsc": "bin/tsc",
|
||||||
"tsserver": "bin/tsserver"
|
"tsserver": "bin/tsserver"
|
||||||
@@ -6187,6 +6198,7 @@
|
|||||||
"resolved": "https://registry.npmjs.org/zod/-/zod-4.1.12.tgz",
|
"resolved": "https://registry.npmjs.org/zod/-/zod-4.1.12.tgz",
|
||||||
"integrity": "sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==",
|
"integrity": "sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"peer": true,
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/colinhacks"
|
"url": "https://github.com/sponsors/colinhacks"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user