WIP: Interactive charts and MapBox integration

This commit is contained in:
zaidmukaddam 2024-11-05 13:12:18 +05:30
parent a3415adee1
commit 065bbe7887
10 changed files with 965 additions and 450 deletions

View File

@ -1,6 +1,5 @@
'use server'; 'use server';
import { OpenAI } from 'openai';
import { generateObject } from 'ai'; import { generateObject } from 'ai';
import { createOpenAI as createGroq } from '@ai-sdk/openai'; import { createOpenAI as createGroq } from '@ai-sdk/openai';
import { z } from 'zod'; import { z } from 'zod';
@ -15,7 +14,7 @@ export async function suggestQuestions(history: any[]) {
'use server'; 'use server';
const { object } = await generateObject({ const { object } = await generateObject({
model: groq('llama-3.2-90b-text-preview'), model: groq('llama-3.2-11b-text-preview'),
temperature: 0, temperature: 0,
system: 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. `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.

View File

@ -5,10 +5,10 @@ import {
convertToCoreMessages, convertToCoreMessages,
streamText, streamText,
tool, tool,
experimental_createProviderRegistry experimental_createProviderRegistry,
} from "ai"; } from "ai";
import { BlobRequestAbortedError, put } from '@vercel/blob'; import { BlobRequestAbortedError, put } from '@vercel/blob';
import { CodeInterpreter } from "@e2b/code-interpreter"; import CodeInterpreter from "@e2b/code-interpreter";
import FirecrawlApp from '@mendable/firecrawl-js'; import FirecrawlApp from '@mendable/firecrawl-js';
// Allow streaming responses up to 60 seconds // Allow streaming responses up to 60 seconds
@ -38,19 +38,30 @@ type SearchResultImage =
number_of_results?: number 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) { export async function POST(req: Request) {
const { messages, model } = await req.json(); const { messages, model } = await req.json();
const provider = model.split(":")[0]; const provider = model.split(":")[0];
const result = await streamText({ const result = await streamText({
maxSteps: 10,
model: registry.languageModel(model), model: registry.languageModel(model),
messages: convertToCoreMessages(messages), messages: convertToCoreMessages(messages),
temperature: provider === "azure" ? 0.72 : 0, temperature: provider === "azure" ? 0.72 : 0,
topP: 0.5, topP: 0.5,
frequencyPenalty: 0, frequencyPenalty: 0,
presencePenalty: 0, presencePenalty: 0,
experimental_activeTools: ["get_weather_data","programming", "web_search", "text_translate"], experimental_activeTools: ["get_weather_data", "programming", "web_search", "text_translate"],
system: ` system: `
You are an expert AI web search engine called MiniPerplx, that helps users find information on the internet with no bullshit talks. 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!! 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 }) => { execute: async ({ code }: { code: string }) => {
const sandbox = await CodeInterpreter.create(); const sandbox = await CodeInterpreter.create();
const execution = await sandbox.notebook.execCell(code); const execution = await sandbox.runCode(code);
let message = ""; let message = "";
let images = []; let images = [];
@ -424,98 +435,177 @@ When asked a "What is" question, maintain the same format as the question and an
} }
} }
sandbox.close(); if (execution.error) {
return { message: message.trim(), images }; 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({ nearby_search: tool({
description: "Search for nearby places using Google Maps API.", description: "Search for nearby places using Mapbox API.",
parameters: z.object({ parameters: z.object({
location: z.string().describe("The location to search near (e.g., 'New York City' or '1600 Amphitheatre Parkway, Mountain View, CA')."), 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)."), 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."), 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)."), 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 }) => { execute: async ({ location, type, keyword, radius }: {
const apiKey = process.env.GOOGLE_MAPS_API_KEY; location: string;
type: string;
keyword?: string;
radius: number;
}) => {
const mapboxToken = process.env.MAPBOX_ACCESS_TOKEN;
// First, use the Geocoding API to get the coordinates // First geocode the location
const geocodeUrl = `https://maps.googleapis.com/maps/api/geocode/json?address=${encodeURIComponent(location)}&key=${apiKey}`; const locationData = await geocodeAddress(location);
const geocodeResponse = await fetch(geocodeUrl); const [lng, lat] = locationData.center;
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}`;
// Construct search query
let searchQuery = type;
if (keyword) { if (keyword) {
searchUrl += `&keyword=${encodeURIComponent(keyword)}`; searchQuery = `${keyword} ${type}`;
} }
const searchResponse = await fetch(searchUrl); // Search for places using Mapbox Geocoding API
const searchData = await searchResponse.json(); 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 { return {
results: searchData.results.slice(0, 5).map((place: any) => ({ results: results.slice(0, 5),
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,
})),
center: { lat, lng }, center: { lat, lng },
formatted_address: geocodeData.results[0].formatted_address, formatted_address: locationData.place_name,
}; };
}, },
}), }),
find_place: tool({ find_place: tool({
description: "Find a specific place using Google Maps API.", description: "Find a specific place using Mapbox API.",
parameters: z.object({ parameters: z.object({
input: z.string().describe("The place to search for (e.g., 'Museum of Contemporary Art Australia')."), 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)."), inputtype: z.enum(["textquery", "phonenumber"]).describe("The type of input (textquery or phonenumber)."),
}), }),
execute: async ({ input, inputtype }: { input: string; inputtype: "textquery" | "phonenumber" }) => { execute: async ({ input, inputtype }: {
console.log("input", input); input: string;
const apiKey = process.env.GOOGLE_MAPS_API_KEY; inputtype: "textquery" | "phonenumber";
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}`; }) => {
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(); 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({ 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({ parameters: z.object({
query: z.string().describe("The search query (e.g., '123 main street')."), 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')."), 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)."), 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 }) => { execute: async ({ query, location, radius }: {
const apiKey = process.env.GOOGLE_MAPS_API_KEY; query: string;
console.log("query", query); location?: string;
console.log("location", location); radius?: number;
console.log("radius", radius); }) => {
let url = `https://maps.googleapis.com/maps/api/place/textsearch/json?query=${encodeURIComponent(query)}&key=${apiKey}`; const mapboxToken = process.env.MAPBOX_ACCESS_TOKEN;
let proximity = '';
if (location) { if (location) {
url += `&location=${encodeURIComponent(location)}`; const [lng, lat] = location.split(',').map(Number);
} proximity = `&proximity=${lng},${lat}`;
if (radius) {
url += `&radius=${radius}`;
} }
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(); 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({ text_translate: tool({

View File

@ -1,6 +1,6 @@
import { cohere } from '@ai-sdk/cohere' import { cohere } from '@ai-sdk/cohere'
import { convertToCoreMessages, streamText, tool } from "ai"; import { convertToCoreMessages, streamText, tool } from "ai";
import { CodeInterpreter } from "@e2b/code-interpreter"; import CodeInterpreter from "@e2b/code-interpreter";
import { z } from "zod"; import { z } from "zod";
import { geolocation } from "@vercel/functions"; 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 }) => { execute: async ({ code }: { code: string }) => {
const sandbox = await CodeInterpreter.create(); const sandbox = await CodeInterpreter.create();
const execution = await sandbox.notebook.execCell(code); const execution = await sandbox.runCode(code);
let message = ""; let message = "";
let images = []; 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 }; return { message: message.trim(), images };
}, },
}), }),

View File

@ -1,5 +1,6 @@
import "./globals.css"; import "./globals.css";
import 'katex/dist/katex.min.css'; import 'katex/dist/katex.min.css';
import 'mapbox-gl/dist/mapbox-gl.css';
import { Metadata, Viewport } from "next"; import { Metadata, Viewport } from "next";
import { Toaster } from "sonner"; import { Toaster } from "sonner";
import { Inter, Instrument_Serif, IBM_Plex_Mono } from 'next/font/google'; import { Inter, Instrument_Serif, IBM_Plex_Mono } from 'next/font/google';

View File

@ -19,7 +19,7 @@ import Marked, { ReactRenderer } from 'marked-react';
import { track } from '@vercel/analytics'; import { track } from '@vercel/analytics';
import { useSearchParams } from 'next/navigation'; import { useSearchParams } from 'next/navigation';
import { useChat } from 'ai/react'; import { useChat } from 'ai/react';
import { ChatRequestOptions, CreateMessage, Message, ToolInvocation } from 'ai'; import { ToolInvocation } from 'ai';
import { toast } from 'sonner'; import { toast } from 'sonner';
import { motion, AnimatePresence } from 'framer-motion'; import { motion, AnimatePresence } from 'framer-motion';
import Image from 'next/image'; import Image from 'next/image';
@ -88,32 +88,17 @@ import {
import { Input } from '@/components/ui/input'; import { Input } from '@/components/ui/input';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge'; import { Badge } from '@/components/ui/badge';
import { Line, LineChart, CartesianGrid, XAxis, YAxis, ResponsiveContainer } from "recharts";
import { import {
Card, Card,
CardContent, CardContent,
CardDescription,
CardFooter,
CardHeader, CardHeader,
CardTitle, CardTitle,
} from "@/components/ui/card"; } from "@/components/ui/card";
import {
ChartConfig,
ChartContainer,
ChartTooltip,
ChartTooltipContent,
} from "@/components/ui/chart";
import { GitHubLogoIcon, PlusCircledIcon } from '@radix-ui/react-icons'; import { GitHubLogoIcon, PlusCircledIcon } from '@radix-ui/react-icons';
import { Skeleton } from '@/components/ui/skeleton'; import { Skeleton } from '@/components/ui/skeleton';
import Link from 'next/link'; import Link from 'next/link';
import { Dialog, DialogContent } from "@/components/ui/dialog"; import { Dialog, DialogContent } from "@/components/ui/dialog";
import { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious } from "@/components/ui/carousel"; 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 { cn } from '@/lib/utils';
import { import {
Table, Table,
@ -124,6 +109,8 @@ import {
import Autoplay from 'embla-carousel-autoplay'; import Autoplay from 'embla-carousel-autoplay';
import FormComponent from '@/components/ui/form-component'; import FormComponent from '@/components/ui/form-component';
import WeatherChart from '@/components/weather-chart'; import WeatherChart from '@/components/weather-chart';
import { MapContainer } from '@/components/map-components';
import InteractiveChart from '@/components/interactive-charts';
export const maxDuration = 60; 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" /> <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> <span className="text-neutral-700 dark:text-neutral-300 text-lg">Searching nearby places...</span>
</div> </div>
<div className="flex space-x-1"> <motion.div className="flex space-x-1">
{[0, 1, 2].map((index) => ( {[0, 1, 2].map((index) => (
<motion.div <motion.div
key={index} 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> </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 ( return (
<Card className="w-full my-4 overflow-hidden bg-white dark:bg-neutral-800 border-neutral-200 dark:border-neutral-700"> <MapContainer
<CardHeader> title={`Nearby ${args.type ? args.type.charAt(0).toUpperCase() + args.type.slice(1) + 's' : 'Places'}`}
<CardTitle className="flex items-center gap-2 text-neutral-800 dark:text-neutral-100"> center={result.center}
<MapPin className="h-5 w-5 text-primary" /> places={result.results}
<span>Nearby {args.type ? args.type.charAt(0).toUpperCase() + args.type.slice(1) + 's' : 'Places'}</span> loading={isLoading}
{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>
); );
} }
@ -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') { 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') { 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 Images
</TabsTrigger> </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> </TabsList>
<TabsContent value="code" className="p-0 m-0 rounded-none"> <TabsContent value="code" className="p-0 m-0 rounded-none">
<div className="relative"> <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> </div>
</TabsContent> </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> </Tabs>
</div> </div>
</AccordionContent> </AccordionContent>

View 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;

View File

@ -1,207 +1,189 @@
import React, { useRef, useState, useEffect, useCallback, memo } from 'react'; import React, { useEffect, useRef, useState } from 'react';
import { Card, CardHeader, CardContent, CardTitle } from "@/components/ui/card"; import mapboxgl from 'mapbox-gl';
import { Badge } from "@/components/ui/badge"; 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 { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion";
import { Badge } from "@/components/ui/badge";
import { MapPin, Star } from 'lucide-react'; import { MapPin, Star } from 'lucide-react';
import { Skeleton } from '@/components/ui/skeleton'; import { Skeleton } from "@/components/ui/skeleton";
const isValidCoordinate = (coord: number) => { mapboxgl.accessToken = process.env.NEXT_PUBLIC_MAPBOX_TOKEN || '';
return typeof coord === 'number' && !isNaN(coord) && isFinite(coord);
};
const loadGoogleMapsScript = (callback: () => void) => { interface Location {
if (window.google && window.google.maps) { lat: number;
callback(); lng: number;
return; }
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'); useEffect(() => {
if (existingScript) { if (!map.current) return;
existingScript.remove();
}
window.initMap = callback; // Update center when it changes
const script = document.createElement('script'); map.current.flyTo({
script.id = 'googleMapsScript'; center: [center.lng, center.lat],
script.src = `https://maps.googleapis.com/maps/api/js?key=${process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY}&libraries=places,marker&callback=initMap`; essential: true
script.async = true; });
script.defer = true;
document.head.appendChild(script);
};
const MapComponent = React.memo(({ center, places }: { center: { lat: number; lng: number }, places: any[] }) => { // Clear existing markers
const mapRef = useRef<HTMLDivElement>(null); markers.current.forEach(marker => marker.remove());
const [mapError, setMapError] = useState<string | null>(null); markers.current = [];
const googleMapRef = useRef<google.maps.Map | null>(null);
const markersRef = useRef<google.maps.marker.AdvancedMarkerElement[]>([]);
const initializeMap = useCallback(async () => { // Add new markers
if (mapRef.current && isValidCoordinate(center.lat) && isValidCoordinate(center.lng)) { places.forEach(place => {
const { Map } = await google.maps.importLibrary("maps") as google.maps.MapsLibrary; const el = document.createElement('div');
const { AdvancedMarkerElement } = await google.maps.importLibrary("marker") as google.maps.MarkerLibrary; 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) { const marker = new mapboxgl.Marker(el)
googleMapRef.current = new Map(mapRef.current, { .setLngLat([place.location.lng, place.location.lat])
center: center, .setPopup(
zoom: 14, new mapboxgl.Popup({ offset: 25 })
mapId: "347ff92e0c7225cf", .setHTML(
}); `<strong>${place.name}</strong>${place.rating ?
} else { `<br>Rating: ${place.rating} ⭐ (${place.user_ratings_total} reviews)` :
googleMapRef.current.setCenter(center); ''}`
} )
)
.addTo(map.current!);
markersRef.current.forEach(marker => marker.map = null); markers.current.push(marker);
markersRef.current = []; });
}, [center, places]);
places.forEach((place) => { if (mapError) {
if (isValidCoordinate(place.location.lat) && isValidCoordinate(place.location.lng)) { return (
const marker = new AdvancedMarkerElement({ <div className="h-64 flex items-center justify-center bg-neutral-100 dark:bg-neutral-800 text-neutral-800 dark:text-neutral-200">
map: googleMapRef.current, {mapError}
position: place.location, </div>
title: place.name, );
}); }
markersRef.current.push(marker);
}
});
} else {
setMapError('Invalid coordinates provided');
}
}, [center, places]);
useEffect(() => { return <div ref={mapContainer} className="w-full h-64" />;
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" />;
}); });
MapComponent.displayName = 'MapComponent'; MapComponent.displayName = 'MapComponent';
const MapSkeleton = () => ( 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 }) => ( const PlaceDetails = ({ place }: { place: Place }) => (
<div className="flex justify-between items-start py-2"> <div className="flex justify-between items-start py-2">
<div> <div>
<h4 className="font-semibold text-neutral-800 dark:text-neutral-200">{place.name}</h4> <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 && (
{place.vicinity} <p className="text-sm text-neutral-600 dark:text-neutral-400 max-w-[200px]" title={place.vicinity}>
</p> {place.vicinity}
</div> </p>
{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> </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 }) => { interface MapContainerProps {
const apiKey = process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY; title: string;
const mapUrl = `https://www.google.com/maps/embed/v1/place?key=${apiKey}&q=${encodeURIComponent(location)}&zoom=${zoom}`; center: Location;
places?: Place[];
loading?: boolean;
}
const MapContainer: React.FC<MapContainerProps> = ({ title, center, places = [], loading = false }) => {
if (loading) {
return ( return (
<div className="aspect-video w-full"> <Card className="w-full my-4 bg-white dark:bg-neutral-800 border-neutral-200 dark:border-neutral-700">
<iframe <CardHeader>
width="100%" <Skeleton className="h-6 w-3/4 bg-neutral-200 dark:bg-neutral-700" />
height="100%" </CardHeader>
style={{ border: 0 }} <CardContent className="p-0 rounded-t-none rounded-b-xl">
loading="lazy" <MapSkeleton />
allowFullScreen </CardContent>
referrerPolicy="no-referrer-when-downgrade" </Card>
src={mapUrl}
className='rounded-xl'
></iframe>
</div>
); );
}); }
MapEmbed.displayName = 'MapEmbed'; return (
<Card className="w-full my-4 overflow-hidden bg-white dark:bg-neutral-800 border-neutral-200 dark:border-neutral-700">
const FindPlaceResult = memo(({ result }: { result: any }) => { <CardHeader>
const place = result.candidates[0]; <CardTitle className="flex items-center gap-2 text-neutral-800 dark:text-neutral-100">
const location = `${place.geometry.location.lat},${place.geometry.location.lng}`; <MapPin className="h-5 w-5 text-primary" />
<span>{title}</span>
return ( </CardTitle>
<Card className="w-full my-4 overflow-hidden shadow-none bg-white dark:bg-neutral-800 border-neutral-200 dark:border-neutral-700"> </CardHeader>
<CardHeader> <CardContent className="p-0">
<CardTitle className="flex items-center gap-2 text-neutral-800 dark:text-neutral-100"> <MapComponent center={center} places={places} />
<MapPin className="h-5 w-5 text-primary" /> {places.length > 0 && (
<span>{place.name}</span> <Accordion type="single" collapsible className="w-full">
</CardTitle> <AccordionItem value="place-details">
</CardHeader> <AccordionTrigger className="px-4 text-neutral-800 dark:text-neutral-200">
<CardContent> Place Details
<MapEmbed location={location} /> </AccordionTrigger>
<div className="mt-4 space-y-2 text-neutral-800 dark:text-neutral-200"> <AccordionContent>
<p><strong>Address:</strong> {place.formatted_address}</p> <div className="px-4 space-y-4 max-h-64 overflow-y-auto">
{place.rating && ( {places.map((place, index) => (
<div className="flex items-center"> <PlaceDetails key={index} place={place} />
<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>
)}
</div> </div>
</CardContent> </AccordionContent>
</Card> </AccordionItem>
); </Accordion>
}); )}
</CardContent>
</Card>
);
};
FindPlaceResult.displayName = 'FindPlaceResult'; export { MapComponent, MapSkeleton, MapContainer, PlaceDetails };
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 };

View File

@ -23,8 +23,9 @@ interface ModelSwitcherProps {
} }
const models = [ const models = [
{ value: "azure:gpt4o-mini", label: "GPT-4o Mini", icon: Zap, description: "High speed, good quality", color: "emerald" }, { value: "azure:gpt4o-mini", label: "GPT-4o Mini", icon: Zap, description: "God 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: "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" }, { 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 return isSelected
? `${baseClasses} ${selectedClasses} !bg-blue-500 dark:!bg-blue-600 !text-white hover:!bg-blue-600 dark:hover:!bg-blue-700` ? `${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`; : `${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: default:
return isSelected return isSelected
? `${baseClasses} ${selectedClasses} !bg-neutral-500 dark:!bg-neutral-600 !text-white hover:!bg-neutral-600 dark:hover:!bg-neutral-700` ? `${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 <ModelSwitcher
selectedModel={selectedModel} selectedModel={selectedModel}
setSelectedModel={setSelectedModel} setSelectedModel={setSelectedModel}
/> />
</div> </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 <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" 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) => { onClick={(event) => {

View File

@ -9,14 +9,14 @@
"lint": "next lint" "lint": "next lint"
}, },
"dependencies": { "dependencies": {
"@ai-sdk/anthropic": "^0.0.51", "@ai-sdk/anthropic": "^0.0.55",
"@ai-sdk/azure": "^0.0.31", "@ai-sdk/azure": "^0.0.51",
"@ai-sdk/cohere": "latest", "@ai-sdk/cohere": "latest",
"@ai-sdk/google": "^0.0.52", "@ai-sdk/google": "^0.0.52",
"@ai-sdk/groq": "^0.0.1", "@ai-sdk/groq": "^0.0.1",
"@ai-sdk/mistral": "^0.0.41", "@ai-sdk/mistral": "^0.0.41",
"@ai-sdk/openai": "^0.0.58", "@ai-sdk/openai": "^0.0.58",
"@e2b/code-interpreter": "^0.0.8", "@e2b/code-interpreter": "^1.0.3",
"@foobar404/wave": "^2.0.5", "@foobar404/wave": "^2.0.5",
"@mendable/firecrawl-js": "^1.4.3", "@mendable/firecrawl-js": "^1.4.3",
"@radix-ui/react-accordion": "^1.2.0", "@radix-ui/react-accordion": "^1.2.0",
@ -33,18 +33,21 @@
"@radix-ui/react-tooltip": "^1.1.2", "@radix-ui/react-tooltip": "^1.1.2",
"@tailwindcss/typography": "^0.5.13", "@tailwindcss/typography": "^0.5.13",
"@types/katex": "^0.16.7", "@types/katex": "^0.16.7",
"@types/mapbox-gl": "^3.4.0",
"@types/unist": "^3.0.3", "@types/unist": "^3.0.3",
"@upstash/ratelimit": "^2.0.3", "@upstash/ratelimit": "^2.0.3",
"@upstash/redis": "^1.34.0", "@upstash/redis": "^1.34.0",
"@vercel/analytics": "^1.3.1", "@vercel/analytics": "^1.3.1",
"@vercel/blob": "^0.23.4", "@vercel/blob": "^0.23.4",
"@vercel/functions": "^1.4.0", "@vercel/functions": "^1.4.0",
"ai": "latest", "ai": "^3.4.33",
"anthropic-vertex-ai": "^1.0.0", "anthropic-vertex-ai": "^1.0.0",
"cheerio": "^1.0.0", "cheerio": "^1.0.0",
"class-variance-authority": "^0.7.0", "class-variance-authority": "^0.7.0",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"date-fns": "^3.6.0", "date-fns": "^3.6.0",
"echarts": "^5.5.1",
"echarts-for-react": "^3.0.2",
"embla-carousel-autoplay": "^8.3.0", "embla-carousel-autoplay": "^8.3.0",
"embla-carousel-react": "^8.3.0", "embla-carousel-react": "^8.3.0",
"framer-motion": "^11.3.19", "framer-motion": "^11.3.19",
@ -52,6 +55,7 @@
"highlight.js": "^11.10.0", "highlight.js": "^11.10.0",
"katex": "^0.16.11", "katex": "^0.16.11",
"lucide-react": "^0.424.0", "lucide-react": "^0.424.0",
"mapbox-gl": "^3.7.0",
"marked-react": "^2.0.0", "marked-react": "^2.0.0",
"next": "^14.2.10", "next": "^14.2.10",
"next-themes": "^0.3.0", "next-themes": "^0.3.0",

View File

@ -6,14 +6,14 @@ settings:
dependencies: dependencies:
'@ai-sdk/anthropic': '@ai-sdk/anthropic':
specifier: ^0.0.55
version: 0.0.55(zod@3.23.8)
'@ai-sdk/azure':
specifier: ^0.0.51 specifier: ^0.0.51
version: 0.0.51(zod@3.23.8) 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': '@ai-sdk/cohere':
specifier: latest specifier: latest
version: 0.0.25(zod@3.23.8) version: 0.0.28(zod@3.23.8)
'@ai-sdk/google': '@ai-sdk/google':
specifier: ^0.0.52 specifier: ^0.0.52
version: 0.0.52(zod@3.23.8) version: 0.0.52(zod@3.23.8)
@ -27,8 +27,8 @@ dependencies:
specifier: ^0.0.58 specifier: ^0.0.58
version: 0.0.58(zod@3.23.8) version: 0.0.58(zod@3.23.8)
'@e2b/code-interpreter': '@e2b/code-interpreter':
specifier: ^0.0.8 specifier: ^1.0.3
version: 0.0.8 version: 1.0.3
'@foobar404/wave': '@foobar404/wave':
specifier: ^2.0.5 specifier: ^2.0.5
version: 2.0.5 version: 2.0.5
@ -77,6 +77,9 @@ dependencies:
'@types/katex': '@types/katex':
specifier: ^0.16.7 specifier: ^0.16.7
version: 0.16.7 version: 0.16.7
'@types/mapbox-gl':
specifier: ^3.4.0
version: 3.4.0
'@types/unist': '@types/unist':
specifier: ^3.0.3 specifier: ^3.0.3
version: 3.0.3 version: 3.0.3
@ -96,8 +99,8 @@ dependencies:
specifier: ^1.4.0 specifier: ^1.4.0
version: 1.4.2 version: 1.4.2
ai: ai:
specifier: latest specifier: ^3.4.33
version: 3.4.18(openai@4.67.2)(react@18.3.1)(svelte@4.2.19)(vue@3.5.11)(zod@3.23.8) 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: anthropic-vertex-ai:
specifier: ^1.0.0 specifier: ^1.0.0
version: 1.0.0(zod@3.23.8) version: 1.0.0(zod@3.23.8)
@ -113,6 +116,12 @@ dependencies:
date-fns: date-fns:
specifier: ^3.6.0 specifier: ^3.6.0
version: 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: embla-carousel-autoplay:
specifier: ^8.3.0 specifier: ^8.3.0
version: 8.3.0(embla-carousel@8.3.0) version: 8.3.0(embla-carousel@8.3.0)
@ -134,6 +143,9 @@ dependencies:
lucide-react: lucide-react:
specifier: ^0.424.0 specifier: ^0.424.0
version: 0.424.0(react@18.3.1) version: 0.424.0(react@18.3.1)
mapbox-gl:
specifier: ^3.7.0
version: 3.7.0
marked-react: marked-react:
specifier: ^2.0.0 specifier: ^2.0.0
version: 2.0.0(react@18.3.1) version: 2.0.0(react@18.3.1)
@ -232,37 +244,37 @@ devDependencies:
packages: packages:
/@ai-sdk/anthropic@0.0.51(zod@3.23.8): /@ai-sdk/anthropic@0.0.55(zod@3.23.8):
resolution: {integrity: sha512-XPLBvdwdMlNAvGMyfsDgrCDXN2Wz7M+wfCJthqiwdiKHmq2jDLGdt0ZCAozgxxW28HVzMfJlFjuyECiA5Le3YA==} resolution: {integrity: sha512-SIPGu8on4PKl+PIdbjOniT5/AiE82Yw8HOE/W0GEb2bNGq2KhfkjVt5MBhppg+ZRme5w2iexB4bl66eRa2o89g==}
engines: {node: '>=18'} engines: {node: '>=18'}
peerDependencies: peerDependencies:
zod: ^3.0.0 zod: ^3.0.0
dependencies: dependencies:
'@ai-sdk/provider': 0.0.24 '@ai-sdk/provider': 0.0.26
'@ai-sdk/provider-utils': 1.0.20(zod@3.23.8) '@ai-sdk/provider-utils': 1.0.22(zod@3.23.8)
zod: 3.23.8 zod: 3.23.8
dev: false dev: false
/@ai-sdk/azure@0.0.31(zod@3.23.8): /@ai-sdk/azure@0.0.51(zod@3.23.8):
resolution: {integrity: sha512-LTiv890qHcw3w87l+OOuYqW1HM9+7olS5mpSOriRY2uZxJWr3MGz8MYqJu2jGNajNKi4j64GsaOuNK69k8KXjw==} resolution: {integrity: sha512-DMPuWURdgoweDlSLTj6o3Yx6+hnfr9idvHaTBwgPY+mayvEwlLZp3l08juMn/d/gKgHheQpUEgCQNhCzk6ZJ5w==}
engines: {node: '>=18'} engines: {node: '>=18'}
peerDependencies: peerDependencies:
zod: ^3.0.0 zod: ^3.0.0
dependencies: dependencies:
'@ai-sdk/openai': 0.0.53(zod@3.23.8) '@ai-sdk/openai': 0.0.71(zod@3.23.8)
'@ai-sdk/provider': 0.0.21 '@ai-sdk/provider': 0.0.26
'@ai-sdk/provider-utils': 1.0.16(zod@3.23.8) '@ai-sdk/provider-utils': 1.0.22(zod@3.23.8)
zod: 3.23.8 zod: 3.23.8
dev: false dev: false
/@ai-sdk/cohere@0.0.25(zod@3.23.8): /@ai-sdk/cohere@0.0.28(zod@3.23.8):
resolution: {integrity: sha512-i7wraTa9/Qmozhw/E5OX+TNIYcPYE7higmCiYvknYyfGTc2XjnVaB2zyIfmbw0TgL+2m3PbVk75vEL5zG1ickQ==} resolution: {integrity: sha512-aWavC7PuC5AcDcwTBcvx2ZemudtjPaZvLDmcVjiIhzvvW2+zoHoWmERD8CtSWIMlQp/vjdTcwNhSXTOqfxm27A==}
engines: {node: '>=18'} engines: {node: '>=18'}
peerDependencies: peerDependencies:
zod: ^3.0.0 zod: ^3.0.0
dependencies: dependencies:
'@ai-sdk/provider': 0.0.24 '@ai-sdk/provider': 0.0.26
'@ai-sdk/provider-utils': 1.0.20(zod@3.23.8) '@ai-sdk/provider-utils': 1.0.22(zod@3.23.8)
zod: 3.23.8 zod: 3.23.8
dev: false dev: false
@ -300,17 +312,6 @@ packages:
zod: 3.23.8 zod: 3.23.8
dev: false 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): /@ai-sdk/openai@0.0.58(zod@3.23.8):
resolution: {integrity: sha512-Eao1L0vzfXdymgvc5FDHwV2g2A7BCWml1cShNA+wliY1RL7NNREGcuQvBDNoggB9PM24fawzZyk0ZJ5jlo9Q0w==} resolution: {integrity: sha512-Eao1L0vzfXdymgvc5FDHwV2g2A7BCWml1cShNA+wliY1RL7NNREGcuQvBDNoggB9PM24fawzZyk0ZJ5jlo9Q0w==}
engines: {node: '>=18'} engines: {node: '>=18'}
@ -322,19 +323,14 @@ packages:
zod: 3.23.8 zod: 3.23.8
dev: false dev: false
/@ai-sdk/provider-utils@1.0.16(zod@3.23.8): /@ai-sdk/openai@0.0.71(zod@3.23.8):
resolution: {integrity: sha512-8Nd8vIkGTIthhfgJEdP9KyMlykehBNP/1J47eMC3vQqYgJV6r5Bgvl3LFVfWi9KzamiD8tp9nU2NJKTeo4MH/A==} resolution: {integrity: sha512-ds7u3sWEnKyHxM3lAL9xTs72228HEKcPZCAEFaxmgrexKPJe2tyLBtvS/Kg39SPKPtY9EeaKqi/nbx1AmnXK6A==}
engines: {node: '>=18'} engines: {node: '>=18'}
peerDependencies: peerDependencies:
zod: ^3.0.0 zod: ^3.0.0
peerDependenciesMeta:
zod:
optional: true
dependencies: dependencies:
'@ai-sdk/provider': 0.0.21 '@ai-sdk/provider': 0.0.26
eventsource-parser: 1.1.2 '@ai-sdk/provider-utils': 1.0.22(zod@3.23.8)
nanoid: 3.3.6
secure-json-parse: 2.7.0
zod: 3.23.8 zod: 3.23.8
dev: false dev: false
@ -402,11 +398,20 @@ packages:
zod: 3.23.8 zod: 3.23.8
dev: false dev: false
/@ai-sdk/provider@0.0.21: /@ai-sdk/provider-utils@1.0.22(zod@3.23.8):
resolution: {integrity: sha512-9j95uaPRxwYkzQdkl4XO/MmWWW5c5vcVSXtqvALpD9SMB9fzH46dO3UN4VbOJR2J3Z84CZAqgZu5tNlkptT9qQ==} resolution: {integrity: sha512-YHK2rpj++wnLVc9vPGzGFP3Pjeld2MwhKinetA0zKXOoHAT/Jit5O8kZsxcSlJPu9wvcGT1UGZEjZrtO7PfFOQ==}
engines: {node: '>=18'} engines: {node: '>=18'}
peerDependencies:
zod: ^3.0.0
peerDependenciesMeta:
zod:
optional: true
dependencies: 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 dev: false
/@ai-sdk/provider@0.0.22: /@ai-sdk/provider@0.0.22:
@ -430,11 +435,18 @@ packages:
json-schema: 0.4.0 json-schema: 0.4.0
dev: false dev: false
/@ai-sdk/react@0.0.64(react@18.3.1)(zod@3.23.8): /@ai-sdk/provider@0.0.26:
resolution: {integrity: sha512-4LN2vleyA6rYHZ4Rk9CdxnJgaVkNPJDD4Wx1brUhc5RvUxj3TODcm2UwGOR/mxv4pcydtZGELfQQs/i/tkAUCw==} 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'} engines: {node: '>=18'}
peerDependencies: peerDependencies:
react: ^18 || ^19 react: ^18 || ^19 || ^19.0.0-rc
zod: ^3.0.0 zod: ^3.0.0
peerDependenciesMeta: peerDependenciesMeta:
react: react:
@ -442,15 +454,16 @@ packages:
zod: zod:
optional: true optional: true
dependencies: dependencies:
'@ai-sdk/provider-utils': 1.0.20(zod@3.23.8) '@ai-sdk/provider-utils': 1.0.22(zod@3.23.8)
'@ai-sdk/ui-utils': 0.0.46(zod@3.23.8) '@ai-sdk/ui-utils': 0.0.50(zod@3.23.8)
react: 18.3.1 react: 18.3.1
swr: 2.2.5(react@18.3.1) swr: 2.2.5(react@18.3.1)
throttleit: 2.1.0
zod: 3.23.8 zod: 3.23.8
dev: false dev: false
/@ai-sdk/solid@0.0.50(zod@3.23.8): /@ai-sdk/solid@0.0.54(zod@3.23.8):
resolution: {integrity: sha512-JF+KKOgGAgcROgae6FU+hAtxMRhR896SzwI3H1h5hFOZrjqYeYzemJoKzA5MR5IBnPSK4FzEjunc8G5L67TyzQ==} resolution: {integrity: sha512-96KWTVK+opdFeRubqrgaJXoNiDP89gNxFRWUp0PJOotZW816AbhUf4EnDjBjXTLjXL1n0h8tGSE9sZsRkj9wQQ==}
engines: {node: '>=18'} engines: {node: '>=18'}
peerDependencies: peerDependencies:
solid-js: ^1.7.7 solid-js: ^1.7.7
@ -458,31 +471,31 @@ packages:
solid-js: solid-js:
optional: true optional: true
dependencies: dependencies:
'@ai-sdk/provider-utils': 1.0.20(zod@3.23.8) '@ai-sdk/provider-utils': 1.0.22(zod@3.23.8)
'@ai-sdk/ui-utils': 0.0.46(zod@3.23.8) '@ai-sdk/ui-utils': 0.0.50(zod@3.23.8)
transitivePeerDependencies: transitivePeerDependencies:
- zod - zod
dev: false dev: false
/@ai-sdk/svelte@0.0.52(svelte@4.2.19)(zod@3.23.8): /@ai-sdk/svelte@0.0.57(svelte@4.2.19)(zod@3.23.8):
resolution: {integrity: sha512-ZGd81ruVuqpOh1Suma+HwBMBywcOV0IUzi96Q3knIoZIz99sVwebSKH8ExMofXm49bQdCTRa73Wn8sTs6QDIYg==} resolution: {integrity: sha512-SyF9ItIR9ALP9yDNAD+2/5Vl1IT6kchgyDH8xkmhysfJI6WrvJbtO1wdQ0nylvPLcsPoYu+cAlz1krU4lFHcYw==}
engines: {node: '>=18'} engines: {node: '>=18'}
peerDependencies: peerDependencies:
svelte: ^3.0.0 || ^4.0.0 svelte: ^3.0.0 || ^4.0.0 || ^5.0.0
peerDependenciesMeta: peerDependenciesMeta:
svelte: svelte:
optional: true optional: true
dependencies: dependencies:
'@ai-sdk/provider-utils': 1.0.20(zod@3.23.8) '@ai-sdk/provider-utils': 1.0.22(zod@3.23.8)
'@ai-sdk/ui-utils': 0.0.46(zod@3.23.8) '@ai-sdk/ui-utils': 0.0.50(zod@3.23.8)
sswr: 2.1.0(svelte@4.2.19) sswr: 2.1.0(svelte@4.2.19)
svelte: 4.2.19 svelte: 4.2.19
transitivePeerDependencies: transitivePeerDependencies:
- zod - zod
dev: false dev: false
/@ai-sdk/ui-utils@0.0.46(zod@3.23.8): /@ai-sdk/ui-utils@0.0.50(zod@3.23.8):
resolution: {integrity: sha512-ZG/wneyJG+6w5Nm/hy1AKMuRgjPQToAxBsTk61c9sVPUTaxo+NNjM2MhXQMtmsja2N5evs8NmHie+ExEgpL3cA==} resolution: {integrity: sha512-Z5QYJVW+5XpSaJ4jYCCAVG7zIAuKOOdikhgpksneNmKvx61ACFaf98pmOd+xnjahl0pIlc/QIe6O4yVaJ1sEaw==}
engines: {node: '>=18'} engines: {node: '>=18'}
peerDependencies: peerDependencies:
zod: ^3.0.0 zod: ^3.0.0
@ -490,16 +503,16 @@ packages:
zod: zod:
optional: true optional: true
dependencies: dependencies:
'@ai-sdk/provider': 0.0.24 '@ai-sdk/provider': 0.0.26
'@ai-sdk/provider-utils': 1.0.20(zod@3.23.8) '@ai-sdk/provider-utils': 1.0.22(zod@3.23.8)
json-schema: 0.4.0 json-schema: 0.4.0
secure-json-parse: 2.7.0 secure-json-parse: 2.7.0
zod: 3.23.8 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 dev: false
/@ai-sdk/vue@0.0.55(vue@3.5.11)(zod@3.23.8): /@ai-sdk/vue@0.0.59(vue@3.5.11)(zod@3.23.8):
resolution: {integrity: sha512-NZ89CeRPO3D9GjI7GmK3vC+YXjsaWi3iCIvxlGqfQYt0JFKcjgM6dfeq8Nkk+qWI9OoxoOhV/yQdqWQKPv3RRg==} resolution: {integrity: sha512-+ofYlnqdc8c4F6tM0IKF0+7NagZRAiqBJpGDJ+6EYhDW8FHLUP/JFBgu32SjxSxC6IKFZxEnl68ZoP/Z38EMlw==}
engines: {node: '>=18'} engines: {node: '>=18'}
peerDependencies: peerDependencies:
vue: ^3.3.4 vue: ^3.3.4
@ -507,8 +520,8 @@ packages:
vue: vue:
optional: true optional: true
dependencies: dependencies:
'@ai-sdk/provider-utils': 1.0.20(zod@3.23.8) '@ai-sdk/provider-utils': 1.0.22(zod@3.23.8)
'@ai-sdk/ui-utils': 0.0.46(zod@3.23.8) '@ai-sdk/ui-utils': 0.0.50(zod@3.23.8)
swrv: 1.0.4(vue@3.5.11) swrv: 1.0.4(vue@3.5.11)
vue: 3.5.11(typescript@5.6.2) vue: 3.5.11(typescript@5.6.2)
transitivePeerDependencies: transitivePeerDependencies:
@ -561,16 +574,33 @@ packages:
to-fast-properties: 2.0.0 to-fast-properties: 2.0.0
dev: false dev: false
/@e2b/code-interpreter@0.0.8: /@bufbuild/protobuf@1.10.0:
resolution: {integrity: sha512-cKDFY9js9l3MfL71x0IDvaz0mAhvHIurVFnimtFRXNzuV0TxhuFqsauKabet0TMOrcDF3H3trC7pct6mNgRYTA==} 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'} engines: {node: '>=18'}
dependencies: dependencies:
e2b: 0.16.2 e2b: 1.0.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
dev: false dev: false
/@eslint-community/eslint-utils@4.4.0(eslint@8.57.1): /@eslint-community/eslint-utils@4.4.0(eslint@8.57.1):
@ -705,6 +735,38 @@ packages:
'@jridgewell/resolve-uri': 3.1.2 '@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.0 '@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): /@mendable/firecrawl-js@1.5.3(ws@8.18.0):
resolution: {integrity: sha512-SMxQAUMixlc01OzYB3/9YvTGe/Po/v2NZx5ccCO3OKBk9Vdbo4a5i1Var591H1NYDEqNnRJ6se0X/Y/IiLVvtQ==} resolution: {integrity: sha512-SMxQAUMixlc01OzYB3/9YvTGe/Po/v2NZx5ccCO3OKBk9Vdbo4a5i1Var591H1NYDEqNnRJ6se0X/Y/IiLVvtQ==}
dependencies: dependencies:
@ -1736,6 +1798,16 @@ packages:
resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
dev: false 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: /@types/google.maps@3.58.1:
resolution: {integrity: sha512-X9QTSvGJ0nCfMzYOnaVs/k6/4L+7F5uCS+4iUmkLEls6J9S/Phv+m/i3mDeyc49ZBgwab3EFO1HEoBY7k98EGQ==} resolution: {integrity: sha512-X9QTSvGJ0nCfMzYOnaVs/k6/4L+7F5uCS+4iUmkLEls6J9S/Phv+m/i3mDeyc49ZBgwab3EFO1HEoBY7k98EGQ==}
dev: true dev: true
@ -1760,6 +1832,24 @@ packages:
resolution: {integrity: sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==} resolution: {integrity: sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==}
dev: false 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: /@types/mdast@4.0.4:
resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
dependencies: dependencies:
@ -1788,6 +1878,10 @@ packages:
dependencies: dependencies:
undici-types: 6.19.8 undici-types: 6.19.8
/@types/pbf@3.0.5:
resolution: {integrity: sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA==}
dev: false
/@types/prop-types@15.7.13: /@types/prop-types@15.7.13:
resolution: {integrity: sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==} resolution: {integrity: sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==}
@ -1808,6 +1902,12 @@ packages:
'@types/prop-types': 15.7.13 '@types/prop-types': 15.7.13
csstype: 3.1.3 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: /@types/unist@2.0.11:
resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==}
dev: false dev: false
@ -2049,14 +2149,14 @@ packages:
humanize-ms: 1.2.1 humanize-ms: 1.2.1
dev: false 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): /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-dc6rSBDgaRMX4VgTBsUZwEN5tBWMpJd+MJxB05E2cL4ft9mOmQEZNS6yeu4Ci5rUDj4ZhnmvANHrP7td8Ko9Og==} resolution: {integrity: sha512-plBlrVZKwPoRTmM8+D1sJac9Bq8eaa2jiZlHLZIWekKWI1yMWYZvCCEezY9ASPwRhULYDJB2VhKOBUUeg3S5JQ==}
engines: {node: '>=18'} engines: {node: '>=18'}
peerDependencies: peerDependencies:
openai: ^4.42.0 openai: ^4.42.0
react: ^18 || ^19 react: ^18 || ^19 || ^19.0.0-rc
sswr: ^2.1.0 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 zod: ^3.0.0
peerDependenciesMeta: peerDependenciesMeta:
openai: openai:
@ -2070,24 +2170,23 @@ packages:
zod: zod:
optional: true optional: true
dependencies: dependencies:
'@ai-sdk/provider': 0.0.24 '@ai-sdk/provider': 0.0.26
'@ai-sdk/provider-utils': 1.0.20(zod@3.23.8) '@ai-sdk/provider-utils': 1.0.22(zod@3.23.8)
'@ai-sdk/react': 0.0.64(react@18.3.1)(zod@3.23.8) '@ai-sdk/react': 0.0.70(react@18.3.1)(zod@3.23.8)
'@ai-sdk/solid': 0.0.50(zod@3.23.8) '@ai-sdk/solid': 0.0.54(zod@3.23.8)
'@ai-sdk/svelte': 0.0.52(svelte@4.2.19)(zod@3.23.8) '@ai-sdk/svelte': 0.0.57(svelte@4.2.19)(zod@3.23.8)
'@ai-sdk/ui-utils': 0.0.46(zod@3.23.8) '@ai-sdk/ui-utils': 0.0.50(zod@3.23.8)
'@ai-sdk/vue': 0.0.55(vue@3.5.11)(zod@3.23.8) '@ai-sdk/vue': 0.0.59(vue@3.5.11)(zod@3.23.8)
'@opentelemetry/api': 1.9.0 '@opentelemetry/api': 1.9.0
eventsource-parser: 1.1.2 eventsource-parser: 1.1.2
json-schema: 0.4.0 json-schema: 0.4.0
jsondiffpatch: 0.6.0 jsondiffpatch: 0.6.0
nanoid: 3.3.6
openai: 4.67.2(zod@3.23.8) openai: 4.67.2(zod@3.23.8)
react: 18.3.1 react: 18.3.1
secure-json-parse: 2.7.0 secure-json-parse: 2.7.0
svelte: 4.2.19 svelte: 4.2.19
zod: 3.23.8 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: transitivePeerDependencies:
- solid-js - solid-js
- vue - vue
@ -2349,14 +2448,6 @@ packages:
resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==}
dev: false 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: /busboy@1.6.0:
resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==}
engines: {node: '>=10.16.0'} engines: {node: '>=10.16.0'}
@ -2438,6 +2529,10 @@ packages:
resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==}
dev: false dev: false
/cheap-ruler@4.0.0:
resolution: {integrity: sha512-0BJa8f4t141BYKQyn9NSQt1PguFQXMXwZiA5shfoaBYHAb2fFk2RAX+tiWMoQU+Agtzt3mdt0JtuyshAXqZ+Vw==}
dev: false
/cheerio-select@2.1.0: /cheerio-select@2.1.0:
resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==}
dependencies: dependencies:
@ -2543,6 +2638,10 @@ packages:
engines: {node: '>= 12'} engines: {node: '>= 12'}
dev: false dev: false
/compare-versions@6.1.1:
resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==}
dev: false
/concat-map@0.0.1: /concat-map@0.0.1:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
dev: true dev: true
@ -2582,6 +2681,10 @@ packages:
engines: {node: '>= 6'} engines: {node: '>= 6'}
dev: false dev: false
/csscolorparser@1.0.3:
resolution: {integrity: sha512-umPSgYwZkdFoUrH5hIq5kf0wPSXiro51nPw0j2K/c83KflkPSTBGMz6NJvMB+07VlL0y7VPo6QJcDjcgKTTm3w==}
dev: false
/cssesc@3.0.0: /cssesc@3.0.0:
resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
engines: {node: '>=4'} engines: {node: '>=4'}
@ -2859,19 +2962,20 @@ packages:
domhandler: 5.0.3 domhandler: 5.0.3
dev: false dev: false
/e2b@0.16.2: /e2b@1.0.2:
resolution: {integrity: sha512-xKmVK4ipgVQPJ/uyyrfH9LnaawERRWt8U2UZhdhGfzdL/QU/OpBjuhoIbFCv1Uy6qXV4nIiJ6Nw4MBC4HmXf1g==} resolution: {integrity: sha512-jChBH34n4ShQlsOCm3ENDtwFqljE6b++C4YC8lTBuN5Go+4uffPyI9GPfDx5nN4Je3+9FLCciRRyCWsqaDWFQQ==}
engines: {node: '>=18'} engines: {node: '>=18'}
dependencies: dependencies:
isomorphic-ws: 5.0.0(ws@8.18.0) '@bufbuild/protobuf': 1.10.0
normalize-path: 3.0.0 '@connectrpc/connect': 1.6.1(@bufbuild/protobuf@1.10.0)
openapi-typescript-fetch: 1.1.3 '@connectrpc/connect-web': 1.6.1(@bufbuild/protobuf@1.10.0)(@connectrpc/connect@1.6.1)
path-browserify: 1.0.1 compare-versions: 6.1.1
openapi-fetch: 0.9.8
platform: 1.3.6 platform: 1.3.6
ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@6.0.4) dev: false
optionalDependencies:
bufferutil: 4.0.8 /earcut@3.0.0:
utf-8-validate: 6.0.4 resolution: {integrity: sha512-41Fs7Q/PLq1SDbqjsgcY7GA42T0jvaCNGXgGtsNdvg+Yv8eIu06bxv4/PoREkZ9nMDNwnUSG9OFB9+yv8eKhDg==}
dev: false dev: false
/eastasianwidth@0.2.0: /eastasianwidth@0.2.0:
@ -2883,6 +2987,25 @@ packages:
safe-buffer: 5.2.1 safe-buffer: 5.2.1
dev: false 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): /embla-carousel-autoplay@8.3.0(embla-carousel@8.3.0):
resolution: {integrity: sha512-h7DFJLf9uQD+XDxr1NwA3/oFIjsnj/iED2RjET5u6/svMec46IbF1CYPhmB5Q/1Fc0WkcvhPpsEsrtVXQLxNzA==} resolution: {integrity: sha512-h7DFJLf9uQD+XDxr1NwA3/oFIjsnj/iED2RjET5u6/svMec46IbF1CYPhmB5Q/1Fc0WkcvhPpsEsrtVXQLxNzA==}
peerDependencies: peerDependencies:
@ -3400,7 +3523,6 @@ packages:
/fast-deep-equal@3.1.3: /fast-deep-equal@3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
dev: true
/fast-equals@5.0.1: /fast-equals@5.0.1:
resolution: {integrity: sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==} resolution: {integrity: sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==}
@ -3591,6 +3713,10 @@ packages:
- supports-color - supports-color
dev: false dev: false
/geojson-vt@4.0.2:
resolution: {integrity: sha512-AV9ROqlNqoZEIJGfm1ncNjEXfkz2hdFlZf0qkVfmkwdKa8vj7H16YUOT81rJw1rdFhyEDlN2Tds91p/glzbl5A==}
dev: false
/get-intrinsic@1.2.4: /get-intrinsic@1.2.4:
resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@ -3622,6 +3748,10 @@ packages:
resolve-pkg-maps: 1.0.0 resolve-pkg-maps: 1.0.0
dev: true dev: true
/gl-matrix@3.4.3:
resolution: {integrity: sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA==}
dev: false
/glob-parent@5.1.2: /glob-parent@5.1.2:
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
engines: {node: '>= 6'} engines: {node: '>= 6'}
@ -3724,6 +3854,10 @@ packages:
resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
dev: true dev: true
/grid-index@1.1.0:
resolution: {integrity: sha512-HZRwumpOGUrHyxO5bqKZL0B0GlUpwtCAzZ42sgxUPniu33R1LSFH5yrIcBCHjkctCAh3mtWKcKd9J4vDDdeVHA==}
dev: false
/gtoken@7.1.0: /gtoken@7.1.0:
resolution: {integrity: sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==} resolution: {integrity: sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==}
engines: {node: '>=14.0.0'} engines: {node: '>=14.0.0'}
@ -3932,6 +4066,10 @@ packages:
safer-buffer: 2.1.2 safer-buffer: 2.1.2
dev: false dev: false
/ieee754@1.2.1:
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
dev: false
/ignore@5.3.2: /ignore@5.3.2:
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
engines: {node: '>= 4'} engines: {node: '>= 4'}
@ -4244,20 +4382,12 @@ packages:
/isexe@2.0.0: /isexe@2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} 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): /isows@1.0.6(ws@8.18.0):
resolution: {integrity: sha512-lPHCayd40oW98/I0uvgaHKWCSvkzY27LjWLbtzOm64yQ+G3Q5npjjbdppU65iZXkK1Zt+kH9pfegli0AYfwYYw==} resolution: {integrity: sha512-lPHCayd40oW98/I0uvgaHKWCSvkzY27LjWLbtzOm64yQ+G3Q5npjjbdppU65iZXkK1Zt+kH9pfegli0AYfwYYw==}
peerDependencies: peerDependencies:
ws: '*' ws: '*'
dependencies: dependencies:
ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@6.0.4) ws: 8.18.0
dev: false dev: false
/iterator.prototype@1.1.3: /iterator.prototype@1.1.3:
@ -4372,6 +4502,10 @@ packages:
commander: 8.3.0 commander: 8.3.0
dev: false dev: false
/kdbush@4.0.2:
resolution: {integrity: sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==}
dev: false
/keyv@4.5.4: /keyv@4.5.4:
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
dependencies: dependencies:
@ -4468,6 +4602,39 @@ packages:
'@jridgewell/sourcemap-codec': 1.5.0 '@jridgewell/sourcemap-codec': 1.5.0
dev: false 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: /markdown-table@3.0.3:
resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==} resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==}
dev: false dev: false
@ -4999,6 +5166,10 @@ packages:
/ms@2.1.3: /ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
/murmurhash-js@1.0.0:
resolution: {integrity: sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw==}
dev: false
/mz@2.7.0: /mz@2.7.0:
resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
dependencies: dependencies:
@ -5090,11 +5261,6 @@ packages:
whatwg-url: 5.0.0 whatwg-url: 5.0.0
dev: false dev: false
/node-gyp-build@4.8.2:
resolution: {integrity: sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==}
hasBin: true
dev: false
/normalize-path@3.0.0: /normalize-path@3.0.0:
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@ -5205,9 +5371,14 @@ packages:
- encoding - encoding
dev: false dev: false
/openapi-typescript-fetch@1.1.3: /openapi-fetch@0.9.8:
resolution: {integrity: sha512-smLZPck4OkKMNExcw8jMgrMOGgVGx2N/s6DbKL2ftNl77g5HfoGpZGFy79RBzU/EkaO0OZpwBnslfdBfh7ZcWg==} resolution: {integrity: sha512-zM6elH0EZStD/gSiNlcPrzXcVQ/pZo3BDvC6CDwRDUt1dDzxlshpmQnpD6cZaJ39THaSmwVCxxRrPKNM1hHrDg==}
engines: {node: '>= 12.0.0', npm: '>= 7.0.0'} dependencies:
openapi-typescript-helpers: 0.0.8
dev: false
/openapi-typescript-helpers@0.0.8:
resolution: {integrity: sha512-1eNjQtbfNi5Z/kFhagDIaIRj6qqDzhjNJKz8cmMW0CVdGwT6e1GLbAfgI0d28VTJa1A8jz82jm/4dG8qNoNS8g==}
dev: false dev: false
/optionator@0.9.4: /optionator@0.9.4:
@ -5289,10 +5460,6 @@ packages:
entities: 4.5.0 entities: 4.5.0
dev: false dev: false
/path-browserify@1.0.1:
resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
dev: false
/path-exists@4.0.0: /path-exists@4.0.0:
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
engines: {node: '>=8'} engines: {node: '>=8'}
@ -5322,6 +5489,14 @@ packages:
engines: {node: '>=8'} engines: {node: '>=8'}
dev: true 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: /periscopic@3.1.0:
resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==} resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==}
dependencies: dependencies:
@ -5434,6 +5609,10 @@ packages:
picocolors: 1.1.0 picocolors: 1.1.0
source-map-js: 1.2.1 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: /prelude-ls@1.2.1:
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
engines: {node: '>= 0.8.0'} engines: {node: '>= 0.8.0'}
@ -5466,6 +5645,10 @@ packages:
resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==} resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==}
dev: false dev: false
/protocol-buffers-schema@3.6.0:
resolution: {integrity: sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==}
dev: false
/proxy-from-env@1.1.0: /proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
dev: false dev: false
@ -5478,6 +5661,10 @@ packages:
/queue-microtask@1.2.3: /queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} 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): /react-dom@18.3.1(react@18.3.1):
resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==}
peerDependencies: peerDependencies:
@ -5782,6 +5969,12 @@ packages:
resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
dev: true 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: /resolve@1.22.8:
resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==}
hasBin: true hasBin: true
@ -5869,6 +6062,11 @@ packages:
hasBin: true hasBin: true
dev: 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: /server-only@0.0.1:
resolution: {integrity: sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==} resolution: {integrity: sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==}
dev: false dev: false
@ -5919,6 +6117,10 @@ packages:
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
engines: {node: '>=14'} engines: {node: '>=14'}
/size-sensor@1.0.2:
resolution: {integrity: sha512-2NCmWxY7A9pYKGXNBfteo4hy14gWu47rg5692peVMst6lQLPKrVjhY+UTEsPI5ceFRJSl3gVgMYaUi/hKuaiKw==}
dev: false
/slash@3.0.0: /slash@3.0.0:
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
engines: {node: '>=8'} engines: {node: '>=8'}
@ -6107,6 +6309,12 @@ packages:
pirates: 4.0.6 pirates: 4.0.6
ts-interface-checker: 0.1.13 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: /supports-color@7.2.0:
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
engines: {node: '>=8'} engines: {node: '>=8'}
@ -6222,10 +6430,19 @@ packages:
dependencies: dependencies:
any-promise: 1.3.0 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: /tiny-invariant@1.3.3:
resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==}
dev: false dev: false
/tinyqueue@3.0.0:
resolution: {integrity: sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==}
dev: false
/to-fast-properties@2.0.0: /to-fast-properties@2.0.0:
resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
engines: {node: '>=4'} engines: {node: '>=4'}
@ -6270,6 +6487,10 @@ packages:
strip-bom: 3.0.0 strip-bom: 3.0.0
dev: true dev: true
/tslib@2.3.0:
resolution: {integrity: sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==}
dev: false
/tslib@2.7.0: /tslib@2.7.0:
resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==}
dev: false dev: false
@ -6471,14 +6692,6 @@ packages:
react: 18.3.1 react: 18.3.1
dev: false 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: /util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
@ -6527,6 +6740,14 @@ packages:
d3-timer: 3.0.1 d3-timer: 3.0.1
dev: false 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): /vue@3.5.11(typescript@5.6.2):
resolution: {integrity: sha512-/8Wurrd9J3lb72FTQS7gRMNQD4nztTtKPmuDuPuhqXmmpD6+skVjAeahNpVzsuky6Sy9gy7wn8UadqPtt9SQIg==} resolution: {integrity: sha512-/8Wurrd9J3lb72FTQS7gRMNQD4nztTtKPmuDuPuhqXmmpD6+skVjAeahNpVzsuky6Sy9gy7wn8UadqPtt9SQIg==}
peerDependencies: peerDependencies:
@ -6656,7 +6877,7 @@ packages:
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
dev: true 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==} resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==}
engines: {node: '>=10.0.0'} engines: {node: '>=10.0.0'}
peerDependencies: peerDependencies:
@ -6667,9 +6888,6 @@ packages:
optional: true optional: true
utf-8-validate: utf-8-validate:
optional: true optional: true
dependencies:
bufferutil: 4.0.8
utf-8-validate: 6.0.4
dev: false dev: false
/xtend@4.0.2: /xtend@4.0.2:
@ -6687,14 +6905,6 @@ packages:
engines: {node: '>=10'} engines: {node: '>=10'}
dev: true 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): /zod-to-json-schema@3.23.3(zod@3.23.8):
resolution: {integrity: sha512-TYWChTxKQbRJp5ST22o/Irt9KC5nj7CdBKYB/AosCRdj/wxEMvv4NNaj9XVUHDOIp53ZxArGhnw5HMZziPFjog==} resolution: {integrity: sha512-TYWChTxKQbRJp5ST22o/Irt9KC5nj7CdBKYB/AosCRdj/wxEMvv4NNaj9XVUHDOIp53ZxArGhnw5HMZziPFjog==}
peerDependencies: peerDependencies:
@ -6707,6 +6917,12 @@ packages:
resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==}
dev: false 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: /zwitch@2.0.4:
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
dev: false dev: false