add graph/visualization for interpolated keyframes
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Enrico Bühler 2023-06-26 23:41:07 +02:00
parent cae187b939
commit f237d73016
13 changed files with 768 additions and 53 deletions

View File

@ -24,6 +24,16 @@
"@tempblade/common": "^2.0.1", "@tempblade/common": "^2.0.1",
"@types/lodash.set": "^4.3.7", "@types/lodash.set": "^4.3.7",
"@unom/style": "^0.2.14", "@unom/style": "^0.2.14",
"@visx/axis": "^3.1.0",
"@visx/event": "^3.0.1",
"@visx/glyph": "^3.0.0",
"@visx/gradient": "^3.0.0",
"@visx/grid": "^3.0.1",
"@visx/group": "^3.0.0",
"@visx/responsive": "^3.0.0",
"@visx/scale": "^3.0.0",
"@visx/shape": "^3.0.0",
"@visx/tooltip": "^3.1.2",
"canvaskit-wasm": "^0.38.1", "canvaskit-wasm": "^0.38.1",
"class-variance-authority": "^0.6.0", "class-variance-authority": "^0.6.0",
"clsx": "^1.2.1", "clsx": "^1.2.1",

View File

@ -2,12 +2,20 @@ use super::{
entities::common::AnimationData, entities::common::AnimationData,
keyframe::{Keyframe, Keyframes}, keyframe::{Keyframe, Keyframes},
}; };
use rayon::prelude::{IndexedParallelIterator, IntoParallelIterator, ParallelIterator};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use uuid::Uuid; use uuid::Uuid;
pub trait AnimatedValue<T> { pub trait AnimatedValue<T> {
fn sort_keyframes(&mut self); fn sort_keyframes(&mut self);
fn get_value_at_frame(&self, curr_frame: i32, animation_data: &AnimationData, fps: i16) -> T; fn get_value_at_frame(&self, curr_frame: i32, animation_data: &AnimationData, fps: i16) -> T;
fn get_values_at_frame_range(
&self,
start_frame: i32,
end_frame: i32,
animation_data: &AnimationData,
fps: i16,
) -> Vec<T>;
} }
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct AnimatedFloat { pub struct AnimatedFloat {
@ -24,6 +32,39 @@ pub struct AnimatedFloatVec3 {
pub keyframes: (AnimatedFloat, AnimatedFloat, AnimatedFloat), pub keyframes: (AnimatedFloat, AnimatedFloat, AnimatedFloat),
} }
#[tauri::command]
pub fn get_values_at_frame_range_from_animated_float(
animated_value: AnimatedFloat,
start_frame: i32,
end_frame: i32,
animation_data: AnimationData,
fps: i16,
) -> Vec<f32> {
animated_value.get_values_at_frame_range(start_frame, end_frame, &animation_data, fps)
}
#[tauri::command]
pub fn get_values_at_frame_range_from_animated_float_vec2(
animated_value: AnimatedFloatVec2,
start_frame: i32,
end_frame: i32,
animation_data: AnimationData,
fps: i16,
) -> Vec<(f32, f32)> {
animated_value.get_values_at_frame_range(start_frame, end_frame, &animation_data, fps)
}
#[tauri::command]
pub fn get_values_at_frame_range_from_animated_float_vec3(
animated_value: AnimatedFloatVec3,
start_frame: i32,
end_frame: i32,
animation_data: AnimationData,
fps: i16,
) -> Vec<(f32, f32, f32)> {
animated_value.get_values_at_frame_range(start_frame, end_frame, &animation_data, fps)
}
impl AnimatedFloat { impl AnimatedFloat {
pub fn new(val: f32) -> AnimatedFloat { pub fn new(val: f32) -> AnimatedFloat {
AnimatedFloat { AnimatedFloat {
@ -68,6 +109,21 @@ impl AnimatedValue<f32> for AnimatedFloat {
self.keyframes self.keyframes
.get_value_at_frame(curr_frame, &animation_data, fps) .get_value_at_frame(curr_frame, &animation_data, fps)
} }
fn get_values_at_frame_range(
&self,
start_frame: i32,
end_frame: i32,
animation_data: &AnimationData,
fps: i16,
) -> Vec<f32> {
let values = (start_frame..end_frame)
.into_par_iter()
.map(|i| self.get_value_at_frame(i, animation_data, fps))
.collect();
values
}
} }
impl AnimatedValue<(f32, f32, f32)> for AnimatedFloatVec3 { impl AnimatedValue<(f32, f32, f32)> for AnimatedFloatVec3 {
@ -100,6 +156,40 @@ impl AnimatedValue<(f32, f32, f32)> for AnimatedFloatVec3 {
return (x, y, z); return (x, y, z);
} }
fn get_values_at_frame_range(
&self,
start_frame: i32,
end_frame: i32,
animation_data: &AnimationData,
fps: i16,
) -> Vec<(f32, f32, f32)> {
let x =
self.keyframes
.0
.get_values_at_frame_range(start_frame, end_frame, animation_data, fps);
let y =
self.keyframes
.1
.get_values_at_frame_range(start_frame, end_frame, animation_data, fps);
let z =
self.keyframes
.2
.get_values_at_frame_range(start_frame, end_frame, animation_data, fps);
let vectors: Vec<(f32, f32, f32)> = x
.into_par_iter()
.enumerate()
.map(|(index, val_x)| {
let val_y: f32 = *y.get(index).unwrap();
let val_z: f32 = *z.get(index).unwrap();
(val_x, val_y, val_z)
})
.collect();
vectors
}
} }
impl AnimatedValue<(f32, f32)> for AnimatedFloatVec2 { impl AnimatedValue<(f32, f32)> for AnimatedFloatVec2 {
@ -126,4 +216,33 @@ impl AnimatedValue<(f32, f32)> for AnimatedFloatVec2 {
return (x, y); return (x, y);
} }
fn get_values_at_frame_range(
&self,
start_frame: i32,
end_frame: i32,
animation_data: &AnimationData,
fps: i16,
) -> Vec<(f32, f32)> {
let x =
self.keyframes
.0
.get_values_at_frame_range(start_frame, end_frame, animation_data, fps);
let y =
self.keyframes
.1
.get_values_at_frame_range(start_frame, end_frame, animation_data, fps);
let vectors: Vec<(f32, f32)> = x
.into_par_iter()
.enumerate()
.map(|(index, val_x)| {
let val_y: f32 = *y.get(index).unwrap();
(val_x, val_y)
})
.collect();
vectors
}
} }

View File

@ -2,7 +2,14 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
use crate::{ use crate::{
animation::timeline::calculate_timeline_entities_at_frame, animation::{
primitives::values::{
get_values_at_frame_range_from_animated_float,
get_values_at_frame_range_from_animated_float_vec2,
get_values_at_frame_range_from_animated_float_vec3,
},
timeline::calculate_timeline_entities_at_frame,
},
fonts::{get_system_families, get_system_font, get_system_fonts}, fonts::{get_system_families, get_system_font, get_system_fonts},
}; };
@ -15,7 +22,10 @@ fn main() {
calculate_timeline_entities_at_frame, calculate_timeline_entities_at_frame,
get_system_font, get_system_font,
get_system_families, get_system_families,
get_system_fonts get_system_fonts,
get_values_at_frame_range_from_animated_float,
get_values_at_frame_range_from_animated_float_vec2,
get_values_at_frame_range_from_animated_float_vec3
]) ])
.run(tauri::generate_context!()) .run(tauri::generate_context!())
.expect("error while running tauri application"); .expect("error while running tauri application");

