WIP: Interactive charts and MapBox integration
This commit is contained in:
parent
a3415adee1
commit
065bbe7887
@ -1,6 +1,5 @@
|
||||
'use server';
|
||||
|
||||
import { OpenAI } from 'openai';
|
||||
import { generateObject } from 'ai';
|
||||
import { createOpenAI as createGroq } from '@ai-sdk/openai';
|
||||
import { z } from 'zod';
|
||||
@ -15,7 +14,7 @@ export async function suggestQuestions(history: any[]) {
|
||||
'use server';
|
||||
|
||||
const { object } = await generateObject({
|
||||
model: groq('llama-3.2-90b-text-preview'),
|
||||
model: groq('llama-3.2-11b-text-preview'),
|
||||
temperature: 0,
|
||||
system:
|
||||
`You are a search engine query generator. You 'have' to create only '3' questions for the search engine based on the message history which has been provided to you.
|
||||
|
||||
@ -5,10 +5,10 @@ import {
|
||||
convertToCoreMessages,
|
||||
streamText,
|
||||
tool,
|
||||
experimental_createProviderRegistry
|
||||
experimental_createProviderRegistry,
|
||||
} from "ai";
|
||||
import { BlobRequestAbortedError, put } from '@vercel/blob';
|
||||
import { CodeInterpreter } from "@e2b/code-interpreter";
|
||||
import CodeInterpreter from "@e2b/code-interpreter";
|
||||
import FirecrawlApp from '@mendable/firecrawl-js';
|
||||
|
||||
// Allow streaming responses up to 60 seconds
|
||||
@ -38,19 +38,30 @@ type SearchResultImage =
|
||||
number_of_results?: number
|
||||
}
|
||||
|
||||
// Helper function to geocode an address
|
||||
const geocodeAddress = async (address: string) => {
|
||||
const mapboxToken = process.env.MAPBOX_ACCESS_TOKEN;
|
||||
const response = await fetch(
|
||||
`https://api.mapbox.com/geocoding/v5/mapbox.places/${encodeURIComponent(address)}.json?access_token=${mapboxToken}`
|
||||
);
|
||||
const data = await response.json();
|
||||
return data.features[0];
|
||||
};
|
||||
|
||||
export async function POST(req: Request) {
|
||||
const { messages, model } = await req.json();
|
||||
|
||||
const provider = model.split(":")[0];
|
||||
|
||||
const result = await streamText({
|
||||
maxSteps: 10,
|
||||
model: registry.languageModel(model),
|
||||
messages: convertToCoreMessages(messages),
|
||||
temperature: provider === "azure" ? 0.72 : 0,
|
||||
topP: 0.5,
|
||||
frequencyPenalty: 0,
|
||||
presencePenalty: 0,
|
||||
experimental_activeTools: ["get_weather_data","programming", "web_search", "text_translate"],
|
||||
experimental_activeTools: ["get_weather_data", "programming", "web_search", "text_translate"],
|
||||
system: `
|
||||
You are an expert AI web search engine called MiniPerplx, that helps users find information on the internet with no bullshit talks.
|
||||
Always start with running the tool(s) and then and then only write your response AT ALL COSTS!!
|
||||
@ -365,7 +376,7 @@ When asked a "What is" question, maintain the same format as the question and an
|
||||
}),
|
||||
execute: async ({ code }: { code: string }) => {
|
||||
const sandbox = await CodeInterpreter.create();
|
||||
const execution = await sandbox.notebook.execCell(code);
|
||||
const execution = await sandbox.runCode(code);
|
||||
let message = "";
|
||||
let images = [];
|
||||
|
||||
@ -424,98 +435,177 @@ When asked a "What is" question, maintain the same format as the question and an
|
||||
}
|
||||
}
|
||||
|
||||
sandbox.close();
|
||||
return { message: message.trim(), images };
|
||||
if (execution.error) {
|
||||
message += `Error: ${execution.error}\n`;
|
||||
console.log("Error: ", execution.error);
|
||||
}
|
||||
|
||||
console.log(execution.results[0].chart)
|
||||
if (execution.results[0].chart) {
|
||||
execution.results[0].chart.elements.map((element: any) => {
|
||||
console.log(element.points)
|
||||
})
|
||||
}
|
||||
|
||||
return { message: message.trim(), images, chart: execution.results[0].chart ?? "" };
|
||||
},
|
||||
}),
|
||||
nearby_search: tool({
|
||||
description: "Search for nearby places using Google Maps API.",
|
||||
description: "Search for nearby places using Mapbox API.",
|
||||
parameters: z.object({
|
||||
location: z.string().describe("The location to search near (e.g., 'New York City' or '1600 Amphitheatre Parkway, Mountain View, CA')."),
|
||||
type: z.string().describe("The type of place to search for (e.g., restaurant, cafe, park)."),
|
||||
keyword: z.string().describe("An optional keyword to refine the search."),
|
||||
radius: z.number().default(3000).describe("The radius of the search area in meters (max 50000, default 3000)."),
|
||||
}),
|
||||
execute: async ({ location, type, keyword, radius }: { location: string; type: string; keyword?: string; radius: number }) => {
|
||||
const apiKey = process.env.GOOGLE_MAPS_API_KEY;
|
||||
execute: async ({ location, type, keyword, radius }: {
|
||||
location: string;
|
||||
type: string;
|
||||
keyword?: string;
|
||||
radius: number;
|
||||
}) => {
|
||||
const mapboxToken = process.env.MAPBOX_ACCESS_TOKEN;
|
||||
|
||||
// First, use the Geocoding API to get the coordinates
|
||||
const geocodeUrl = `https://maps.googleapis.com/maps/api/geocode/json?address=${encodeURIComponent(location)}&key=${apiKey}`;
|
||||
const geocodeResponse = await fetch(geocodeUrl);
|
||||
const geocodeData = await geocodeResponse.json();
|
||||
|
||||
if (geocodeData.status !== "OK" || !geocodeData.results[0]) {
|
||||
throw new Error("Failed to geocode the location");
|
||||
}
|
||||
|
||||
const { lat, lng } = geocodeData.results[0].geometry.location;
|
||||
|
||||
// perform the nearby search
|
||||
let searchUrl = `https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${lat},${lng}&radius=${radius}&type=${type}&key=${apiKey}`;
|
||||
// First geocode the location
|
||||
const locationData = await geocodeAddress(location);
|
||||
const [lng, lat] = locationData.center;
|
||||
|
||||
// Construct search query
|
||||
let searchQuery = type;
|
||||
if (keyword) {
|
||||
searchUrl += `&keyword=${encodeURIComponent(keyword)}`;
|
||||
searchQuery = `${keyword} ${type}`;
|
||||
}
|
||||
|
||||
const searchResponse = await fetch(searchUrl);
|
||||
const searchData = await searchResponse.json();
|
||||
// Search for places using Mapbox Geocoding API
|
||||
const response = await fetch(
|
||||
`https://api.mapbox.com/geocoding/v5/mapbox.places/${encodeURIComponent(searchQuery)}.json?proximity=${lng},${lat}&limit=10&types=poi&access_token=${mapboxToken}`
|
||||
);
|
||||
const data = await response.json();
|
||||
|
||||
// Filter results by distance
|
||||
const radiusInDegrees = radius / 111320; // Approximate conversion from meters to degrees
|
||||
const results = data.features
|
||||
.filter((feature: any) => {
|
||||
const [placeLng, placeLat] = feature.center;
|
||||
const distance = Math.sqrt(
|
||||
Math.pow(placeLng - lng, 2) + Math.pow(placeLat - lat, 2)
|
||||
);
|
||||
return distance <= radiusInDegrees;
|
||||
})
|
||||
.map((feature: any) => ({
|
||||
name: feature.text,
|
||||
vicinity: feature.place_name,
|
||||
place_id: feature.id,
|
||||
location: {
|
||||
lat: feature.center[1],
|
||||
lng: feature.center[0]
|
||||
},
|
||||
// Note: Mapbox doesn't provide ratings, so we'll exclude those
|
||||
}));
|
||||
|
||||
return {
|
||||
results: searchData.results.slice(0, 5).map((place: any) => ({
|
||||
name: place.name,
|
||||
vicinity: place.vicinity,
|
||||
rating: place.rating,
|
||||
user_ratings_total: place.user_ratings_total,
|
||||
place_id: place.place_id,
|
||||
location: place.geometry.location,
|
||||
})),
|
||||
results: results.slice(0, 5),
|
||||
center: { lat, lng },
|
||||
formatted_address: geocodeData.results[0].formatted_address,
|
||||
formatted_address: locationData.place_name,
|
||||
};
|
||||
},
|
||||
}),
|
||||
find_place: tool({
|
||||
description: "Find a specific place using Google Maps API.",
|
||||
description: "Find a specific place using Mapbox API.",
|
||||
parameters: z.object({
|
||||
input: z.string().describe("The place to search for (e.g., 'Museum of Contemporary Art Australia')."),
|
||||
inputtype: z.enum(["textquery", "phonenumber"]).describe("The type of input (textquery or phonenumber)."),
|
||||
}),
|
||||
execute: async ({ input, inputtype }: { input: string; inputtype: "textquery" | "phonenumber" }) => {
|
||||
console.log("input", input);
|
||||
const apiKey = process.env.GOOGLE_MAPS_API_KEY;
|
||||
const url = `https://maps.googleapis.com/maps/api/place/findplacefromtext/json?fields=formatted_address,name,rating,opening_hours,geometry&input=${encodeURIComponent(input)}&inputtype=${inputtype}&key=${apiKey}`;
|
||||
execute: async ({ input, inputtype }: {
|
||||
input: string;
|
||||
inputtype: "textquery" | "phonenumber";
|
||||
}) => {
|
||||
const mapboxToken = process.env.MAPBOX_ACCESS_TOKEN;
|
||||
|
||||
const response = await fetch(url);
|
||||
let searchEndpoint = `https://api.mapbox.com/geocoding/v5/mapbox.places/${encodeURIComponent(input)}.json`;
|
||||
if (inputtype === "phonenumber") {
|
||||
// Note: Mapbox doesn't support phone number search directly
|
||||
// We'll just search the number as text
|
||||
searchEndpoint = `https://api.mapbox.com/geocoding/v5/mapbox.places/${encodeURIComponent(input)}.json`;
|
||||
}
|
||||
|
||||
const response = await fetch(`${searchEndpoint}?types=poi&access_token=${mapboxToken}`);
|
||||
const data = await response.json();
|
||||
|
||||
return data;
|
||||
if (!data.features || data.features.length === 0) {
|
||||
return { candidates: [] };
|
||||
}
|
||||
|
||||
const place = data.features[0];
|
||||
|
||||
return {
|
||||
candidates: [{
|
||||
name: place.text,
|
||||
formatted_address: place.place_name,
|
||||
geometry: {
|
||||
location: {
|
||||
lat: place.center[1],
|
||||
lng: place.center[0]
|
||||
}
|
||||
},
|
||||
// Note: Mapbox doesn't provide these fields
|
||||
rating: null,
|
||||
opening_hours: null
|
||||
}]
|
||||
};
|
||||
},
|
||||
}),
|
||||
text_search: tool({
|
||||
description: "Perform a text-based search for places using Google Maps API.",
|
||||
description: "Perform a text-based search for places using Mapbox API.",
|
||||
parameters: z.object({
|
||||
query: z.string().describe("The search query (e.g., '123 main street')."),
|
||||
location: z.string().describe("The location to center the search (e.g., '42.3675294,-71.186966')."),
|
||||
radius: z.number().describe("The radius of the search area in meters (max 50000)."),
|
||||
}),
|
||||
execute: async ({ query, location, radius }: { query: string; location?: string; radius?: number }) => {
|
||||
const apiKey = process.env.GOOGLE_MAPS_API_KEY;
|
||||
console.log("query", query);
|
||||
console.log("location", location);
|
||||
console.log("radius", radius);
|
||||
let url = `https://maps.googleapis.com/maps/api/place/textsearch/json?query=${encodeURIComponent(query)}&key=${apiKey}`;
|
||||
execute: async ({ query, location, radius }: {
|
||||
query: string;
|
||||
location?: string;
|
||||
radius?: number;
|
||||
}) => {
|
||||
const mapboxToken = process.env.MAPBOX_ACCESS_TOKEN;
|
||||
|
||||
let proximity = '';
|
||||
if (location) {
|
||||
url += `&location=${encodeURIComponent(location)}`;
|
||||
}
|
||||
if (radius) {
|
||||
url += `&radius=${radius}`;
|
||||
const [lng, lat] = location.split(',').map(Number);
|
||||
proximity = `&proximity=${lng},${lat}`;
|
||||
}
|
||||
|
||||
const response = await fetch(url);
|
||||
const response = await fetch(
|
||||
`https://api.mapbox.com/geocoding/v5/mapbox.places/${encodeURIComponent(query)}.json?types=poi${proximity}&access_token=${mapboxToken}`
|
||||
);
|
||||
const data = await response.json();
|
||||
|
||||
return data;
|
||||
// If location and radius provided, filter results by distance
|
||||
let results = data.features;
|
||||
if (location && radius) {
|
||||
const [centerLng, centerLat] = location.split(',').map(Number);
|
||||
const radiusInDegrees = radius / 111320;
|
||||
results = results.filter((feature: any) => {
|
||||
const [placeLng, placeLat] = feature.center;
|
||||
const distance = Math.sqrt(
|
||||
Math.pow(placeLng - centerLng, 2) + Math.pow(placeLat - centerLat, 2)
|
||||
);
|
||||
return distance <= radiusInDegrees;
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
results: results.map((feature: any) => ({
|
||||
name: feature.text,
|
||||
formatted_address: feature.place_name,
|
||||
geometry: {
|
||||
location: {
|
||||
lat: feature.center[1],
|
||||
lng: feature.center[0]
|
||||
}
|
||||
}
|
||||
}))
|
||||
};
|
||||
},
|
||||
}),
|
||||
text_translate: tool({
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { cohere } from '@ai-sdk/cohere'
|
||||
import { convertToCoreMessages, streamText, tool } from "ai";
|
||||
import { CodeInterpreter } from "@e2b/code-interpreter";
|
||||
import CodeInterpreter from "@e2b/code-interpreter";
|
||||
import { z } from "zod";
|
||||
import { geolocation } from "@vercel/functions";
|
||||
|
||||
@ -272,7 +272,7 @@ Remember to always run the appropriate tool(s) first and compose your response b
|
||||
}),
|
||||
execute: async ({ code }: { code: string }) => {
|
||||
const sandbox = await CodeInterpreter.create();
|
||||
const execution = await sandbox.notebook.execCell(code);
|
||||
const execution = await sandbox.runCode(code);
|
||||
let message = "";
|
||||
let images = [];
|
||||
|
||||
@ -307,7 +307,6 @@ Remember to always run the appropriate tool(s) first and compose your response b
|
||||
}
|
||||
}
|
||||
|
||||
sandbox.close();
|
||||
return { message: message.trim(), images };
|
||||
},
|
||||
}),
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import "./globals.css";
|
||||
import 'katex/dist/katex.min.css';
|
||||
import 'mapbox-gl/dist/mapbox-gl.css';
|
||||
import { Metadata, Viewport } from "next";
|
||||
import { Toaster } from "sonner";
|
||||
import { Inter, Instrument_Serif, IBM_Plex_Mono } from 'next/font/google';
|
||||
|
||||
@ -19,7 +19,7 @@ import Marked, { ReactRenderer } from 'marked-react';
|
||||
import { track } from '@vercel/analytics';
|
||||
import { useSearchParams } from 'next/navigation';
|
||||
import { useChat } from 'ai/react';
|
||||
import { ChatRequestOptions, CreateMessage, Message, ToolInvocation } from 'ai';
|
||||
import { ToolInvocation } from 'ai';
|
||||
import { toast } from 'sonner';
|
||||
import { motion, AnimatePresence } from 'framer-motion';
|
||||
import Image from 'next/image';
|
||||
@ -88,32 +88,17 @@ import {
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Line, LineChart, CartesianGrid, XAxis, YAxis, ResponsiveContainer } from "recharts";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import {
|
||||
ChartConfig,
|
||||
ChartContainer,
|
||||
ChartTooltip,
|
||||
ChartTooltipContent,
|
||||
} from "@/components/ui/chart";
|
||||
import { GitHubLogoIcon, PlusCircledIcon } from '@radix-ui/react-icons';
|
||||
import { Skeleton } from '@/components/ui/skeleton';
|
||||
import Link from 'next/link';
|
||||
import { Dialog, DialogContent } from "@/components/ui/dialog";
|
||||
import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from "@/components/ui/carousel";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu"
|
||||
import { cn } from '@/lib/utils';
|
||||
import {
|
||||
Table,
|
||||
@ -124,6 +109,8 @@ import {
|
||||
import Autoplay from 'embla-carousel-autoplay';
|
||||
import FormComponent from '@/components/ui/form-component';
|
||||
import WeatherChart from '@/components/weather-chart';
|
||||
import { MapContainer } from '@/components/map-components';
|
||||
import InteractiveChart from '@/components/interactive-charts';
|
||||
|
||||
export const maxDuration = 60;
|
||||
|
||||
@ -884,7 +871,7 @@ GPT-4o has been re-enabled! You can use it by selecting the model from the dropd
|
||||
<MapPin className="h-5 w-5 text-neutral-700 dark:text-neutral-300 animate-pulse" />
|
||||
<span className="text-neutral-700 dark:text-neutral-300 text-lg">Searching nearby places...</span>
|
||||
</div>
|
||||
<div className="flex space-x-1">
|
||||
<motion.div className="flex space-x-1">
|
||||
{[0, 1, 2].map((index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
@ -899,49 +886,18 @@ GPT-4o has been re-enabled! You can use it by selecting the model from the dropd
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<Card className="w-full my-4 overflow-hidden bg-white dark:bg-neutral-800 border-neutral-200 dark:border-neutral-700">
|
||||
<CardHeader>
|
||||
<Skeleton className="h-6 w-3/4 bg-neutral-200 dark:bg-neutral-700" />
|
||||
</CardHeader>
|
||||
<CardContent className="p-0 rounded-t-none rounded-b-xl">
|
||||
<MapSkeleton />
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Card className="w-full my-4 overflow-hidden bg-white dark:bg-neutral-800 border-neutral-200 dark:border-neutral-700">
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-2 text-neutral-800 dark:text-neutral-100">
|
||||
<MapPin className="h-5 w-5 text-primary" />
|
||||
<span>Nearby {args.type ? args.type.charAt(0).toUpperCase() + args.type.slice(1) + 's' : 'Places'}</span>
|
||||
{args.keyword && <Badge variant="secondary" className="bg-neutral-200 dark:bg-neutral-700 text-neutral-800 dark:text-neutral-200">{args.keyword}</Badge>}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="p-0">
|
||||
<MapComponent center={result.center} places={result.results} />
|
||||
<Accordion type="single" collapsible className="w-full">
|
||||
<AccordionItem value="place-details">
|
||||
<AccordionTrigger className="px-4 text-neutral-800 dark:text-neutral-200">Place Details</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
<div className="px-4 space-y-4 max-h-64 overflow-y-auto">
|
||||
{result.results.map((place: any, placeIndex: number) => (
|
||||
<PlaceDetails key={placeIndex} place={place} />
|
||||
))}
|
||||
</div>
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<MapContainer
|
||||
title={`Nearby ${args.type ? args.type.charAt(0).toUpperCase() + args.type.slice(1) + 's' : 'Places'}`}
|
||||
center={result.center}
|
||||
places={result.results}
|
||||
loading={isLoading}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@ -973,7 +929,19 @@ GPT-4o has been re-enabled! You can use it by selecting the model from the dropd
|
||||
);
|
||||
}
|
||||
|
||||
return <FindPlaceResult result={result} />;
|
||||
const place = result.candidates[0];
|
||||
return (
|
||||
<MapContainer
|
||||
title={place.name}
|
||||
center={place.geometry.location}
|
||||
places={[{
|
||||
name: place.name,
|
||||
location: place.geometry.location,
|
||||
rating: place.rating,
|
||||
vicinity: place.formatted_address
|
||||
}]}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (toolInvocation.toolName === 'text_search') {
|
||||
@ -1004,7 +972,18 @@ GPT-4o has been re-enabled! You can use it by selecting the model from the dropd
|
||||
);
|
||||
}
|
||||
|
||||
return <TextSearchResult result={result} />;
|
||||
const centerLocation = result.results[0]?.geometry?.location;
|
||||
return (
|
||||
<MapContainer
|
||||
title="Search Results"
|
||||
center={centerLocation}
|
||||
places={result.results.map((place: any) => ({
|
||||
name: place.name,
|
||||
location: place.geometry.location,
|
||||
vicinity: place.formatted_address
|
||||
}))}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (toolInvocation.toolName === 'get_weather_data') {
|
||||
@ -1091,6 +1070,14 @@ GPT-4o has been re-enabled! You can use it by selecting the model from the dropd
|
||||
Images
|
||||
</TabsTrigger>
|
||||
)}
|
||||
{result?.chart && (
|
||||
<TabsTrigger
|
||||
value="visualization"
|
||||
className="px-4 py-2 text-sm data-[state=active]:bg-white dark:data-[state=active]:bg-neutral-800 data-[state=active]:border-b data-[state=active]:border-blue-500 rounded-none shadow-sm"
|
||||
>
|
||||
Visualization
|
||||
</TabsTrigger>
|
||||
)}
|
||||
</TabsList>
|
||||
<TabsContent value="code" className="p-0 m-0 rounded-none">
|
||||
<div className="relative">
|
||||
@ -1178,6 +1165,19 @@ GPT-4o has been re-enabled! You can use it by selecting the model from the dropd
|
||||
</div>
|
||||
</TabsContent>
|
||||
)}
|
||||
{result?.chart && (
|
||||
<TabsContent value="visualization" className="p-4 m-0 bg-white dark:bg-neutral-800">
|
||||
<InteractiveChart
|
||||
type={result.chart.type as 'bar' | 'line'}
|
||||
title={result.chart.title}
|
||||
xLabel={result.chart.x_label}
|
||||
yLabel={result.chart.y_label}
|
||||
xUnit={result.chart.x_unit}
|
||||
yUnit={result.chart.y_unit}
|
||||
elements={result.chart.elements}
|
||||
/>
|
||||
</TabsContent>
|
||||
)}
|
||||
</Tabs>
|
||||
</div>
|
||||
</AccordionContent>
|
||||
|
||||
219
components/interactive-charts.tsx
Normal file
219
components/interactive-charts.tsx
Normal file
@ -0,0 +1,219 @@
|
||||
// components/interactive-charts.tsx
|
||||
import React from 'react';
|
||||
import ReactECharts from 'echarts-for-react';
|
||||
import * as echarts from 'echarts';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { useTheme } from 'next-themes';
|
||||
|
||||
interface BaseChartProps {
|
||||
title: string;
|
||||
xLabel?: string;
|
||||
yLabel?: string;
|
||||
xUnit?: string | null;
|
||||
yUnit?: string | null;
|
||||
x_ticks?: (number | string)[];
|
||||
x_tick_labels?: string[];
|
||||
x_scale?: string;
|
||||
y_ticks?: (number | string)[];
|
||||
y_tick_labels?: string[];
|
||||
y_scale?: string;
|
||||
}
|
||||
|
||||
type BarChartElement = {
|
||||
label: string;
|
||||
group: string;
|
||||
value: number;
|
||||
};
|
||||
|
||||
type PointData = {
|
||||
label: string;
|
||||
points: [number | string, number | string][];
|
||||
};
|
||||
|
||||
interface ChartProps extends BaseChartProps {
|
||||
type: 'bar' | 'line';
|
||||
elements: BarChartElement[] | PointData[];
|
||||
}
|
||||
|
||||
const InteractiveChart: React.FC<ChartProps> = ({
|
||||
type,
|
||||
title,
|
||||
xLabel = '',
|
||||
yLabel = '',
|
||||
xUnit = '',
|
||||
yUnit = '',
|
||||
elements,
|
||||
x_ticks,
|
||||
x_tick_labels,
|
||||
x_scale = 'value',
|
||||
y_ticks,
|
||||
y_tick_labels,
|
||||
y_scale = 'value',
|
||||
}) => {
|
||||
const { theme } = useTheme();
|
||||
|
||||
const getChartOptions = () => {
|
||||
if (!elements || elements.length === 0) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const textColor = theme === 'dark' ? '#e5e5e5' : '#171717';
|
||||
const axisLineColor = theme === 'dark' ? '#404040' : '#e5e5e5';
|
||||
|
||||
if (type === 'line') {
|
||||
const lineElements = elements as PointData[];
|
||||
|
||||
const xAxisType = x_scale === 'datetime' ? 'time' : x_scale;
|
||||
|
||||
const series = lineElements.map(el => ({
|
||||
name: el.label,
|
||||
type: 'line',
|
||||
data: el.points.map(point => {
|
||||
const xValue =
|
||||
xAxisType === 'time'
|
||||
? new Date(point[0] as string).getTime()
|
||||
: point[0];
|
||||
return [xValue, point[1]];
|
||||
}),
|
||||
smooth: true,
|
||||
}));
|
||||
|
||||
return {
|
||||
title: {
|
||||
text: title || '',
|
||||
textStyle: { color: textColor },
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'cross',
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
data: lineElements.map(el => el.label),
|
||||
textStyle: { color: textColor },
|
||||
},
|
||||
xAxis: {
|
||||
type: xAxisType,
|
||||
name: xLabel,
|
||||
nameTextStyle: { color: textColor },
|
||||
axisLabel: {
|
||||
color: textColor,
|
||||
formatter: (value: number) => {
|
||||
if (xAxisType === 'time') {
|
||||
return echarts.format.formatTime('yyyy-MM', value);
|
||||
}
|
||||
return xUnit ? `${value} ${xUnit}` : `${value}`;
|
||||
},
|
||||
},
|
||||
axisLine: { lineStyle: { color: axisLineColor } },
|
||||
},
|
||||
yAxis: {
|
||||
type: y_scale,
|
||||
name: yLabel,
|
||||
nameTextStyle: { color: textColor },
|
||||
axisLabel: {
|
||||
color: textColor,
|
||||
formatter: (value: number) =>
|
||||
yUnit ? `${value} ${yUnit}` : `${value}`,
|
||||
},
|
||||
axisLine: { lineStyle: { color: axisLineColor } },
|
||||
...(y_ticks && {
|
||||
min: Math.min(...(y_ticks as number[])),
|
||||
max: Math.max(...(y_ticks as number[])),
|
||||
}),
|
||||
},
|
||||
series,
|
||||
};
|
||||
} else if (type === 'bar') {
|
||||
const barElements = elements as BarChartElement[];
|
||||
|
||||
const groups = Array.from(new Set(barElements.map(el => el.group))).filter(Boolean);
|
||||
const labels = Array.from(new Set(barElements.map(el => el.label))).filter(Boolean);
|
||||
|
||||
const series = groups.map(group => ({
|
||||
name: group,
|
||||
type: 'bar',
|
||||
data: labels.map(label => {
|
||||
const el = barElements.find(e => e.group === group && e.label === label);
|
||||
return el ? el.value : 0;
|
||||
}),
|
||||
}));
|
||||
|
||||
return {
|
||||
title: {
|
||||
text: title || '',
|
||||
textStyle: { color: textColor },
|
||||
},
|
||||
tooltip: { trigger: 'axis' },
|
||||
legend: {
|
||||
data: groups,
|
||||
textStyle: { color: textColor },
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: labels,
|
||||
name: xLabel,
|
||||
nameTextStyle: { color: textColor },
|
||||
axisLabel: { color: textColor },
|
||||
axisLine: { lineStyle: { color: axisLineColor } },
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
name: yLabel,
|
||||
nameTextStyle: { color: textColor },
|
||||
axisLabel: {
|
||||
color: textColor,
|
||||
formatter: (value: number) =>
|
||||
yUnit ? `${value} ${yUnit}` : value.toString(),
|
||||
},
|
||||
axisLine: { lineStyle: { color: axisLineColor } },
|
||||
...(y_ticks && {
|
||||
min: Math.min(...(y_ticks as number[])),
|
||||
max: Math.max(...(y_ticks as number[])),
|
||||
}),
|
||||
},
|
||||
series,
|
||||
};
|
||||
}
|
||||
|
||||
return {};
|
||||
};
|
||||
|
||||
const options = getChartOptions();
|
||||
|
||||
if (!options || Object.keys(options).length === 0) {
|
||||
return (
|
||||
<Card className="w-full bg-white dark:bg-neutral-800">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-neutral-800 dark:text-neutral-200">
|
||||
{title || 'Chart'}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-neutral-600 dark:text-neutral-400">
|
||||
No data available to display the chart.
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Card className="w-full bg-white dark:bg-neutral-800">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-neutral-800 dark:text-neutral-200">
|
||||
{title || 'Chart'}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ReactECharts
|
||||
option={options}
|
||||
style={{ height: '400px', width: '100%' }}
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
export default InteractiveChart;
|
||||
@ -1,207 +1,189 @@
|
||||
import React, { useRef, useState, useEffect, useCallback, memo } from 'react';
|
||||
import { Card, CardHeader, CardContent, CardTitle } from "@/components/ui/card";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import mapboxgl from 'mapbox-gl';
|
||||
import 'mapbox-gl/dist/mapbox-gl.css';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { MapPin, Star } from 'lucide-react';
|
||||
import { Skeleton } from '@/components/ui/skeleton';
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
|
||||
const isValidCoordinate = (coord: number) => {
|
||||
return typeof coord === 'number' && !isNaN(coord) && isFinite(coord);
|
||||
};
|
||||
mapboxgl.accessToken = process.env.NEXT_PUBLIC_MAPBOX_TOKEN || '';
|
||||
|
||||
const loadGoogleMapsScript = (callback: () => void) => {
|
||||
if (window.google && window.google.maps) {
|
||||
callback();
|
||||
return;
|
||||
interface Location {
|
||||
lat: number;
|
||||
lng: number;
|
||||
}
|
||||
|
||||
interface Place {
|
||||
name: string;
|
||||
location: Location;
|
||||
vicinity?: string;
|
||||
rating?: number;
|
||||
user_ratings_total?: number;
|
||||
}
|
||||
|
||||
interface MapProps {
|
||||
center: Location;
|
||||
places?: Place[];
|
||||
zoom?: number;
|
||||
}
|
||||
|
||||
const MapComponent = React.memo(({ center, places = [], zoom = 14 }: MapProps) => {
|
||||
const mapContainer = useRef<HTMLDivElement>(null);
|
||||
const map = useRef<mapboxgl.Map | null>(null);
|
||||
const markers = useRef<mapboxgl.Marker[]>([]);
|
||||
const [mapError, setMapError] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!mapContainer.current) return;
|
||||
|
||||
try {
|
||||
map.current = new mapboxgl.Map({
|
||||
container: mapContainer.current,
|
||||
style: 'mapbox://styles/mapbox/streets-v12',
|
||||
center: [center.lng, center.lat],
|
||||
zoom: zoom
|
||||
});
|
||||
|
||||
// Add navigation control
|
||||
map.current.addControl(new mapboxgl.NavigationControl(), 'top-right');
|
||||
|
||||
// Clean up markers when component unmounts
|
||||
return () => {
|
||||
markers.current.forEach(marker => marker.remove());
|
||||
map.current?.remove();
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error initializing map:', error);
|
||||
setMapError('Failed to initialize map');
|
||||
}
|
||||
}, [center.lat, center.lng, zoom]);
|
||||
|
||||
const existingScript = document.getElementById('googleMapsScript');
|
||||
if (existingScript) {
|
||||
existingScript.remove();
|
||||
}
|
||||
useEffect(() => {
|
||||
if (!map.current) return;
|
||||
|
||||
window.initMap = callback;
|
||||
const script = document.createElement('script');
|
||||
script.id = 'googleMapsScript';
|
||||
script.src = `https://maps.googleapis.com/maps/api/js?key=${process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY}&libraries=places,marker&callback=initMap`;
|
||||
script.async = true;
|
||||
script.defer = true;
|
||||
document.head.appendChild(script);
|
||||
};
|
||||
// Update center when it changes
|
||||
map.current.flyTo({
|
||||
center: [center.lng, center.lat],
|
||||
essential: true
|
||||
});
|
||||
|
||||
const MapComponent = React.memo(({ center, places }: { center: { lat: number; lng: number }, places: any[] }) => {
|
||||
const mapRef = useRef<HTMLDivElement>(null);
|
||||
const [mapError, setMapError] = useState<string | null>(null);
|
||||
const googleMapRef = useRef<google.maps.Map | null>(null);
|
||||
const markersRef = useRef<google.maps.marker.AdvancedMarkerElement[]>([]);
|
||||
// Clear existing markers
|
||||
markers.current.forEach(marker => marker.remove());
|
||||
markers.current = [];
|
||||
|
||||
const initializeMap = useCallback(async () => {
|
||||
if (mapRef.current && isValidCoordinate(center.lat) && isValidCoordinate(center.lng)) {
|
||||
const { Map } = await google.maps.importLibrary("maps") as google.maps.MapsLibrary;
|
||||
const { AdvancedMarkerElement } = await google.maps.importLibrary("marker") as google.maps.MarkerLibrary;
|
||||
// Add new markers
|
||||
places.forEach(place => {
|
||||
const el = document.createElement('div');
|
||||
el.className = 'marker';
|
||||
el.innerHTML = '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"></path><circle cx="12" cy="10" r="3"></circle></svg>';
|
||||
el.style.color = 'hsl(var(--primary))';
|
||||
el.style.width = '24px';
|
||||
el.style.height = '24px';
|
||||
el.style.cursor = 'pointer';
|
||||
|
||||
if (!googleMapRef.current) {
|
||||
googleMapRef.current = new Map(mapRef.current, {
|
||||
center: center,
|
||||
zoom: 14,
|
||||
mapId: "347ff92e0c7225cf",
|
||||
});
|
||||
} else {
|
||||
googleMapRef.current.setCenter(center);
|
||||
}
|
||||
const marker = new mapboxgl.Marker(el)
|
||||
.setLngLat([place.location.lng, place.location.lat])
|
||||
.setPopup(
|
||||
new mapboxgl.Popup({ offset: 25 })
|
||||
.setHTML(
|
||||
`<strong>${place.name}</strong>${place.rating ?
|
||||
`<br>Rating: ${place.rating} ⭐ (${place.user_ratings_total} reviews)` :
|
||||
''}`
|
||||
)
|
||||
)
|
||||
.addTo(map.current!);
|
||||
|
||||
markersRef.current.forEach(marker => marker.map = null);
|
||||
markersRef.current = [];
|
||||
markers.current.push(marker);
|
||||
});
|
||||
}, [center, places]);
|
||||
|
||||
places.forEach((place) => {
|
||||
if (isValidCoordinate(place.location.lat) && isValidCoordinate(place.location.lng)) {
|
||||
const marker = new AdvancedMarkerElement({
|
||||
map: googleMapRef.current,
|
||||
position: place.location,
|
||||
title: place.name,
|
||||
});
|
||||
markersRef.current.push(marker);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
setMapError('Invalid coordinates provided');
|
||||
}
|
||||
}, [center, places]);
|
||||
if (mapError) {
|
||||
return (
|
||||
<div className="h-64 flex items-center justify-center bg-neutral-100 dark:bg-neutral-800 text-neutral-800 dark:text-neutral-200">
|
||||
{mapError}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
loadGoogleMapsScript(() => {
|
||||
try {
|
||||
initializeMap();
|
||||
} catch (error) {
|
||||
console.error('Error initializing map:', error);
|
||||
setMapError('Failed to initialize Google Maps');
|
||||
}
|
||||
});
|
||||
|
||||
return () => {
|
||||
markersRef.current.forEach(marker => marker.map = null);
|
||||
};
|
||||
}, [initializeMap]);
|
||||
|
||||
if (mapError) {
|
||||
return <div className="h-64 flex items-center justify-center bg-neutral-100 dark:bg-neutral-800 text-neutral-800 dark:text-neutral-200">{mapError}</div>;
|
||||
}
|
||||
|
||||
return <div ref={mapRef} className="w-full h-64" />;
|
||||
return <div ref={mapContainer} className="w-full h-64" />;
|
||||
});
|
||||
|
||||
MapComponent.displayName = 'MapComponent';
|
||||
|
||||
const MapSkeleton = () => (
|
||||
<Skeleton className="w-full h-64 bg-neutral-200 dark:bg-neutral-700" />
|
||||
<Skeleton className="w-full h-64 bg-neutral-200 dark:bg-neutral-700" />
|
||||
);
|
||||
|
||||
const PlaceDetails = ({ place }: { place: any }) => (
|
||||
<div className="flex justify-between items-start py-2">
|
||||
<div>
|
||||
<h4 className="font-semibold text-neutral-800 dark:text-neutral-200">{place.name}</h4>
|
||||
<p className="text-sm text-neutral-600 dark:text-neutral-400 max-w-[200px]" title={place.vicinity}>
|
||||
{place.vicinity}
|
||||
</p>
|
||||
</div>
|
||||
{place.rating && (
|
||||
<Badge variant="secondary" className="flex items-center bg-neutral-200 dark:bg-neutral-700 text-neutral-800 dark:text-neutral-200">
|
||||
<Star className="h-3 w-3 mr-1 text-yellow-400" />
|
||||
{place.rating} ({place.user_ratings_total})
|
||||
</Badge>
|
||||
)}
|
||||
const PlaceDetails = ({ place }: { place: Place }) => (
|
||||
<div className="flex justify-between items-start py-2">
|
||||
<div>
|
||||
<h4 className="font-semibold text-neutral-800 dark:text-neutral-200">{place.name}</h4>
|
||||
{place.vicinity && (
|
||||
<p className="text-sm text-neutral-600 dark:text-neutral-400 max-w-[200px]" title={place.vicinity}>
|
||||
{place.vicinity}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
{place.rating && (
|
||||
<Badge variant="secondary" className="flex items-center bg-neutral-200 dark:bg-neutral-700 text-neutral-800 dark:text-neutral-200">
|
||||
<Star className="h-3 w-3 mr-1 text-yellow-400" />
|
||||
{place.rating} ({place.user_ratings_total})
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
const MapEmbed = memo(({ location, zoom = 15 }: { location: string, zoom?: number }) => {
|
||||
const apiKey = process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY;
|
||||
const mapUrl = `https://www.google.com/maps/embed/v1/place?key=${apiKey}&q=${encodeURIComponent(location)}&zoom=${zoom}`;
|
||||
interface MapContainerProps {
|
||||
title: string;
|
||||
center: Location;
|
||||
places?: Place[];
|
||||
loading?: boolean;
|
||||
}
|
||||
|
||||
const MapContainer: React.FC<MapContainerProps> = ({ title, center, places = [], loading = false }) => {
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="aspect-video w-full">
|
||||
<iframe
|
||||
width="100%"
|
||||
height="100%"
|
||||
style={{ border: 0 }}
|
||||
loading="lazy"
|
||||
allowFullScreen
|
||||
referrerPolicy="no-referrer-when-downgrade"
|
||||
src={mapUrl}
|
||||
className='rounded-xl'
|
||||
></iframe>
|
||||
</div>
|
||||
<Card className="w-full my-4 bg-white dark:bg-neutral-800 border-neutral-200 dark:border-neutral-700">
|
||||
<CardHeader>
|
||||
<Skeleton className="h-6 w-3/4 bg-neutral-200 dark:bg-neutral-700" />
|
||||
</CardHeader>
|
||||
<CardContent className="p-0 rounded-t-none rounded-b-xl">
|
||||
<MapSkeleton />
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
MapEmbed.displayName = 'MapEmbed';
|
||||
|
||||
const FindPlaceResult = memo(({ result }: { result: any }) => {
|
||||
const place = result.candidates[0];
|
||||
const location = `${place.geometry.location.lat},${place.geometry.location.lng}`;
|
||||
|
||||
return (
|
||||
<Card className="w-full my-4 overflow-hidden shadow-none bg-white dark:bg-neutral-800 border-neutral-200 dark:border-neutral-700">
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-2 text-neutral-800 dark:text-neutral-100">
|
||||
<MapPin className="h-5 w-5 text-primary" />
|
||||
<span>{place.name}</span>
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<MapEmbed location={location} />
|
||||
<div className="mt-4 space-y-2 text-neutral-800 dark:text-neutral-200">
|
||||
<p><strong>Address:</strong> {place.formatted_address}</p>
|
||||
{place.rating && (
|
||||
<div className="flex items-center">
|
||||
<strong className="mr-2">Rating:</strong>
|
||||
<Badge variant="secondary" className="flex items-center bg-neutral-200 dark:bg-neutral-700 text-neutral-800 dark:text-neutral-200">
|
||||
<Star className="h-3 w-3 mr-1 text-yellow-400" />
|
||||
{place.rating}
|
||||
</Badge>
|
||||
</div>
|
||||
)}
|
||||
{place.opening_hours && (
|
||||
<p><strong>Open now:</strong> {place.opening_hours.open_now ? 'Yes' : 'No'}</p>
|
||||
)}
|
||||
return (
|
||||
<Card className="w-full my-4 overflow-hidden bg-white dark:bg-neutral-800 border-neutral-200 dark:border-neutral-700">
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-2 text-neutral-800 dark:text-neutral-100">
|
||||
<MapPin className="h-5 w-5 text-primary" />
|
||||
<span>{title}</span>
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="p-0">
|
||||
<MapComponent center={center} places={places} />
|
||||
{places.length > 0 && (
|
||||
<Accordion type="single" collapsible className="w-full">
|
||||
<AccordionItem value="place-details">
|
||||
<AccordionTrigger className="px-4 text-neutral-800 dark:text-neutral-200">
|
||||
Place Details
|
||||
</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
<div className="px-4 space-y-4 max-h-64 overflow-y-auto">
|
||||
{places.map((place, index) => (
|
||||
<PlaceDetails key={index} place={place} />
|
||||
))}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
});
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
FindPlaceResult.displayName = 'FindPlaceResult';
|
||||
|
||||
const TextSearchResult = React.memo(({ result }: { result: any }) => {
|
||||
const centerLocation = result.results[0]?.geometry?.location;
|
||||
const mapLocation = centerLocation ? `${centerLocation.lat},${centerLocation.lng}` : '';
|
||||
|
||||
return (
|
||||
<Card className="w-full my-4 overflow-hidden shadow-none bg-white dark:bg-neutral-800 border-neutral-200 dark:border-neutral-700">
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center gap-2 text-neutral-800 dark:text-neutral-100">
|
||||
<MapPin className="h-5 w-5 text-primary" />
|
||||
<span>Text Search Results</span>
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
{mapLocation && <MapComponent center={centerLocation} places={result.results} />}
|
||||
<Accordion type="single" collapsible className="w-full mt-4">
|
||||
<AccordionItem value="place-details">
|
||||
<AccordionTrigger className="text-neutral-800 dark:text-neutral-200">Place Details</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
<div className="space-y-4 max-h-64 overflow-y-auto">
|
||||
{result.results.map((place: any, index: number) => (
|
||||
<PlaceDetails key={index} place={place} />
|
||||
))}
|
||||
</div>
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
});
|
||||
|
||||
TextSearchResult.displayName = 'TextSearchResult';
|
||||
|
||||
export { MapComponent, MapSkeleton, FindPlaceResult, TextSearchResult };
|
||||
export { MapComponent, MapSkeleton, MapContainer, PlaceDetails };
|
||||
@ -23,8 +23,9 @@ interface ModelSwitcherProps {
|
||||
}
|
||||
|
||||
const models = [
|
||||
{ value: "azure:gpt4o-mini", label: "GPT-4o Mini", icon: Zap, description: "High speed, good quality", color: "emerald" },
|
||||
{ value: "anthropic:claude-3-5-sonnet-latest", label: "Claude 3.5 Sonnet (New)", icon: Sparkles, description: "High quality, lower speed", color: "indigo" },
|
||||
{ value: "azure:gpt4o-mini", label: "GPT-4o Mini", icon: Zap, description: "God speed, good quality", color: "emerald" },
|
||||
{ value: "anthropic:claude-3-5-haiku-20241022", label: "Claude 3.5 Haiku", icon: Sparkles, description: "Good quality, high speed", color: "orange" },
|
||||
{ value: "anthropic:claude-3-5-sonnet-latest", label: "Claude 3.5 Sonnet (New)", icon: Sparkles, description: "High quality, good speed", color: "indigo" },
|
||||
{ value: "azure:gpt-4o", label: "GPT-4o", icon: Cpu, description: "Higher quality, normal speed", color: "blue" },
|
||||
];
|
||||
|
||||
@ -46,6 +47,10 @@ const getColorClasses = (color: string, isSelected: boolean = false) => {
|
||||
return isSelected
|
||||
? `${baseClasses} ${selectedClasses} !bg-blue-500 dark:!bg-blue-600 !text-white hover:!bg-blue-600 dark:hover:!bg-blue-700`
|
||||
: `${baseClasses} !text-blue-700 dark:!text-blue-300 hover:!bg-blue-200 dark:hover:!bg-blue-800/70`;
|
||||
case 'orange':
|
||||
return isSelected
|
||||
? `${baseClasses} ${selectedClasses} !bg-orange-500 dark:!bg-orange-600 !text-white hover:!bg-orange-600 dark:hover:!bg-orange-700`
|
||||
: `${baseClasses} !text-orange-700 dark:!text-orange-300 hover:!bg-orange-200 dark:hover:!bg-orange-800/70`;
|
||||
default:
|
||||
return isSelected
|
||||
? `${baseClasses} ${selectedClasses} !bg-neutral-500 dark:!bg-neutral-600 !text-white hover:!bg-neutral-600 dark:hover:!bg-neutral-700`
|
||||
@ -486,14 +491,14 @@ const FormComponent: React.FC<FormComponentProps> = ({
|
||||
}}
|
||||
/>
|
||||
|
||||
<div className="absolute left-2 bottom-2">
|
||||
<div className="absolute left-2 bottom-2 mt-4">
|
||||
<ModelSwitcher
|
||||
selectedModel={selectedModel}
|
||||
setSelectedModel={setSelectedModel}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="absolute right-2 bottom-2 flex items-center gap-2">
|
||||
<div className="absolute right-2 bottom-2 flex items-center gap-2 mt-4">
|
||||
<Button
|
||||
className="rounded-full p-1.5 h-8 w-8 bg-white dark:bg-neutral-700 text-neutral-700 dark:text-neutral-300 hover:bg-neutral-300 dark:hover:bg-neutral-600"
|
||||
onClick={(event) => {
|
||||
|
||||
12
package.json
12
package.json
@ -9,14 +9,14 @@
|
||||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ai-sdk/anthropic": "^0.0.51",
|
||||
"@ai-sdk/azure": "^0.0.31",
|
||||
"@ai-sdk/anthropic": "^0.0.55",
|
||||
"@ai-sdk/azure": "^0.0.51",
|
||||
"@ai-sdk/cohere": "latest",
|
||||
"@ai-sdk/google": "^0.0.52",
|
||||
"@ai-sdk/groq": "^0.0.1",
|
||||
"@ai-sdk/mistral": "^0.0.41",
|
||||
"@ai-sdk/openai": "^0.0.58",
|
||||
"@e2b/code-interpreter": "^0.0.8",
|
||||
"@e2b/code-interpreter": "^1.0.3",
|
||||
"@foobar404/wave": "^2.0.5",
|
||||
"@mendable/firecrawl-js": "^1.4.3",
|
||||
"@radix-ui/react-accordion": "^1.2.0",
|
||||
@ -33,18 +33,21 @@
|
||||
"@radix-ui/react-tooltip": "^1.1.2",
|
||||
"@tailwindcss/typography": "^0.5.13",
|
||||
"@types/katex": "^0.16.7",
|
||||
"@types/mapbox-gl": "^3.4.0",
|
||||
"@types/unist": "^3.0.3",
|
||||
"@upstash/ratelimit": "^2.0.3",
|
||||
"@upstash/redis": "^1.34.0",
|
||||
"@vercel/analytics": "^1.3.1",
|
||||
"@vercel/blob": "^0.23.4",
|
||||
"@vercel/functions": "^1.4.0",
|
||||
"ai": "latest",
|
||||
"ai": "^3.4.33",
|
||||
"anthropic-vertex-ai": "^1.0.0",
|
||||
"cheerio": "^1.0.0",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.1.1",
|
||||
"date-fns": "^3.6.0",
|
||||
"echarts": "^5.5.1",
|
||||
"echarts-for-react": "^3.0.2",
|
||||
"embla-carousel-autoplay": "^8.3.0",
|
||||
"embla-carousel-react": "^8.3.0",
|
||||
"framer-motion": "^11.3.19",
|
||||
@ -52,6 +55,7 @@
|
||||
"highlight.js": "^11.10.0",
|
||||
"katex": "^0.16.11",
|
||||
"lucide-react": "^0.424.0",
|
||||
"mapbox-gl": "^3.7.0",
|
||||
"marked-react": "^2.0.0",
|
||||
"next": "^14.2.10",
|
||||
"next-themes": "^0.3.0",
|
||||
|
||||
512
pnpm-lock.yaml
512
pnpm-lock.yaml
@ -6,14 +6,14 @@ settings:
|
||||
|
||||
dependencies:
|
||||
'@ai-sdk/anthropic':
|
||||
specifier: ^0.0.55
|
||||
version: 0.0.55(zod@3.23.8)
|
||||
'@ai-sdk/azure':
|
||||
specifier: ^0.0.51
|
||||
version: 0.0.51(zod@3.23.8)
|
||||
'@ai-sdk/azure':
|
||||
specifier: ^0.0.31
|
||||
version: 0.0.31(zod@3.23.8)
|
||||
'@ai-sdk/cohere':
|
||||
specifier: latest
|
||||
version: 0.0.25(zod@3.23.8)
|
||||
version: 0.0.28(zod@3.23.8)
|
||||
'@ai-sdk/google':
|
||||
specifier: ^0.0.52
|
||||
version: 0.0.52(zod@3.23.8)
|
||||
@ -27,8 +27,8 @@ dependencies:
|
||||
specifier: ^0.0.58
|
||||
version: 0.0.58(zod@3.23.8)
|
||||
'@e2b/code-interpreter':
|
||||
specifier: ^0.0.8
|
||||
version: 0.0.8
|
||||
specifier: ^1.0.3
|
||||
version: 1.0.3
|
||||
'@foobar404/wave':
|
||||
specifier: ^2.0.5
|
||||
version: 2.0.5
|
||||
@ -77,6 +77,9 @@ dependencies:
|
||||
'@types/katex':
|
||||
specifier: ^0.16.7
|
||||
version: 0.16.7
|
||||
'@types/mapbox-gl':
|
||||
specifier: ^3.4.0
|
||||
version: 3.4.0
|
||||
'@types/unist':
|
||||
specifier: ^3.0.3
|
||||
version: 3.0.3
|
||||
@ -96,8 +99,8 @@ dependencies:
|
||||
specifier: ^1.4.0
|
||||
version: 1.4.2
|
||||
ai:
|
||||
specifier: latest
|
||||
version: 3.4.18(openai@4.67.2)(react@18.3.1)(svelte@4.2.19)(vue@3.5.11)(zod@3.23.8)
|
||||
specifier: ^3.4.33
|
||||
version: 3.4.33(openai@4.67.2)(react@18.3.1)(svelte@4.2.19)(vue@3.5.11)(zod@3.23.8)
|
||||
anthropic-vertex-ai:
|
||||
specifier: ^1.0.0
|
||||
version: 1.0.0(zod@3.23.8)
|
||||
@ -113,6 +116,12 @@ dependencies:
|
||||
date-fns:
|
||||
specifier: ^3.6.0
|
||||
version: 3.6.0
|
||||
echarts:
|
||||
specifier: ^5.5.1
|
||||
version: 5.5.1
|
||||
echarts-for-react:
|
||||
specifier: ^3.0.2
|
||||
version: 3.0.2(echarts@5.5.1)(react@18.3.1)
|
||||
embla-carousel-autoplay:
|
||||
specifier: ^8.3.0
|
||||
version: 8.3.0(embla-carousel@8.3.0)
|
||||
@ -134,6 +143,9 @@ dependencies:
|
||||
lucide-react:
|
||||
specifier: ^0.424.0
|
||||
version: 0.424.0(react@18.3.1)
|
||||
mapbox-gl:
|
||||
specifier: ^3.7.0
|
||||
version: 3.7.0
|
||||
marked-react:
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.0(react@18.3.1)
|
||||
@ -232,37 +244,37 @@ devDependencies:
|
||||
|
||||
packages:
|
||||
|
||||
/@ai-sdk/anthropic@0.0.51(zod@3.23.8):
|
||||
resolution: {integrity: sha512-XPLBvdwdMlNAvGMyfsDgrCDXN2Wz7M+wfCJthqiwdiKHmq2jDLGdt0ZCAozgxxW28HVzMfJlFjuyECiA5Le3YA==}
|
||||
/@ai-sdk/anthropic@0.0.55(zod@3.23.8):
|
||||
resolution: {integrity: sha512-SIPGu8on4PKl+PIdbjOniT5/AiE82Yw8HOE/W0GEb2bNGq2KhfkjVt5MBhppg+ZRme5w2iexB4bl66eRa2o89g==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
zod: ^3.0.0
|
||||
dependencies:
|
||||
'@ai-sdk/provider': 0.0.24
|
||||
'@ai-sdk/provider-utils': 1.0.20(zod@3.23.8)
|
||||
'@ai-sdk/provider': 0.0.26
|
||||
'@ai-sdk/provider-utils': 1.0.22(zod@3.23.8)
|
||||
zod: 3.23.8
|
||||
dev: false
|
||||
|
||||
/@ai-sdk/azure@0.0.31(zod@3.23.8):
|
||||
resolution: {integrity: sha512-LTiv890qHcw3w87l+OOuYqW1HM9+7olS5mpSOriRY2uZxJWr3MGz8MYqJu2jGNajNKi4j64GsaOuNK69k8KXjw==}
|
||||
/@ai-sdk/azure@0.0.51(zod@3.23.8):
|
||||
resolution: {integrity: sha512-DMPuWURdgoweDlSLTj6o3Yx6+hnfr9idvHaTBwgPY+mayvEwlLZp3l08juMn/d/gKgHheQpUEgCQNhCzk6ZJ5w==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
zod: ^3.0.0
|
||||
dependencies:
|
||||
'@ai-sdk/openai': 0.0.53(zod@3.23.8)
|
||||
'@ai-sdk/provider': 0.0.21
|
||||
'@ai-sdk/provider-utils': 1.0.16(zod@3.23.8)
|
||||
'@ai-sdk/openai': 0.0.71(zod@3.23.8)
|
||||
'@ai-sdk/provider': 0.0.26
|
||||
'@ai-sdk/provider-utils': 1.0.22(zod@3.23.8)
|
||||
zod: 3.23.8
|
||||
dev: false
|
||||
|
||||
/@ai-sdk/cohere@0.0.25(zod@3.23.8):
|
||||
resolution: {integrity: sha512-i7wraTa9/Qmozhw/E5OX+TNIYcPYE7higmCiYvknYyfGTc2XjnVaB2zyIfmbw0TgL+2m3PbVk75vEL5zG1ickQ==}
|
||||
/@ai-sdk/cohere@0.0.28(zod@3.23.8):
|
||||
resolution: {integrity: sha512-aWavC7PuC5AcDcwTBcvx2ZemudtjPaZvLDmcVjiIhzvvW2+zoHoWmERD8CtSWIMlQp/vjdTcwNhSXTOqfxm27A==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
zod: ^3.0.0
|
||||
dependencies:
|
||||
'@ai-sdk/provider': 0.0.24
|
||||
'@ai-sdk/provider-utils': 1.0.20(zod@3.23.8)
|
||||
'@ai-sdk/provider': 0.0.26
|
||||
'@ai-sdk/provider-utils': 1.0.22(zod@3.23.8)
|
||||
zod: 3.23.8
|
||||
dev: false
|
||||
|
||||
@ -300,17 +312,6 @@ packages:
|
||||
zod: 3.23.8
|
||||
dev: false
|
||||
|
||||
/@ai-sdk/openai@0.0.53(zod@3.23.8):
|
||||
resolution: {integrity: sha512-Wm4+EYG2Zl5WmhvZJrLhrBY+C46FEQmDjQ9ZB5h2DvRoJZNKtNiVNFMEQuyBK7QwivvlCSMJkPRBfFcbJgNLMQ==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
zod: ^3.0.0
|
||||
dependencies:
|
||||
'@ai-sdk/provider': 0.0.21
|
||||
'@ai-sdk/provider-utils': 1.0.16(zod@3.23.8)
|
||||
zod: 3.23.8
|
||||
dev: false
|
||||
|
||||
/@ai-sdk/openai@0.0.58(zod@3.23.8):
|
||||
resolution: {integrity: sha512-Eao1L0vzfXdymgvc5FDHwV2g2A7BCWml1cShNA+wliY1RL7NNREGcuQvBDNoggB9PM24fawzZyk0ZJ5jlo9Q0w==}
|
||||
engines: {node: '>=18'}
|
||||
@ -322,19 +323,14 @@ packages:
|
||||
zod: 3.23.8
|
||||
dev: false
|
||||
|
||||
/@ai-sdk/provider-utils@1.0.16(zod@3.23.8):
|
||||
resolution: {integrity: sha512-8Nd8vIkGTIthhfgJEdP9KyMlykehBNP/1J47eMC3vQqYgJV6r5Bgvl3LFVfWi9KzamiD8tp9nU2NJKTeo4MH/A==}
|
||||
/@ai-sdk/openai@0.0.71(zod@3.23.8):
|
||||
resolution: {integrity: sha512-ds7u3sWEnKyHxM3lAL9xTs72228HEKcPZCAEFaxmgrexKPJe2tyLBtvS/Kg39SPKPtY9EeaKqi/nbx1AmnXK6A==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
zod: ^3.0.0
|
||||
peerDependenciesMeta:
|
||||
zod:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@ai-sdk/provider': 0.0.21
|
||||
eventsource-parser: 1.1.2
|
||||
nanoid: 3.3.6
|
||||
secure-json-parse: 2.7.0
|
||||
'@ai-sdk/provider': 0.0.26
|
||||
'@ai-sdk/provider-utils': 1.0.22(zod@3.23.8)
|
||||
zod: 3.23.8
|
||||
dev: false
|
||||
|
||||
@ -402,11 +398,20 @@ packages:
|
||||
zod: 3.23.8
|
||||
dev: false
|
||||
|
||||
/@ai-sdk/provider@0.0.21:
|
||||
resolution: {integrity: sha512-9j95uaPRxwYkzQdkl4XO/MmWWW5c5vcVSXtqvALpD9SMB9fzH46dO3UN4VbOJR2J3Z84CZAqgZu5tNlkptT9qQ==}
|
||||
/@ai-sdk/provider-utils@1.0.22(zod@3.23.8):
|
||||
resolution: {integrity: sha512-YHK2rpj++wnLVc9vPGzGFP3Pjeld2MwhKinetA0zKXOoHAT/Jit5O8kZsxcSlJPu9wvcGT1UGZEjZrtO7PfFOQ==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
zod: ^3.0.0
|
||||
peerDependenciesMeta:
|
||||
zod:
|
||||
optional: true
|
||||
dependencies:
|
||||
json-schema: 0.4.0
|
||||
'@ai-sdk/provider': 0.0.26
|
||||
eventsource-parser: 1.1.2
|
||||
nanoid: 3.3.7
|
||||
secure-json-parse: 2.7.0
|
||||
zod: 3.23.8
|
||||
dev: false
|
||||
|
||||
/@ai-sdk/provider@0.0.22:
|
||||
@ -430,11 +435,18 @@ packages:
|
||||
json-schema: 0.4.0
|
||||
dev: false
|
||||
|
||||
/@ai-sdk/react@0.0.64(react@18.3.1)(zod@3.23.8):
|
||||
resolution: {integrity: sha512-4LN2vleyA6rYHZ4Rk9CdxnJgaVkNPJDD4Wx1brUhc5RvUxj3TODcm2UwGOR/mxv4pcydtZGELfQQs/i/tkAUCw==}
|
||||
/@ai-sdk/provider@0.0.26:
|
||||
resolution: {integrity: sha512-dQkfBDs2lTYpKM8389oopPdQgIU007GQyCbuPPrV+K6MtSII3HBfE0stUIMXUb44L+LK1t6GXPP7wjSzjO6uKg==}
|
||||
engines: {node: '>=18'}
|
||||
dependencies:
|
||||
json-schema: 0.4.0
|
||||
dev: false
|
||||
|
||||
/@ai-sdk/react@0.0.70(react@18.3.1)(zod@3.23.8):
|
||||
resolution: {integrity: sha512-GnwbtjW4/4z7MleLiW+TOZC2M29eCg1tOUpuEiYFMmFNZK8mkrqM0PFZMo6UsYeUYMWqEOOcPOU9OQVJMJh7IQ==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
react: ^18 || ^19
|
||||
react: ^18 || ^19 || ^19.0.0-rc
|
||||
zod: ^3.0.0
|
||||
peerDependenciesMeta:
|
||||
react:
|
||||
@ -442,15 +454,16 @@ packages:
|
||||
zod:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@ai-sdk/provider-utils': 1.0.20(zod@3.23.8)
|
||||
'@ai-sdk/ui-utils': 0.0.46(zod@3.23.8)
|
||||
'@ai-sdk/provider-utils': 1.0.22(zod@3.23.8)
|
||||
'@ai-sdk/ui-utils': 0.0.50(zod@3.23.8)
|
||||
react: 18.3.1
|
||||
swr: 2.2.5(react@18.3.1)
|
||||
throttleit: 2.1.0
|
||||
zod: 3.23.8
|
||||
dev: false
|
||||
|
||||
/@ai-sdk/solid@0.0.50(zod@3.23.8):
|
||||
resolution: {integrity: sha512-JF+KKOgGAgcROgae6FU+hAtxMRhR896SzwI3H1h5hFOZrjqYeYzemJoKzA5MR5IBnPSK4FzEjunc8G5L67TyzQ==}
|
||||
/@ai-sdk/solid@0.0.54(zod@3.23.8):
|
||||
resolution: {integrity: sha512-96KWTVK+opdFeRubqrgaJXoNiDP89gNxFRWUp0PJOotZW816AbhUf4EnDjBjXTLjXL1n0h8tGSE9sZsRkj9wQQ==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
solid-js: ^1.7.7
|
||||
@ -458,31 +471,31 @@ packages:
|
||||
solid-js:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@ai-sdk/provider-utils': 1.0.20(zod@3.23.8)
|
||||
'@ai-sdk/ui-utils': 0.0.46(zod@3.23.8)
|
||||
'@ai-sdk/provider-utils': 1.0.22(zod@3.23.8)
|
||||
'@ai-sdk/ui-utils': 0.0.50(zod@3.23.8)
|
||||
transitivePeerDependencies:
|
||||
- zod
|
||||
dev: false
|
||||
|
||||
/@ai-sdk/svelte@0.0.52(svelte@4.2.19)(zod@3.23.8):
|
||||
resolution: {integrity: sha512-ZGd81ruVuqpOh1Suma+HwBMBywcOV0IUzi96Q3knIoZIz99sVwebSKH8ExMofXm49bQdCTRa73Wn8sTs6QDIYg==}
|
||||
/@ai-sdk/svelte@0.0.57(svelte@4.2.19)(zod@3.23.8):
|
||||
resolution: {integrity: sha512-SyF9ItIR9ALP9yDNAD+2/5Vl1IT6kchgyDH8xkmhysfJI6WrvJbtO1wdQ0nylvPLcsPoYu+cAlz1krU4lFHcYw==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
svelte: ^3.0.0 || ^4.0.0
|
||||
svelte: ^3.0.0 || ^4.0.0 || ^5.0.0
|
||||
peerDependenciesMeta:
|
||||
svelte:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@ai-sdk/provider-utils': 1.0.20(zod@3.23.8)
|
||||
'@ai-sdk/ui-utils': 0.0.46(zod@3.23.8)
|
||||
'@ai-sdk/provider-utils': 1.0.22(zod@3.23.8)
|
||||
'@ai-sdk/ui-utils': 0.0.50(zod@3.23.8)
|
||||
sswr: 2.1.0(svelte@4.2.19)
|
||||
svelte: 4.2.19
|
||||
transitivePeerDependencies:
|
||||
- zod
|
||||
dev: false
|
||||
|
||||
/@ai-sdk/ui-utils@0.0.46(zod@3.23.8):
|
||||
resolution: {integrity: sha512-ZG/wneyJG+6w5Nm/hy1AKMuRgjPQToAxBsTk61c9sVPUTaxo+NNjM2MhXQMtmsja2N5evs8NmHie+ExEgpL3cA==}
|
||||
/@ai-sdk/ui-utils@0.0.50(zod@3.23.8):
|
||||
resolution: {integrity: sha512-Z5QYJVW+5XpSaJ4jYCCAVG7zIAuKOOdikhgpksneNmKvx61ACFaf98pmOd+xnjahl0pIlc/QIe6O4yVaJ1sEaw==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
zod: ^3.0.0
|
||||
@ -490,16 +503,16 @@ packages:
|
||||
zod:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@ai-sdk/provider': 0.0.24
|
||||
'@ai-sdk/provider-utils': 1.0.20(zod@3.23.8)
|
||||
'@ai-sdk/provider': 0.0.26
|
||||
'@ai-sdk/provider-utils': 1.0.22(zod@3.23.8)
|
||||
json-schema: 0.4.0
|
||||
secure-json-parse: 2.7.0
|
||||
zod: 3.23.8
|
||||
zod-to-json-schema: 3.23.2(zod@3.23.8)
|
||||
zod-to-json-schema: 3.23.3(zod@3.23.8)
|
||||
dev: false
|
||||
|
||||
/@ai-sdk/vue@0.0.55(vue@3.5.11)(zod@3.23.8):
|
||||
resolution: {integrity: sha512-NZ89CeRPO3D9GjI7GmK3vC+YXjsaWi3iCIvxlGqfQYt0JFKcjgM6dfeq8Nkk+qWI9OoxoOhV/yQdqWQKPv3RRg==}
|
||||
/@ai-sdk/vue@0.0.59(vue@3.5.11)(zod@3.23.8):
|
||||
resolution: {integrity: sha512-+ofYlnqdc8c4F6tM0IKF0+7NagZRAiqBJpGDJ+6EYhDW8FHLUP/JFBgu32SjxSxC6IKFZxEnl68ZoP/Z38EMlw==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
vue: ^3.3.4
|
||||
@ -507,8 +520,8 @@ packages:
|
||||
vue:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@ai-sdk/provider-utils': 1.0.20(zod@3.23.8)
|
||||
'@ai-sdk/ui-utils': 0.0.46(zod@3.23.8)
|
||||
'@ai-sdk/provider-utils': 1.0.22(zod@3.23.8)
|
||||
'@ai-sdk/ui-utils': 0.0.50(zod@3.23.8)
|
||||
swrv: 1.0.4(vue@3.5.11)
|
||||
vue: 3.5.11(typescript@5.6.2)
|
||||
transitivePeerDependencies:
|
||||
@ -561,16 +574,33 @@ packages:
|
||||
to-fast-properties: 2.0.0
|
||||
dev: false
|
||||
|
||||
/@e2b/code-interpreter@0.0.8:
|
||||
resolution: {integrity: sha512-cKDFY9js9l3MfL71x0IDvaz0mAhvHIurVFnimtFRXNzuV0TxhuFqsauKabet0TMOrcDF3H3trC7pct6mNgRYTA==}
|
||||
/@bufbuild/protobuf@1.10.0:
|
||||
resolution: {integrity: sha512-QDdVFLoN93Zjg36NoQPZfsVH9tZew7wKDKyV5qRdj8ntT4wQCOradQjRaTdwMhWUYsgKsvCINKKm87FdEk96Ag==}
|
||||
dev: false
|
||||
|
||||
/@connectrpc/connect-web@1.6.1(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.6.1):
|
||||
resolution: {integrity: sha512-GVfxQOmt3TtgTaKeXLS/EA2IHa3nHxwe2BCHT7X0Q/0hohM+nP5DDnIItGEjGrGdt3LTTqWqE4s70N4h+qIMlQ==}
|
||||
peerDependencies:
|
||||
'@bufbuild/protobuf': ^1.10.0
|
||||
'@connectrpc/connect': 1.6.1
|
||||
dependencies:
|
||||
'@bufbuild/protobuf': 1.10.0
|
||||
'@connectrpc/connect': 1.6.1(@bufbuild/protobuf@1.10.0)
|
||||
dev: false
|
||||
|
||||
/@connectrpc/connect@1.6.1(@bufbuild/protobuf@1.10.0):
|
||||
resolution: {integrity: sha512-KchMDNtU4CDTdkyf0qG7ugJ6qHTOR/aI7XebYn3OTCNagaDYWiZUVKgRgwH79yeMkpNgvEUaXSK7wKjaBK9b/Q==}
|
||||
peerDependencies:
|
||||
'@bufbuild/protobuf': ^1.10.0
|
||||
dependencies:
|
||||
'@bufbuild/protobuf': 1.10.0
|
||||
dev: false
|
||||
|
||||
/@e2b/code-interpreter@1.0.3:
|
||||
resolution: {integrity: sha512-/dfMagUEytQtwqkab+0glMPCpPvOwhGaUZvOscT/YvxJxaYPswwjIWb3TXa9DeV25XYw//72syT2wo6rGnnCKw==}
|
||||
engines: {node: '>=18'}
|
||||
dependencies:
|
||||
e2b: 0.16.2
|
||||
isomorphic-ws: 5.0.0(ws@8.18.0)
|
||||
ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@6.0.4)
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- utf-8-validate
|
||||
e2b: 1.0.2
|
||||
dev: false
|
||||
|
||||
/@eslint-community/eslint-utils@4.4.0(eslint@8.57.1):
|
||||
@ -705,6 +735,38 @@ packages:
|
||||
'@jridgewell/resolve-uri': 3.1.2
|
||||
'@jridgewell/sourcemap-codec': 1.5.0
|
||||
|
||||
/@mapbox/jsonlint-lines-primitives@2.0.2:
|
||||
resolution: {integrity: sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ==}
|
||||
engines: {node: '>= 0.6'}
|
||||
dev: false
|
||||
|
||||
/@mapbox/mapbox-gl-supported@3.0.0:
|
||||
resolution: {integrity: sha512-2XghOwu16ZwPJLOFVuIOaLbN0iKMn867evzXFyf0P22dqugezfJwLmdanAgU25ITvz1TvOfVP4jsDImlDJzcWg==}
|
||||
dev: false
|
||||
|
||||
/@mapbox/point-geometry@0.1.0:
|
||||
resolution: {integrity: sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ==}
|
||||
dev: false
|
||||
|
||||
/@mapbox/tiny-sdf@2.0.6:
|
||||
resolution: {integrity: sha512-qMqa27TLw+ZQz5Jk+RcwZGH7BQf5G/TrutJhspsca/3SHwmgKQ1iq+d3Jxz5oysPVYTGP6aXxCo5Lk9Er6YBAA==}
|
||||
dev: false
|
||||
|
||||
/@mapbox/unitbezier@0.0.1:
|
||||
resolution: {integrity: sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw==}
|
||||
dev: false
|
||||
|
||||
/@mapbox/vector-tile@1.3.1:
|
||||
resolution: {integrity: sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw==}
|
||||
dependencies:
|
||||
'@mapbox/point-geometry': 0.1.0
|
||||
dev: false
|
||||
|
||||
/@mapbox/whoots-js@3.1.0:
|
||||
resolution: {integrity: sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
dev: false
|
||||
|
||||
/@mendable/firecrawl-js@1.5.3(ws@8.18.0):
|
||||
resolution: {integrity: sha512-SMxQAUMixlc01OzYB3/9YvTGe/Po/v2NZx5ccCO3OKBk9Vdbo4a5i1Var591H1NYDEqNnRJ6se0X/Y/IiLVvtQ==}
|
||||
dependencies:
|
||||
@ -1736,6 +1798,16 @@ packages:
|
||||
resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
|
||||
dev: false
|
||||
|
||||
/@types/geojson-vt@3.2.5:
|
||||
resolution: {integrity: sha512-qDO7wqtprzlpe8FfQ//ClPV9xiuoh2nkIgiouIptON9w5jvD/fA4szvP9GBlDVdJ5dldAl0kX/sy3URbWwLx0g==}
|
||||
dependencies:
|
||||
'@types/geojson': 7946.0.14
|
||||
dev: false
|
||||
|
||||
/@types/geojson@7946.0.14:
|
||||
resolution: {integrity: sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==}
|
||||
dev: false
|
||||
|
||||
/@types/google.maps@3.58.1:
|
||||
resolution: {integrity: sha512-X9QTSvGJ0nCfMzYOnaVs/k6/4L+7F5uCS+4iUmkLEls6J9S/Phv+m/i3mDeyc49ZBgwab3EFO1HEoBY7k98EGQ==}
|
||||
dev: true
|
||||
@ -1760,6 +1832,24 @@ packages:
|
||||
resolution: {integrity: sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==}
|
||||
dev: false
|
||||
|
||||
/@types/mapbox-gl@3.4.0:
|
||||
resolution: {integrity: sha512-tbn++Mm94H1kE7W6FF0oVC9rMXHVzDDNUbS7KfBMRF8NV/8csFi+67ytKcZJ4LsrpsJ+8MC6Os6ZinEDCsrunw==}
|
||||
dependencies:
|
||||
'@types/geojson': 7946.0.14
|
||||
dev: false
|
||||
|
||||
/@types/mapbox__point-geometry@0.1.4:
|
||||
resolution: {integrity: sha512-mUWlSxAmYLfwnRBmgYV86tgYmMIICX4kza8YnE/eIlywGe2XoOxlpVnXWwir92xRLjwyarqwpu2EJKD2pk0IUA==}
|
||||
dev: false
|
||||
|
||||
/@types/mapbox__vector-tile@1.3.4:
|
||||
resolution: {integrity: sha512-bpd8dRn9pr6xKvuEBQup8pwQfD4VUyqO/2deGjfpe6AwC8YRlyEipvefyRJUSiCJTZuCb8Pl1ciVV5ekqJ96Bg==}
|
||||
dependencies:
|
||||
'@types/geojson': 7946.0.14
|
||||
'@types/mapbox__point-geometry': 0.1.4
|
||||
'@types/pbf': 3.0.5
|
||||
dev: false
|
||||
|
||||
/@types/mdast@4.0.4:
|
||||
resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
|
||||
dependencies:
|
||||
@ -1788,6 +1878,10 @@ packages:
|
||||
dependencies:
|
||||
undici-types: 6.19.8
|
||||
|
||||
/@types/pbf@3.0.5:
|
||||
resolution: {integrity: sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA==}
|
||||
dev: false
|
||||
|
||||
/@types/prop-types@15.7.13:
|
||||
resolution: {integrity: sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==}
|
||||
|
||||
@ -1808,6 +1902,12 @@ packages:
|
||||
'@types/prop-types': 15.7.13
|
||||
csstype: 3.1.3
|
||||
|
||||
/@types/supercluster@7.1.3:
|
||||
resolution: {integrity: sha512-Z0pOY34GDFl3Q6hUFYf3HkTwKEE02e7QgtJppBt+beEAxnyOpJua+voGFvxINBHa06GwLFFym7gRPY2SiKIfIA==}
|
||||
dependencies:
|
||||
'@types/geojson': 7946.0.14
|
||||
dev: false
|
||||
|
||||
/@types/unist@2.0.11:
|
||||
resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==}
|
||||
dev: false
|
||||
@ -2049,14 +2149,14 @@ packages:
|
||||
humanize-ms: 1.2.1
|
||||
dev: false
|
||||
|
||||
/ai@3.4.18(openai@4.67.2)(react@18.3.1)(svelte@4.2.19)(vue@3.5.11)(zod@3.23.8):
|
||||
resolution: {integrity: sha512-dc6rSBDgaRMX4VgTBsUZwEN5tBWMpJd+MJxB05E2cL4ft9mOmQEZNS6yeu4Ci5rUDj4ZhnmvANHrP7td8Ko9Og==}
|
||||
/ai@3.4.33(openai@4.67.2)(react@18.3.1)(svelte@4.2.19)(vue@3.5.11)(zod@3.23.8):
|
||||
resolution: {integrity: sha512-plBlrVZKwPoRTmM8+D1sJac9Bq8eaa2jiZlHLZIWekKWI1yMWYZvCCEezY9ASPwRhULYDJB2VhKOBUUeg3S5JQ==}
|
||||
engines: {node: '>=18'}
|
||||
peerDependencies:
|
||||
openai: ^4.42.0
|
||||
react: ^18 || ^19
|
||||
react: ^18 || ^19 || ^19.0.0-rc
|
||||
sswr: ^2.1.0
|
||||
svelte: ^3.0.0 || ^4.0.0
|
||||
svelte: ^3.0.0 || ^4.0.0 || ^5.0.0
|
||||
zod: ^3.0.0
|
||||
peerDependenciesMeta:
|
||||
openai:
|
||||
@ -2070,24 +2170,23 @@ packages:
|
||||
zod:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@ai-sdk/provider': 0.0.24
|
||||
'@ai-sdk/provider-utils': 1.0.20(zod@3.23.8)
|
||||
'@ai-sdk/react': 0.0.64(react@18.3.1)(zod@3.23.8)
|
||||
'@ai-sdk/solid': 0.0.50(zod@3.23.8)
|
||||
'@ai-sdk/svelte': 0.0.52(svelte@4.2.19)(zod@3.23.8)
|
||||
'@ai-sdk/ui-utils': 0.0.46(zod@3.23.8)
|
||||
'@ai-sdk/vue': 0.0.55(vue@3.5.11)(zod@3.23.8)
|
||||
'@ai-sdk/provider': 0.0.26
|
||||
'@ai-sdk/provider-utils': 1.0.22(zod@3.23.8)
|
||||
'@ai-sdk/react': 0.0.70(react@18.3.1)(zod@3.23.8)
|
||||
'@ai-sdk/solid': 0.0.54(zod@3.23.8)
|
||||
'@ai-sdk/svelte': 0.0.57(svelte@4.2.19)(zod@3.23.8)
|
||||
'@ai-sdk/ui-utils': 0.0.50(zod@3.23.8)
|
||||
'@ai-sdk/vue': 0.0.59(vue@3.5.11)(zod@3.23.8)
|
||||
'@opentelemetry/api': 1.9.0
|
||||
eventsource-parser: 1.1.2
|
||||
json-schema: 0.4.0
|
||||
jsondiffpatch: 0.6.0
|
||||
nanoid: 3.3.6
|
||||
openai: 4.67.2(zod@3.23.8)
|
||||
react: 18.3.1
|
||||
secure-json-parse: 2.7.0
|
||||
svelte: 4.2.19
|
||||
zod: 3.23.8
|
||||
zod-to-json-schema: 3.23.2(zod@3.23.8)
|
||||
zod-to-json-schema: 3.23.3(zod@3.23.8)
|
||||
transitivePeerDependencies:
|
||||
- solid-js
|
||||
- vue
|
||||
@ -2349,14 +2448,6 @@ packages:
|
||||
resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==}
|
||||
dev: false
|
||||
|
||||
/bufferutil@4.0.8:
|
||||
resolution: {integrity: sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==}
|
||||
engines: {node: '>=6.14.2'}
|
||||
requiresBuild: true
|
||||
dependencies:
|
||||
node-gyp-build: 4.8.2
|
||||
dev: false
|
||||
|
||||
/busboy@1.6.0:
|
||||
resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==}
|
||||
engines: {node: '>=10.16.0'}
|
||||
@ -2438,6 +2529,10 @@ packages:
|
||||
resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==}
|
||||
dev: false
|
||||
|
||||
/cheap-ruler@4.0.0:
|
||||
resolution: {integrity: sha512-0BJa8f4t141BYKQyn9NSQt1PguFQXMXwZiA5shfoaBYHAb2fFk2RAX+tiWMoQU+Agtzt3mdt0JtuyshAXqZ+Vw==}
|
||||
dev: false
|
||||
|
||||
/cheerio-select@2.1.0:
|
||||
resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==}
|
||||
dependencies:
|
||||
@ -2543,6 +2638,10 @@ packages:
|
||||
engines: {node: '>= 12'}
|
||||
dev: false
|
||||
|
||||
/compare-versions@6.1.1:
|
||||
resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==}
|
||||
dev: false
|
||||
|
||||
/concat-map@0.0.1:
|
||||
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
|
||||
dev: true
|
||||
@ -2582,6 +2681,10 @@ packages:
|
||||
engines: {node: '>= 6'}
|
||||
dev: false
|
||||
|
||||
/csscolorparser@1.0.3:
|
||||
resolution: {integrity: sha512-umPSgYwZkdFoUrH5hIq5kf0wPSXiro51nPw0j2K/c83KflkPSTBGMz6NJvMB+07VlL0y7VPo6QJcDjcgKTTm3w==}
|
||||
dev: false
|
||||
|
||||
/cssesc@3.0.0:
|
||||
resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
|
||||
engines: {node: '>=4'}
|
||||
@ -2859,19 +2962,20 @@ packages:
|
||||
domhandler: 5.0.3
|
||||
dev: false
|
||||
|
||||
/e2b@0.16.2:
|
||||
resolution: {integrity: sha512-xKmVK4ipgVQPJ/uyyrfH9LnaawERRWt8U2UZhdhGfzdL/QU/OpBjuhoIbFCv1Uy6qXV4nIiJ6Nw4MBC4HmXf1g==}
|
||||
/e2b@1.0.2:
|
||||
resolution: {integrity: sha512-jChBH34n4ShQlsOCm3ENDtwFqljE6b++C4YC8lTBuN5Go+4uffPyI9GPfDx5nN4Je3+9FLCciRRyCWsqaDWFQQ==}
|
||||
engines: {node: '>=18'}
|
||||
dependencies:
|
||||
isomorphic-ws: 5.0.0(ws@8.18.0)
|
||||
normalize-path: 3.0.0
|
||||
openapi-typescript-fetch: 1.1.3
|
||||
path-browserify: 1.0.1
|
||||
'@bufbuild/protobuf': 1.10.0
|
||||
'@connectrpc/connect': 1.6.1(@bufbuild/protobuf@1.10.0)
|
||||
'@connectrpc/connect-web': 1.6.1(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.6.1)
|
||||
compare-versions: 6.1.1
|
||||
openapi-fetch: 0.9.8
|
||||
platform: 1.3.6
|
||||
ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@6.0.4)
|
||||
optionalDependencies:
|
||||
bufferutil: 4.0.8
|
||||
utf-8-validate: 6.0.4
|
||||
dev: false
|
||||
|
||||
/earcut@3.0.0:
|
||||
resolution: {integrity: sha512-41Fs7Q/PLq1SDbqjsgcY7GA42T0jvaCNGXgGtsNdvg+Yv8eIu06bxv4/PoREkZ9nMDNwnUSG9OFB9+yv8eKhDg==}
|
||||
dev: false
|
||||
|
||||
/eastasianwidth@0.2.0:
|
||||
@ -2883,6 +2987,25 @@ packages:
|
||||
safe-buffer: 5.2.1
|
||||
dev: false
|
||||
|
||||
/echarts-for-react@3.0.2(echarts@5.5.1)(react@18.3.1):
|
||||
resolution: {integrity: sha512-DRwIiTzx8JfwPOVgGttDytBqdp5VzCSyMRIxubgU/g2n9y3VLUmF2FK7Icmg/sNVkv4+rktmrLN9w22U2yy3fA==}
|
||||
peerDependencies:
|
||||
echarts: ^3.0.0 || ^4.0.0 || ^5.0.0
|
||||
react: ^15.0.0 || >=16.0.0
|
||||
dependencies:
|
||||
echarts: 5.5.1
|
||||
fast-deep-equal: 3.1.3
|
||||
react: 18.3.1
|
||||
size-sensor: 1.0.2
|
||||
dev: false
|
||||
|
||||
/echarts@5.5.1:
|
||||
resolution: {integrity: sha512-Fce8upazaAXUVUVsjgV6mBnGuqgO+JNDlcgF79Dksy4+wgGpQB2lmYoO4TSweFg/mZITdpGHomw/cNBJZj1icA==}
|
||||
dependencies:
|
||||
tslib: 2.3.0
|
||||
zrender: 5.6.0
|
||||
dev: false
|
||||
|
||||
/embla-carousel-autoplay@8.3.0(embla-carousel@8.3.0):
|
||||
resolution: {integrity: sha512-h7DFJLf9uQD+XDxr1NwA3/oFIjsnj/iED2RjET5u6/svMec46IbF1CYPhmB5Q/1Fc0WkcvhPpsEsrtVXQLxNzA==}
|
||||
peerDependencies:
|
||||
@ -3400,7 +3523,6 @@ packages:
|
||||
|
||||
/fast-deep-equal@3.1.3:
|
||||
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
|
||||
dev: true
|
||||
|
||||
/fast-equals@5.0.1:
|
||||
resolution: {integrity: sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==}
|
||||
@ -3591,6 +3713,10 @@ packages:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/geojson-vt@4.0.2:
|
||||
resolution: {integrity: sha512-AV9ROqlNqoZEIJGfm1ncNjEXfkz2hdFlZf0qkVfmkwdKa8vj7H16YUOT81rJw1rdFhyEDlN2Tds91p/glzbl5A==}
|
||||
dev: false
|
||||
|
||||
/get-intrinsic@1.2.4:
|
||||
resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@ -3622,6 +3748,10 @@ packages:
|
||||
resolve-pkg-maps: 1.0.0
|
||||
dev: true
|
||||
|
||||
/gl-matrix@3.4.3:
|
||||
resolution: {integrity: sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA==}
|
||||
dev: false
|
||||
|
||||
/glob-parent@5.1.2:
|
||||
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
|
||||
engines: {node: '>= 6'}
|
||||
@ -3724,6 +3854,10 @@ packages:
|
||||
resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
|
||||
dev: true
|
||||
|
||||
/grid-index@1.1.0:
|
||||
resolution: {integrity: sha512-HZRwumpOGUrHyxO5bqKZL0B0GlUpwtCAzZ42sgxUPniu33R1LSFH5yrIcBCHjkctCAh3mtWKcKd9J4vDDdeVHA==}
|
||||
dev: false
|
||||
|
||||
/gtoken@7.1.0:
|
||||
resolution: {integrity: sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
@ -3932,6 +4066,10 @@ packages:
|
||||
safer-buffer: 2.1.2
|
||||
dev: false
|
||||
|
||||
/ieee754@1.2.1:
|
||||
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
|
||||
dev: false
|
||||
|
||||
/ignore@5.3.2:
|
||||
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
|
||||
engines: {node: '>= 4'}
|
||||
@ -4244,20 +4382,12 @@ packages:
|
||||
/isexe@2.0.0:
|
||||
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
||||
|
||||
/isomorphic-ws@5.0.0(ws@8.18.0):
|
||||
resolution: {integrity: sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==}
|
||||
peerDependencies:
|
||||
ws: '*'
|
||||
dependencies:
|
||||
ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@6.0.4)
|
||||
dev: false
|
||||
|
||||
/isows@1.0.6(ws@8.18.0):
|
||||
resolution: {integrity: sha512-lPHCayd40oW98/I0uvgaHKWCSvkzY27LjWLbtzOm64yQ+G3Q5npjjbdppU65iZXkK1Zt+kH9pfegli0AYfwYYw==}
|
||||
peerDependencies:
|
||||
ws: '*'
|
||||
dependencies:
|
||||
ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@6.0.4)
|
||||
ws: 8.18.0
|
||||
dev: false
|
||||
|
||||
/iterator.prototype@1.1.3:
|
||||
@ -4372,6 +4502,10 @@ packages:
|
||||
commander: 8.3.0
|
||||
dev: false
|
||||
|
||||
/kdbush@4.0.2:
|
||||
resolution: {integrity: sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==}
|
||||
dev: false
|
||||
|
||||
/keyv@4.5.4:
|
||||
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
|
||||
dependencies:
|
||||
@ -4468,6 +4602,39 @@ packages:
|
||||
'@jridgewell/sourcemap-codec': 1.5.0
|
||||
dev: false
|
||||
|
||||
/mapbox-gl@3.7.0:
|
||||
resolution: {integrity: sha512-dCbVyH1uGobwv6f4QKRv2Z2wuVT/RmspsudK3sTxGRFxZi6Pd2P9axdbVyZpmGddCAREy44pHhvzvO0qgpdKAg==}
|
||||
dependencies:
|
||||
'@mapbox/jsonlint-lines-primitives': 2.0.2
|
||||
'@mapbox/mapbox-gl-supported': 3.0.0
|
||||
'@mapbox/point-geometry': 0.1.0
|
||||
'@mapbox/tiny-sdf': 2.0.6
|
||||
'@mapbox/unitbezier': 0.0.1
|
||||
'@mapbox/vector-tile': 1.3.1
|
||||
'@mapbox/whoots-js': 3.1.0
|
||||
'@types/geojson': 7946.0.14
|
||||
'@types/geojson-vt': 3.2.5
|
||||
'@types/mapbox__point-geometry': 0.1.4
|
||||
'@types/mapbox__vector-tile': 1.3.4
|
||||
'@types/pbf': 3.0.5
|
||||
'@types/supercluster': 7.1.3
|
||||
cheap-ruler: 4.0.0
|
||||
csscolorparser: 1.0.3
|
||||
earcut: 3.0.0
|
||||
geojson-vt: 4.0.2
|
||||
gl-matrix: 3.4.3
|
||||
grid-index: 1.1.0
|
||||
kdbush: 4.0.2
|
||||
murmurhash-js: 1.0.0
|
||||
pbf: 3.3.0
|
||||
potpack: 2.0.0
|
||||
quickselect: 3.0.0
|
||||
serialize-to-js: 3.1.2
|
||||
supercluster: 8.0.1
|
||||
tinyqueue: 3.0.0
|
||||
vt-pbf: 3.1.3
|
||||
dev: false
|
||||
|
||||
/markdown-table@3.0.3:
|
||||
resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==}
|
||||
dev: false
|
||||
@ -4999,6 +5166,10 @@ packages:
|
||||
/ms@2.1.3:
|
||||
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
||||
|
||||
/murmurhash-js@1.0.0:
|
||||
resolution: {integrity: sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw==}
|
||||
dev: false
|
||||
|
||||
/mz@2.7.0:
|
||||
resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
|
||||
dependencies:
|
||||
@ -5090,11 +5261,6 @@ packages:
|
||||
whatwg-url: 5.0.0
|
||||
dev: false
|
||||
|
||||
/node-gyp-build@4.8.2:
|
||||
resolution: {integrity: sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==}
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/normalize-path@3.0.0:
|
||||
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@ -5205,9 +5371,14 @@ packages:
|
||||
- encoding
|
||||
dev: false
|
||||
|
||||
/openapi-typescript-fetch@1.1.3:
|
||||
resolution: {integrity: sha512-smLZPck4OkKMNExcw8jMgrMOGgVGx2N/s6DbKL2ftNl77g5HfoGpZGFy79RBzU/EkaO0OZpwBnslfdBfh7ZcWg==}
|
||||
engines: {node: '>= 12.0.0', npm: '>= 7.0.0'}
|
||||
/openapi-fetch@0.9.8:
|
||||
resolution: {integrity: sha512-zM6elH0EZStD/gSiNlcPrzXcVQ/pZo3BDvC6CDwRDUt1dDzxlshpmQnpD6cZaJ39THaSmwVCxxRrPKNM1hHrDg==}
|
||||
dependencies:
|
||||
openapi-typescript-helpers: 0.0.8
|
||||
dev: false
|
||||
|
||||
/openapi-typescript-helpers@0.0.8:
|
||||
resolution: {integrity: sha512-1eNjQtbfNi5Z/kFhagDIaIRj6qqDzhjNJKz8cmMW0CVdGwT6e1GLbAfgI0d28VTJa1A8jz82jm/4dG8qNoNS8g==}
|
||||
dev: false
|
||||
|
||||
/optionator@0.9.4:
|
||||
@ -5289,10 +5460,6 @@ packages:
|
||||
entities: 4.5.0
|
||||
dev: false
|
||||
|
||||
/path-browserify@1.0.1:
|
||||
resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
|
||||
dev: false
|
||||
|
||||
/path-exists@4.0.0:
|
||||
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
|
||||
engines: {node: '>=8'}
|
||||
@ -5322,6 +5489,14 @@ packages:
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/pbf@3.3.0:
|
||||
resolution: {integrity: sha512-XDF38WCH3z5OV/OVa8GKUNtLAyneuzbCisx7QUCF8Q6Nutx0WnJrQe5O+kOtBlLfRNUws98Y58Lblp+NJG5T4Q==}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
ieee754: 1.2.1
|
||||
resolve-protobuf-schema: 2.1.0
|
||||
dev: false
|
||||
|
||||
/periscopic@3.1.0:
|
||||
resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==}
|
||||
dependencies:
|
||||
@ -5434,6 +5609,10 @@ packages:
|
||||
picocolors: 1.1.0
|
||||
source-map-js: 1.2.1
|
||||
|
||||
/potpack@2.0.0:
|
||||
resolution: {integrity: sha512-Q+/tYsFU9r7xoOJ+y/ZTtdVQwTWfzjbiXBDMM/JKUux3+QPP02iUuIoeBQ+Ot6oEDlC+/PGjB/5A3K7KKb7hcw==}
|
||||
dev: false
|
||||
|
||||
/prelude-ls@1.2.1:
|
||||
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
@ -5466,6 +5645,10 @@ packages:
|
||||
resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==}
|
||||
dev: false
|
||||
|
||||
/protocol-buffers-schema@3.6.0:
|
||||
resolution: {integrity: sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==}
|
||||
dev: false
|
||||
|
||||
/proxy-from-env@1.1.0:
|
||||
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
|
||||
dev: false
|
||||
@ -5478,6 +5661,10 @@ packages:
|
||||
/queue-microtask@1.2.3:
|
||||
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
|
||||
|
||||
/quickselect@3.0.0:
|
||||
resolution: {integrity: sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==}
|
||||
dev: false
|
||||
|
||||
/react-dom@18.3.1(react@18.3.1):
|
||||
resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==}
|
||||
peerDependencies:
|
||||
@ -5782,6 +5969,12 @@ packages:
|
||||
resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
|
||||
dev: true
|
||||
|
||||
/resolve-protobuf-schema@2.1.0:
|
||||
resolution: {integrity: sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==}
|
||||
dependencies:
|
||||
protocol-buffers-schema: 3.6.0
|
||||
dev: false
|
||||
|
||||
/resolve@1.22.8:
|
||||
resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==}
|
||||
hasBin: true
|
||||
@ -5869,6 +6062,11 @@ packages:
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/serialize-to-js@3.1.2:
|
||||
resolution: {integrity: sha512-owllqNuDDEimQat7EPG0tH7JjO090xKNzUtYz6X+Sk2BXDnOCilDdNLwjWeFywG9xkJul1ULvtUQa9O4pUaY0w==}
|
||||
engines: {node: '>=4.0.0'}
|
||||
dev: false
|
||||
|
||||
/server-only@0.0.1:
|
||||
resolution: {integrity: sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==}
|
||||
dev: false
|
||||
@ -5919,6 +6117,10 @@ packages:
|
||||
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
/size-sensor@1.0.2:
|
||||
resolution: {integrity: sha512-2NCmWxY7A9pYKGXNBfteo4hy14gWu47rg5692peVMst6lQLPKrVjhY+UTEsPI5ceFRJSl3gVgMYaUi/hKuaiKw==}
|
||||
dev: false
|
||||
|
||||
/slash@3.0.0:
|
||||
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
|
||||
engines: {node: '>=8'}
|
||||
@ -6107,6 +6309,12 @@ packages:
|
||||
pirates: 4.0.6
|
||||
ts-interface-checker: 0.1.13
|
||||
|
||||
/supercluster@8.0.1:
|
||||
resolution: {integrity: sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==}
|
||||
dependencies:
|
||||
kdbush: 4.0.2
|
||||
dev: false
|
||||
|
||||
/supports-color@7.2.0:
|
||||
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
|
||||
engines: {node: '>=8'}
|
||||
@ -6222,10 +6430,19 @@ packages:
|
||||
dependencies:
|
||||
any-promise: 1.3.0
|
||||
|
||||
/throttleit@2.1.0:
|
||||
resolution: {integrity: sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw==}
|
||||
engines: {node: '>=18'}
|
||||
dev: false
|
||||
|
||||
/tiny-invariant@1.3.3:
|
||||
resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==}
|
||||
dev: false
|
||||
|
||||
/tinyqueue@3.0.0:
|
||||
resolution: {integrity: sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==}
|
||||
dev: false
|
||||
|
||||
/to-fast-properties@2.0.0:
|
||||
resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
|
||||
engines: {node: '>=4'}
|
||||
@ -6270,6 +6487,10 @@ packages:
|
||||
strip-bom: 3.0.0
|
||||
dev: true
|
||||
|
||||
/tslib@2.3.0:
|
||||
resolution: {integrity: sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==}
|
||||
dev: false
|
||||
|
||||
/tslib@2.7.0:
|
||||
resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==}
|
||||
dev: false
|
||||
@ -6471,14 +6692,6 @@ packages:
|
||||
react: 18.3.1
|
||||
dev: false
|
||||
|
||||
/utf-8-validate@6.0.4:
|
||||
resolution: {integrity: sha512-xu9GQDeFp+eZ6LnCywXN/zBancWvOpUMzgjLPSjy4BRHSmTelvn2E0DG0o1sTiw5hkCKBHo8rwSKncfRfv2EEQ==}
|
||||
engines: {node: '>=6.14.2'}
|
||||
requiresBuild: true
|
||||
dependencies:
|
||||
node-gyp-build: 4.8.2
|
||||
dev: false
|
||||
|
||||
/util-deprecate@1.0.2:
|
||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||
|
||||
@ -6527,6 +6740,14 @@ packages:
|
||||
d3-timer: 3.0.1
|
||||
dev: false
|
||||
|
||||
/vt-pbf@3.1.3:
|
||||
resolution: {integrity: sha512-2LzDFzt0mZKZ9IpVF2r69G9bXaP2Q2sArJCmcCgvfTdCCZzSyz4aCLoQyUilu37Ll56tCblIZrXFIjNUpGIlmA==}
|
||||
dependencies:
|
||||
'@mapbox/point-geometry': 0.1.0
|
||||
'@mapbox/vector-tile': 1.3.1
|
||||
pbf: 3.3.0
|
||||
dev: false
|
||||
|
||||
/vue@3.5.11(typescript@5.6.2):
|
||||
resolution: {integrity: sha512-/8Wurrd9J3lb72FTQS7gRMNQD4nztTtKPmuDuPuhqXmmpD6+skVjAeahNpVzsuky6Sy9gy7wn8UadqPtt9SQIg==}
|
||||
peerDependencies:
|
||||
@ -6656,7 +6877,7 @@ packages:
|
||||
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
||||
dev: true
|
||||
|
||||
/ws@8.18.0(bufferutil@4.0.8)(utf-8-validate@6.0.4):
|
||||
/ws@8.18.0:
|
||||
resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
peerDependencies:
|
||||
@ -6667,9 +6888,6 @@ packages:
|
||||
optional: true
|
||||
utf-8-validate:
|
||||
optional: true
|
||||
dependencies:
|
||||
bufferutil: 4.0.8
|
||||
utf-8-validate: 6.0.4
|
||||
dev: false
|
||||
|
||||
/xtend@4.0.2:
|
||||
@ -6687,14 +6905,6 @@ packages:
|
||||
engines: {node: '>=10'}
|
||||
dev: true
|
||||
|
||||
/zod-to-json-schema@3.23.2(zod@3.23.8):
|
||||
resolution: {integrity: sha512-uSt90Gzc/tUfyNqxnjlfBs8W6WSGpNBv0rVsNxP/BVSMHMKGdthPYff4xtCHYloJGM0CFxFsb3NbC0eqPhfImw==}
|
||||
peerDependencies:
|
||||
zod: ^3.23.3
|
||||
dependencies:
|
||||
zod: 3.23.8
|
||||
dev: false
|
||||
|
||||
/zod-to-json-schema@3.23.3(zod@3.23.8):
|
||||
resolution: {integrity: sha512-TYWChTxKQbRJp5ST22o/Irt9KC5nj7CdBKYB/AosCRdj/wxEMvv4NNaj9XVUHDOIp53ZxArGhnw5HMZziPFjog==}
|
||||
peerDependencies:
|
||||
@ -6707,6 +6917,12 @@ packages:
|
||||
resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==}
|
||||
dev: false
|
||||
|
||||
/zrender@5.6.0:
|
||||
resolution: {integrity: sha512-uzgraf4njmmHAbEUxMJ8Oxg+P3fT04O+9p7gY+wJRVxo8Ge+KmYv0WJev945EH4wFuc4OY2NLXz46FZrWS9xJg==}
|
||||
dependencies:
|
||||
tslib: 2.3.0
|
||||
dev: false
|
||||
|
||||
/zwitch@2.0.4:
|
||||
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
|
||||
dev: false
|
||||
|
||||
Loading…
Reference in New Issue
Block a user