diff --git a/apps/webapp/app/components/primitives/Input.tsx b/apps/webapp/app/components/primitives/Input.tsx index 7cb4b8a32d..5b421fd3b9 100644 --- a/apps/webapp/app/components/primitives/Input.tsx +++ b/apps/webapp/app/components/primitives/Input.tsx @@ -1,7 +1,7 @@ import * as React from "react"; import { useImperativeHandle, useRef } from "react"; import { cn } from "~/utils/cn"; -import { Icon, RenderIcon } from "./Icon"; +import { Icon, type RenderIcon } from "./Icon"; const containerBase = "has-[:focus-visible]:outline-none has-[:focus-visible]:ring-1 has-[:focus-visible]:ring-charcoal-650 has-[:focus-visible]:ring-offset-0 has-[:focus]:border-ring has-[:focus]:outline-none has-[:focus]:ring-1 has-[:focus]:ring-ring has-[:disabled]:cursor-not-allowed has-[:disabled]:opacity-50 ring-offset-background transition cursor-text"; @@ -9,61 +9,78 @@ const containerBase = const inputBase = "h-full w-full text-text-bright bg-transparent file:border-0 file:bg-transparent file:text-base file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-0 disabled:cursor-not-allowed outline-none ring-0 border-none"; -const shortcutBase = - "grid h-fit place-content-center border border-dimmed/40 font-normal text-text-dimmed"; - const variants = { large: { container: "px-1 w-full h-10 rounded-[3px] border border-charcoal-800 bg-charcoal-750 hover:border-charcoal-600 hover:bg-charcoal-650", input: "px-2 text-sm", iconSize: "size-4 ml-1", - shortcut: "mr-1 min-w-[22px] rounded-sm py-[3px] px-[5px] text-[0.6rem] select-none", + accessory: "pr-1", }, medium: { container: "px-1 h-8 w-full rounded border border-charcoal-800 bg-charcoal-750 hover:border-charcoal-600 hover:bg-charcoal-650", input: "px-1.5 rounded text-sm", iconSize: "size-4 ml-0.5", - shortcut: "min-w-[22px] rounded-sm py-[3px] px-[5px] text-[0.6rem]", + accessory: "pr-1", }, small: { container: "px-1 h-6 w-full rounded border border-charcoal-800 bg-charcoal-750 hover:border-charcoal-600 hover:bg-charcoal-650", input: "px-1 rounded text-xs", iconSize: "size-3 ml-0.5", - shortcut: "min-w-[22px] rounded-[2px] py-px px-[3px] text-[0.5rem]", + accessory: "pr-0.5", }, tertiary: { container: "px-1 h-6 w-full rounded hover:bg-charcoal-750", input: "px-1 rounded text-xs", iconSize: "size-3 ml-0.5", - shortcut: "min-w-[22px] rounded-[2px] py-px px-[3px] text-[0.5rem]", + accessory: "pr-0.5", + }, + "secondary-small": { + container: + "px-1 h-6 w-full rounded border border-charcoal-600 hover:border-charcoal-550 bg-grid-dimmed hover:bg-charcoal-650", + input: "px-1 rounded text-xs", + iconSize: "size-3 ml-0.5", + accessory: "pr-0.5", }, }; export type InputProps = React.InputHTMLAttributes & { variant?: keyof typeof variants; icon?: RenderIcon; - shortcut?: string; + accessory?: React.ReactNode; fullWidth?: boolean; + containerClassName?: string; }; const Input = React.forwardRef( - ({ className, type, shortcut, fullWidth = true, variant = "medium", icon, ...props }, ref) => { + ( + { + className, + type, + accessory, + fullWidth = true, + variant = "medium", + icon, + containerClassName, + ...props + }, + ref + ) => { const innerRef = useRef(null); useImperativeHandle(ref, () => innerRef.current as HTMLInputElement); - const containerClassName = variants[variant].container; + const variantContainerClassName = variants[variant].container; const inputClassName = variants[variant].input; const iconClassName = variants[variant].iconSize; - const shortcutClassName = variants[variant].shortcut; return (
( ref={innerRef} {...props} /> - {shortcut &&
{shortcut}
} + {accessory &&
{accessory}
}
); } diff --git a/apps/webapp/app/components/runs/v3/AIFilterInput.tsx b/apps/webapp/app/components/runs/v3/AIFilterInput.tsx new file mode 100644 index 0000000000..ef8384894d --- /dev/null +++ b/apps/webapp/app/components/runs/v3/AIFilterInput.tsx @@ -0,0 +1,185 @@ +import { useFetcher, useNavigate } from "@remix-run/react"; +import { AnimatePresence, motion } from "framer-motion"; +import { useEffect, useRef, useState } from "react"; +import { AISparkleIcon } from "~/assets/icons/AISparkleIcon"; +import { Input } from "~/components/primitives/Input"; +import { Popover, PopoverContent, PopoverTrigger } from "~/components/primitives/Popover"; +import { ShortcutKey } from "~/components/primitives/ShortcutKey"; +import { Spinner } from "~/components/primitives/Spinner"; +import { useEnvironment } from "~/hooks/useEnvironment"; +import { useOrganization } from "~/hooks/useOrganizations"; +import { useProject } from "~/hooks/useProject"; +import { cn } from "~/utils/cn"; +import { objectToSearchParams } from "~/utils/searchParams"; +import { type TaskRunListSearchFilters } from "./RunFilters"; + +type AIFilterResult = + | { + success: true; + filters: TaskRunListSearchFilters; + explanation?: string; + } + | { + success: false; + error: string; + suggestions?: string[]; + }; + +export function AIFilterInput() { + const [text, setText] = useState(""); + const [isFocused, setIsFocused] = useState(false); + const navigate = useNavigate(); + const organization = useOrganization(); + const project = useProject(); + const environment = useEnvironment(); + const inputRef = useRef(null); + const fetcher = useFetcher(); + + useEffect(() => { + if (fetcher.data?.success && fetcher.state === "loading") { + setText(""); + setIsFocused(false); + + const searchParams = objectToSearchParams(fetcher.data.filters); + if (!searchParams) { + return; + } + + navigate(`${location.pathname}?${searchParams.toString()}`, { replace: true }); + + if (inputRef.current) { + inputRef.current.focus(); + } + } + }, [fetcher.data, navigate]); + + const isLoading = fetcher.state === "submitting"; + + return ( + + + 0 ? "24rem" : "auto" }} + transition={{ + type: "spring", + stiffness: 300, + damping: 30, + }} + className="relative h-6 min-w-44" + > + + {isFocused && ( + + )} + +
+ setText(e.target.value)} + disabled={isLoading} + fullWidth + ref={inputRef} + className={cn( + "disabled:text-text-dimmed/50", + isFocused && "placeholder:text-text-dimmed/70" + )} + containerClassName="has-[:disabled]:opacity-100" + onKeyDown={(e) => { + if (e.key === "Enter" && text.trim() && !isLoading) { + e.preventDefault(); + const form = e.currentTarget.closest("form"); + if (form) { + form.requestSubmit(); + } + } + }} + onFocus={() => setIsFocused(true)} + onBlur={() => { + if (text.length === 0 || !isLoading) { + setIsFocused(false); + } + }} + icon={} + accessory={ + isLoading ? ( + + ) : text.length > 0 ? ( + + ) : undefined + } + /> +
+
+
+
+ ); +} + +function ErrorPopover({ + children, + error, + durationMs = 10_000, +}: { + children: React.ReactNode; + error?: string; + durationMs?: number; +}) { + const [isOpen, setIsOpen] = useState(false); + const timeout = useRef(); + + useEffect(() => { + if (error) { + setIsOpen(true); + } + if (timeout.current) { + clearTimeout(timeout.current); + } + timeout.current = setTimeout(() => { + setIsOpen(false); + }, durationMs); + + return () => { + if (timeout.current) { + clearTimeout(timeout.current); + } + }; + }, [error, durationMs]); + + return ( + + {children} + + {error} + + + ); +} diff --git a/apps/webapp/app/components/runs/v3/RunFilters.tsx b/apps/webapp/app/components/runs/v3/RunFilters.tsx index a44cd808a3..9eae1e1eb5 100644 --- a/apps/webapp/app/components/runs/v3/RunFilters.tsx +++ b/apps/webapp/app/components/runs/v3/RunFilters.tsx @@ -9,7 +9,7 @@ import { XMarkIcon, } from "@heroicons/react/20/solid"; import { Form, useFetcher } from "@remix-run/react"; -import { IconToggleLeft, IconRotateClockwise2 } from "@tabler/icons-react"; +import { IconRotateClockwise2, IconToggleLeft } from "@tabler/icons-react"; import { MachinePresetName } from "@trigger.dev/core/v3"; import type { BulkActionType, TaskRunStatus, TaskTriggerSource } from "@trigger.dev/database"; import { ListFilterIcon } from "lucide-react"; @@ -26,6 +26,7 @@ import { machines, } from "~/components/MachineLabelCombo"; import { AppliedFilter } from "~/components/primitives/AppliedFilter"; +import { Badge } from "~/components/primitives/Badge"; import { DateTime } from "~/components/primitives/DateTime"; import { FormError } from "~/components/primitives/FormError"; import { Input } from "~/components/primitives/Input"; @@ -56,11 +57,12 @@ import { useOrganization } from "~/hooks/useOrganizations"; import { useProject } from "~/hooks/useProject"; import { useSearchParams } from "~/hooks/useSearchParam"; import { type loader as queuesLoader } from "~/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.queues"; -import { type loader as tagsLoader } from "~/routes/resources.projects.$projectParam.runs.tags"; import { type loader as versionsLoader } from "~/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.versions"; +import { type loader as tagsLoader } from "~/routes/resources.projects.$projectParam.runs.tags"; import { Button } from "../../primitives/Buttons"; import { BulkActionTypeCombo } from "./BulkAction"; import { appliedSummary, FilterMenuProvider, TimeFilter } from "./SharedFilters"; +import { AIFilterInput } from "./AIFilterInput"; import { allTaskRunStatuses, descriptionForTaskRunStatus, @@ -69,7 +71,6 @@ import { TaskRunStatusCombo, } from "./TaskRunStatus"; import { TaskTriggerSourceIcon } from "./TaskTriggerSource"; -import { Badge } from "~/components/primitives/Badge"; export const RunStatus = z.enum(allTaskRunStatuses); @@ -111,37 +112,74 @@ export const MachinePresetOrMachinePresetArray = z.preprocess((value) => { }, MachinePresetName.array().optional()); export const TaskRunListSearchFilters = z.object({ - cursor: z.string().optional(), - direction: z.enum(["forward", "backward"]).optional(), - environments: StringOrStringArray, - tasks: StringOrStringArray, - versions: StringOrStringArray, - statuses: z.preprocess((value) => { - if (typeof value === "string") { - if (value.length > 0) { - return [value]; - } + cursor: z.string().optional().describe("Cursor for pagination - used internally for navigation"), + direction: z + .enum(["forward", "backward"]) + .optional() + .describe("Pagination direction - forward or backward. Used internally for navigation"), + environments: StringOrStringArray.describe( + "Environment names to filter by (DEVELOPMENT, STAGING, PREVIEW, PRODUCTION)" + ), + tasks: StringOrStringArray.describe( + "Task identifiers to filter by (these are user-defined names)" + ), + versions: StringOrStringArray.describe( + "Version identifiers to filter by (these are in this format 20250718.1). Needs to be looked up." + ), + statuses: z + .preprocess((value) => { + if (typeof value === "string") { + if (value.length > 0) { + return [value]; + } - return undefined; - } + return undefined; + } - if (Array.isArray(value)) { - return value.filter((v) => typeof v === "string" && v.length > 0); - } + if (Array.isArray(value)) { + return value.filter((v) => typeof v === "string" && v.length > 0); + } - return undefined; - }, RunStatus.array().optional()), - tags: StringOrStringArray, - bulkId: z.string().optional(), - period: z.preprocess((value) => (value === "all" ? undefined : value), z.string().optional()), - from: z.coerce.number().optional(), - to: z.coerce.number().optional(), - rootOnly: z.coerce.boolean().optional(), - batchId: z.string().optional(), - runId: StringOrStringArray, - scheduleId: z.string().optional(), - queues: StringOrStringArray, - machines: MachinePresetOrMachinePresetArray, + return undefined; + }, RunStatus.array().optional()) + .describe(`Run statuses to filter by (${filterableTaskRunStatuses.join(", ")})`), + tags: StringOrStringArray.describe("Tag names to filter by (these are user-defined names)"), + bulkId: z + .string() + .optional() + .describe("Bulk action ID to filter by - shows runs from a specific bulk operation"), + period: z + .preprocess((value) => (value === "all" ? undefined : value), z.string().optional()) + .describe("Time period string (e.g., '1h', '7d', '30d', '1y') for relative time filtering"), + from: z.coerce + .number() + .optional() + .describe("Unix timestamp for start of time range - absolute time filtering"), + to: z.coerce + .number() + .optional() + .describe("Unix timestamp for end of time range - absolute time filtering"), + rootOnly: z.coerce + .boolean() + .optional() + .describe("Show only root runs (not child runs) - set to true to exclude sub-runs"), + batchId: z + .string() + .optional() + .describe( + "Batch ID to filter by - shows runs from a specific batch operation. They start with batch_" + ), + runId: StringOrStringArray.describe("Specific run IDs to filter by. They start with run_"), + scheduleId: z + .string() + .optional() + .describe( + "Schedule ID to filter by - shows runs from a specific schedule. They start with sched_" + ), + queues: StringOrStringArray.describe("Queue names to filter by (these are user-defined names)"), + machines: MachinePresetOrMachinePresetArray.describe( + `Machine presets to filter by (${machines.join(", ")})` + ), }); export type TaskRunListSearchFilters = z.infer; @@ -306,6 +344,7 @@ export function RunsFilters(props: RunFiltersProps) { return (
+ @@ -355,8 +394,9 @@ function FilterMenu(props: RunFiltersProps) { variant={"secondary/small"} shortcut={shortcut} tooltipTitle={"Filter runs"} + className="pr-0.5" > - Filter + <> ); diff --git a/apps/webapp/app/env.server.ts b/apps/webapp/app/env.server.ts index 104b280c66..6fd895c456 100644 --- a/apps/webapp/app/env.server.ts +++ b/apps/webapp/app/env.server.ts @@ -975,6 +975,9 @@ const EnvironmentSchema = z.object({ BULK_ACTION_BATCH_SIZE: z.coerce.number().int().default(100), BULK_ACTION_BATCH_DELAY_MS: z.coerce.number().int().default(200), BULK_ACTION_SUBBATCH_CONCURRENCY: z.coerce.number().int().default(5), + + // AI Run Filter + AI_RUN_FILTER_MODEL: z.string().optional(), }); export type Environment = z.infer; diff --git a/apps/webapp/app/hooks/useSearchParam.ts b/apps/webapp/app/hooks/useSearchParam.ts index 3d0bb07e1b..c619312428 100644 --- a/apps/webapp/app/hooks/useSearchParam.ts +++ b/apps/webapp/app/hooks/useSearchParam.ts @@ -11,7 +11,6 @@ export function useSearchParams() { const replace = useCallback( (values: Values) => { const s = set(new URLSearchParams(location.search), values); - navigate(`${location.pathname}?${s.toString()}`, { replace: true }); }, [location, navigate] diff --git a/apps/webapp/app/presenters/v3/ApiRunListPresenter.server.ts b/apps/webapp/app/presenters/v3/ApiRunListPresenter.server.ts index a2e44969bf..254ec18d1c 100644 --- a/apps/webapp/app/presenters/v3/ApiRunListPresenter.server.ts +++ b/apps/webapp/app/presenters/v3/ApiRunListPresenter.server.ts @@ -251,6 +251,14 @@ export class ApiRunListPresenter extends BasePresenter { options.batchId = searchParams["filter[batch]"]; } + if (searchParams["filter[queue]"]) { + options.queues = searchParams["filter[queue]"]; + } + + if (searchParams["filter[machine]"]) { + options.machines = searchParams["filter[machine]"]; + } + const presenter = new NextRunListPresenter(this._replica, clickhouseClient); logger.debug("Calling RunListPresenter", { options }); diff --git a/apps/webapp/app/presenters/v3/QueueListPresenter.server.ts b/apps/webapp/app/presenters/v3/QueueListPresenter.server.ts index 8dc50e96e3..ec60db8b92 100644 --- a/apps/webapp/app/presenters/v3/QueueListPresenter.server.ts +++ b/apps/webapp/app/presenters/v3/QueueListPresenter.server.ts @@ -1,9 +1,9 @@ +import { TaskQueueType } from "@trigger.dev/database"; import { type AuthenticatedEnvironment } from "~/services/apiAuth.server"; import { determineEngineVersion } from "~/v3/engineVersion.server"; import { engine } from "~/v3/runEngine.server"; import { BasePresenter } from "./basePresenter.server"; import { toQueueItem } from "./QueueRetrievePresenter.server"; -import { TaskQueueType } from "@trigger.dev/database"; const DEFAULT_ITEMS_PER_PAGE = 25; const MAX_ITEMS_PER_PAGE = 100; diff --git a/apps/webapp/app/presenters/v3/VersionListPresenter.server.ts b/apps/webapp/app/presenters/v3/VersionListPresenter.server.ts index f8a4a36538..f541d884f8 100644 --- a/apps/webapp/app/presenters/v3/VersionListPresenter.server.ts +++ b/apps/webapp/app/presenters/v3/VersionListPresenter.server.ts @@ -1,6 +1,6 @@ -import { type AuthenticatedEnvironment } from "~/services/apiAuth.server"; -import { BasePresenter } from "./basePresenter.server"; import { CURRENT_DEPLOYMENT_LABEL } from "@trigger.dev/core/v3/isomorphic"; +import { type RuntimeEnvironment } from "@trigger.dev/database"; +import { BasePresenter } from "./basePresenter.server"; const DEFAULT_ITEMS_PER_PAGE = 25; const MAX_ITEMS_PER_PAGE = 100; @@ -17,7 +17,7 @@ export class VersionListPresenter extends BasePresenter { environment, query, }: { - environment: AuthenticatedEnvironment; + environment: Pick; query?: string; }) { const hasFilters = query !== undefined && query.length > 0; diff --git a/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.ai-filter.tsx b/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.ai-filter.tsx new file mode 100644 index 0000000000..9249d7afe9 --- /dev/null +++ b/apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.ai-filter.tsx @@ -0,0 +1,159 @@ +import { openai } from "@ai-sdk/openai"; +import { type ActionFunctionArgs, json } from "@remix-run/server-runtime"; +import { tryCatch } from "@trigger.dev/core"; +import { z } from "zod"; +import { $replica } from "~/db.server"; +import { env } from "~/env.server"; +import { findProjectBySlug } from "~/models/project.server"; +import { findEnvironmentBySlug } from "~/models/runtimeEnvironment.server"; +import { getAllTaskIdentifiers } from "~/models/task.server"; +import { QueueListPresenter } from "~/presenters/v3/QueueListPresenter.server"; +import { RunTagListPresenter } from "~/presenters/v3/RunTagListPresenter.server"; +import { VersionListPresenter } from "~/presenters/v3/VersionListPresenter.server"; +import { requireUserId } from "~/services/session.server"; +import { EnvironmentParamSchema } from "~/utils/pathBuilder"; +import { + AIRunFilterService, + type QueryQueues, + type QueryTags, + type QueryTasks, + type QueryVersions, +} from "~/v3/services/aiRunFilterService.server"; + +const RequestSchema = z.object({ + text: z.string().min(1), +}); + +export async function action({ request, params }: ActionFunctionArgs) { + const userId = await requireUserId(request); + const { organizationSlug, projectParam, envParam } = EnvironmentParamSchema.parse(params); + + // Parse the request body + const formData = await request.formData(); + const submission = RequestSchema.safeParse(Object.fromEntries(formData)); + + if (!submission.success) { + return json<{ success: false; error: string }>( + { + success: false, + error: "Invalid request data", + }, + { status: 400 } + ); + } + + const project = await findProjectBySlug(organizationSlug, projectParam, userId); + if (!project) { + throw new Response(undefined, { + status: 404, + statusText: "Project not found", + }); + } + + const environment = await findEnvironmentBySlug(project.id, envParam, userId); + if (!environment) { + throw new Response(undefined, { + status: 404, + statusText: "Environment not found", + }); + } + + const { text } = submission.data; + + //Tags querying + const queryTags: QueryTags = { + query: async (search) => { + const tagPresenter = new RunTagListPresenter(); + const tags = await tagPresenter.call({ + projectId: environment.projectId, + name: search, + page: 1, + pageSize: 50, + }); + return { + tags: tags.tags.map((t) => t.name), + }; + }, + }; + + const queryQueues: QueryQueues = { + query: async (query, type) => { + const queuePresenter = new QueueListPresenter(); + const queues = await queuePresenter.call({ + environment, + query, + page: 1, + type, + }); + return { + queues: queues.success ? queues.queues.map((q) => q.name) : [], + }; + }, + }; + + const queryVersions: QueryVersions = { + query: async (versionPrefix, isCurrent) => { + const versionPresenter = new VersionListPresenter(); + const versions = await versionPresenter.call({ + environment, + query: versionPrefix ? versionPrefix : undefined, + }); + + if (isCurrent) { + const currentVersion = versions.versions.find((v) => v.isCurrent); + if (currentVersion) { + return { + version: currentVersion.version, + }; + } + + const newestVersion = versions.versions.at(0)?.version; + if (newestVersion) { + return { + version: newestVersion, + }; + } + } + + return { + versions: versions.versions.map((v) => v.version), + }; + }, + }; + + const queryTasks: QueryTasks = { + query: async () => { + const tasks = await getAllTaskIdentifiers($replica, environment.id); + return { + tasks, + }; + }, + }; + + if (!env.OPENAI_API_KEY) { + return json( + { + success: false, + error: "OpenAI API key is not configured", + }, + { status: 400 } + ); + } + + const service = new AIRunFilterService( + { + queryTags, + queryVersions, + queryQueues, + queryTasks, + }, + openai(env.AI_RUN_FILTER_MODEL ?? "gpt-4o-mini") + ); + + const [error, result] = await tryCatch(service.call(text, environment.id)); + if (error) { + return json({ success: false, error: error.message }, { status: 400 }); + } + + return json(result); +} diff --git a/apps/webapp/app/routes/storybook.input-fields/route.tsx b/apps/webapp/app/routes/storybook.input-fields/route.tsx index 6e5b95fe95..62794fab7b 100644 --- a/apps/webapp/app/routes/storybook.input-fields/route.tsx +++ b/apps/webapp/app/routes/storybook.input-fields/route.tsx @@ -1,6 +1,7 @@ import { MagnifyingGlassIcon } from "@heroicons/react/20/solid"; import { EnvironmentLabel } from "~/components/environments/EnvironmentLabel"; import { Input } from "~/components/primitives/Input"; +import { ShortcutKey } from "~/components/primitives/ShortcutKey"; export default function Story() { return ( @@ -26,28 +27,28 @@ function InputFieldSet({ disabled }: { disabled?: boolean }) { variant="large" placeholder="Search" icon={MagnifyingGlassIcon} - shortcut="⌘K" + accessory={} /> } /> } /> } />
@@ -56,42 +57,42 @@ function InputFieldSet({ disabled }: { disabled?: boolean }) { variant="large" placeholder="Search" icon={} - shortcut="⌘K" + accessory={} /> } - shortcut="⌘K" + accessory={} /> } - shortcut="⌘K" + accessory={} /> } - shortcut="⌘K" + accessory={} /> } - shortcut="⌘K" + accessory={} /> } - shortcut="⌘K" + accessory={} />
diff --git a/apps/webapp/app/routes/storybook.search-fields/route.tsx b/apps/webapp/app/routes/storybook.search-fields/route.tsx index 86bd7abe0b..53ae707486 100644 --- a/apps/webapp/app/routes/storybook.search-fields/route.tsx +++ b/apps/webapp/app/routes/storybook.search-fields/route.tsx @@ -5,6 +5,7 @@ import { Fieldset } from "~/components/primitives/Fieldset"; import { Input } from "~/components/primitives/Input"; import { InputGroup } from "~/components/primitives/InputGroup"; import { Label } from "~/components/primitives/Label"; +import { ShortcutKey } from "~/components/primitives/ShortcutKey"; export default function Story() { return ( @@ -18,9 +19,12 @@ export default function Story() { placeholder="Search" required={true} icon={MagnifyingGlassIcon} - shortcut="⌘K" + accessory={ + + } /> + + } fullWidth={false} /> @@ -48,7 +54,9 @@ export default function Story() { placeholder="Search" required={true} icon={MagnifyingGlassIcon} - shortcut="⌘K" + accessory={ + + } /> @@ -57,7 +65,9 @@ export default function Story() { placeholder="Search" required={true} icon={MagnifyingGlassIcon} - shortcut="⌘K" + accessory={ + + } /> @@ -66,7 +76,9 @@ export default function Story() { placeholder="Search" required={true} icon={MagnifyingGlassIcon} - shortcut="⌘K" + accessory={ + + } /> diff --git a/apps/webapp/app/tailwind.css b/apps/webapp/app/tailwind.css index 860ffa0e74..3d68e87811 100644 --- a/apps/webapp/app/tailwind.css +++ b/apps/webapp/app/tailwind.css @@ -71,6 +71,31 @@ filter: blur(0.5rem); opacity: 0.1; } + + .animated-gradient-glow-small { + position: relative; + overflow: visible; + } + + .animated-gradient-glow-small::before { + content: ""; + position: absolute; + inset: -1px; + z-index: -1; + background: conic-gradient( + from var(--gradient-angle), + rgb(99 102 241), + rgb(245 158 11), + rgb(236 72 153), + rgb(245 158 11), + rgb(99 102 241) + ); + border-radius: inherit; + animation: gradient-rotation 3s linear infinite; + pointer-events: none; + filter: blur(0.2rem); + opacity: 0.3; + } } @keyframes gradient-rotation { diff --git a/apps/webapp/app/v3/services/aiRunFilterService.server.ts b/apps/webapp/app/v3/services/aiRunFilterService.server.ts new file mode 100644 index 0000000000..04a4c227c2 --- /dev/null +++ b/apps/webapp/app/v3/services/aiRunFilterService.server.ts @@ -0,0 +1,265 @@ +import { openai } from "@ai-sdk/openai"; +import { type TaskTriggerSource } from "@trigger.dev/database"; +import { generateText, LanguageModelV1, Output, tool } from "ai"; +import { z } from "zod"; +import { TaskRunListSearchFilters } from "~/components/runs/v3/RunFilters"; +import { logger } from "~/services/logger.server"; + +const AIFilters = TaskRunListSearchFilters.omit({ + environments: true, + from: true, + to: true, +}).extend({ + from: z.string().optional().describe("The ISO datetime to filter from"), + to: z.string().optional().describe("The ISO datetime to filter to"), +}); + +const AIFilterResponseSchema = z + .discriminatedUnion("success", [ + z.object({ + success: z.literal(true), + filters: AIFilters, + }), + z.object({ + success: z.literal(false), + error: z.string().describe("A short human-readable error message"), + }), + ]) + .describe("The response from the AI filter service"); + +export interface QueryQueues { + query( + search: string | undefined, + type: "task" | "custom" | undefined + ): Promise<{ + queues: string[]; + }>; +} + +export interface QueryVersions { + query( + versionPrefix: string | undefined, + isCurrent: boolean | undefined + ): Promise< + | { + versions: string[]; + } + | { + version: string; + } + >; +} + +export interface QueryTags { + query(search: string | undefined): Promise<{ + tags: string[]; + }>; +} + +export interface QueryTasks { + query(): Promise<{ + tasks: { slug: string; triggerSource: TaskTriggerSource }[]; + }>; +} + +export type AIFilterResult = + | { + success: true; + filters: TaskRunListSearchFilters; + } + | { + success: false; + error: string; + }; + +export class AIRunFilterService { + constructor( + private readonly queryFns: { + queryTags: QueryTags; + queryVersions: QueryVersions; + queryQueues: QueryQueues; + queryTasks: QueryTasks; + }, + private readonly model: LanguageModelV1 = openai("gpt-4o-mini") + ) {} + + async call(text: string, environmentId: string): Promise { + try { + const result = await generateText({ + model: this.model, + experimental_output: Output.object({ schema: AIFilterResponseSchema }), + tools: { + lookupTags: tool({ + description: "Look up available tags in the environment", + parameters: z.object({ + query: z.string().optional().describe("Optional search query to filter tags"), + }), + execute: async ({ query }) => { + return await this.queryFns.queryTags.query(query); + }, + }), + lookupVersions: tool({ + description: + "Look up available versions in the environment. If you specify `isCurrent` it will return a single version string if it finds one. Otherwise it will return an array of version strings.", + parameters: z.object({ + isCurrent: z + .boolean() + .optional() + .describe("If true, only return the current version"), + versionPrefix: z + .string() + .optional() + .describe( + "Optional version name to filter (e.g. 20250701.1), it uses contains to compare. Don't pass `latest` or `current`, the query has to be in the reverse date format specified. Leave out to get all recent versions." + ), + }), + execute: async ({ versionPrefix, isCurrent }) => { + return await this.queryFns.queryVersions.query(versionPrefix, isCurrent); + }, + }), + lookupQueues: tool({ + description: "Look up available queues in the environment", + parameters: z.object({ + query: z.string().optional().describe("Optional search query to filter queues"), + type: z + .enum(["task", "custom"]) + .optional() + .describe( + "Filter by queue type, only do this if the user specifies it explicitly." + ), + }), + execute: async ({ query, type }) => { + return await this.queryFns.queryQueues.query(query, type); + }, + }), + lookupTasks: tool({ + description: + "Look up available tasks in the environment. It will return each one. The `slug` is used for the filtering. You also get the triggerSource which is either `STANDARD` or `SCHEDULED`", + parameters: z.object({}), + execute: async () => { + return await this.queryFns.queryTasks.query(); + }, + }), + }, + maxSteps: 5, + system: `You are an AI assistant that converts natural language descriptions into structured filter parameters for a task run filtering system. + + Available filter options: + - statuses: Array of run statuses (PENDING, EXECUTING, COMPLETED_SUCCESSFULLY, COMPLETED_WITH_ERRORS, CANCELED, TIMED_OUT, CRASHED, etc.) + - period: Time period string (e.g., "1h", "7d", "30d", "1y") + - from/to: ISO date string. Today's date is ${new Date().toISOString()}, if they only specify a day use the current month. If they don't specify a year use the current year. If they don't specify a time of day use midnight. + - tags: Array of tag names to filter by. Use the lookupTags tool to get the tags. + - tasks: Array of task identifiers to filter by. Use the lookupTasks tool to get the tasks. + - machines: Array of machine presets (micro, small, small-2x, medium, large, xlarge, etc.) + - queues: Array of queue names to filter by. Use the lookupQueues tool to get the queues. + - versions: Array of version identifiers to filter by. Use the lookupVersions tool to get the versions. The "latest" version will be the first returned. The "current" or "deployed" version will have isCurrent set to true. + - rootOnly: Boolean to show only root runs (not child runs) + - runId: Array of specific run IDs to filter by + - batchId: Specific batch ID to filter by + - scheduleId: Specific schedule ID to filter by + + + Common patterns to recognize: + - "failed runs" → statuses: ["COMPLETED_WITH_ERRORS", "CRASHED", "TIMED_OUT", "SYSTEM_FAILURE"]. + - "runs not dequeued yet" → statuses: ["PENDING", "PENDING_VERSION", "DELAYED"] + - If they say "only failed" then only use "COMPLETED_WITH_ERRORS". + - "successful runs" → statuses: ["COMPLETED_SUCCESSFULLY"] + - "running runs" → statuses: ["EXECUTING", "RETRYING_AFTER_FAILURE", "WAITING_TO_RESUME"] + - "pending runs" → statuses: ["PENDING", "PENDING_VERSION", "DELAYED"] + - "past 7 days" → period: "7d" + - "last hour" → period: "1h" + - "this month" → period: "30d" + - "June 16" -> return a from/to filter. + - "with tag X" → tags: ["X"] + - "from task Y" → tasks: ["Y"] + - "using large machine" → machines: ["large-1x", "large-2x"] + - "root only" → rootOnly: true + + Use the available tools to look up actual tags, versions, queues, and tasks in the environment when the user mentions them. This will help you provide accurate filter values. + + Unless they specify they only want root runs, set rootOnly to false. + + IMPORTANT: Return ONLY the filters that are explicitly mentioned or can be reasonably inferred. If the description is unclear or doesn't match any known patterns, return an empty filters object {} and explain why in the explanation field. + + The filters object should only contain the fields that are actually being filtered. Do not include fields with empty arrays or undefined values. + + CRITICAL: The response must be a valid JSON object with exactly this structure: + { + "success": true, + "filters": { + // only include fields that have actual values + }, + "explanation": "string explaining what filters were applied" + } + + or if you can't figure out the filters then return: + { + "success": false, + "error": "" + } + + Make the error no more than 8 words. + `, + prompt: text, + experimental_telemetry: { + isEnabled: true, + metadata: { + environmentId, + }, + }, + }); + + if (!result.experimental_output.success) { + return { + success: false, + error: result.experimental_output.error, + }; + } + + // Validate the filters against the schema to catch any issues + const validationResult = AIFilters.safeParse(result.experimental_output.filters); + if (!validationResult.success) { + logger.error("AI filter validation failed", { + errors: validationResult.error.errors, + filters: result.experimental_output.filters, + }); + + return { + success: false, + error: "AI response validation failed", + }; + } + + return { + success: true, + filters: { + ...validationResult.data, + from: validationResult.data.from + ? new Date(validationResult.data.from).getTime() + : undefined, + to: validationResult.data.to ? new Date(validationResult.data.to).getTime() : undefined, + }, + }; + } catch (error) { + logger.error("AI filter processing failed", { + error, + errorMessage: error instanceof Error ? error.message : String(error), + text, + environmentId, + }); + + // If it's a schema validation error, provide more specific feedback + if (error instanceof Error && error.message.includes("schema")) { + return { + success: false, + error: error.message, + }; + } + + return { + success: false, + error: error instanceof Error ? error.message : String(error), + }; + } + } +} diff --git a/apps/webapp/evals/aiRunFilter.eval.ts b/apps/webapp/evals/aiRunFilter.eval.ts new file mode 100644 index 0000000000..68f3ac2068 --- /dev/null +++ b/apps/webapp/evals/aiRunFilter.eval.ts @@ -0,0 +1,251 @@ +import { evalite } from "evalite"; +import { Levenshtein } from "autoevals"; +import { + AIRunFilterService, + type QueryQueues, + type QueryTags, + type QueryTasks, + type QueryVersions, +} from "~/v3/services/aiRunFilterService.server"; +import dotenv from "dotenv"; +import { traceAISDKModel } from "evalite/ai-sdk"; +import { openai } from "@ai-sdk/openai"; + +dotenv.config({ path: "../../.env" }); + +const queryTags: QueryTags = { + query: async (search) => { + return { + tags: ["user_1", "user_2", "org_1", "org_2"], + }; + }, +}; + +const queryVersions: QueryVersions = { + query: async (versionPrefix, isCurrent) => { + if (isCurrent) { + return { + version: "20250721.1", + }; + } + + return { + versions: ["20250721.1", "20250720.2", "20250720.1"], + }; + }, +}; + +const queryQueues: QueryQueues = { + query: async (query, type) => { + return { + queues: ["shared", "paid"], + }; + }, +}; + +const queryTasks: QueryTasks = { + query: async () => { + return { + tasks: [ + { slug: "email-sender", triggerSource: "STANDARD" }, + { slug: "email-sender-scheduled", triggerSource: "SCHEDULED" }, + ], + }; + }, +}; + +evalite("AI Run Filter", { + data: async () => { + return [ + // Basic status filtering + { + input: "Completed runs", + expected: JSON.stringify({ + success: true, + filters: { + statuses: ["COMPLETED_SUCCESSFULLY"], + }, + }), + }, + { + input: "Failed runs", + expected: JSON.stringify({ + success: true, + filters: { + statuses: ["COMPLETED_WITH_ERRORS", "CRASHED", "TIMED_OUT", "SYSTEM_FAILURE"], + }, + }), + }, + { + input: "Executing runs", + expected: JSON.stringify({ + success: true, + filters: { + statuses: ["EXECUTING", "RETRYING_AFTER_FAILURE", "WAITING_TO_RESUME"], + }, + }), + }, + // Time filters + { + input: "Runs from the past 7 days", + expected: JSON.stringify({ + success: true, + filters: { + period: "7d", + }, + }), + }, + { + input: "Runs from the last hour", + expected: JSON.stringify({ + success: true, + filters: { + period: "1h", + }, + }), + }, + { + input: "Runs from this month", + expected: JSON.stringify({ + success: true, + filters: { + period: "30d", + }, + }), + }, + { + input: "June 16", + expected: JSON.stringify({ + success: true, + filters: { + from: new Date("2025-06-16").getTime(), + to: new Date("2025-06-17").getTime(), + }, + }), + }, + // Combined filters + { + input: "Failed runs from the past week", + expected: JSON.stringify({ + success: true, + filters: { + statuses: ["COMPLETED_WITH_ERRORS", "CRASHED", "TIMED_OUT", "SYSTEM_FAILURE"], + period: "7d", + }, + }), + }, + { + input: "Successful runs from the last 24 hours", + expected: JSON.stringify({ + success: true, + filters: { + statuses: ["COMPLETED_SUCCESSFULLY"], + period: "1d", + }, + }), + }, + // Root-only filtering + { + input: "Root runs only", + expected: JSON.stringify({ + success: true, + filters: { + rootOnly: true, + }, + }), + }, + { + input: "Failed root runs from yesterday", + expected: JSON.stringify({ + success: true, + filters: { + statuses: ["COMPLETED_WITH_ERRORS", "CRASHED", "TIMED_OUT", "SYSTEM_FAILURE"], + rootOnly: true, + period: "1d", + }, + }), + }, + // Machine filtering + { + input: "Runs using large machines", + expected: JSON.stringify({ + success: true, + filters: { + machines: ["large-1x", "large-2x"], + }, + }), + }, + // Edge cases and error handling + { + input: "Runs with tag production", + expected: JSON.stringify({ + success: true, + filters: { + tags: ["production"], + }, + }), + }, + { + input: "Runs from task email-sender", + expected: JSON.stringify({ + success: true, + filters: { + tasks: ["email-sender"], + }, + }), + }, + { + input: "Runs in the shared queue", + expected: JSON.stringify({ + success: true, + filters: { + queues: ["shared"], + }, + }), + }, + // Complex combinations + { + input: "Failed production runs from the past 3 days using large machines", + expected: JSON.stringify({ + success: true, + filters: { + statuses: ["COMPLETED_WITH_ERRORS", "CRASHED", "TIMED_OUT", "SYSTEM_FAILURE"], + tags: ["production"], + period: "3d", + machines: ["large-1x", "large-2x"], + }, + }), + }, + // Ambiguous cases that should return errors + { + input: "Show me something", + expected: JSON.stringify({ + success: false, + error: "Unclear what to filter", + }), + }, + { + input: "Runs with unknown status", + expected: JSON.stringify({ + success: false, + error: "Unknown status specified", + }), + }, + ]; + }, + task: async (input) => { + const service = new AIRunFilterService( + { + queryTags, + queryVersions, + queryQueues, + queryTasks, + }, + traceAISDKModel(openai("gpt-4o-mini")) + ); + + const result = await service.call(input, "123456"); + return JSON.stringify(result); + }, + scorers: [Levenshtein], +}); diff --git a/apps/webapp/package.json b/apps/webapp/package.json index 42a77d62e6..c0ed2e0c58 100644 --- a/apps/webapp/package.json +++ b/apps/webapp/package.json @@ -23,7 +23,8 @@ "clean:sourcemaps": "run-s clean:sourcemaps:*", "clean:sourcemaps:public": "rimraf ./build/**/*.map", "clean:sourcemaps:build": "rimraf ./public/build/**/*.map", - "test": "vitest --no-file-parallelism" + "test": "vitest --no-file-parallelism", + "eval:dev": "evalite watch" }, "eslintIgnore": [ "/node_modules", @@ -31,6 +32,7 @@ "/public/build" ], "dependencies": { + "@ai-sdk/openai": "^1.3.23", "@ariakit/react": "^0.4.6", "@ariakit/react-core": "^0.4.6", "@aws-sdk/client-ecr": "^3.839.0", @@ -84,6 +86,7 @@ "@radix-ui/react-dialog": "^1.0.3", "@radix-ui/react-label": "^2.0.1", "@radix-ui/react-popover": "^1.0.5", + "@radix-ui/react-portal": "^1.1.9", "@radix-ui/react-radio-group": "^1.1.3", "@radix-ui/react-select": "^1.2.1", "@radix-ui/react-slider": "^1.1.2", @@ -120,6 +123,7 @@ "@unkey/error": "^0.2.0", "@upstash/ratelimit": "^1.1.3", "@whatwg-node/fetch": "^0.9.14", + "ai": "^4.3.19", "assert-never": "^1.2.1", "aws4fetch": "^1.0.18", "class-variance-authority": "^0.5.2", @@ -245,6 +249,7 @@ "@types/ws": "^8.5.3", "@typescript-eslint/eslint-plugin": "^5.59.6", "@typescript-eslint/parser": "^5.59.6", + "autoevals": "^0.0.130", "autoprefixer": "^10.4.13", "css-loader": "^6.10.0", "datepicker": "link:@types/@react-aria/datepicker", @@ -255,6 +260,7 @@ "eslint-plugin-import": "^2.29.1", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-turbo": "^2.0.4", + "evalite": "^0.11.4", "npm-run-all": "^4.1.5", "postcss-import": "^16.0.1", "postcss-loader": "^8.1.1", @@ -273,4 +279,4 @@ "engines": { "node": ">=16.0.0" } -} \ No newline at end of file +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b403ee6c86..c8b4b4dc17 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -188,6 +188,9 @@ importers: apps/webapp: dependencies: + '@ai-sdk/openai': + specifier: ^1.3.23 + version: 1.3.23(zod@3.23.8) '@ariakit/react': specifier: ^0.4.6 version: 0.4.6(react-dom@18.2.0)(react@18.2.0) @@ -347,6 +350,9 @@ importers: '@radix-ui/react-popover': specifier: ^1.0.5 version: 1.0.5(@types/react@18.2.69)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-portal': + specifier: ^1.1.9 + version: 1.1.9(@types/react-dom@18.2.7)(@types/react@18.2.69)(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-radio-group': specifier: ^1.1.3 version: 1.1.3(@types/react-dom@18.2.7)(@types/react@18.2.69)(react-dom@18.2.0)(react@18.2.0) @@ -455,6 +461,9 @@ importers: '@whatwg-node/fetch': specifier: ^0.9.14 version: 0.9.14 + ai: + specifier: ^4.3.19 + version: 4.3.19(react@18.2.0)(zod@3.23.8) assert-never: specifier: ^1.2.1 version: 1.2.1 @@ -825,6 +834,9 @@ importers: '@typescript-eslint/parser': specifier: ^5.59.6 version: 5.59.6(eslint@8.31.0)(typescript@5.5.4) + autoevals: + specifier: ^0.0.130 + version: 0.0.130(ws@8.12.0) autoprefixer: specifier: ^10.4.13 version: 10.4.13(postcss@8.5.4) @@ -855,6 +867,9 @@ importers: eslint-plugin-turbo: specifier: ^2.0.4 version: 2.0.5(eslint@8.31.0) + evalite: + specifier: ^0.11.4 + version: 0.11.4 npm-run-all: specifier: ^4.1.5 version: 4.1.5 @@ -2067,7 +2082,7 @@ importers: version: link:../../packages/trigger-sdk openai: specifier: ^4.97.0 - version: 4.97.0(zod@3.23.8) + version: 4.97.0(ws@8.12.0)(zod@3.23.8) replicate: specifier: ^1.0.1 version: 1.0.1 @@ -2499,6 +2514,17 @@ packages: zod: 3.23.8 dev: false + /@ai-sdk/openai@1.3.23(zod@3.23.8): + resolution: {integrity: sha512-86U7rFp8yacUAOE/Jz8WbGcwMCqWvjK33wk5DXkfnAOEn3mx2r7tNSJdjukQFZbAK97VMXGPPHxF+aEARDXRXQ==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.0.0 + dependencies: + '@ai-sdk/provider': 1.1.3 + '@ai-sdk/provider-utils': 2.2.8(zod@3.23.8) + zod: 3.23.8 + dev: false + /@ai-sdk/openai@1.3.3(zod@3.23.8): resolution: {integrity: sha512-CH57tonLB4DwkwqwnMmTCoIOR7cNW3bP5ciyloI7rBGJS/Bolemsoo+vn5YnwkyT9O1diWJyvYeTh7A4UfiYOw==} engines: {node: '>=18'} @@ -2581,6 +2607,18 @@ packages: zod: 3.23.8 dev: false + /@ai-sdk/provider-utils@2.2.8(zod@3.23.8): + resolution: {integrity: sha512-fqhG+4sCVv8x7nFzYnFo19ryhAa3w096Kmc3hWxMQfW/TubPOmt3A6tYZhl4mUfQWWQMsuSkLrtjlWuXBVSGQA==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.23.8 + dependencies: + '@ai-sdk/provider': 1.1.3 + nanoid: 3.3.8 + secure-json-parse: 2.7.0 + zod: 3.23.8 + dev: false + /@ai-sdk/provider@0.0.22: resolution: {integrity: sha512-smZ1/2jL/JSKnbhC6ama/PxI2D/psj+YAe0c0qpd5ComQCNFltg72VFf0rpUSFMmFuj1pCCNoBOCrvyl8HTZHQ==} engines: {node: '>=18'} @@ -2608,6 +2646,13 @@ packages: dependencies: json-schema: 0.4.0 + /@ai-sdk/provider@1.1.3: + resolution: {integrity: sha512-qZMxYJ0qqX/RfnuIaab+zp8UAeJn/ygXXAffR5I4N0n1IrvA6qBsjc8hXLmBiMV2zoXlifkacF7sEFnYnjBcqg==} + engines: {node: '>=18'} + dependencies: + json-schema: 0.4.0 + dev: false + /@ai-sdk/react@0.0.53(react@19.0.0-rc.0)(zod@3.23.8): resolution: {integrity: sha512-sIsmTFoR/QHvUUkltmHwP4bPjwy2vko6j/Nj8ayxLhEHs04Ug+dwXQyfA7MwgimEE3BcDQpWL8ikVj0m3ZILWQ==} engines: {node: '>=18'} @@ -2667,6 +2712,24 @@ packages: zod: 3.23.8 dev: false + /@ai-sdk/react@1.2.12(react@18.2.0)(zod@3.23.8): + resolution: {integrity: sha512-jK1IZZ22evPZoQW3vlkZ7wvjYGYF+tRBKXtrcolduIkQ/m/sOAVcVeVDUDvh1T91xCnWCdUGCPZg2avZ90mv3g==} + engines: {node: '>=18'} + peerDependencies: + react: ^18 || ^19 || ^19.0.0-rc + zod: ^3.23.8 + peerDependenciesMeta: + zod: + optional: true + dependencies: + '@ai-sdk/provider-utils': 2.2.8(zod@3.23.8) + '@ai-sdk/ui-utils': 1.2.11(zod@3.23.8) + react: 18.2.0 + swr: 2.2.5(react@18.2.0) + throttleit: 2.1.0 + zod: 3.23.8 + dev: false + /@ai-sdk/react@1.2.2(react@18.3.1)(zod@3.23.8): resolution: {integrity: sha512-rxyNTFjUd3IilVOJFuUJV5ytZBYAIyRi50kFS2gNmSEiG4NHMBBm31ddrxI/i86VpY8gzZVp1/igtljnWBihUA==} engines: {node: '>=18'} @@ -2827,6 +2890,18 @@ packages: zod: 3.23.8 zod-to-json-schema: 3.24.5(zod@3.23.8) + /@ai-sdk/ui-utils@1.2.11(zod@3.23.8): + resolution: {integrity: sha512-3zcwCc8ezzFlwp3ZD15wAPjf2Au4s3vAbKsXQVyhxODHcmu0iyPO2Eua6D/vicq/AUm/BAo60r97O6HU+EI0+w==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.23.8 + dependencies: + '@ai-sdk/provider': 1.1.3 + '@ai-sdk/provider-utils': 2.2.8(zod@3.23.8) + zod: 3.23.8 + zod-to-json-schema: 3.24.5(zod@3.23.8) + dev: false + /@ai-sdk/vue@0.0.45(vue@3.5.16)(zod@3.23.8): resolution: {integrity: sha512-bqeoWZqk88TQmfoPgnFUKkrvhOIcOcSH5LMPgzZ8XwDqz5tHHrMHzpPfHCj7XyYn4ROTFK/2kKdC/ta6Ko0fMw==} engines: {node: '>=18'} @@ -7868,10 +7943,81 @@ packages: lodash.uniq: 4.5.0 dev: false + /@fastify/accept-negotiator@2.0.1: + resolution: {integrity: sha512-/c/TW2bO/v9JeEgoD/g1G5GxGeCF1Hafdf79WPmUlgYiBXummY0oX3VVq4yFkKKVBKDNlaDUYoab7g38RpPqCQ==} + dev: true + + /@fastify/ajv-compiler@4.0.2: + resolution: {integrity: sha512-Rkiu/8wIjpsf46Rr+Fitd3HRP+VsxUFDDeag0hs9L0ksfnwx2g7SPQQTFL0E8Qv+rfXzQOxBJnjUB9ITUDjfWQ==} + dependencies: + ajv: 8.17.1 + ajv-formats: 3.0.1(ajv@8.17.1) + fast-uri: 3.0.6 + dev: true + /@fastify/busboy@2.0.0: resolution: {integrity: sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ==} engines: {node: '>=14'} + /@fastify/error@4.2.0: + resolution: {integrity: sha512-RSo3sVDXfHskiBZKBPRgnQTtIqpi/7zhJOEmAxCiBcM7d0uwdGdxLlsCaLzGs8v8NnxIRlfG0N51p5yFaOentQ==} + dev: true + + /@fastify/fast-json-stringify-compiler@5.0.3: + resolution: {integrity: sha512-uik7yYHkLr6fxd8hJSZ8c+xF4WafPK+XzneQDPU+D10r5X19GW8lJcom2YijX2+qtFF1ENJlHXKFM9ouXNJYgQ==} + dependencies: + fast-json-stringify: 6.0.1 + dev: true + + /@fastify/forwarded@3.0.0: + resolution: {integrity: sha512-kJExsp4JCms7ipzg7SJ3y8DwmePaELHxKYtg+tZow+k0znUTf3cb+npgyqm8+ATZOdmfgfydIebPDWM172wfyA==} + dev: true + + /@fastify/merge-json-schemas@0.2.1: + resolution: {integrity: sha512-OA3KGBCy6KtIvLf8DINC5880o5iBlDX4SxzLQS8HorJAbqluzLRn80UXU0bxZn7UOFhFgpRJDasfwn9nG4FG4A==} + dependencies: + dequal: 2.0.3 + dev: true + + /@fastify/proxy-addr@5.0.0: + resolution: {integrity: sha512-37qVVA1qZ5sgH7KpHkkC4z9SK6StIsIcOmpjvMPXNb3vx2GQxhZocogVYbr2PbbeLCQxYIPDok307xEvRZOzGA==} + dependencies: + '@fastify/forwarded': 3.0.0 + ipaddr.js: 2.2.0 + dev: true + + /@fastify/send@4.1.0: + resolution: {integrity: sha512-TMYeQLCBSy2TOFmV95hQWkiTYgC/SEx7vMdV+wnZVX4tt8VBLKzmH8vV9OzJehV0+XBfg+WxPMt5wp+JBUKsVw==} + dependencies: + '@lukeed/ms': 2.0.2 + escape-html: 1.0.3 + fast-decode-uri-component: 1.0.1 + http-errors: 2.0.0 + mime: 3.0.0 + dev: true + + /@fastify/static@8.2.0: + resolution: {integrity: sha512-PejC/DtT7p1yo3p+W7LiUtLMsV8fEvxAK15sozHy9t8kwo5r0uLYmhV/inURmGz1SkHZFz/8CNtHLPyhKcx4SQ==} + dependencies: + '@fastify/accept-negotiator': 2.0.1 + '@fastify/send': 4.1.0 + content-disposition: 0.5.4 + fastify-plugin: 5.0.1 + fastq: 1.19.1 + glob: 11.0.0 + dev: true + + /@fastify/websocket@11.0.1: + resolution: {integrity: sha512-44yam5+t1I9v09hWBYO+ezV88+mb9Se2BjgERtzB/68+0mGeTfFkjBeDBe2y+ZdiPpeO2rhevhdnfrBm5mqH+Q==} + dependencies: + duplexify: 4.1.3 + fastify-plugin: 5.0.1 + ws: 8.18.0(bufferutil@4.0.9) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: true + /@fingerprintjs/fingerprintjs-pro-react@2.6.3: resolution: {integrity: sha512-/axCq/cfjZkIM+WFZM/05FQvqtNfdKbIFKU6b2yrwPKlgT8BqWkAq8XvFX6JCPlq8/udVLJjFEDCK+1JQh1L6g==} requiresBuild: true @@ -8981,6 +9127,11 @@ packages: '@lezer/common': 1.2.3 dev: false + /@lukeed/ms@2.0.2: + resolution: {integrity: sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA==} + engines: {node: '>=8'} + dev: true + /@manypkg/cli@0.19.2: resolution: {integrity: sha512-DXx/P1lyunNoFWwOj1MWBucUhaIJljoiAGOpO2fE0GKMBCI6EZBZD0Up1+fQZoXBecKXRgV9mGgLvIB2fOQ0KQ==} hasBin: true @@ -9477,7 +9628,7 @@ packages: requiresBuild: true dependencies: '@gar/promisify': 1.1.3 - semver: 7.6.3 + semver: 7.7.2 dev: false optional: true @@ -12057,6 +12208,27 @@ packages: react-dom: 18.2.0(react@18.3.1) dev: false + /@radix-ui/react-portal@1.1.9(@types/react-dom@18.2.7)(@types/react@18.2.69)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.2.7)(@types/react@18.2.69)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.2.69)(react@18.2.0) + '@types/react': 18.2.69 + '@types/react-dom': 18.2.7 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@radix-ui/react-presence@1.0.0(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-A+6XEvN01NfVWiKu38ybawfHsBjWum42MRPnEuqPsBZ4eV7e/7K321B5VgYMPv3Xx5An6o1/l9ZuDBgmcmWK3w==} peerDependencies: @@ -16775,6 +16947,10 @@ packages: resolution: {integrity: sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==} dev: true + /@sec-ant/readable-stream@0.4.1: + resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + dev: true + /@selderee/plugin-htmlparser2@0.11.0: resolution: {integrity: sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==} dependencies: @@ -18142,6 +18318,17 @@ packages: resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} dev: false + /@stricli/auto-complete@1.2.0: + resolution: {integrity: sha512-r9/msiloVmTF95mdhe04Uzqei1B0ZofhYRLeiPqpJ1W1RMCC8p9iW7kqBZEbALl2aRL5ZK9OEW3Q1cIejH7KEQ==} + hasBin: true + dependencies: + '@stricli/core': 1.2.0 + dev: true + + /@stricli/core@1.2.0: + resolution: {integrity: sha512-5b+npntDY0TAB7wAw0daGlh3/R2sf0TDLyrB1By2jCNH+C+lmcSqMtJXOMLVtEGSkIOvqAgIWpLMSs1PXqzt3w==} + dev: true + /@sveltejs/acorn-typescript@1.0.5(acorn@8.14.1): resolution: {integrity: sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ==} peerDependencies: @@ -18712,6 +18899,10 @@ packages: redent: 3.0.0 dev: false + /@tokenizer/token@0.3.0: + resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} + dev: true + /@tootallnate/once@1.1.2: resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==} engines: {node: '>= 6'} @@ -19149,7 +19340,6 @@ packages: dependencies: '@types/node': 20.14.14 form-data: 4.0.0 - dev: false /@types/node-fetch@2.6.2: resolution: {integrity: sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==} @@ -19200,6 +19390,7 @@ packages: resolution: {integrity: sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw==} dependencies: undici-types: 6.20.0 + dev: false /@types/nodemailer@6.4.17: resolution: {integrity: sha512-I9CCaIp6DTldEg7vyUTZi8+9Vo0hi1/T8gv3C89yk1rSAAzoKQ8H8ki/jBYJSFoH/BisgLP8tkZMlQ91CIquww==} @@ -19892,12 +20083,25 @@ packages: vite: 5.2.7(@types/node@20.14.14) dev: true + /@vitest/pretty-format@2.1.9: + resolution: {integrity: sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==} + dependencies: + tinyrainbow: 1.2.0 + dev: true + /@vitest/pretty-format@3.1.4: resolution: {integrity: sha512-cqv9H9GvAEoTaoq+cYqUTCGscUjKqlJZC7PRwY5FMySVj5J+xOm1KQcCiYHJOEzOKRUhLH4R2pTwvFlWCEScsg==} dependencies: tinyrainbow: 2.0.0 dev: true + /@vitest/runner@2.1.9: + resolution: {integrity: sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==} + dependencies: + '@vitest/utils': 2.1.9 + pathe: 1.1.2 + dev: true + /@vitest/runner@3.1.4: resolution: {integrity: sha512-djTeF1/vt985I/wpKVFBMWUlk/I7mb5hmD5oP8K9ACRmVXgKTae3TUOtXAEBfslNKPzUQvnKhNd34nnRSYgLNQ==} dependencies: @@ -19919,6 +20123,14 @@ packages: tinyspy: 3.0.2 dev: true + /@vitest/utils@2.1.9: + resolution: {integrity: sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==} + dependencies: + '@vitest/pretty-format': 2.1.9 + loupe: 3.1.3 + tinyrainbow: 1.2.0 + dev: true + /@vitest/utils@3.1.4: resolution: {integrity: sha512-yriMuO1cfFhmiGc8ataN51+9ooHRuURdfAZfwFd3usWynjzpLslZdYnRegTv32qdgtJTsj15FoeZe2g15fY1gg==} dependencies: @@ -20292,6 +20504,10 @@ packages: dependencies: event-target-shim: 5.0.1 + /abstract-logging@2.0.1: + resolution: {integrity: sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==} + dev: true + /accepts@1.3.8: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} @@ -20406,7 +20622,6 @@ packages: engines: {node: '>= 8.0.0'} dependencies: humanize-ms: 1.2.1 - dev: false /aggregate-error@3.1.0: resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} @@ -20576,6 +20791,26 @@ packages: zod: 3.23.8 dev: false + /ai@4.3.19(react@18.2.0)(zod@3.23.8): + resolution: {integrity: sha512-dIE2bfNpqHN3r6IINp9znguYdhIOheKW2LDigAMrgt/upT3B8eBGPSCblENvaZGoq+hxaN9fSMzjWpbqloP+7Q==} + engines: {node: '>=18'} + peerDependencies: + react: ^18 || ^19 || ^19.0.0-rc + zod: ^3.23.8 + peerDependenciesMeta: + react: + optional: true + dependencies: + '@ai-sdk/provider': 1.1.3 + '@ai-sdk/provider-utils': 2.2.8(zod@3.23.8) + '@ai-sdk/react': 1.2.12(react@18.2.0)(zod@3.23.8) + '@ai-sdk/ui-utils': 1.2.11(zod@3.23.8) + '@opentelemetry/api': 1.9.0 + jsondiffpatch: 0.6.0 + react: 18.2.0 + zod: 3.23.8 + dev: false + /ajv-formats@2.1.1(ajv@8.17.1): resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} peerDependencies: @@ -20587,6 +20822,17 @@ packages: ajv: 8.17.1 dev: true + /ajv-formats@3.0.1(ajv@8.17.1): + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + dependencies: + ajv: 8.17.1 + dev: true + /ajv-keywords@3.5.2(ajv@6.12.6): resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} peerDependencies: @@ -21003,6 +21249,28 @@ packages: /asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + /atomic-sleep@1.0.0: + resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} + engines: {node: '>=8.0.0'} + dev: true + + /autoevals@0.0.130(ws@8.12.0): + resolution: {integrity: sha512-JS0T/YCEH13AAOGiWWGJDkIPP8LsDmRBYr3EazTukHxvd0nidOW7fGj0qVPFx2bARrSNO9AfCR6xoTP/5m3Bmw==} + dependencies: + ajv: 8.17.1 + compute-cosine-similarity: 1.1.0 + js-levenshtein: 1.1.6 + js-yaml: 4.1.0 + linear-sum-assignment: 1.0.7 + mustache: 4.2.0 + openai: 4.97.0(ws@8.12.0)(zod@3.23.8) + zod: 3.23.8 + zod-to-json-schema: 3.24.5(zod@3.23.8) + transitivePeerDependencies: + - encoding + - ws + dev: true + /autoprefixer@10.4.13(postcss@8.5.4): resolution: {integrity: sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==} engines: {node: ^10 || ^12 || >=14} @@ -21059,6 +21327,13 @@ packages: possible-typed-array-names: 1.0.0 dev: true + /avvio@9.1.0: + resolution: {integrity: sha512-fYASnYi600CsH/j9EQov7lECAniYiBFiiAtBNuZYLA2leLe9qOvZzqYHFjtIj6gD2VMoMLP14834LFWvr4IfDw==} + dependencies: + '@fastify/error': 4.2.0 + fastq: 1.19.1 + dev: true + /aws-sign2@0.7.0: resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} dev: false @@ -21200,6 +21475,14 @@ packages: is-windows: 1.0.2 dev: false + /better-sqlite3@11.10.0: + resolution: {integrity: sha512-EwhOpyXiOEL/lKzHz9AW1msWFNzGc/z+LzeB3/jnFJpxu+th2yqvzsSWas1v9jgs9+xiXJcD5A8CJxAG2TaghQ==} + requiresBuild: true + dependencies: + bindings: 1.5.0 + prebuild-install: 7.1.3 + dev: true + /big.js@6.2.2: resolution: {integrity: sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==} dev: false @@ -21208,11 +21491,14 @@ packages: resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} engines: {node: '>=8'} + /binary-search@1.3.6: + resolution: {integrity: sha512-nbE1WxOTTrUWIfsfZ4aHGYu5DOuNkbxGokjV6Z2kxfJK3uaAb8zNK1muzOeipoLHZjInT4Br88BHpzevc681xA==} + dev: true + /bindings@1.5.0: resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} dependencies: file-uri-to-path: 1.0.0 - dev: false /bintrees@1.0.2: resolution: {integrity: sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw==} @@ -21384,7 +21670,7 @@ packages: /builtins@5.0.1: resolution: {integrity: sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==} dependencies: - semver: 7.6.3 + semver: 7.7.2 dev: true /bun-types@1.1.17: @@ -21715,6 +22001,10 @@ packages: - encoding dev: true + /cheminfo-types@1.8.1: + resolution: {integrity: sha512-FRcpVkox+cRovffgqNdDFQ1eUav+i/Vq/CUd1hcfEl2bevntFlzznL+jE8g4twl6ElB7gZjCko6pYpXyMn+6dA==} + dev: true + /chevrotain@10.5.0: resolution: {integrity: sha512-Pkv5rBY3+CsHOYfV5g/Vs5JY9WTHHDEKOlohI2XeygaZhUeqhAlldZ8Hz9cRmxu709bvS08YzxHdTPHhffc13A==} dependencies: @@ -22108,6 +22398,29 @@ packages: transitivePeerDependencies: - supports-color + /compute-cosine-similarity@1.1.0: + resolution: {integrity: sha512-FXhNx0ILLjGi9Z9+lglLzM12+0uoTnYkHm7GiadXDAr0HGVLm25OivUS1B/LPkbzzvlcXz/1EvWg9ZYyJSdhTw==} + dependencies: + compute-dot: 1.1.0 + compute-l2norm: 1.1.0 + validate.io-array: 1.0.6 + validate.io-function: 1.0.2 + dev: true + + /compute-dot@1.1.0: + resolution: {integrity: sha512-L5Ocet4DdMrXboss13K59OK23GXjiSia7+7Ukc7q4Bl+RVpIXK2W9IHMbWDZkh+JUEvJAwOKRaJDiFUa1LTnJg==} + dependencies: + validate.io-array: 1.0.6 + validate.io-function: 1.0.2 + dev: true + + /compute-l2norm@1.1.0: + resolution: {integrity: sha512-6EHh1Elj90eU28SXi+h2PLnTQvZmkkHWySpoFz+WOlVNLz3DQoC4ISUHSV9n5jMxPHtKGJ01F4uu2PsXBB8sSg==} + dependencies: + validate.io-array: 1.0.6 + validate.io-function: 1.0.2 + dev: true + /concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} @@ -22194,6 +22507,11 @@ packages: engines: {node: '>= 0.6'} dev: false + /cookie@1.0.2: + resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} + engines: {node: '>=18'} + dev: true + /cookiejar@2.1.4: resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==} dev: true @@ -22733,7 +23051,6 @@ packages: engines: {node: '>=10'} dependencies: mimic-response: 3.1.0 - dev: false /deep-eql@5.0.2: resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} @@ -23099,6 +23416,15 @@ packages: stream-shift: 1.0.1 dev: true + /duplexify@4.1.3: + resolution: {integrity: sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==} + dependencies: + end-of-stream: 1.4.4 + inherits: 2.0.4 + readable-stream: 3.6.2 + stream-shift: 1.0.3 + dev: true + /e2b@1.2.1: resolution: {integrity: sha512-ii/Bw55ecxgORqkArKNbuVTwqLgVZ0rH1X3J/NOe4LMZaVETm3qNpPBjoPkpQAsQjw2ew0Ad2sd54epqm9nLCw==} engines: {node: '>=18'} @@ -23129,7 +23455,7 @@ packages: '@one-ini/wasm': 0.1.1 commander: 10.0.1 minimatch: 9.0.1 - semver: 7.6.3 + semver: 7.7.2 dev: false /ee-first@1.1.1: @@ -24472,6 +24798,25 @@ packages: require-like: 0.1.2 dev: true + /evalite@0.11.4: + resolution: {integrity: sha512-t12sJlfkxo0Hon6MYCwOd2qliAjGObrnGL6hYXP9h8AiNAVQCiyGrFrqtOH8TIhM0kgaGrq3s/DeZ679Sr8ipw==} + hasBin: true + dependencies: + '@fastify/static': 8.2.0 + '@fastify/websocket': 11.0.1 + '@stricli/auto-complete': 1.2.0 + '@stricli/core': 1.2.0 + '@vitest/runner': 2.1.9 + better-sqlite3: 11.10.0 + fastify: 5.4.0 + file-type: 19.6.0 + table: 6.9.0 + tinyrainbow: 1.2.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: true + /event-target-shim@5.0.1: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} @@ -24553,7 +24898,6 @@ packages: /expand-template@2.0.3: resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} engines: {node: '>=6'} - dev: false /expect-type@1.2.1: resolution: {integrity: sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==} @@ -24702,7 +25046,6 @@ packages: /fast-decode-uri-component@1.0.1: resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==} - dev: false /fast-deep-equal@2.0.1: resolution: {integrity: sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==} @@ -24732,6 +25075,17 @@ packages: /fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + /fast-json-stringify@6.0.1: + resolution: {integrity: sha512-s7SJE83QKBZwg54dIbD5rCtzOBVD43V1ReWXXYqBgwCwHLYAAT0RQc/FmrQglXqWPpz6omtryJQOau5jI4Nrvg==} + dependencies: + '@fastify/merge-json-schemas': 0.2.1 + ajv: 8.17.1 + ajv-formats: 3.0.1(ajv@8.17.1) + fast-uri: 3.0.6 + json-schema-ref-resolver: 2.0.1 + rfdc: 1.4.1 + dev: true + /fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} @@ -24743,7 +25097,11 @@ packages: resolution: {integrity: sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==} dependencies: fast-decode-uri-component: 1.0.1 - dev: false + + /fast-redact@3.5.0: + resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} + engines: {node: '>=6'} + dev: true /fast-safe-stringify@2.1.1: resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} @@ -24781,11 +25139,41 @@ packages: resolution: {integrity: sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q==} dev: false + /fastify-plugin@5.0.1: + resolution: {integrity: sha512-HCxs+YnRaWzCl+cWRYFnHmeRFyR5GVnJTAaCJQiYzQSDwK9MgJdyAsuL3nh0EWRCYMgQ5MeziymvmAhUHYHDUQ==} + dev: true + + /fastify@5.4.0: + resolution: {integrity: sha512-I4dVlUe+WNQAhKSyv15w+dwUh2EPiEl4X2lGYMmNSgF83WzTMAPKGdWEv5tPsCQOb+SOZwz8Vlta2vF+OeDgRw==} + dependencies: + '@fastify/ajv-compiler': 4.0.2 + '@fastify/error': 4.2.0 + '@fastify/fast-json-stringify-compiler': 5.0.3 + '@fastify/proxy-addr': 5.0.0 + abstract-logging: 2.0.1 + avvio: 9.1.0 + fast-json-stringify: 6.0.1 + find-my-way: 9.3.0 + light-my-request: 6.6.0 + pino: 9.7.0 + process-warning: 5.0.0 + rfdc: 1.4.1 + secure-json-parse: 4.0.0 + semver: 7.7.2 + toad-cache: 3.7.0 + dev: true + /fastq@1.15.0: resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} dependencies: reusify: 1.0.4 + /fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + dependencies: + reusify: 1.0.4 + dev: true + /fault@2.0.1: resolution: {integrity: sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==} dependencies: @@ -24838,6 +25226,10 @@ packages: resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} dev: true + /fft.js@4.0.4: + resolution: {integrity: sha512-f9c00hphOgeQTlDyavwTtu6RiK8AIFjD6+jvXkNkpeQ7rirK3uFWVpalkoS4LAwbdX7mfZ8aoBfFVQX1Re/8aw==} + dev: true + /figures@3.2.0: resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} engines: {node: '>=8'} @@ -24858,9 +25250,18 @@ packages: tslib: 2.8.1 dev: false + /file-type@19.6.0: + resolution: {integrity: sha512-VZR5I7k5wkD0HgFnMsq5hOsSc710MJMu5Nc5QYsbe38NN5iPV/XTObYLc/cpttRTf6lX538+5uO1ZQRhYibiZQ==} + engines: {node: '>=18'} + dependencies: + get-stream: 9.0.1 + strtok3: 9.1.1 + token-types: 6.0.3 + uint8array-extras: 1.4.0 + dev: true + /file-uri-to-path@1.0.0: resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} - dev: false /fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} @@ -24909,6 +25310,15 @@ packages: resolution: {integrity: sha512-4GOTMrpGQVzsCH2ruUn2vmwzV/02zF4q+ybhCIrw/Rkt3L8KWcycdC6aJMctJzwN4fXD4SD5F/4B9Sksh5rE0A==} dev: false + /find-my-way@9.3.0: + resolution: {integrity: sha512-eRoFWQw+Yv2tuYlK2pjFS2jGXSxSppAs3hSQjfxVKxM5amECzIgYYc1FEI8ZmhSh/Ig+FrKEz43NLRKJjYCZVg==} + engines: {node: '>=20'} + dependencies: + fast-deep-equal: 3.1.3 + fast-querystring: 1.1.2 + safe-regex2: 5.0.0 + dev: true + /find-up@4.1.0: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} engines: {node: '>=8'} @@ -24985,7 +25395,6 @@ packages: /form-data-encoder@1.7.2: resolution: {integrity: sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==} - dev: false /form-data@2.3.3: resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} @@ -25032,7 +25441,6 @@ packages: dependencies: node-domexception: 1.0.0 web-streams-polyfill: 4.0.0-beta.3 - dev: false /formidable@3.5.1: resolution: {integrity: sha512-WJWKelbRHN41m5dumb0/k8TeAx7Id/y3a+Z7QfhxP/htI9Js5zYaEDtG8uMgG0vM0lOlqnmjE99/kfpOYi/0Og==} @@ -25315,6 +25723,14 @@ packages: resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} engines: {node: '>=16'} + /get-stream@9.0.1: + resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} + engines: {node: '>=18'} + dependencies: + '@sec-ant/readable-stream': 0.4.1 + is-stream: 4.0.1 + dev: true + /get-symbol-description@1.0.0: resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} engines: {node: '>= 0.4'} @@ -25381,7 +25797,6 @@ packages: /github-from-package@0.0.0: resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} - dev: false /glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} @@ -25958,7 +26373,6 @@ packages: resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} dependencies: ms: 2.1.3 - dev: false /hyphenate-style-name@1.0.4: resolution: {integrity: sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==} @@ -26117,6 +26531,11 @@ packages: hasBin: true dev: false + /install@0.13.0: + resolution: {integrity: sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA==} + engines: {node: '>= 0.10'} + dev: true + /internal-slot@1.0.4: resolution: {integrity: sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ==} engines: {node: '>= 0.4'} @@ -26199,6 +26618,11 @@ packages: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} + /ipaddr.js@2.2.0: + resolution: {integrity: sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==} + engines: {node: '>= 10'} + dev: true + /is-alphabetical@2.0.1: resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} @@ -26208,6 +26632,10 @@ packages: is-alphabetical: 2.0.1 is-decimal: 2.0.1 + /is-any-array@2.0.1: + resolution: {integrity: sha512-UtilS7hLRu++wb/WBAw9bNuP1Eg04Ivn1vERJck8zJthEvXCBEBpGR/33u/xLKWEQf95803oalHrVDptcAvFdQ==} + dev: true + /is-arguments@1.1.1: resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} engines: {node: '>= 0.4'} @@ -26467,6 +26895,11 @@ packages: resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + /is-stream@4.0.1: + resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} + engines: {node: '>=18'} + dev: true + /is-string@1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} engines: {node: '>= 0.4'} @@ -26645,7 +27078,7 @@ packages: resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} engines: {node: '>= 10.13.0'} dependencies: - '@types/node': 22.13.9 + '@types/node': 20.14.14 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -26713,6 +27146,11 @@ packages: engines: {node: '>=14'} dev: false + /js-levenshtein@1.1.6: + resolution: {integrity: sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==} + engines: {node: '>=0.10.0'} + dev: true + /js-sdsl@4.2.0: resolution: {integrity: sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==} @@ -26779,6 +27217,12 @@ packages: engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} dev: true + /json-schema-ref-resolver@2.0.1: + resolution: {integrity: sha512-HG0SIB9X4J8bwbxCbnd5FfPEbcXAJYTi1pBJeP/QPON+w8ovSME8iRG+ElHNxZNX2Qh6eYn1GdzJFS4cDFfx0Q==} + dependencies: + dequal: 2.0.3 + dev: true + /json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} @@ -27048,6 +27492,14 @@ packages: prelude-ls: 1.2.1 type-check: 0.4.0 + /light-my-request@6.6.0: + resolution: {integrity: sha512-CHYbu8RtboSIoVsHZ6Ye4cj4Aw/yg2oAFimlF7mNvfDV192LR7nDiKtSIfCuLT7KokPSTn/9kfVLm5OGN0A28A==} + dependencies: + cookie: 1.0.2 + process-warning: 4.0.1 + set-cookie-parser: 2.6.0 + dev: true + /lightningcss-darwin-arm64@1.29.2: resolution: {integrity: sha512-cK/eMabSViKn/PG8U/a7aCorpeKLMlK0bQeNHmdb7qUnBkNPnL+oV5DjJUo0kqWsJUapZsM4jCfYItbqBDvlcA==} engines: {node: '>= 12.0.0'} @@ -27164,6 +27616,15 @@ packages: resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} engines: {node: '>=14'} + /linear-sum-assignment@1.0.7: + resolution: {integrity: sha512-jfLoSGwZNyjfY8eK4ayhjfcIu3BfWvP6sWieYzYI3AWldwXVoWEz1gtrQL10v/8YltYLBunqNjeVFXPMUs+MJg==} + dependencies: + cheminfo-types: 1.8.1 + install: 0.13.0 + ml-matrix: 6.12.1 + ml-spectra-processing: 14.13.0 + dev: true + /lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} @@ -27301,6 +27762,10 @@ packages: resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} dev: false + /lodash.truncate@4.4.2: + resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} + dev: true + /lodash.union@4.6.0: resolution: {integrity: sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==} dev: true @@ -27467,7 +27932,7 @@ packages: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} dependencies: - semver: 7.6.3 + semver: 7.7.2 dev: true /make-error@1.3.6: @@ -28385,7 +28850,6 @@ packages: resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} engines: {node: '>=10.0.0'} hasBin: true - dev: false /mimic-fn@2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} @@ -28403,7 +28867,6 @@ packages: /mimic-response@3.1.0: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} - dev: false /min-indent@1.0.1: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} @@ -28631,6 +29094,48 @@ packages: engines: {node: '>=10'} hasBin: true + /ml-array-max@1.2.4: + resolution: {integrity: sha512-BlEeg80jI0tW6WaPyGxf5Sa4sqvcyY6lbSn5Vcv44lp1I2GR6AWojfUvLnGTNsIXrZ8uqWmo8VcG1WpkI2ONMQ==} + dependencies: + is-any-array: 2.0.1 + dev: true + + /ml-array-min@1.2.3: + resolution: {integrity: sha512-VcZ5f3VZ1iihtrGvgfh/q0XlMobG6GQ8FsNyQXD3T+IlstDv85g8kfV0xUG1QPRO/t21aukaJowDzMTc7j5V6Q==} + dependencies: + is-any-array: 2.0.1 + dev: true + + /ml-array-rescale@1.3.7: + resolution: {integrity: sha512-48NGChTouvEo9KBctDfHC3udWnQKNKEWN0ziELvY3KG25GR5cA8K8wNVzracsqSW1QEkAXjTNx+ycgAv06/1mQ==} + dependencies: + is-any-array: 2.0.1 + ml-array-max: 1.2.4 + ml-array-min: 1.2.3 + dev: true + + /ml-matrix@6.12.1: + resolution: {integrity: sha512-TJ+8eOFdp+INvzR4zAuwBQJznDUfktMtOB6g/hUcGh3rcyjxbz4Te57Pgri8Q9bhSQ7Zys4IYOGhFdnlgeB6Lw==} + dependencies: + is-any-array: 2.0.1 + ml-array-rescale: 1.3.7 + dev: true + + /ml-spectra-processing@14.13.0: + resolution: {integrity: sha512-AZPE+XrBoRhSRwzUm0IbiQlAPbetDtndDnoq9VO/SzRkN82wrxJpU+urH4aaFVnxTJhxtGOI81FiAxjFe7xQtQ==} + dependencies: + binary-search: 1.3.6 + cheminfo-types: 1.8.1 + fft.js: 4.0.4 + is-any-array: 2.0.1 + ml-matrix: 6.12.1 + ml-xsadd: 3.0.1 + dev: true + + /ml-xsadd@3.0.1: + resolution: {integrity: sha512-Fz2q6dwgzGM8wYKGArTUTZDGa4lQFA2Vi6orjGeTVRy22ZnQFKlJuwS9n8NRviqz1KHAHAzdKJwbnYhdo38uYg==} + dev: true + /mlly@1.7.1: resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==} dependencies: @@ -28728,7 +29233,6 @@ packages: /mustache@4.2.0: resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} hasBin: true - dev: false /mute-stream@1.0.0: resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} @@ -28805,7 +29309,6 @@ packages: /napi-build-utils@2.0.0: resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==} - dev: false /napi_thread_safe_promise@1.2.6: resolution: {integrity: sha512-Magj7jWzspQiYlqBt4sieiOvWmNJgL/hCWeQaKFpFam82QZJ/etvOfAxlqhPtuUspMABTEgikULHaJA3aDVTNQ==} @@ -29029,8 +29532,7 @@ packages: resolution: {integrity: sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg==} engines: {node: '>=10'} dependencies: - semver: 7.6.3 - dev: false + semver: 7.7.2 /node-abort-controller@3.1.1: resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==} @@ -29056,7 +29558,6 @@ packages: /node-domexception@1.0.0: resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} engines: {node: '>=10.5.0'} - dev: false /node-emoji@1.11.0: resolution: {integrity: sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==} @@ -29138,7 +29639,7 @@ packages: make-fetch-happen: 13.0.1 nopt: 7.2.0 proc-log: 4.2.0 - semver: 7.6.3 + semver: 7.7.2 tar: 6.2.1 which: 4.0.0 transitivePeerDependencies: @@ -29255,7 +29756,7 @@ packages: resolution: {integrity: sha512-744wat5wAAHsxa4590mWO0tJ8PKxR8ORZsH9wGpQc3nWTzozMAgBN/XyqYw7mg3yqLM8dLwEnwSfKMmXAjF69g==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} dependencies: - semver: 7.6.3 + semver: 7.7.2 dev: true /npm-normalize-package-bin@2.0.0: @@ -29274,7 +29775,7 @@ packages: dependencies: hosted-git-info: 6.1.1 proc-log: 3.0.0 - semver: 7.6.3 + semver: 7.7.2 validate-npm-package-name: 5.0.0 dev: true @@ -29296,7 +29797,7 @@ packages: npm-install-checks: 6.2.0 npm-normalize-package-bin: 3.0.1 npm-package-arg: 10.1.0 - semver: 7.6.3 + semver: 7.7.2 dev: true /npm-run-all@4.1.5: @@ -29500,6 +30001,11 @@ packages: engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dev: false + /on-exit-leak-free@2.1.2: + resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} + engines: {node: '>=14.0.0'} + dev: true + /on-finished@2.3.0: resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==} engines: {node: '>= 0.8'} @@ -29618,7 +30124,7 @@ packages: - encoding dev: false - /openai@4.97.0(zod@3.23.8): + /openai@4.97.0(ws@8.12.0)(zod@3.23.8): resolution: {integrity: sha512-LRoiy0zvEf819ZUEJhgfV8PfsE8G5WpQi4AwA1uCV8SKvvtXQkoWUFkepD6plqyJQRghy2+AEPQ07FrJFKHZ9Q==} hasBin: true peerDependencies: @@ -29637,10 +30143,10 @@ packages: form-data-encoder: 1.7.2 formdata-node: 4.4.1 node-fetch: 2.6.12 + ws: 8.12.0 zod: 3.23.8 transitivePeerDependencies: - encoding - dev: false /openapi-fetch@0.9.8: resolution: {integrity: sha512-zM6elH0EZStD/gSiNlcPrzXcVQ/pZo3BDvC6CDwRDUt1dDzxlshpmQnpD6cZaJ39THaSmwVCxxRrPKNM1hHrDg==} @@ -30085,6 +30591,11 @@ packages: resolution: {integrity: sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ==} dev: false + /peek-readable@5.4.2: + resolution: {integrity: sha512-peBp3qZyuS6cNIJ2akRNG1uo1WJ1d0wTxg/fxMdZ0BqCVhx242bSFHM9eNqflfJVS9SsgkzgT/1UgnsurBOTMg==} + engines: {node: '>=14.16'} + dev: true + /peek-stream@1.1.3: resolution: {integrity: sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA==} dependencies: @@ -30269,6 +30780,33 @@ packages: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} engines: {node: '>=6'} + /pino-abstract-transport@2.0.0: + resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==} + dependencies: + split2: 4.2.0 + dev: true + + /pino-std-serializers@7.0.0: + resolution: {integrity: sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==} + dev: true + + /pino@9.7.0: + resolution: {integrity: sha512-vnMCM6xZTb1WDmLvtG2lE/2p+t9hDEIvTWJsu6FejkE62vB7gDhvzrpFR4Cw2to+9JNQxVnkAKVPA1KPB98vWg==} + hasBin: true + dependencies: + atomic-sleep: 1.0.0 + fast-redact: 3.5.0 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 2.0.0 + pino-std-serializers: 7.0.0 + process-warning: 5.0.0 + quick-format-unescaped: 4.0.4 + real-require: 0.2.0 + safe-stable-stringify: 2.5.0 + sonic-boom: 4.2.0 + thread-stream: 3.1.0 + dev: true + /pirates@4.0.5: resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==} engines: {node: '>= 6'} @@ -30762,7 +31300,6 @@ packages: simple-get: 4.0.1 tar-fs: 2.1.3 tunnel-agent: 0.6.0 - dev: false /preferred-pm@3.0.3: resolution: {integrity: sha512-+wZgbxNES/KlJs9q40F/1sfOd/j7f1O9JaHcW5Dsn3aUUOZg3L2bjpVUcKV2jvtElYfoTuQiNeMfQJ4kwUAhCQ==} @@ -30950,6 +31487,14 @@ packages: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} dev: true + /process-warning@4.0.1: + resolution: {integrity: sha512-3c2LzQ3rY9d0hc1emcsHhfT9Jwz0cChib/QN89oME2R451w5fy3f0afAhERFZAwrbDU43wk12d0ORBpDVME50Q==} + dev: true + + /process-warning@5.0.0: + resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==} + dev: true + /process@0.11.10: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} engines: {node: '>= 0.6.0'} @@ -31092,7 +31637,6 @@ packages: dependencies: end-of-stream: 1.4.4 once: 1.4.0 - dev: false /pump@3.0.2: resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} @@ -31206,6 +31750,10 @@ packages: /queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + /quick-format-unescaped@4.0.4: + resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + dev: true + /quick-lru@4.0.1: resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} engines: {node: '>=8'} @@ -31970,6 +32518,11 @@ packages: engines: {node: '>= 14.18.0'} dev: true + /real-require@0.2.0: + resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} + engines: {node: '>= 12.13.0'} + dev: true + /recharts-scale@0.4.5: resolution: {integrity: sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==} dependencies: @@ -32431,6 +32984,11 @@ packages: onetime: 5.1.2 signal-exit: 3.0.7 + /ret@0.5.0: + resolution: {integrity: sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw==} + engines: {node: '>=10'} + dev: true + /retry@0.12.0: resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} engines: {node: '>= 4'} @@ -32447,6 +33005,10 @@ packages: resolution: {integrity: sha512-MjOWxM065+WswwnmNONOT+bD1nXzY9Km6u3kzvnx8F8/HXGZdz3T6e6vZJ8Q/RIMUSp/nxqjH3GwvJDy8ijeQQ==} dev: false + /rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + dev: true + /rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} deprecated: Rimraf versions prior to v4 are no longer supported @@ -32627,6 +33189,17 @@ packages: is-regex: 1.1.4 dev: true + /safe-regex2@5.0.0: + resolution: {integrity: sha512-YwJwe5a51WlK7KbOJREPdjNrpViQBI3p4T50lfwPuDhZnE3XGVTlGvi+aolc5+RvxDD6bnUmjVsU9n1eboLUYw==} + dependencies: + ret: 0.5.0 + dev: true + + /safe-stable-stringify@2.5.0: + resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} + engines: {node: '>=10'} + dev: true + /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} requiresBuild: true @@ -32677,6 +33250,10 @@ packages: /secure-json-parse@2.7.0: resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} + /secure-json-parse@4.0.0: + resolution: {integrity: sha512-dxtLJO6sc35jWidmLxo7ij+Eg48PM/kleBsxpC8QJE0qJICe+KawkDQmvCMZUr9u7WKVHgMW6vy3fQ7zMiFZMA==} + dev: true + /seedrandom@3.0.5: resolution: {integrity: sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==} dev: false @@ -32723,7 +33300,6 @@ packages: resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} engines: {node: '>=10'} hasBin: true - dev: false /send@0.18.0: resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} @@ -33017,7 +33593,6 @@ packages: /simple-concat@1.0.1: resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} - dev: false /simple-get@4.0.1: resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} @@ -33025,7 +33600,6 @@ packages: decompress-response: 6.0.0 once: 1.4.0 simple-concat: 1.0.1 - dev: false /simple-oauth2@5.0.0: resolution: {integrity: sha512-8291lo/z5ZdpmiOFzOs1kF3cxn22bMj5FFH+DNUppLJrpoIlM1QnFiE7KpshHu3J3i21TVcx4yW+gXYjdCKDLQ==} @@ -33086,6 +33660,15 @@ packages: is-fullwidth-code-point: 3.0.0 dev: true + /slice-ansi@4.0.0: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + dev: true + /slug@6.1.0: resolution: {integrity: sha512-x6vLHCMasg4DR2LPiyFGI0gJJhywY6DTiGhCrOMzb3SOk/0JVLIaL4UhyFSHu04SD3uAavrKY/K3zZ3i6iRcgA==} dev: false @@ -33241,6 +33824,12 @@ packages: smart-buffer: 4.2.0 dev: false + /sonic-boom@4.2.0: + resolution: {integrity: sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==} + dependencies: + atomic-sleep: 1.0.0 + dev: true + /sonner@1.0.3(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-hBoA2zKuYW3lUnpx4K0vAn8j77YuYiwvP9sLQfieNS2pd5FkT20sMyPTDJnl9S+5T27ZJbwQRPiujwvDBwhZQg==} peerDependencies: @@ -33338,7 +33927,6 @@ packages: /split2@4.2.0: resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} engines: {node: '>= 10.x'} - dev: false /sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} @@ -33513,6 +34101,10 @@ packages: resolution: {integrity: sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==} dev: true + /stream-shift@1.0.3: + resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} + dev: true + /stream-slice@0.1.2: resolution: {integrity: sha512-QzQxpoacatkreL6jsxnVb7X5R/pGw9OUv2qWTYWnmLpg4NdN31snPy/f3TdQE1ZUXaThRvj1Zw4/OGg0ZkaLMA==} @@ -33691,6 +34283,14 @@ packages: resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==} dev: false + /strtok3@9.1.1: + resolution: {integrity: sha512-FhwotcEqjr241ZbjFzjlIYg6c5/L/s4yBGWSMvJ9UoExiSqL+FnFA/CaeZx17WGaZMS/4SOZp8wH18jSS4R4lw==} + engines: {node: '>=16'} + dependencies: + '@tokenizer/token': 0.3.0 + peek-readable: 5.4.2 + dev: true + /style-loader@3.3.4(webpack@5.99.9): resolution: {integrity: sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==} engines: {node: '>= 12.13.0'} @@ -33902,6 +34502,16 @@ packages: magic-string: 0.30.17 zimmerframe: 1.1.2 + /swr@2.2.5(react@18.2.0): + resolution: {integrity: sha512-QtxqyclFeAsxEUeZIYmsaQ0UjimSq1RZ9Un7I68/0ClKK/U3LoyQunwkQfJZr2fc22DfIXLNDc2wFyTEikCUpg==} + peerDependencies: + react: ^16.11.0 || ^17.0.0 || ^18.0.0 + dependencies: + client-only: 0.0.1 + react: 18.2.0 + use-sync-external-store: 1.2.2(react@18.2.0) + dev: false + /swr@2.2.5(react@18.3.1): resolution: {integrity: sha512-QtxqyclFeAsxEUeZIYmsaQ0UjimSq1RZ9Un7I68/0ClKK/U3LoyQunwkQfJZr2fc22DfIXLNDc2wFyTEikCUpg==} peerDependencies: @@ -33961,6 +34571,17 @@ packages: tslib: 2.8.1 dev: true + /table@6.9.0: + resolution: {integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==} + engines: {node: '>=10.0.0'} + dependencies: + ajv: 8.17.1 + lodash.truncate: 4.4.2 + slice-ansi: 4.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + /tailwind-merge@1.12.0: resolution: {integrity: sha512-Y17eDp7FtN1+JJ4OY0Bqv9OA41O+MS8c1Iyr3T6JFLnOgLg3EvcyMKZAnQ8AGyvB5Nxm3t9Xb5Mhe139m8QT/g==} dev: false @@ -34352,6 +34973,12 @@ packages: dependencies: any-promise: 1.3.0 + /thread-stream@3.1.0: + resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} + dependencies: + real-require: 0.2.0 + dev: true + /throttle-debounce@3.0.1: resolution: {integrity: sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==} engines: {node: '>=10'} @@ -34449,6 +35076,11 @@ packages: engines: {node: ^18.0.0 || >=20.0.0} dev: true + /tinyrainbow@1.2.0: + resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} + engines: {node: '>=14.0.0'} + dev: true + /tinyrainbow@2.0.0: resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} engines: {node: '>=14.0.0'} @@ -34509,6 +35141,11 @@ packages: dependencies: is-number: 7.0.0 + /toad-cache@3.7.0: + resolution: {integrity: sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==} + engines: {node: '>=12'} + dev: true + /toggle-selection@1.0.6: resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==} dev: false @@ -34517,6 +35154,14 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} + /token-types@6.0.3: + resolution: {integrity: sha512-IKJ6EzuPPWtKtEIEPpIdXv9j5j2LGJEYk0CKY2efgKoYKLBiZdh6iQkLVBow/CB3phyWAWCyk+bZeaimJn6uRQ==} + engines: {node: '>=14.16'} + dependencies: + '@tokenizer/token': 0.3.0 + ieee754: 1.2.1 + dev: true + /toml@3.0.0: resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==} dev: true @@ -34898,7 +35543,6 @@ packages: resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} dependencies: safe-buffer: 5.2.1 - dev: false /turbo-darwin-64@1.10.3: resolution: {integrity: sha512-IIB9IomJGyD3EdpSscm7Ip1xVWtYb7D0x7oH3vad3gjFcjHJzDz9xZ/iw/qItFEW+wGFcLSRPd+1BNnuLM8AsA==} @@ -35206,6 +35850,11 @@ packages: engines: {node: '>= 4.0.0'} dev: false + /uint8array-extras@1.4.0: + resolution: {integrity: sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ==} + engines: {node: '>=18'} + dev: true + /ulid@2.3.0: resolution: {integrity: sha512-keqHubrlpvT6G2wH0OEfSW4mquYRcbe/J8NMmveoQOjUqmo+hXtO+ORCpWhdbZ7k72UtY61BL7haGxW6enBnjw==} hasBin: true @@ -35242,6 +35891,7 @@ packages: /undici-types@6.20.0: resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + dev: false /undici@5.28.4: resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} @@ -35746,6 +36396,14 @@ packages: builtins: 5.0.1 dev: true + /validate.io-array@1.0.6: + resolution: {integrity: sha512-DeOy7CnPEziggrOO5CZhVKJw6S3Yi7e9e65R1Nl/RTN1vTQKnzjfvks0/8kQ40FP/dsjRAOd4hxmJ7uLa6vxkg==} + dev: true + + /validate.io-function@1.0.2: + resolution: {integrity: sha512-LlFybRJEriSuBnUhQyG5bwglhh50EpTL2ul23MPIuR1odjO7XaMLFV8vHGwp7AZciFxtYOeiSCT5st+XSPONiQ==} + dev: true + /vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} @@ -36107,7 +36765,6 @@ packages: /web-streams-polyfill@4.0.0-beta.3: resolution: {integrity: sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==} engines: {node: '>= 14'} - dev: false /webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} @@ -36453,7 +37110,6 @@ packages: optional: true utf-8-validate: optional: true - dev: false /ws@8.16.0: resolution: {integrity: sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==}