View File

@ -17,8 +17,13 @@ const SelectTrigger = React.forwardRef<
<SelectPrimitive.Trigger <SelectPrimitive.Trigger
ref={ref} ref={ref}
className={cn( className={cn(
"flex h-10 w-full items-center justify-between rounded-md border border-input bg-transparent px-3 py-2 text-sm", "shadow-main/10 shadow-[0_0_0_1px]",
"placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50", "flex h-10 w-full items-center justify-between rounded-md",
"text-main bg-transparent px-3 py-2 text-sm placeholder:text-main outline-none",
"disabled:cursor-not-allowed disabled:opacity-50 transition-all",
"focus:outline-none focus:ring-2 focus:ring-offset-1 focus:shadow-primary",
"focus:ring-primary",
"hover:shadow-primary/50",
className className
)} )}
{...props} {...props}
@ -39,7 +44,8 @@ const SelectContent = React.forwardRef<
<SelectPrimitive.Content <SelectPrimitive.Content
ref={ref} ref={ref}
className={cn( className={cn(
"relative z-50 min-w-[8rem] overflow-hidden rounded-md border bg-neutral-accent text-popover-foreground shadow-md animate-in fade-in-80", "relative z-50 min-w-[8rem] overflow-hidden rounded-md border bg-neutral-accent",
"text-main shadow-md animate-in fade-in-80",
className className
)} )}
{...props} {...props}
@ -58,7 +64,7 @@ const SelectLabel = React.forwardRef<
>(({ className, ...props }, ref) => ( >(({ className, ...props }, ref) => (
<SelectPrimitive.Label <SelectPrimitive.Label
ref={ref} ref={ref}
className={cn("py-1.5 pl-8 pr-2 text-sm font-semibold", className)} className={cn("py-1.5 pl-8 pr-2 text-sm text-main font-semibold", className)}
{...props} {...props}
/> />
)); ));
@ -72,7 +78,7 @@ const SelectItem = React.forwardRef<
ref={ref} ref={ref}
className={cn( className={cn(
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none", "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none",
"focus:bg-primary focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50", "focus:bg-primary focus:text-neutral dark:focus:text-main text-main data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className className
)} )}
{...props} {...props}
@ -83,7 +89,7 @@ const SelectItem = React.forwardRef<
</SelectPrimitive.ItemIndicator> </SelectPrimitive.ItemIndicator>
</span> </span>
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText> <SelectPrimitive.ItemText className="text-main">{children}</SelectPrimitive.ItemText>
</SelectPrimitive.Item> </SelectPrimitive.Item>
)); ));
SelectItem.displayName = SelectPrimitive.Item.displayName; SelectItem.displayName = SelectPrimitive.Item.displayName;
@ -94,7 +100,7 @@ const SelectSeparator = React.forwardRef<
>(({ className, ...props }, ref) => ( >(({ className, ...props }, ref) => (
<SelectPrimitive.Separator <SelectPrimitive.Separator
ref={ref} ref={ref}
className={cn("-mx-1 my-1 h-px bg-slate-800", className)} className={cn("-mx-1 my-1 h-px bg-slate-main", className)}
{...props} {...props}
/> />
)); ));

View File

@ -8,8 +8,8 @@ import { shallow } from "zustand/shallow";
import KeyframeIndicator from "./KeyframeIndicator"; import KeyframeIndicator from "./KeyframeIndicator";
import { TIMELINE_SCALE, calculateOffset } from "./common"; import { TIMELINE_SCALE, calculateOffset } from "./common";
import { TriangleDownIcon } from "@radix-ui/react-icons"; import { TriangleDownIcon } from "@radix-ui/react-icons";
import TrackPropertiesEditor from "./TrackPropertiesEditor"; import TrackPropertiesEditor from "./TrackDisplay/TrackPropertiesEditor";
import { flattenedKeyframesByEntity } from "utils"; import { cn, flattenedKeyframesByEntity } from "utils";
type TrackProps = { type TrackProps = {
animationData: z.input<typeof AnimationData>; animationData: z.input<typeof AnimationData>;
@ -18,6 +18,10 @@ type TrackProps = {
entity: z.input<typeof AnimatedEntity>; entity: z.input<typeof AnimatedEntity>;
}; };
const TrackDisplayTypeOptions = ["Default", "Graph"] as const;
export const TrackDisplayType = z.enum(TrackDisplayTypeOptions);
const Track: FC<TrackProps> = ({ animationData, index, name, entity }) => { const Track: FC<TrackProps> = ({ animationData, index, name, entity }) => {
const controls = useDragControls(); const controls = useDragControls();
@ -56,20 +60,18 @@ const Track: FC<TrackProps> = ({ animationData, index, name, entity }) => {
onMouseDown={(e) => e.preventDefault()} onMouseDown={(e) => e.preventDefault()}
onPointerDown={(e) => controls.start(e)} onPointerDown={(e) => controls.start(e)}
className={`h-full transition-all rounded-sm min-w-[200px] p-1 px-2 flex flex-col ${ className={`h-full transition-all rounded-sm min-w-[200px] p-1 px-2 flex flex-col ${
selectedEntity === index ? "bg-highlight" : "bg-neutral-accent" selectedEntity === index
? "bg-highlight text-neutral dark:text-main"
: "bg-neutral-accent text-main"
}`} }`}
> >
<div className="flex flex-row"> <div className="flex flex-row">
<motion.div <motion.div
onClick={() => setIsExpanded(!isExpanded)} onClick={() => setIsExpanded(!isExpanded)}
className="will-change-transform" className={cn("will-change-transform")}
animate={{ rotate: isExpanded ? 0 : -90 }} animate={{ rotate: isExpanded ? 0 : -90 }}
> >
<TriangleDownIcon <TriangleDownIcon width="32px" height="32px" />
width="32px"
height="32px"
className="text-main"
/>
</motion.div> </motion.div>
<h3 <h3
onClick={() => onClick={() =>
@ -77,7 +79,7 @@ const Track: FC<TrackProps> = ({ animationData, index, name, entity }) => {
? deselectEntity() ? deselectEntity()
: selectEntity(index) : selectEntity(index)
} }
className="text-white-800 h-2 text-base leading-loose font-semibold select-none cursor-pointer" className="h-2 text-base leading-loose font-semibold select-none cursor-pointer"
> >
{name} {name}
</h3> </h3>

View File

@ -0,0 +1,64 @@
import { FC } from "react";
import { extent, bisector } from "d3-array";
import { curveNatural } from "@visx/curve";
import { scaleLinear } from "@visx/scale";
import { LinePath } from "@visx/shape";
import { Group } from "@visx/group";
const HEIGHT = 300;
const WIDTH = 1200;
type PropertyValue = {
value: number;
frame: number;
};
const getValue = (d: PropertyValue) => d.value;
const getFrame = (d: PropertyValue) => d.frame;
const PropertyGraph: FC<{
values: Array<{ frame: number; value: number }>;
}> = ({ values }) => {
const framesScale = scaleLinear({
range: [0, WIDTH],
domain: extent(values, getFrame) as [number, number],
nice: true,
});
const valuesScale = scaleLinear({
range: [HEIGHT, 0],
domain: extent(values, getValue) as [number, number],
nice: true,
});
return (
<Group>
<LinePath
curve={curveNatural}
stroke="white"
strokeWidth={3}
data={values}
x={(d) => framesScale(getFrame(d)) ?? 0}
y={(d) => valuesScale(getValue(d)) ?? 0}
/>
</Group>
);
};
const Graphs: FC<{ values: Array<Array<number>> }> = ({ values }) => {
return (
<svg width={WIDTH} height={HEIGHT}>
{values.map((propertyValues) => (
<PropertyGraph
values={propertyValues.map((val, index) => ({
frame: index,
value: val,
}))}
/>
))}
</svg>
);
};
export default Graphs;

View File

@ -11,15 +11,22 @@ import {
AnimatedNumberKeyframeIndicator, AnimatedNumberKeyframeIndicator,
AnimatedVec2KeyframeIndicator, AnimatedVec2KeyframeIndicator,
AnimatedVec3KeyframeIndicator, AnimatedVec3KeyframeIndicator,
} from "./KeyframeIndicator"; } from "../KeyframeIndicator";
import { ToggleGroup, ToggleGroupItem } from "components/ToggleGroup"; import { ToggleGroup, ToggleGroupItem } from "components/ToggleGroup";
import { produce } from "immer"; import { produce } from "immer";
import set from "lodash.set"; import set from "lodash.set";
import { useEntitiesStore } from "stores/entities.store"; import { useEntitiesStore } from "stores/entities.store";
import { shallow } from "zustand/shallow";
import { AnimatedValue } from "primitives/Values"; import { AnimatedValue } from "primitives/Values";
import { motion } from "framer-motion"; import { motion } from "framer-motion";
import { ease } from "@unom/style"; import { ease } from "@unom/style";
import { TrackDisplayType } from "../Track";
import TrackPropertyGraph from "./TrackPropertyGraph";
import { LineChart } from "lucide-react";
type DisplayState = {
type: z.input<typeof TrackDisplayType>;
selectedAnimatedProperties: Array<number>;
};
const TrackAnimatedPropertyKeyframes: FC<{ const TrackAnimatedPropertyKeyframes: FC<{
animatedProperty: z.input<typeof AnimatedProperty>; animatedProperty: z.input<typeof AnimatedProperty>;
@ -70,12 +77,23 @@ const TrackAnimatedPropertyKeyframes: FC<{
const TrackAnimatedProperty: FC<{ const TrackAnimatedProperty: FC<{
animatedProperty: z.input<typeof AnimatedProperty>; animatedProperty: z.input<typeof AnimatedProperty>;
animationData: z.input<typeof AnimationData>; animationData: z.input<typeof AnimationData>;
displayState: DisplayState;
index: number;
onDisplayStateUpdate: (s: DisplayState) => void;
onUpdate: (e: z.input<typeof AnimatedProperty>) => void; onUpdate: (e: z.input<typeof AnimatedProperty>) => void;
}> = ({ animatedProperty, animationData, onUpdate }) => { }> = ({
animatedProperty,
animationData,
onUpdate,
displayState,
index,
onDisplayStateUpdate,
}) => {
const [selectedDimension, setSelectedDimension] = useState<"x" | "y" | "z">(); const [selectedDimension, setSelectedDimension] = useState<"x" | "y" | "z">();
return ( return (
<motion.div <motion.div
layout
transition={ease.quint(0.8).out} transition={ease.quint(0.8).out}
variants={{ enter: { y: 0, opacity: 1 }, from: { y: -10, opacity: 0 } }} variants={{ enter: { y: 0, opacity: 1 }, from: { y: -10, opacity: 0 } }}
className="flex flex-row bg-neutral-accent ml-2 align-center" className="flex flex-row bg-neutral-accent ml-2 align-center"
@ -115,8 +133,33 @@ const TrackAnimatedProperty: FC<{
Z Z
</ToggleGroupItem> </ToggleGroupItem>
)} )}
<ToggleGroupItem
selected={displayState.selectedAnimatedProperties.includes(index)}
onClick={() => {
if (displayState.selectedAnimatedProperties.includes(index)) {
onDisplayStateUpdate({
...displayState,
selectedAnimatedProperties:
displayState.selectedAnimatedProperties.filter(
(index) => index !== index
),
});
} else {
onDisplayStateUpdate({
...displayState,
selectedAnimatedProperties: [
...displayState.selectedAnimatedProperties,
index,
],
});
}
}}
>
<LineChart />
</ToggleGroupItem>
</ToggleGroup> </ToggleGroup>
</div> </div>
<div className="relative"> <div className="relative">
<TrackAnimatedPropertyKeyframes <TrackAnimatedPropertyKeyframes
selectedDimension={ selectedDimension={
@ -153,24 +196,30 @@ const TrackPropertiesEditor: FC<{
const parsedEntity = AnimatedEntity.parse(nextValue); const parsedEntity = AnimatedEntity.parse(nextValue);
console.log("reacreated callback");
entitiesStore.updateEntityById(parsedEntity.id, parsedEntity); entitiesStore.updateEntityById(parsedEntity.id, parsedEntity);
}, },
[entity] [entity]
); );
const [displayState, setDisplayState] = useState<DisplayState>({
type: TrackDisplayType.Enum.Default,
selectedAnimatedProperties: [],
});
return ( return (
<motion.div layout className="flex flex-row">
<motion.div <motion.div
animate="enter" animate="enter"
initial="from" initial="from"
variants={{ enter: {}, from: {} }} variants={{ enter: {}, from: {} }}
transition={{ staggerChildren: 0.05 }} transition={{ staggerChildren: 0.05 }}
layout
className="flex flex-col gap-1" className="flex flex-col gap-1"
> >
{animatedProperties.map((animatedProperty, index) => ( {animatedProperties.map((animatedProperty, index) => (
<TrackAnimatedProperty <TrackAnimatedProperty
index={index}
onDisplayStateUpdate={setDisplayState}
displayState={displayState}
onUpdate={handleUpdate} onUpdate={handleUpdate}
animationData={entity.animation_data} animationData={entity.animation_data}
key={index} key={index}
@ -178,6 +227,15 @@ const TrackPropertiesEditor: FC<{
/> />
))} ))}
</motion.div> </motion.div>
{displayState.selectedAnimatedProperties.length > 0 && (
<TrackPropertyGraph
animationData={entity.animation_data}
animatedProperties={displayState.selectedAnimatedProperties.map(
(index) => animatedProperties[index]
)}
/>
)}
</motion.div>
); );
}; };

View File

@ -0,0 +1,108 @@
import { invoke } from "@tauri-apps/api";
import { AnimationData } from "primitives/AnimatedEntities";
import { AnimatedProperty } from "primitives/AnimatedProperty";
import { AnimatedValue, ValueType } from "primitives/Values";
import { FC, useEffect, useState } from "react";
import { z } from "zod";
import Graph from "./Graph";
type TrackPropertyPathProps = {
animatedProperties: Array<z.input<typeof AnimatedProperty>>;
animationData: z.input<typeof AnimationData>;
};
const TrackPropertyGraph: FC<TrackPropertyPathProps> = ({
animatedProperties,
animationData,
}) => {
const [values, setValues] = useState<Array<Array<number>>>([]);
useEffect(() => {
const tasks: Array<Promise<Array<Array<number>>>> = [];
animatedProperties.forEach((animatedProperty) => {
animatedProperty.animatedValue.type;
const animatedValue = animatedProperty.animatedValue;
const commonValues: {
animatedValue: z.input<typeof AnimatedValue>;
startFrame: number;
endFrame: number;
fps: number;
animationData: z.input<typeof AnimationData>;
} = {
animatedValue: AnimatedValue.parse(animatedValue),
startFrame: 0,
endFrame: 600,
fps: 60,
animationData: AnimationData.parse(animationData),
};
switch (animatedValue.type) {
case ValueType.Enum.Number:
tasks.push(
invoke(
"get_values_at_frame_range_from_animated_float",
commonValues
).then((data) => {
const numbers = data as Array<number>;
return [numbers];
})
);
break;
case ValueType.Enum.Vec2:
tasks.push(
invoke(
"get_values_at_frame_range_from_animated_float_vec2",
commonValues
).then((data) => {
const vectors = data as [Array<number>, Array<number>];
const xValues = vectors.map((vec2) => vec2[0]);
const yValues = vectors.map((vec2) => vec2[1]);
return [xValues, yValues];
})
);
break;
case ValueType.Enum.Vec3:
tasks.push(
invoke(
"get_values_at_frame_range_from_animated_float_vec3",
commonValues
).then((data) => {
const vectors = data as [
Array<number>,
Array<number>,
Array<number>
];
const xValues = vectors.map((vec2) => vec2[0]);
const yValues = vectors.map((vec2) => vec2[1]);
const zValues = vectors.map((vec2) => vec2[2]);
return [xValues, yValues, zValues];
})
);
break;
}
});
Promise.all(tasks).then((values) => {
const flatValues = values.flat();
console.log("flattened Values", flatValues);
setValues(flatValues);
});
}, animatedProperties);
return (
<div>
<Graph values={values} />
</div>
);
};
export default TrackPropertyGraph;

View File

@ -1,6 +1,5 @@
import { z } from "zod"; import { z } from "zod";
import { Interpolation } from "./Interpolation"; import { Interpolation } from "./Interpolation";
import { v4 as uuid } from "uuid";
export const Keyframe = z.object({ export const Keyframe = z.object({
id: z.string().uuid(), id: z.string().uuid(),

View File

@ -5,6 +5,8 @@ import { v4 as uuid } from "uuid";
export const Vec2 = z.array(z.number()).length(2); export const Vec2 = z.array(z.number()).length(2);
export const Vec3 = z.array(z.number()).length(3); export const Vec3 = z.array(z.number()).length(3);
const ValueTypeOptions = ["Vec2", "Vec3", "Number"] as const; const ValueTypeOptions = ["Vec2", "Vec3", "Number"] as const;
export const ValueType = z.enum(ValueTypeOptions); export const ValueType = z.enum(ValueTypeOptions);

View File

@ -13,24 +13,16 @@
@apply text-lg; @apply text-lg;
} }
span {
@apply text-white;
}
a { a {
@apply text-blue-600 underline; @apply text-blue-600 underline;
} }
select,
input { input {
@apply box-border bg-transparent shadow-main/10 hover:shadow-primary/50 @apply box-border bg-transparent shadow-main/10 hover:shadow-primary/50
focus:ring-primary focus:ring-2 focus:ring-offset-2 focus:ring-primary focus:ring-2 focus:ring-offset-1
focus:shadow-primary selection:bg-secondary selection:text-black focus:shadow-primary selection:bg-secondary selection:text-black
outline-none px-3 py-2 rounded-md shadow-[0_0_0_1px]; outline-none px-3 py-2 rounded-md shadow-[0_0_0_1px]
} appearance-none items-center justify-center
input {
@apply appearance-none items-center justify-center
w-full text-base leading-none transition-all; w-full text-base leading-none transition-all;
} }

View File

@ -971,6 +971,47 @@
resolved "https://packages.unom.io/@tempblade%2fcommon/-/common-2.0.1.tgz" resolved "https://packages.unom.io/@tempblade%2fcommon/-/common-2.0.1.tgz"
integrity sha512-8uCqsfu2tcQq4O4XODS7Hn7Mj9hZh+Rh+Y0Fsej9Bbemn/WwlIT0WrUSzWGMZLcTspvgl6kz/ljBzCqLAa3Yyw== integrity sha512-8uCqsfu2tcQq4O4XODS7Hn7Mj9hZh+Rh+Y0Fsej9Bbemn/WwlIT0WrUSzWGMZLcTspvgl6kz/ljBzCqLAa3Yyw==
"@types/d3-color@*":
version "3.1.0"
resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-3.1.0.tgz#6594da178ded6c7c3842f3cc0ac84b156f12f2d4"
integrity sha512-HKuicPHJuvPgCD+np6Se9MQvS6OCbJmOjGvylzMJRlDwUXjKTTXs6Pwgk79O09Vj/ho3u1ofXnhFOaEWWPrlwA==
"@types/d3-interpolate@^3.0.1":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-3.0.1.tgz#e7d17fa4a5830ad56fe22ce3b4fac8541a9572dc"
integrity sha512-jx5leotSeac3jr0RePOH1KdR9rISG91QIE4Q2PYTu4OymLTZfA3SrnURSLzKH48HmXVUru50b8nje4E79oQSQw==
dependencies:
"@types/d3-color" "*"
"@types/d3-path@^1", "@types/d3-path@^1.0.8":
version "1.0.9"
resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-1.0.9.tgz#73526b150d14cd96e701597cbf346cfd1fd4a58c"
integrity sha512-NaIeSIBiFgSC6IGUBjZWcscUJEq7vpVu7KthHN8eieTV9d9MqkSOZLH4chq1PmcKy06PNe3axLeKmRIyxJ+PZQ==
"@types/d3-scale@^4.0.2":
version "4.0.3"
resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-4.0.3.tgz#7a5780e934e52b6f63ad9c24b105e33dd58102b5"
integrity sha512-PATBiMCpvHJSMtZAMEhc2WyL+hnzarKzI6wAHYjhsonjWJYGq5BXTzQjv4l8m2jO183/4wZ90rKvSeT7o72xNQ==
dependencies:
"@types/d3-time" "*"
"@types/d3-shape@^1.3.1":
version "1.3.8"
resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-1.3.8.tgz#c3c15ec7436b4ce24e38de517586850f1fea8e89"
integrity sha512-gqfnMz6Fd5H6GOLYixOZP/xlrMtJms9BaS+6oWxTKHNqPGZ93BkWWupQSCYm6YHqx6h9wjRupuJb90bun6ZaYg==
dependencies:
"@types/d3-path" "^1"
"@types/d3-time@*":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-3.0.0.tgz#e1ac0f3e9e195135361fa1a1d62f795d87e6e819"
integrity sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==
"@types/d3-time@^2.0.0":
version "2.1.1"
resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-2.1.1.tgz#743fdc821c81f86537cbfece07093ac39b4bc342"
integrity sha512-9MVYlmIgmRR31C5b4FVSWtuMmBHh2mOWQYfl7XAYOa8dsnb7iEmUmRSWSFgXFtkjxO65d7hTUHQC+RhR/9IWFg==
"@types/lodash.set@^4.3.7": "@types/lodash.set@^4.3.7":
version "4.3.7" version "4.3.7"
resolved "https://registry.npmjs.org/@types/lodash.set/-/lodash.set-4.3.7.tgz" resolved "https://registry.npmjs.org/@types/lodash.set/-/lodash.set-4.3.7.tgz"
@ -978,7 +1019,7 @@
dependencies: dependencies:
"@types/lodash" "*" "@types/lodash" "*"
"@types/lodash@*": "@types/lodash@*", "@types/lodash@^4.14.172":
version "4.14.195" version "4.14.195"
resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.195.tgz" resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.195.tgz"
integrity sha512-Hwx9EUgdwf2GLarOjQp5ZH8ZmblzcbTBC2wtQWNKARBSxM9ezRIAUpeDTgoQRAFB0+8CNWXVA9+MaSOzOF3nPg== integrity sha512-Hwx9EUgdwf2GLarOjQp5ZH8ZmblzcbTBC2wtQWNKARBSxM9ezRIAUpeDTgoQRAFB0+8CNWXVA9+MaSOzOF3nPg==
@ -993,6 +1034,13 @@
resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz" resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz"
integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==
"@types/react-dom@*":
version "18.2.6"
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.6.tgz#ad621fa71a8db29af7c31b41b2ea3d8a6f4144d1"
integrity sha512-2et4PDvg6PVCyS7fuTc4gPoksV58bW0RwSxWKcPRcHZf0PRUGq03TKcD/rUHe3azfV6/5/biUBJw+HhCQjaP0A==
dependencies:
"@types/react" "*"
"@types/react-dom@^18.0.6": "@types/react-dom@^18.0.6":
version "18.2.4" version "18.2.4"
resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.4.tgz" resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.4.tgz"
@ -1026,6 +1074,156 @@
dependencies: dependencies:
css-color-converter "^2.0.0" css-color-converter "^2.0.0"
"@visx/axis@^3.1.0":
version "3.1.0"
resolved "https://registry.yarnpkg.com/@visx/axis/-/axis-3.1.0.tgz#775b221e5abfdec25304c607eeae8cda1a8bade6"
integrity sha512-JDj/1VYx0JO0pHFtwoFtYcnqdoZFh/dpHImEl169S5nTslSFlIoNTXA/ekpBP6ELkEZ59gmF1X5k29x6MFBwCA==
dependencies:
"@types/react" "*"
"@visx/group" "3.0.0"
"@visx/point" "3.0.1"
"@visx/scale" "3.0.0"
"@visx/shape" "3.0.0"
"@visx/text" "3.0.0"
classnames "^2.3.1"
prop-types "^15.6.0"
"@visx/bounds@3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@visx/bounds/-/bounds-3.0.0.tgz#cf357cbff90a1fe5f95eb9d9288dd8794b744a7f"
integrity sha512-YQaSSER9erxlhppzRms6cvYdKqcIwk6eksrGdbJkBoHobhPo1JCIUXlmrA4qgrEnXInPJpueGE+PE5F+Dk12DA==
dependencies:
"@types/react" "*"
"@types/react-dom" "*"
prop-types "^15.5.10"
"@visx/curve@3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@visx/curve/-/curve-3.0.0.tgz#c54568472e00a38483c58cf52e4a6ddb2887c2d4"
integrity sha512-kvHJDLBeczTQ87ZExSTfRxej06l6o6UiQ0NHf9+xpAin06y6Qk1ThOHHWJTGM6KGzwlu7jEauJGHwZs6nMhDvA==
dependencies:
"@types/d3-shape" "^1.3.1"
d3-shape "^1.0.6"
"@visx/event@^3.0.1":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@visx/event/-/event-3.0.1.tgz#d5358f52ff5ef30036d955bd2b68b96472ff2d6f"
integrity sha512-tK1EUYQLLStBuoCMbm8LJ3VbDyCVI8HjT0pMRQxm+C75FSIVWvrThgrfrC9sWOFnEMEYWspZO7hI5zjsPKjLQA==
dependencies:
"@types/react" "*"
"@visx/point" "3.0.1"
"@visx/glyph@^3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@visx/glyph/-/glyph-3.0.0.tgz#218a96aa0ccba95dc77e46ab08d26ad89198f3a8"
integrity sha512-r1B0IocfWfhTABKjam0qqsWKjxLxZfGwefnwn8IcfELSd9iAUtLbI/46nP4roQRHhB/Wl3RBbgA97fZw8f1MxA==
dependencies:
"@types/d3-shape" "^1.3.1"
"@types/react" "*"
"@visx/group" "3.0.0"
classnames "^2.3.1"
d3-shape "^1.2.0"
prop-types "^15.6.2"
"@visx/gradient@^3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@visx/gradient/-/gradient-3.0.0.tgz#39b55dd5a0b34feb219fcb2ea5525388c5ae0c1b"
integrity sha512-UoM9R9PIPLO/w7hCW9gFncrLdpKNqh13sLS9/0Iy6b75uP2l05FLG2HX4kXljeyOrj4/XyzRCMYm0HHk/p5iMA==
dependencies:
"@types/react" "*"
prop-types "^15.5.7"
"@visx/grid@^3.0.1":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@visx/grid/-/grid-3.0.1.tgz#d91085ed92e7e1c0c2e58710bc33b2f0f33b8e74"
integrity sha512-cln5CVvFG58C5Uz1Uf0KRBFmGmgD1NALOQdYDu5yPsTuY2yLzVYPvCIlYBMdUtE0uzfNq972SmkZHfZYs03jxQ==
dependencies:
"@types/react" "*"
"@visx/curve" "3.0.0"
"@visx/group" "3.0.0"
"@visx/point" "3.0.1"
"@visx/scale" "3.0.0"
"@visx/shape" "3.0.0"
classnames "^2.3.1"
prop-types "^15.6.2"
"@visx/group@3.0.0", "@visx/group@^3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@visx/group/-/group-3.0.0.tgz#e7f9752599bcc7e141ff5317a2a9a502577ab8df"
integrity sha512-SFjXhTMcsaVAb1/TVL1KM5vn8gQTIVgSx0ATdDl4BJSFp2ym1lO8LY4jpV4SFweaHnWxVwrrfGLTn5QsYnvmjQ==
dependencies:
"@types/react" "*"
classnames "^2.3.1"
prop-types "^15.6.2"
"@visx/point@3.0.1":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@visx/point/-/point-3.0.1.tgz#77587ddaabf6f3023f09f8a0ce33a2c27c9d64c8"
integrity sha512-S5WOBMgEP2xHcgs3A2BFB2vwzrk0tMmn3PGZAbQJ+lu4HlnalDP72klUnxLTH8xclNNvpUHtHM5eLIJXyHx6Pw==
"@visx/responsive@^3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@visx/responsive/-/responsive-3.0.0.tgz#e183c54ce04cffe756378872d30ac88c66a137ac"
integrity sha512-immnxQwOWlrxbnlCIqJWuDpPfrM6tglgMTN1WsyXyGluLMJqhuuxqxllfXaRPkQFS4fcvs66KCEELdazh96U2w==
dependencies:
"@types/lodash" "^4.14.172"
"@types/react" "*"
lodash "^4.17.21"
prop-types "^15.6.1"
"@visx/scale@3.0.0", "@visx/scale@^3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@visx/scale/-/scale-3.0.0.tgz#727123f0c930d3346a4473e926831c45997e0312"
integrity sha512-WSf+wrxZEvu5TPGfGTafzzX1MbogbIxfD9ZKM9p7xfw65v23G0dNMy4bqVBUbOJigONoQkIZyqQ+gz5AJ/ioIg==
dependencies:
"@types/d3-interpolate" "^3.0.1"
"@types/d3-scale" "^4.0.2"
"@types/d3-time" "^2.0.0"
d3-interpolate "^3.0.1"
d3-scale "^4.0.2"
d3-time "^2.1.1"
"@visx/shape@3.0.0", "@visx/shape@^3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@visx/shape/-/shape-3.0.0.tgz#a1d4bd0e12cc94c164252f175997932a09c24652"
integrity sha512-t6lpP9bIA1vwChDwiOUWl92ro29XF/M8IVNWRA0pm4LGxGGTACvxG3Agfcdi3JprahUVqPpnRCwuR36PDanq3Q==
dependencies:
"@types/d3-path" "^1.0.8"
"@types/d3-shape" "^1.3.1"
"@types/lodash" "^4.14.172"
"@types/react" "*"
"@visx/curve" "3.0.0"
"@visx/group" "3.0.0"
"@visx/scale" "3.0.0"
classnames "^2.3.1"
d3-path "^1.0.5"
d3-shape "^1.2.0"
lodash "^4.17.21"
prop-types "^15.5.10"
"@visx/text@3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@visx/text/-/text-3.0.0.tgz#9099c3605027b9ab4c54bde97518a648136c3629"
integrity sha512-LW6v5T/gpd9RGw83/ScXncYc6IlcfzXTpaN8WbbxLRI65gdvSqrykwAMR0cbpQmzoVFuZXljqOf0QslHGnBg1w==
dependencies:
"@types/lodash" "^4.14.172"
"@types/react" "*"
classnames "^2.3.1"
lodash "^4.17.21"
prop-types "^15.7.2"
reduce-css-calc "^1.3.0"
"@visx/tooltip@^3.1.2":
version "3.1.2"
resolved "https://registry.yarnpkg.com/@visx/tooltip/-/tooltip-3.1.2.tgz#6c7bb36a296f4501adb99b59487412e39fe06f44"
integrity sha512-p46qztGRNkEDbxzc3V1virahvz3UQ29TzddUjA0oaTIBCrOd9UJuLvv1Tq9OpeUYPdbrO/ZRwaEeri2pbwv04Q==
dependencies:
"@types/react" "*"
"@visx/bounds" "3.0.0"
classnames "^2.3.1"
prop-types "^15.5.10"
react-use-measure "^2.0.4"
"@vitejs/plugin-react@^3.0.0": "@vitejs/plugin-react@^3.0.0":
version "3.1.0" version "3.1.0"
resolved "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-3.1.0.tgz" resolved "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-3.1.0.tgz"
@ -1081,6 +1279,11 @@ autoprefixer@^10.4.14:
picocolors "^1.0.0" picocolors "^1.0.0"
postcss-value-parser "^4.2.0" postcss-value-parser "^4.2.0"
balanced-match@^0.4.2:
version "0.4.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838"
integrity sha512-STw03mQKnGUYtoNjmowo4F2cRmIIxYEGiMsjjwla/u5P1lxadj/05WkNaFjNiKTgJkj8KiXbgAiRTmcQRwQNtg==
balanced-match@^1.0.0: balanced-match@^1.0.0:
version "1.0.2" version "1.0.2"
resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz"
@ -1162,6 +1365,11 @@ class-variance-authority@^0.6.0:
dependencies: dependencies:
clsx "1.2.1" clsx "1.2.1"
classnames@^2.3.1:
version "2.3.2"
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924"
integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==
clsx@1.2.1, clsx@^1.2.1: clsx@1.2.1, clsx@^1.2.1:
version "1.2.1" version "1.2.1"
resolved "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz" resolved "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz"
@ -1228,6 +1436,86 @@ csstype@^3.0.2:
resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz" resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz"
integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==
d3-array@2:
version "2.12.1"
resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-2.12.1.tgz#e20b41aafcdffdf5d50928004ececf815a465e81"
integrity sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==
dependencies:
internmap "^1.0.0"
"d3-array@2 - 3", "d3-array@2.10.0 - 3":
version "3.2.4"
resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-3.2.4.tgz#15fec33b237f97ac5d7c986dc77da273a8ed0bb5"
integrity sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==
dependencies:
internmap "1 - 2"
"d3-color@1 - 3":
version "3.1.0"
resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-3.1.0.tgz#395b2833dfac71507f12ac2f7af23bf819de24e2"
integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==
"d3-format@1 - 3":
version "3.1.0"
resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-3.1.0.tgz#9260e23a28ea5cb109e93b21a06e24e2ebd55641"
integrity sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==
"d3-interpolate@1.2.0 - 3", d3-interpolate@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz#3c47aa5b32c5b3dfb56ef3fd4342078a632b400d"
integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==
dependencies:
d3-color "1 - 3"
d3-path@1, d3-path@^1.0.5:
version "1.0.9"
resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.9.tgz#48c050bb1fe8c262493a8caf5524e3e9591701cf"
integrity sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==
d3-scale@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-4.0.2.tgz#82b38e8e8ff7080764f8dcec77bd4be393689396"
integrity sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==
dependencies:
d3-array "2.10.0 - 3"
d3-format "1 - 3"
d3-interpolate "1.2.0 - 3"
d3-time "2.1.1 - 3"
d3-time-format "2 - 4"
d3-shape@^1.0.6, d3-shape@^1.2.0:
version "1.3.7"
resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.3.7.tgz#df63801be07bc986bc54f63789b4fe502992b5d7"
integrity sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==
dependencies:
d3-path "1"
"d3-time-format@2 - 4":
version "4.1.0"
resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-4.1.0.tgz#7ab5257a5041d11ecb4fe70a5c7d16a195bb408a"
integrity sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==
dependencies:
d3-time "1 - 3"
"d3-time@1 - 3", "d3-time@2.1.1 - 3":
version "3.1.0"
resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-3.1.0.tgz#9310db56e992e3c0175e1ef385e545e48a9bb5c7"
integrity sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==
dependencies:
d3-array "2 - 3"
d3-time@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-2.1.1.tgz#e9d8a8a88691f4548e68ca085e5ff956724a6682"
integrity sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==
dependencies:
d3-array "2"
debounce@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5"
integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==
debug@^4.1.0, debug@^4.1.1: debug@^4.1.0, debug@^4.1.1:
version "4.3.4" version "4.3.4"
resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz"
@ -1423,6 +1711,16 @@ inherits@2:
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
"internmap@1 - 2":
version "2.0.3"
resolved "https://registry.yarnpkg.com/internmap/-/internmap-2.0.3.tgz#6685f23755e43c524e251d29cbc97248e3061009"
integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==
internmap@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/internmap/-/internmap-1.0.1.tgz#0017cc8a3b99605f0302f2b198d272e015e5df95"
integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==
invariant@^2.2.4: invariant@^2.2.4:
version "2.2.4" version "2.2.4"
resolved "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz" resolved "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz"
@ -1496,7 +1794,12 @@ lodash.set@^4.3.2:
resolved "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz" resolved "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz"
integrity sha512-4hNPN5jlm/N/HLMCO43v8BXKq9Z7QdAGc/VGrRD61w8gN9g/6jF9A4L1pbUgBLCffi0w9VsXfTOij5x8iTyFvg== integrity sha512-4hNPN5jlm/N/HLMCO43v8BXKq9Z7QdAGc/VGrRD61w8gN9g/6jF9A4L1pbUgBLCffi0w9VsXfTOij5x8iTyFvg==
loose-envify@^1.0.0, loose-envify@^1.1.0: lodash@^4.17.21:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
version "1.4.0" version "1.4.0"
resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz" resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz"
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
@ -1522,6 +1825,11 @@ magic-string@^0.27.0:
dependencies: dependencies:
"@jridgewell/sourcemap-codec" "^1.4.13" "@jridgewell/sourcemap-codec" "^1.4.13"
math-expression-evaluator@^1.2.14:
version "1.4.0"
resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.4.0.tgz#3d66031117fbb7b9715ea6c9c68c2cd2eebd37e2"
integrity sha512-4vRUvPyxdO8cWULGTh9dZWL2tZK6LDBvj+OGHBER7poH9Qdt7kXEoj20wiz4lQUbUXQZFjPbe5mVDo9nutizCw==
merge2@^1.3.0: merge2@^1.3.0:
version "1.4.1" version "1.4.1"
resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz"
@ -1576,7 +1884,7 @@ normalize-range@^0.1.2:
resolved "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz" resolved "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz"
integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==
object-assign@^4.0.1: object-assign@^4.0.1, object-assign@^4.1.1:
version "4.1.1" version "4.1.1"
resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz"
integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
@ -1676,6 +1984,15 @@ postcss@^8.4.23:
picocolors "^1.0.0" picocolors "^1.0.0"
source-map-js "^1.0.2" source-map-js "^1.0.2"
prop-types@^15.5.10, prop-types@^15.5.7, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
dependencies:
loose-envify "^1.4.0"
object-assign "^4.1.1"
react-is "^16.13.1"
queue-microtask@^1.2.2: queue-microtask@^1.2.2:
version "1.2.3" version "1.2.3"
resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz"
@ -1689,6 +2006,11 @@ react-dom@^18.2.0:
loose-envify "^1.1.0" loose-envify "^1.1.0"
scheduler "^0.23.0" scheduler "^0.23.0"
react-is@^16.13.1:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
react-refresh@^0.14.0: react-refresh@^0.14.0:
version "0.14.0" version "0.14.0"
resolved "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz" resolved "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz"
@ -1722,6 +2044,13 @@ react-style-singleton@^2.2.1:
invariant "^2.2.4" invariant "^2.2.4"
tslib "^2.0.0" tslib "^2.0.0"
react-use-measure@^2.0.4:
version "2.1.1"
resolved "https://registry.yarnpkg.com/react-use-measure/-/react-use-measure-2.1.1.tgz#5824537f4ee01c9469c45d5f7a8446177c6cc4ba"
integrity sha512-nocZhN26cproIiIduswYpV5y5lQpSQS1y/4KuvUCjSKmw7ZWIS/+g3aFnX3WdBkyuGUtTLif3UTqnLLhbDoQig==
dependencies:
debounce "^1.2.1"
react@^18.2.0: react@^18.2.0:
version "18.2.0" version "18.2.0"
resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz" resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz"
@ -1743,6 +2072,22 @@ readdirp@~3.6.0:
dependencies: dependencies:
picomatch "^2.2.1" picomatch "^2.2.1"
reduce-css-calc@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz#747c914e049614a4c9cfbba629871ad1d2927716"
integrity sha512-0dVfwYVOlf/LBA2ec4OwQ6p3X9mYxn/wOl2xTcLwjnPYrkgEfPx3VI4eGCH3rQLlPISG5v9I9bkZosKsNRTRKA==
dependencies:
balanced-match "^0.4.2"
math-expression-evaluator "^1.2.14"
reduce-function-call "^1.0.1"
reduce-function-call@^1.0.1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/reduce-function-call/-/reduce-function-call-1.0.3.tgz#60350f7fb252c0a67eb10fd4694d16909971300f"
integrity sha512-Hl/tuV2VDgWgCSEeWMLwxLZqX7OK59eU1guxXsRKTAyeYimivsKdtcV4fu3r710tpG5GmDKDhQ0HSZLExnNmyQ==
dependencies:
balanced-match "^1.0.0"
regenerator-runtime@^0.13.11: regenerator-runtime@^0.13.11:
version "0.13.11" version "0.13.11"
resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz" resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz"