Merge remote-tracking branch 'origin/main' into feat/model-plugins-implementing

This commit is contained in:
yyh 2026-03-16 18:00:14 +08:00
commit e6b6849791
No known key found for this signature in database
25 changed files with 794 additions and 376 deletions

View File

@ -737,24 +737,25 @@ SANDBOX_EXPIRED_RECORDS_RETENTION_DAYS=30
SANDBOX_EXPIRED_RECORDS_CLEAN_TASK_LOCK_TTL=90000
# Redis URL used for PubSub between API and
# Redis URL used for event bus between API and
# celery worker
# defaults to url constructed from `REDIS_*`
# configurations
PUBSUB_REDIS_URL=
# Pub/sub channel type for streaming events.
# valid options are:
EVENT_BUS_REDIS_URL=
# Event transport type. Options are:
#
# - pubsub: for normal Pub/Sub
# - sharded: for sharded Pub/Sub
# - pubsub: normal Pub/Sub (at-most-once)
# - sharded: sharded Pub/Sub (at-most-once)
# - streams: Redis Streams (at-least-once, recommended to avoid subscriber races)
#
# It's highly recommended to use sharded Pub/Sub AND redis cluster
# for large deployments.
PUBSUB_REDIS_CHANNEL_TYPE=pubsub
# Whether to use Redis cluster mode while running
# PubSub.
# Note: Before enabling 'streams' in production, estimate your expected event volume and retention needs.
# Configure Redis memory limits and stream trimming appropriately (e.g., MAXLEN and key expiry) to reduce
# the risk of data loss from Redis auto-eviction under memory pressure.
# Also accepts ENV: EVENT_BUS_REDIS_CHANNEL_TYPE.
EVENT_BUS_REDIS_CHANNEL_TYPE=pubsub
# Whether to use Redis cluster mode while use redis as event bus.
# It's highly recommended to enable this for large deployments.
PUBSUB_REDIS_USE_CLUSTERS=false
EVENT_BUS_REDIS_USE_CLUSTERS=false
# Whether to Enable human input timeout check task
ENABLE_HUMAN_INPUT_TIMEOUT_TASK=true

View File

@ -41,10 +41,10 @@ class RedisPubSubConfig(BaseSettings, RedisConfigDefaultsMixin):
)
PUBSUB_REDIS_USE_CLUSTERS: bool = Field(
validation_alias=AliasChoices("EVENT_BUS_REDIS_CLUSTERS", "PUBSUB_REDIS_USE_CLUSTERS"),
validation_alias=AliasChoices("EVENT_BUS_REDIS_USE_CLUSTERS", "PUBSUB_REDIS_USE_CLUSTERS"),
description=(
"Enable Redis Cluster mode for pub/sub or streams transport. Recommended for large deployments. "
"Also accepts ENV: EVENT_BUS_REDIS_CLUSTERS."
"Also accepts ENV: EVENT_BUS_REDIS_USE_CLUSTERS."
),
default=False,
)

View File

@ -186,7 +186,7 @@ class DifyTestContainers:
# Start Dify Plugin Daemon container for plugin management
# Dify Plugin Daemon provides plugin lifecycle management and execution
logger.info("Initializing Dify Plugin Daemon container...")
self.dify_plugin_daemon = DockerContainer(image="langgenius/dify-plugin-daemon:0.3.0-local").with_network(
self.dify_plugin_daemon = DockerContainer(image="langgenius/dify-plugin-daemon:0.5.4-local").with_network(
self.network
)
self.dify_plugin_daemon.with_exposed_ports(5002)

View File

@ -1546,24 +1546,25 @@ SANDBOX_EXPIRED_RECORDS_CLEAN_BATCH_MAX_INTERVAL=200
SANDBOX_EXPIRED_RECORDS_RETENTION_DAYS=30
# Redis URL used for PubSub between API and
# Redis URL used for event bus between API and
# celery worker
# defaults to url constructed from `REDIS_*`
# configurations
PUBSUB_REDIS_URL=
# Pub/sub channel type for streaming events.
# valid options are:
EVENT_BUS_REDIS_URL=
# Event transport type. Options are:
#
# - pubsub: for normal Pub/Sub
# - sharded: for sharded Pub/Sub
# - pubsub: normal Pub/Sub (at-most-once)
# - sharded: sharded Pub/Sub (at-most-once)
# - streams: Redis Streams (at-least-once, recommended to avoid subscriber races)
#
# It's highly recommended to use sharded Pub/Sub AND redis cluster
# for large deployments.
PUBSUB_REDIS_CHANNEL_TYPE=pubsub
# Whether to use Redis cluster mode while running
# PubSub.
# Note: Before enabling 'streams' in production, estimate your expected event volume and retention needs.
# Configure Redis memory limits and stream trimming appropriately (e.g., MAXLEN and key expiry) to reduce
# the risk of data loss from Redis auto-eviction under memory pressure.
# Also accepts ENV: EVENT_BUS_REDIS_CHANNEL_TYPE.
EVENT_BUS_REDIS_CHANNEL_TYPE=pubsub
# Whether to use Redis cluster mode while use redis as event bus.
# It's highly recommended to enable this for large deployments.
PUBSUB_REDIS_USE_CLUSTERS=false
EVENT_BUS_REDIS_USE_CLUSTERS=false
# Whether to Enable human input timeout check task
ENABLE_HUMAN_INPUT_TIMEOUT_TASK=true

View File

@ -269,7 +269,7 @@ services:
# plugin daemon
plugin_daemon:
image: langgenius/dify-plugin-daemon:0.5.3-local
image: langgenius/dify-plugin-daemon:0.5.4-local
restart: always
environment:
# Use the shared environment variables.

View File

@ -123,7 +123,7 @@ services:
# plugin daemon
plugin_daemon:
image: langgenius/dify-plugin-daemon:0.5.3-local
image: langgenius/dify-plugin-daemon:0.5.4-local
restart: always
env_file:
- ./middleware.env

View File

@ -699,9 +699,9 @@ x-shared-env: &shared-api-worker-env
SANDBOX_EXPIRED_RECORDS_CLEAN_BATCH_SIZE: ${SANDBOX_EXPIRED_RECORDS_CLEAN_BATCH_SIZE:-1000}
SANDBOX_EXPIRED_RECORDS_CLEAN_BATCH_MAX_INTERVAL: ${SANDBOX_EXPIRED_RECORDS_CLEAN_BATCH_MAX_INTERVAL:-200}
SANDBOX_EXPIRED_RECORDS_RETENTION_DAYS: ${SANDBOX_EXPIRED_RECORDS_RETENTION_DAYS:-30}
PUBSUB_REDIS_URL: ${PUBSUB_REDIS_URL:-}
PUBSUB_REDIS_CHANNEL_TYPE: ${PUBSUB_REDIS_CHANNEL_TYPE:-pubsub}
PUBSUB_REDIS_USE_CLUSTERS: ${PUBSUB_REDIS_USE_CLUSTERS:-false}
EVENT_BUS_REDIS_URL: ${EVENT_BUS_REDIS_URL:-}
EVENT_BUS_REDIS_CHANNEL_TYPE: ${EVENT_BUS_REDIS_CHANNEL_TYPE:-pubsub}
EVENT_BUS_REDIS_USE_CLUSTERS: ${EVENT_BUS_REDIS_USE_CLUSTERS:-false}
ENABLE_HUMAN_INPUT_TIMEOUT_TASK: ${ENABLE_HUMAN_INPUT_TIMEOUT_TASK:-true}
HUMAN_INPUT_TIMEOUT_TASK_INTERVAL: ${HUMAN_INPUT_TIMEOUT_TASK_INTERVAL:-1}
SANDBOX_EXPIRED_RECORDS_CLEAN_TASK_LOCK_TTL: ${SANDBOX_EXPIRED_RECORDS_CLEAN_TASK_LOCK_TTL:-90000}
@ -976,7 +976,7 @@ services:
# plugin daemon
plugin_daemon:
image: langgenius/dify-plugin-daemon:0.5.3-local
image: langgenius/dify-plugin-daemon:0.5.4-local
restart: always
environment:
# Use the shared environment variables.

View File

@ -218,7 +218,7 @@ describe('ParamConfigContent', () => {
})
render(<ParamConfigContent />)
const input = screen.getByRole('spinbutton') as HTMLInputElement
const input = screen.getByRole('textbox') as HTMLInputElement
fireEvent.change(input, { target: { value: '4' } })
const updatedFile = getLatestFileConfig()

View File

@ -184,8 +184,8 @@ describe('dataset-config/params-config', () => {
await user.click(incrementButtons[0])
await waitFor(() => {
const [topKInput] = dialogScope.getAllByRole('spinbutton')
expect(topKInput).toHaveValue(5)
const [topKInput] = dialogScope.getAllByRole('textbox')
expect(topKInput).toHaveValue('5')
})
await user.click(dialogScope.getByRole('button', { name: 'common.operation.save' }))
@ -197,10 +197,10 @@ describe('dataset-config/params-config', () => {
await user.click(screen.getByRole('button', { name: 'dataset.retrievalSettings' }))
const reopenedDialog = await screen.findByRole('dialog', {}, { timeout: 3000 })
const reopenedScope = within(reopenedDialog)
const [reopenedTopKInput] = reopenedScope.getAllByRole('spinbutton')
const [reopenedTopKInput] = reopenedScope.getAllByRole('textbox')
// Assert
expect(reopenedTopKInput).toHaveValue(5)
expect(reopenedTopKInput).toHaveValue('5')
})
it('should discard changes when cancel is clicked', async () => {
@ -217,8 +217,8 @@ describe('dataset-config/params-config', () => {
await user.click(incrementButtons[0])
await waitFor(() => {
const [topKInput] = dialogScope.getAllByRole('spinbutton')
expect(topKInput).toHaveValue(5)
const [topKInput] = dialogScope.getAllByRole('textbox')
expect(topKInput).toHaveValue('5')
})
const cancelButton = await dialogScope.findByRole('button', { name: 'common.operation.cancel' })
@ -231,10 +231,10 @@ describe('dataset-config/params-config', () => {
await user.click(screen.getByRole('button', { name: 'dataset.retrievalSettings' }))
const reopenedDialog = await screen.findByRole('dialog', {}, { timeout: 3000 })
const reopenedScope = within(reopenedDialog)
const [reopenedTopKInput] = reopenedScope.getAllByRole('spinbutton')
const [reopenedTopKInput] = reopenedScope.getAllByRole('textbox')
// Assert
expect(reopenedTopKInput).toHaveValue(4)
expect(reopenedTopKInput).toHaveValue('4')
})
it('should prevent saving when rerank model is required but invalid', async () => {

View File

@ -22,7 +22,7 @@ describe('NumberInputField', () => {
it('should render current number value', () => {
render(<NumberInputField label="Count" />)
expect(screen.getByDisplayValue('2')).toBeInTheDocument()
expect(screen.getByRole('textbox')).toHaveValue('2')
})
it('should update value when users click increment', () => {

View File

@ -45,7 +45,7 @@ describe('BaseField', () => {
it('should render a number input when configured as number input', () => {
render(<FieldHarness config={createConfig({ type: BaseFieldType.numberInput, label: 'Age' })} initialData={{ fieldA: 20 }} />)
expect(screen.getByRole('spinbutton')).toBeInTheDocument()
expect(screen.getByRole('textbox')).toBeInTheDocument()
expect(screen.getByText('Age')).toBeInTheDocument()
})

View File

@ -13,7 +13,7 @@ describe('InputNumber Component', () => {
it('renders input with default values', () => {
render(<InputNumber {...defaultProps} />)
const input = screen.getByRole('spinbutton')
const input = screen.getByRole('textbox')
expect(input).toBeInTheDocument()
})
@ -60,7 +60,7 @@ describe('InputNumber Component', () => {
it('handles direct input changes', () => {
const onChange = vi.fn()
render(<InputNumber onChange={onChange} />)
const input = screen.getByRole('spinbutton')
const input = screen.getByRole('textbox')
fireEvent.change(input, { target: { value: '42' } })
expect(onChange).toHaveBeenCalledWith(42)
@ -69,38 +69,25 @@ describe('InputNumber Component', () => {
it('handles empty input', () => {
const onChange = vi.fn()
render(<InputNumber onChange={onChange} value={1} />)
const input = screen.getByRole('spinbutton')
const input = screen.getByRole('textbox')
fireEvent.change(input, { target: { value: '' } })
expect(onChange).toHaveBeenCalledWith(0)
})
it('does not call onChange when parsed value is NaN', () => {
it('does not call onChange when input is not parseable', () => {
const onChange = vi.fn()
render(<InputNumber onChange={onChange} />)
const input = screen.getByRole('spinbutton')
const input = screen.getByRole('textbox')
const originalNumber = globalThis.Number
const numberSpy = vi.spyOn(globalThis, 'Number').mockImplementation((val: unknown) => {
if (val === '123') {
return Number.NaN
}
return originalNumber(val)
})
try {
fireEvent.change(input, { target: { value: '123' } })
expect(onChange).not.toHaveBeenCalled()
}
finally {
numberSpy.mockRestore()
}
fireEvent.change(input, { target: { value: 'abc' } })
expect(onChange).not.toHaveBeenCalled()
})
it('does not call onChange when direct input exceeds range', () => {
const onChange = vi.fn()
render(<InputNumber onChange={onChange} max={10} min={0} />)
const input = screen.getByRole('spinbutton')
const input = screen.getByRole('textbox')
fireEvent.change(input, { target: { value: '11' } })
@ -141,7 +128,7 @@ describe('InputNumber Component', () => {
it('disables controls when disabled prop is true', () => {
const onChange = vi.fn()
render(<InputNumber onChange={onChange} disabled />)
const input = screen.getByRole('spinbutton')
const input = screen.getByRole('textbox')
const incrementBtn = screen.getByRole('button', { name: /increment/i })
const decrementBtn = screen.getByRole('button', { name: /decrement/i })
@ -211,6 +198,16 @@ describe('InputNumber Component', () => {
expect(onChange).not.toHaveBeenCalled()
})
it('uses fallback step guard when step is any', async () => {
const user = userEvent.setup()
const onChange = vi.fn()
render(<InputNumber onChange={onChange} value={10} max={10} step="any" />)
const incrementBtn = screen.getByRole('button', { name: /increment/i })
await user.click(incrementBtn)
expect(onChange).not.toHaveBeenCalled()
})
it('prevents decrement below min with custom amount', async () => {
const user = userEvent.setup()
const onChange = vi.fn()
@ -244,7 +241,7 @@ describe('InputNumber Component', () => {
it('validates input against max constraint', () => {
const onChange = vi.fn()
render(<InputNumber onChange={onChange} max={10} />)
const input = screen.getByRole('spinbutton')
const input = screen.getByRole('textbox')
fireEvent.change(input, { target: { value: '15' } })
expect(onChange).not.toHaveBeenCalled()
@ -253,7 +250,7 @@ describe('InputNumber Component', () => {
it('validates input against min constraint', () => {
const onChange = vi.fn()
render(<InputNumber onChange={onChange} min={5} />)
const input = screen.getByRole('spinbutton')
const input = screen.getByRole('textbox')
fireEvent.change(input, { target: { value: '2' } })
expect(onChange).not.toHaveBeenCalled()
@ -262,7 +259,7 @@ describe('InputNumber Component', () => {
it('accepts input within min and max constraints', () => {
const onChange = vi.fn()
render(<InputNumber onChange={onChange} min={0} max={100} />)
const input = screen.getByRole('spinbutton')
const input = screen.getByRole('textbox')
fireEvent.change(input, { target: { value: '50' } })
expect(onChange).toHaveBeenCalledWith(50)
@ -296,6 +293,25 @@ describe('InputNumber Component', () => {
expect(wrapper).toHaveClass(wrapClassName)
})
it('applies wrapperClassName to outer div for Input compatibility', () => {
const onChange = vi.fn()
const wrapperClassName = 'custom-input-wrapper'
render(<InputNumber onChange={onChange} wrapperClassName={wrapperClassName} />)
const input = screen.getByRole('textbox')
const wrapper = screen.getByTestId('input-number-wrapper')
expect(input).not.toHaveAttribute('wrapperClassName')
expect(wrapper).toHaveClass(wrapperClassName)
})
it('applies styleCss to the input element', () => {
const onChange = vi.fn()
render(<InputNumber onChange={onChange} styleCss={{ color: 'red' }} />)
expect(screen.getByRole('textbox')).toHaveStyle({ color: 'rgb(255, 0, 0)' })
})
it('applies controlWrapClassName to control buttons container', () => {
const onChange = vi.fn()
const controlWrapClassName = 'custom-control-wrap'
@ -327,7 +343,7 @@ describe('InputNumber Component', () => {
it('handles zero as a valid input', () => {
const onChange = vi.fn()
render(<InputNumber onChange={onChange} min={-5} max={5} value={1} />)
const input = screen.getByRole('spinbutton')
const input = screen.getByRole('textbox')
fireEvent.change(input, { target: { value: '0' } })
expect(onChange).toHaveBeenCalledWith(0)

View File

@ -1,10 +1,23 @@
import type { FC } from 'react'
import type { InputProps } from '../input'
import type { NumberFieldRoot as BaseNumberFieldRoot } from '@base-ui/react/number-field'
import type { CSSProperties, FC, InputHTMLAttributes } from 'react'
import { useCallback } from 'react'
import {
NumberField,
NumberFieldControls,
NumberFieldDecrement,
NumberFieldGroup,
NumberFieldIncrement,
NumberFieldInput,
NumberFieldUnit,
} from '@/app/components/base/ui/number-field'
import { cn } from '@/utils/classnames'
import Input from '../input'
export type InputNumberProps = {
type InputNumberInputProps = Omit<
InputHTMLAttributes<HTMLInputElement>,
'defaultValue' | 'max' | 'min' | 'onChange' | 'size' | 'type' | 'value'
>
export type InputNumberProps = InputNumberInputProps & {
unit?: string
value?: number
onChange: (value: number) => void
@ -12,19 +25,69 @@ export type InputNumberProps = {
size?: 'regular' | 'large'
max?: number
min?: number
step?: number | 'any'
defaultValue?: number
disabled?: boolean
wrapClassName?: string
wrapperClassName?: string
styleCss?: CSSProperties
controlWrapClassName?: string
controlClassName?: string
} & Omit<InputProps, 'value' | 'onChange' | 'size' | 'min' | 'max' | 'defaultValue'>
type?: 'number'
}
const STEPPER_REASONS = new Set<BaseNumberFieldRoot.ChangeEventDetails['reason']>([
'increment-press',
'decrement-press',
])
const isValueWithinBounds = (value: number, min?: number, max?: number) => {
if (typeof min === 'number' && value < min)
return false
if (typeof max === 'number' && value > max)
return false
return true
}
const resolveStep = (amount?: number, step?: InputNumberProps['step']) => (
amount ?? (step === 'any' || typeof step === 'number' ? step : undefined) ?? 1
)
const exceedsStepBounds = ({
value,
reason,
stepAmount,
min,
max,
}: {
value?: number
reason: BaseNumberFieldRoot.ChangeEventDetails['reason']
stepAmount: number
min?: number
max?: number
}) => {
if (typeof value !== 'number')
return false
if (reason === 'increment-press' && typeof max === 'number')
return value + stepAmount > max
if (reason === 'decrement-press' && typeof min === 'number')
return value - stepAmount < min
return false
}
export const InputNumber: FC<InputNumberProps> = (props) => {
const {
unit,
className,
wrapperClassName,
styleCss,
onChange,
amount = 1,
amount,
value,
size = 'regular',
max,
@ -34,96 +97,97 @@ export const InputNumber: FC<InputNumberProps> = (props) => {
controlWrapClassName,
controlClassName,
disabled,
step,
id,
name,
readOnly,
required,
type: _type,
...rest
} = props
const isValidValue = useCallback((v: number) => {
if (typeof max === 'number' && v > max)
return false
return !(typeof min === 'number' && v < min)
}, [max, min])
const resolvedStep = resolveStep(amount, step)
const stepAmount = typeof resolvedStep === 'number' ? resolvedStep : 1
const inc = () => {
/* v8 ignore next 2 - @preserve */
if (disabled)
return
if (value === undefined) {
const handleValueChange = useCallback((
nextValue: number | null,
eventDetails: BaseNumberFieldRoot.ChangeEventDetails,
) => {
if (value === undefined && STEPPER_REASONS.has(eventDetails.reason)) {
onChange(defaultValue ?? 0)
return
}
const newValue = value + amount
if (!isValidValue(newValue))
return
onChange(newValue)
}
const dec = () => {
/* v8 ignore next 2 - @preserve */
if (disabled)
return
if (value === undefined) {
onChange(defaultValue ?? 0)
return
}
const newValue = value - amount
if (!isValidValue(newValue))
return
onChange(newValue)
}
const handleInputChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.value === '') {
if (nextValue === null) {
onChange(0)
return
}
const parsed = Number(e.target.value)
if (Number.isNaN(parsed))
if (exceedsStepBounds({
value,
reason: eventDetails.reason,
stepAmount,
min,
max,
})) {
return
}
if (!isValueWithinBounds(nextValue, min, max))
return
if (!isValidValue(parsed))
return
onChange(parsed)
}, [isValidValue, onChange])
onChange(nextValue)
}, [defaultValue, max, min, onChange, stepAmount, value])
return (
<div data-testid="input-number-wrapper" className={cn('flex', wrapClassName)}>
<Input
{...rest}
// disable default controller
type="number"
className={cn('rounded-r-none no-spinner', className)}
value={value ?? 0}
max={max}
<div data-testid="input-number-wrapper" className={cn('flex w-full min-w-0', wrapClassName, wrapperClassName)}>
<NumberField
className="min-w-0 grow"
value={value ?? null}
min={min}
max={max}
step={resolvedStep}
disabled={disabled}
onChange={handleInputChange}
unit={unit}
size={size}
/>
<div
data-testid="input-number-controls"
className={cn('flex flex-col rounded-r-md border-l border-divider-subtle bg-components-input-bg-normal text-text-tertiary focus:shadow-xs', disabled && 'cursor-not-allowed opacity-50', controlWrapClassName)}
readOnly={readOnly}
required={required}
id={id}
name={name}
allowOutOfRange
onValueChange={handleValueChange}
>
<button
type="button"
onClick={inc}
disabled={disabled}
aria-label="increment"
className={cn(size === 'regular' ? 'pt-1' : 'pt-1.5', 'px-1.5 hover:bg-components-input-bg-hover', disabled && 'cursor-not-allowed hover:bg-transparent', controlClassName)}
>
<span className="i-ri-arrow-up-s-line size-3" />
</button>
<button
type="button"
onClick={dec}
disabled={disabled}
aria-label="decrement"
className={cn(size === 'regular' ? 'pb-1' : 'pb-1.5', 'px-1.5 hover:bg-components-input-bg-hover', disabled && 'cursor-not-allowed hover:bg-transparent', controlClassName)}
>
<span className="i-ri-arrow-down-s-line size-3" />
</button>
</div>
<NumberFieldGroup size={size}>
<NumberFieldInput
{...rest}
size={size}
style={styleCss}
className={className}
/>
{unit && (
<NumberFieldUnit size={size}>
{unit}
</NumberFieldUnit>
)}
<NumberFieldControls
data-testid="input-number-controls"
className={controlWrapClassName}
>
<NumberFieldIncrement
aria-label="increment"
size={size}
className={controlClassName}
>
<span aria-hidden="true" className="i-ri-arrow-up-s-line size-3" />
</NumberFieldIncrement>
<NumberFieldDecrement
aria-label="decrement"
size={size}
className={controlClassName}
>
<span aria-hidden="true" className="i-ri-arrow-down-s-line size-3" />
</NumberFieldDecrement>
</NumberFieldControls>
</NumberFieldGroup>
</NumberField>
</div>
)
}

View File

@ -53,7 +53,7 @@ describe('ParamItem', () => {
it('should render InputNumber and Slider', () => {
render(<ParamItem {...defaultProps} />)
expect(screen.getByRole('spinbutton')).toBeInTheDocument()
expect(screen.getByRole('textbox')).toBeInTheDocument()
expect(screen.getByRole('slider')).toBeInTheDocument()
})
})
@ -68,7 +68,7 @@ describe('ParamItem', () => {
it('should disable InputNumber when enable is false', () => {
render(<ParamItem {...defaultProps} enable={false} />)
expect(screen.getByRole('spinbutton')).toBeDisabled()
expect(screen.getByRole('textbox')).toBeDisabled()
})
it('should disable Slider when enable is false', () => {
@ -104,7 +104,7 @@ describe('ParamItem', () => {
}
render(<StatefulParamItem />)
const input = screen.getByRole('spinbutton')
const input = screen.getByRole('textbox')
await user.clear(input)
await user.type(input, '0.8')
@ -166,14 +166,10 @@ describe('ParamItem', () => {
expect(slider).toHaveAttribute('aria-valuemax', '10')
})
it('should use default step of 0.1 and min of 0 when not provided', () => {
it('should expose default minimum of 0 when min is not provided', () => {
render(<ParamItem {...defaultProps} />)
const input = screen.getByRole('spinbutton')
// Component renders without error with default step/min
expect(screen.getByRole('spinbutton')).toBeInTheDocument()
expect(input).toHaveAttribute('step', '0.1')
expect(input).toHaveAttribute('min', '0')
const input = screen.getByRole('textbox')
expect(input).toBeInTheDocument()
})
})
})

View File

@ -31,7 +31,7 @@ describe('ScoreThresholdItem', () => {
it('should render InputNumber and Slider', () => {
render(<ScoreThresholdItem {...defaultProps} />)
expect(screen.getByRole('spinbutton')).toBeInTheDocument()
expect(screen.getByRole('textbox')).toBeInTheDocument()
expect(screen.getByRole('slider')).toBeInTheDocument()
})
})
@ -62,7 +62,7 @@ describe('ScoreThresholdItem', () => {
it('should disable controls when enable is false', () => {
render(<ScoreThresholdItem {...defaultProps} enable={false} />)
expect(screen.getByRole('spinbutton')).toBeDisabled()
expect(screen.getByRole('textbox')).toBeDisabled()
expect(screen.getByRole('slider')).toHaveAttribute('aria-disabled', 'true')
})
})
@ -70,23 +70,19 @@ describe('ScoreThresholdItem', () => {
describe('Value Clamping', () => {
it('should clamp values to minimum of 0', () => {
render(<ScoreThresholdItem {...defaultProps} />)
const input = screen.getByRole('spinbutton')
expect(input).toHaveAttribute('min', '0')
const input = screen.getByRole('textbox')
expect(input).toBeInTheDocument()
})
it('should clamp values to maximum of 1', () => {
render(<ScoreThresholdItem {...defaultProps} />)
const input = screen.getByRole('spinbutton')
expect(input).toHaveAttribute('max', '1')
const input = screen.getByRole('textbox')
expect(input).toBeInTheDocument()
})
it('should use step of 0.01', () => {
render(<ScoreThresholdItem {...defaultProps} />)
const input = screen.getByRole('spinbutton')
expect(input).toHaveAttribute('step', '0.01')
render(<ScoreThresholdItem {...defaultProps} value={0.5} />)
expect(screen.getByRole('textbox')).toHaveValue('0.5')
})
it('should call onChange with rounded value when input changes', async () => {
@ -107,7 +103,7 @@ describe('ScoreThresholdItem', () => {
}
render(<StatefulScoreThresholdItem />)
const input = screen.getByRole('spinbutton')
const input = screen.getByRole('textbox')
await user.clear(input)
await user.type(input, '0.55')
@ -138,8 +134,8 @@ describe('ScoreThresholdItem', () => {
it('should clamp to max=1 when value exceeds maximum', () => {
render(<ScoreThresholdItem {...defaultProps} value={1.5} />)
const input = screen.getByRole('spinbutton')
expect(input).toHaveValue(1)
const input = screen.getByRole('textbox')
expect(input).toHaveValue('1')
})
})
})

View File

@ -36,7 +36,7 @@ describe('TopKItem', () => {
it('should render InputNumber and Slider', () => {
render(<TopKItem {...defaultProps} />)
expect(screen.getByRole('spinbutton')).toBeInTheDocument()
expect(screen.getByRole('textbox')).toBeInTheDocument()
expect(screen.getByRole('slider')).toBeInTheDocument()
})
})
@ -51,7 +51,7 @@ describe('TopKItem', () => {
it('should disable controls when enable is false', () => {
render(<TopKItem {...defaultProps} enable={false} />)
expect(screen.getByRole('spinbutton')).toBeDisabled()
expect(screen.getByRole('textbox')).toBeDisabled()
expect(screen.getByRole('slider')).toHaveAttribute('aria-disabled', 'true')
})
})
@ -59,23 +59,20 @@ describe('TopKItem', () => {
describe('Value Limits', () => {
it('should use step of 1', () => {
render(<TopKItem {...defaultProps} />)
const input = screen.getByRole('spinbutton')
expect(input).toHaveAttribute('step', '1')
const input = screen.getByRole('textbox')
expect(input).toHaveValue('2')
})
it('should use minimum of 1', () => {
render(<TopKItem {...defaultProps} />)
const input = screen.getByRole('spinbutton')
expect(input).toHaveAttribute('min', '1')
const input = screen.getByRole('textbox')
expect(input).toBeInTheDocument()
})
it('should use maximum from env (10)', () => {
render(<TopKItem {...defaultProps} />)
const input = screen.getByRole('spinbutton')
expect(input).toHaveAttribute('max', '10')
const input = screen.getByRole('textbox')
expect(input).toBeInTheDocument()
})
it('should render slider with max >= 5 so no scaling is applied', () => {

View File

@ -0,0 +1,113 @@
import { NumberField as BaseNumberField } from '@base-ui/react/number-field'
import { render, screen } from '@testing-library/react'
import {
NumberField,
NumberFieldControls,
NumberFieldDecrement,
NumberFieldGroup,
NumberFieldIncrement,
NumberFieldInput,
NumberFieldUnit,
} from '../index'
describe('NumberField wrapper', () => {
describe('Exports', () => {
it('should map NumberField to the matching base primitive root', () => {
expect(NumberField).toBe(BaseNumberField.Root)
})
})
describe('Variants', () => {
it('should apply regular variant classes and forward className to group and input', () => {
render(
<NumberField defaultValue={12}>
<NumberFieldGroup size="regular" className="custom-group" data-testid="group">
<NumberFieldInput
aria-label="Regular amount"
placeholder="Regular placeholder"
size="regular"
className="custom-input"
/>
</NumberFieldGroup>
</NumberField>,
)
const group = screen.getByTestId('group')
const input = screen.getByRole('textbox', { name: 'Regular amount' })
expect(group).toHaveClass('radius-md')
expect(group).toHaveClass('custom-group')
expect(input).toHaveAttribute('placeholder', 'Regular placeholder')
expect(input).toHaveClass('px-3')
expect(input).toHaveClass('py-[7px]')
expect(input).toHaveClass('custom-input')
})
it('should apply large variant classes to grouped parts when large size is provided', () => {
render(
<NumberField defaultValue={24}>
<NumberFieldGroup size="large" data-testid="group">
<NumberFieldInput aria-label="Large amount" size="large" />
<NumberFieldUnit size="large">ms</NumberFieldUnit>
<NumberFieldControls>
<NumberFieldIncrement aria-label="Increment amount" size="large" />
<NumberFieldDecrement aria-label="Decrement amount" size="large" />
</NumberFieldControls>
</NumberFieldGroup>
</NumberField>,
)
const group = screen.getByTestId('group')
const input = screen.getByRole('textbox', { name: 'Large amount' })
const unit = screen.getByText('ms')
const increment = screen.getByRole('button', { name: 'Increment amount' })
const decrement = screen.getByRole('button', { name: 'Decrement amount' })
expect(group).toHaveClass('radius-lg')
expect(input).toHaveClass('px-4')
expect(input).toHaveClass('py-2')
expect(unit).toHaveClass('flex')
expect(unit).toHaveClass('items-center')
expect(unit).toHaveClass('pr-2.5')
expect(increment).toHaveClass('pt-1.5')
expect(decrement).toHaveClass('pb-1.5')
})
})
describe('Passthrough props', () => {
it('should forward passthrough props and custom classes to controls and buttons', () => {
render(
<NumberField defaultValue={8}>
<NumberFieldGroup size="regular">
<NumberFieldInput aria-label="Amount" size="regular" />
<NumberFieldControls className="custom-controls" data-testid="controls">
<NumberFieldIncrement
aria-label="Increment"
size="regular"
className="custom-increment"
data-track-id="increment-track"
/>
<NumberFieldDecrement
aria-label="Decrement"
size="regular"
className="custom-decrement"
data-track-id="decrement-track"
/>
</NumberFieldControls>
</NumberFieldGroup>
</NumberField>,
)
const controls = screen.getByTestId('controls')
const increment = screen.getByRole('button', { name: 'Increment' })
const decrement = screen.getByRole('button', { name: 'Decrement' })
expect(controls).toHaveClass('border-l')
expect(controls).toHaveClass('custom-controls')
expect(increment).toHaveClass('custom-increment')
expect(increment).toHaveAttribute('data-track-id', 'increment-track')
expect(decrement).toHaveClass('custom-decrement')
expect(decrement).toHaveAttribute('data-track-id', 'decrement-track')
})
})
})

View File

@ -0,0 +1,211 @@
'use client'
import type { VariantProps } from 'class-variance-authority'
import { NumberField as BaseNumberField } from '@base-ui/react/number-field'
import { cva } from 'class-variance-authority'
import * as React from 'react'
import { cn } from '@/utils/classnames'
export const NumberField = BaseNumberField.Root
export const numberFieldGroupVariants = cva(
[
'group/number-field flex w-full min-w-0 items-stretch overflow-hidden border border-transparent bg-components-input-bg-normal text-components-input-text-filled shadow-none outline-none transition-[background-color,border-color,box-shadow]',
'hover:border-components-input-border-hover hover:bg-components-input-bg-hover',
'data-[focused]:border-components-input-border-active data-[focused]:bg-components-input-bg-active data-[focused]:shadow-xs',
'data-[disabled]:cursor-not-allowed data-[disabled]:border-transparent data-[disabled]:bg-components-input-bg-disabled data-[disabled]:text-components-input-text-filled-disabled',
'data-[disabled]:hover:border-transparent data-[disabled]:hover:bg-components-input-bg-disabled',
'data-[readonly]:shadow-none motion-reduce:transition-none',
],
{
variants: {
size: {
regular: 'radius-md',
large: 'radius-lg',
},
},
defaultVariants: {
size: 'regular',
},
},
)
type NumberFieldGroupProps = React.ComponentPropsWithoutRef<typeof BaseNumberField.Group> & VariantProps<typeof numberFieldGroupVariants>
export function NumberFieldGroup({
className,
size = 'regular',
...props
}: NumberFieldGroupProps) {
return (
<BaseNumberField.Group
className={cn(numberFieldGroupVariants({ size }), className)}
{...props}
/>
)
}
export const numberFieldInputVariants = cva(
[
'w-0 min-w-0 flex-1 appearance-none border-0 bg-transparent text-components-input-text-filled caret-primary-600 outline-none',
'placeholder:text-components-input-text-placeholder',
'disabled:cursor-not-allowed disabled:text-components-input-text-filled-disabled disabled:placeholder:text-components-input-text-disabled',
'data-[readonly]:cursor-default',
],
{
variants: {
size: {
regular: 'px-3 py-[7px] system-sm-regular',
large: 'px-4 py-2 system-md-regular',
},
},
defaultVariants: {
size: 'regular',
},
},
)
type NumberFieldInputProps = Omit<React.ComponentPropsWithoutRef<typeof BaseNumberField.Input>, 'size'> & VariantProps<typeof numberFieldInputVariants>
export function NumberFieldInput({
className,
size = 'regular',
...props
}: NumberFieldInputProps) {
return (
<BaseNumberField.Input
className={cn(numberFieldInputVariants({ size }), className)}
{...props}
/>
)
}
export const numberFieldUnitVariants = cva(
'flex shrink-0 items-center self-stretch text-text-tertiary system-sm-regular',
{
variants: {
size: {
regular: 'pr-2',
large: 'pr-2.5',
},
},
defaultVariants: {
size: 'regular',
},
},
)
type NumberFieldUnitProps = React.HTMLAttributes<HTMLSpanElement> & VariantProps<typeof numberFieldUnitVariants>
export function NumberFieldUnit({
className,
size = 'regular',
...props
}: NumberFieldUnitProps) {
return (
<span
className={cn(numberFieldUnitVariants({ size }), className)}
{...props}
/>
)
}
export const numberFieldControlsVariants = cva(
'flex shrink-0 flex-col items-stretch border-l border-divider-subtle bg-transparent text-text-tertiary',
)
type NumberFieldControlsProps = React.HTMLAttributes<HTMLDivElement>
export function NumberFieldControls({
className,
...props
}: NumberFieldControlsProps) {
return (
<div
className={cn(numberFieldControlsVariants(), className)}
{...props}
/>
)
}
export const numberFieldControlButtonVariants = cva(
[
'flex items-center justify-center px-1.5 text-text-tertiary outline-none transition-colors',
'hover:bg-components-input-bg-hover focus-visible:bg-components-input-bg-hover',
'disabled:cursor-not-allowed disabled:hover:bg-transparent',
'group-data-[disabled]/number-field:cursor-not-allowed group-data-[disabled]/number-field:hover:bg-transparent',
'group-data-[readonly]/number-field:cursor-default group-data-[readonly]/number-field:hover:bg-transparent',
'motion-reduce:transition-none',
],
{
variants: {
size: {
regular: '',
large: '',
},
direction: {
increment: '',
decrement: '',
},
},
compoundVariants: [
{
size: 'regular',
direction: 'increment',
className: 'pt-1',
},
{
size: 'regular',
direction: 'decrement',
className: 'pb-1',
},
{
size: 'large',
direction: 'increment',
className: 'pt-1.5',
},
{
size: 'large',
direction: 'decrement',
className: 'pb-1.5',
},
],
defaultVariants: {
size: 'regular',
direction: 'increment',
},
},
)
type NumberFieldButtonVariantProps = Omit<
VariantProps<typeof numberFieldControlButtonVariants>,
'direction'
>
type NumberFieldButtonProps = React.ComponentPropsWithoutRef<typeof BaseNumberField.Increment> & NumberFieldButtonVariantProps
export function NumberFieldIncrement({
className,
size = 'regular',
...props
}: NumberFieldButtonProps) {
return (
<BaseNumberField.Increment
className={cn(numberFieldControlButtonVariants({ size, direction: 'increment' }), className)}
{...props}
/>
)
}
export function NumberFieldDecrement({
className,
size = 'regular',
...props
}: NumberFieldButtonProps) {
return (
<BaseNumberField.Decrement
className={cn(numberFieldControlButtonVariants({ size, direction: 'decrement' }), className)}
{...props}
/>
)
}

View File

@ -47,19 +47,19 @@ describe('MaxLengthInput', () => {
it('should render number input', () => {
render(<MaxLengthInput onChange={vi.fn()} />)
const input = screen.getByRole('spinbutton')
const input = screen.getByRole('textbox')
expect(input).toBeInTheDocument()
})
it('should accept value prop', () => {
render(<MaxLengthInput value={500} onChange={vi.fn()} />)
expect(screen.getByDisplayValue('500')).toBeInTheDocument()
expect(screen.getByRole('textbox')).toHaveValue('500')
})
it('should have min of 1', () => {
render(<MaxLengthInput onChange={vi.fn()} />)
const input = screen.getByRole('spinbutton')
expect(input).toHaveAttribute('min', '1')
const input = screen.getByRole('textbox')
expect(input).toBeInTheDocument()
})
})
@ -75,18 +75,18 @@ describe('OverlapInput', () => {
it('should render number input', () => {
render(<OverlapInput onChange={vi.fn()} />)
const input = screen.getByRole('spinbutton')
const input = screen.getByRole('textbox')
expect(input).toBeInTheDocument()
})
it('should accept value prop', () => {
render(<OverlapInput value={50} onChange={vi.fn()} />)
expect(screen.getByDisplayValue('50')).toBeInTheDocument()
expect(screen.getByRole('textbox')).toHaveValue('50')
})
it('should have min of 1', () => {
render(<OverlapInput onChange={vi.fn()} />)
const input = screen.getByRole('spinbutton')
expect(input).toHaveAttribute('min', '1')
const input = screen.getByRole('textbox')
expect(input).toBeInTheDocument()
})
})

View File

@ -905,8 +905,8 @@ describe('ExternalKnowledgeBaseCreate', () => {
/>,
)
// The TopKItem should render an input
const inputs = screen.getAllByRole('spinbutton')
// The TopKItem renders the visible number-field input as a textbox.
const inputs = screen.getAllByRole('textbox')
const topKInput = inputs[0]
fireEvent.change(topKInput, { target: { value: '8' } })
@ -924,8 +924,8 @@ describe('ExternalKnowledgeBaseCreate', () => {
/>,
)
// The ScoreThresholdItem should render an input
const inputs = screen.getAllByRole('spinbutton')
// The ScoreThresholdItem renders the visible number-field input as a textbox.
const inputs = screen.getAllByRole('textbox')
const scoreThresholdInput = inputs[1]
fireEvent.change(scoreThresholdInput, { target: { value: '0.8' } })

View File

@ -43,8 +43,9 @@ describe('InputCombined', () => {
render(
<InputCombined type={DataType.number} value={42} onChange={handleChange} />,
)
const input = screen.getByDisplayValue('42')
const input = screen.getByRole('textbox')
expect(input).toBeInTheDocument()
expect(input).toHaveValue('42')
})
it('should render date picker for time type', () => {
@ -96,7 +97,7 @@ describe('InputCombined', () => {
<InputCombined type={DataType.number} value={0} onChange={handleChange} />,
)
const input = screen.getByRole('spinbutton')
const input = screen.getByRole('textbox')
fireEvent.change(input, { target: { value: '123' } })
expect(handleChange).toHaveBeenCalled()
@ -108,7 +109,7 @@ describe('InputCombined', () => {
<InputCombined type={DataType.number} value={999} onChange={handleChange} />,
)
expect(screen.getByDisplayValue('999')).toBeInTheDocument()
expect(screen.getByRole('textbox')).toHaveValue('999')
})
it('should apply readOnly prop to number input', () => {
@ -117,7 +118,7 @@ describe('InputCombined', () => {
<InputCombined type={DataType.number} value={42} onChange={handleChange} readOnly />,
)
const input = screen.getByRole('spinbutton')
const input = screen.getByRole('textbox')
expect(input).toHaveAttribute('readonly')
})
})
@ -186,7 +187,7 @@ describe('InputCombined', () => {
<InputCombined type={DataType.number} value={null} onChange={handleChange} />,
)
const input = screen.getByRole('spinbutton')
const input = screen.getByRole('textbox')
expect(input).toBeInTheDocument()
})
})
@ -208,7 +209,7 @@ describe('InputCombined', () => {
<InputCombined type={DataType.number} value={0} onChange={handleChange} />,
)
const input = screen.getByRole('spinbutton')
const input = screen.getByRole('textbox')
expect(input).toHaveClass('rounded-l-md')
})
})
@ -230,7 +231,7 @@ describe('InputCombined', () => {
<InputCombined type={DataType.number} value={0} onChange={handleChange} />,
)
expect(screen.getByDisplayValue('0')).toBeInTheDocument()
expect(screen.getByRole('textbox')).toHaveValue('0')
})
it('should handle negative number', () => {
@ -239,7 +240,7 @@ describe('InputCombined', () => {
<InputCombined type={DataType.number} value={-100} onChange={handleChange} />,
)
expect(screen.getByDisplayValue('-100')).toBeInTheDocument()
expect(screen.getByRole('textbox')).toHaveValue('-100')
})
it('should handle special characters in string', () => {
@ -263,7 +264,7 @@ describe('InputCombined', () => {
<InputCombined type={DataType.number} value={42} onChange={handleChange} />,
)
expect(screen.getByRole('spinbutton')).toBeInTheDocument()
expect(screen.getByRole('textbox')).toBeInTheDocument()
})
})
})

View File

@ -129,15 +129,15 @@ describe('IndexMethod', () => {
it('should pass keywordNumber to KeywordNumber component', () => {
render(<IndexMethod {...defaultProps} keywordNumber={25} />)
const input = screen.getByRole('spinbutton')
expect(input).toHaveValue(25)
const input = screen.getByRole('textbox')
expect(input).toHaveValue('25')
})
it('should call onKeywordNumberChange when KeywordNumber changes', () => {
const handleKeywordChange = vi.fn()
render(<IndexMethod {...defaultProps} onKeywordNumberChange={handleKeywordChange} />)
const input = screen.getByRole('spinbutton')
const input = screen.getByRole('textbox')
fireEvent.change(input, { target: { value: '30' } })
expect(handleKeywordChange).toHaveBeenCalled()
@ -192,14 +192,14 @@ describe('IndexMethod', () => {
it('should handle keywordNumber of 0', () => {
render(<IndexMethod {...defaultProps} keywordNumber={0} />)
const input = screen.getByRole('spinbutton')
expect(input).toHaveValue(0)
const input = screen.getByRole('textbox')
expect(input).toHaveValue('0')
})
it('should handle max keywordNumber', () => {
render(<IndexMethod {...defaultProps} keywordNumber={50} />)
const input = screen.getByRole('spinbutton')
expect(input).toHaveValue(50)
const input = screen.getByRole('textbox')
expect(input).toHaveValue('50')
})
})
})

View File

@ -38,15 +38,15 @@ describe('KeyWordNumber', () => {
it('should render input number field', () => {
render(<KeyWordNumber {...defaultProps} />)
expect(screen.getByRole('spinbutton')).toBeInTheDocument()
expect(screen.getByRole('textbox')).toBeInTheDocument()
})
})
describe('Props', () => {
it('should display correct keywordNumber value in input', () => {
render(<KeyWordNumber {...defaultProps} keywordNumber={25} />)
const input = screen.getByRole('spinbutton')
expect(input).toHaveValue(25)
const input = screen.getByRole('textbox')
expect(input).toHaveValue('25')
})
it('should display different keywordNumber values', () => {
@ -54,8 +54,8 @@ describe('KeyWordNumber', () => {
values.forEach((value) => {
const { unmount } = render(<KeyWordNumber {...defaultProps} keywordNumber={value} />)
const input = screen.getByRole('spinbutton')
expect(input).toHaveValue(value)
const input = screen.getByRole('textbox')
expect(input).toHaveValue(String(value))
unmount()
})
})
@ -82,7 +82,7 @@ describe('KeyWordNumber', () => {
const handleChange = vi.fn()
render(<KeyWordNumber {...defaultProps} onKeywordNumberChange={handleChange} />)
const input = screen.getByRole('spinbutton')
const input = screen.getByRole('textbox')
fireEvent.change(input, { target: { value: '30' } })
expect(handleChange).toHaveBeenCalled()
@ -92,7 +92,7 @@ describe('KeyWordNumber', () => {
const handleChange = vi.fn()
render(<KeyWordNumber {...defaultProps} onKeywordNumberChange={handleChange} />)
const input = screen.getByRole('spinbutton')
const input = screen.getByRole('textbox')
fireEvent.change(input, { target: { value: '' } })
// When value is empty/undefined, handleInputChange should not call onKeywordNumberChange
@ -117,32 +117,32 @@ describe('KeyWordNumber', () => {
describe('Edge Cases', () => {
it('should handle minimum value (0)', () => {
render(<KeyWordNumber {...defaultProps} keywordNumber={0} />)
const input = screen.getByRole('spinbutton')
expect(input).toHaveValue(0)
const input = screen.getByRole('textbox')
expect(input).toHaveValue('0')
})
it('should handle maximum value (50)', () => {
render(<KeyWordNumber {...defaultProps} keywordNumber={50} />)
const input = screen.getByRole('spinbutton')
expect(input).toHaveValue(50)
const input = screen.getByRole('textbox')
expect(input).toHaveValue('50')
})
it('should handle value updates correctly', () => {
const { rerender } = render(<KeyWordNumber {...defaultProps} keywordNumber={10} />)
let input = screen.getByRole('spinbutton')
expect(input).toHaveValue(10)
let input = screen.getByRole('textbox')
expect(input).toHaveValue('10')
rerender(<KeyWordNumber {...defaultProps} keywordNumber={25} />)
input = screen.getByRole('spinbutton')
expect(input).toHaveValue(25)
input = screen.getByRole('textbox')
expect(input).toHaveValue('25')
})
it('should handle rapid value changes', () => {
const handleChange = vi.fn()
render(<KeyWordNumber {...defaultProps} onKeywordNumberChange={handleChange} />)
const input = screen.getByRole('spinbutton')
const input = screen.getByRole('textbox')
// Simulate rapid changes via input with different values
fireEvent.change(input, { target: { value: '15' } })
@ -162,7 +162,7 @@ describe('KeyWordNumber', () => {
it('should have accessible input', () => {
render(<KeyWordNumber {...defaultProps} />)
const input = screen.getByRole('spinbutton')
const input = screen.getByRole('textbox')
expect(input).toBeInTheDocument()
})
})

View File

@ -295,9 +295,11 @@
"svgo@>=3.0.0,<3.3.3": "3.3.3",
"tar@<=7.5.10": "7.5.11",
"typed-array-buffer": "npm:@nolyfill/typed-array-buffer@^1.0.44",
"undici@>=7.0.0,<7.24.0": "7.24.0",
"vite": "npm:@voidzero-dev/vite-plus-core@0.1.11",
"vitest": "npm:@voidzero-dev/vite-plus-test@0.1.11",
"which-typed-array": "npm:@nolyfill/which-typed-array@^1.0.44"
"which-typed-array": "npm:@nolyfill/which-typed-array@^1.0.44",
"yauzl@<3.2.1": "3.2.1"
},
"ignoredBuiltDependencies": [
"canvas",

View File

@ -50,9 +50,11 @@ overrides:
svgo@>=3.0.0,<3.3.3: 3.3.3
tar@<=7.5.10: 7.5.11
typed-array-buffer: npm:@nolyfill/typed-array-buffer@^1.0.44
undici@>=7.0.0,<7.24.0: 7.24.0
vite: npm:@voidzero-dev/vite-plus-core@0.1.11
vitest: npm:@voidzero-dev/vite-plus-test@0.1.11
which-typed-array: npm:@nolyfill/which-typed-array@^1.0.44
yauzl@<3.2.1: 3.2.1
importers:
@ -96,7 +98,7 @@ importers:
version: 0.41.0
'@lexical/react':
specifier: 0.41.0
version: 0.41.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(yjs@13.6.29)
version: 0.41.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(yjs@13.6.30)
'@lexical/selection':
specifier: 0.41.0
version: 0.41.0
@ -980,8 +982,13 @@ packages:
peerDependencies:
'@csstools/css-tokenizer': ^4.0.0
'@csstools/css-syntax-patches-for-csstree@1.1.0':
resolution: {integrity: sha512-H4tuz2nhWgNKLt1inYpoVCfbJbMwX/lQKp3g69rrrIMIYlFD9+zTykOKhNR8uGrAmbS/kT9n6hTFkmDkxLgeTA==}
'@csstools/css-syntax-patches-for-csstree@1.1.1':
resolution: {integrity: sha512-BvqN0AMWNAnLk9G8jnUT77D+mUbY/H2b3uDTvg2isJkHaOufUE2R3AOwxWo7VBQKT1lOdwdvorddo2B/lk64+w==}
peerDependencies:
css-tree: ^3.2.1
peerDependenciesMeta:
css-tree:
optional: true
'@csstools/css-tokenizer@4.0.0':
resolution: {integrity: sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==}
@ -1003,14 +1010,14 @@ packages:
peerDependencies:
tailwindcss: '*'
'@emnapi/core@1.8.1':
resolution: {integrity: sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==}
'@emnapi/core@1.9.0':
resolution: {integrity: sha512-0DQ98G9ZQZOxfUcQn1waV2yS8aWdZ6kJMbYCJB3oUBecjWYO1fqJ+a1DRfPF3O5JEkwqwP1A9QEN/9mYm2Yd0w==}
'@emnapi/runtime@1.8.1':
resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==}
'@emnapi/runtime@1.9.0':
resolution: {integrity: sha512-QN75eB0IH2ywSpRpNddCRfQIhmJYBCJ1x5Lb3IscKAL8bMnVAKnRg8dCoXbHzVLLH7P38N2Z3mtulB7W0J0FKw==}
'@emnapi/wasi-threads@1.1.0':
resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==}
'@emnapi/wasi-threads@1.2.0':
resolution: {integrity: sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==}
'@emoji-mart/data@1.2.1':
resolution: {integrity: sha512-no2pQMWiBy6gpBEiqGeU77/bFejDqUTRY7KX+0+iur13op3bqUsXdnwoZs6Xb1zbv0gAj5VvS1PWoUUckSr5Dw==}
@ -3042,9 +3049,10 @@ packages:
resolution: {integrity: sha512-cNnJ89Q021Zf883rlbBTfsaxTfi2r73/qejGtyTa7ksErF3hyDyAq1aTbo5crK9dAL7zSHh9viKY1BtMls1QOA==}
engines: {node: '>=18'}
'@tanstack/devtools-event-client@0.4.1':
resolution: {integrity: sha512-GRxmPw4OHZ2oZeIEUkEwt/NDvuEqzEYRAjzUVMs+I0pd4C7k1ySOiuJK2CqF+K/yEAR3YZNkW3ExrpDarh9Vwg==}
'@tanstack/devtools-event-client@0.4.3':
resolution: {integrity: sha512-OZI6QyULw0FI0wjgmeYzCIfbgPsOEzwJtCpa69XrfLMtNXLGnz3d/dIabk7frg0TmHo+Ah49w5I4KC7Tufwsvw==}
engines: {node: '>=18'}
hasBin: true
'@tanstack/devtools-ui@0.5.0':
resolution: {integrity: sha512-nNZ14054n31fWB61jtWhZYLRdQ3yceCE3G/RINoINUB0RqIGZAIm9DnEDwOTAOfqt4/a/D8vNk8pJu6RQUp74g==}
@ -3052,9 +3060,16 @@ packages:
peerDependencies:
solid-js: 1.9.11
'@tanstack/devtools-utils@0.3.2':
resolution: {integrity: sha512-fu9wmE2bHigiE1Lc5RFSchgdN35wX15TqfB4O4vJa6SqX9JH2ov57J60u18lheROaBiteloPzcCbkLNpx0aacw==}
'@tanstack/devtools-ui@0.5.1':
resolution: {integrity: sha512-T9JjAdqMSnxsVO6AQykD5vhxPF4iFLKtbYxee/bU3OLlk446F5C1220GdCmhDSz7y4lx+m8AvIS0bq6zzvdDUA==}
engines: {node: '>=18'}
peerDependencies:
solid-js: 1.9.11
'@tanstack/devtools-utils@0.3.4':
resolution: {integrity: sha512-lQdUdpSh1odWCZjtjOi9FA+MJWvIK/4TkGyeJeiOX7eY3JW+z3FNwHUR10vToHOwAJB6UGJhi04RNZQRpiM7GQ==}
engines: {node: '>=18'}
hasBin: true
peerDependencies:
'@types/react': '>=17.0.0'
preact: '>=10.0.0'
@ -3147,8 +3162,8 @@ packages:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
'@tanstack/react-virtual@3.13.21':
resolution: {integrity: sha512-SYXFrmrbPgXBvf+HsOsKhFgqSe4M6B29VHOsX9Jih9TlNkNkDWx0hWMiMLUghMEzyUz772ndzdEeCEBx+3GIZw==}
'@tanstack/react-virtual@3.13.23':
resolution: {integrity: sha512-XnMRnHQ23piOVj2bzJqHrRrLg4r+F86fuBcwteKfbIjJrtGxb4z7tIvPVAe4B+4UVwo9G4Giuz5fmapcrnZ0OQ==}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
@ -3156,8 +3171,8 @@ packages:
'@tanstack/store@0.9.2':
resolution: {integrity: sha512-K013lUJEFJK2ofFQ/hZKJUmCnpcV00ebLyOyFOWQvyQHUOZp/iYO84BM6aOGiV81JzwbX0APTVmW8YI7yiG5oA==}
'@tanstack/virtual-core@3.13.21':
resolution: {integrity: sha512-ww+fmLHyCbPSf7JNbWZP3g7wl6SdNo3ah5Aiw+0e9FDErkVHLKprYUrwTm7dF646FtEkN/KkAKPYezxpmvOjxw==}
'@tanstack/virtual-core@3.13.23':
resolution: {integrity: sha512-zSz2Z2HNyLjCplANTDyl3BcdQJc2k1+yyFoKhNRmCr7V7dY8o8q5m8uFTI1/Pg1kL+Hgrz6u3Xo6eFUB7l66cg==}
'@testing-library/dom@10.4.1':
resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==}
@ -3577,11 +3592,11 @@ packages:
resolution: {integrity: sha512-hBcWIOppZV14bi+eAmCZj8Elj8hVSUZJTpf1lgGBhVD85pervzQ1poM/qYfFUlPraYSZYP+ASg6To5BwYmUSGQ==}
engines: {node: '>=16'}
'@vitejs/plugin-react@5.1.4':
resolution: {integrity: sha512-VIcFLdRi/VYRU8OL/puL7QXMYafHmqOnwTZY50U1JPlCNj30PxCMx65c494b1K9be9hX83KVt0+gTEwTWLqToA==}
'@vitejs/plugin-react@5.2.0':
resolution: {integrity: sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw==}
engines: {node: ^20.19.0 || >=22.12.0}
peerDependencies:
vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0
vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0
'@vitejs/plugin-react@6.0.0':
resolution: {integrity: sha512-Bu5/eP6td3WI654+tRq+ryW1PbgA90y5pqMKpb3U7UpNk6VjI53P/ncPUd192U9dSrepLy7DHnq1XEMDz5H++w==}
@ -3616,8 +3631,8 @@ packages:
'@vitest/browser':
optional: true
'@vitest/eslint-plugin@1.6.10':
resolution: {integrity: sha512-/cOf+mTu4HBJIYHTETo8/OFCSZv3T2p+KfGnouzKfjK063cWLZp0TzvK7EU5B3eFG7ypUNtw6l+jK+SA+p1g8g==}
'@vitest/eslint-plugin@1.6.12':
resolution: {integrity: sha512-4kI47BJNFE+EQ5bmPbHzBF+ibNzx2Fj0Jo9xhWsTPxMddlHwIWl6YAxagefh461hrwx/W0QwBZpxGS404kBXyg==}
engines: {node: '>=18'}
peerDependencies:
eslint: '>=8.57.0'
@ -4016,8 +4031,8 @@ packages:
base64-js@1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
baseline-browser-mapping@2.10.0:
resolution: {integrity: sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==}
baseline-browser-mapping@2.10.8:
resolution: {integrity: sha512-PCLz/LXGBsNTErbtB6i5u4eLpHeMfi93aUv5duMmj6caNu6IphS4q6UevDnL36sZQv9lrP11dbPKGMaXPwMKfQ==}
engines: {node: '>=6.0.0'}
hasBin: true
@ -4106,8 +4121,8 @@ packages:
camelize@1.0.1:
resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==}
caniuse-lite@1.0.30001777:
resolution: {integrity: sha512-tmN+fJxroPndC74efCdp12j+0rk0RHwV5Jwa1zWaFVyw2ZxAuPeG8ZgWC3Wz7uSjT3qMRQ5XHZ4COgQmsCMJAQ==}
caniuse-lite@1.0.30001779:
resolution: {integrity: sha512-U5og2PN7V4DMgF50YPNtnZJGWVLFjjsN3zb6uMT5VGYIewieDj1upwfuVNXf4Kor+89c3iCRJnSzMD5LmTvsfA==}
canvas@3.2.1:
resolution: {integrity: sha512-ej1sPFR5+0YWtaVp6S1N1FVz69TQCqmrkGeRvQxZeAB1nAIcjNTHVwrZtYtWFFBmQsF40/uDLehsW5KuYC99mg==}
@ -4655,8 +4670,8 @@ packages:
echarts@6.0.0:
resolution: {integrity: sha512-Tte/grDQRiETQP4xz3iZWSvoHrkCQtwqd6hs+mifXcjrCuo2iKWbajFObuLJVBlDIJlOzgQPd1hsaKt/3+OMkQ==}
electron-to-chromium@1.5.307:
resolution: {integrity: sha512-5z3uFKBWjiNR44nFcYdkcXjKMbg5KXNdciu7mhTPo9tB7NbqSNP2sSnGR+fqknZSCwKkBN+oxiiajWs4dT6ORg==}
electron-to-chromium@1.5.313:
resolution: {integrity: sha512-QBMrTWEf00GXZmJyx2lbYD45jpI3TUFnNIzJ5BBc8piGUDwMPa1GV6HJWTZVvY/eiN3fSopl7NRbgGp9sZ9LTA==}
elkjs@0.11.1:
resolution: {integrity: sha512-zxxR9k+rx5ktMwT/FwyLdPCrq7xN6e4VGGHH8hA01vVYKjTFik7nHOxBnAYtrgYUB1RpAiLvA1/U2YraWxyKKg==}
@ -4772,8 +4787,8 @@ packages:
eslint-flat-config-utils@3.0.2:
resolution: {integrity: sha512-mPvevWSDQFwgABvyCurwIu6ZdKxGI5NW22/BGDwA1T49NO6bXuxbV9VfJK/tkQoNyPogT6Yu1d57iM0jnZVWmg==}
eslint-json-compat-utils@0.2.2:
resolution: {integrity: sha512-KcTUifi8VSSHkrOY0FzB7smuTZRU9T2nCrcCy6k2b+Q77+uylBQVIxN4baVCIWvWJEpud+IsrYgco4JJ6io05g==}
eslint-json-compat-utils@0.2.3:
resolution: {integrity: sha512-RbBmDFyu7FqnjE8F0ZxPNzx5UaptdeS9Uu50r7A+D7s/+FCX+ybiyViYEgFUaFIFqSWJgZRTpL5d8Kanxxl2lQ==}
engines: {node: '>=12'}
peerDependencies:
'@eslint/json': '*'
@ -4836,14 +4851,14 @@ packages:
peerDependencies:
eslint: '>=9.0.0'
eslint-plugin-jsdoc@62.7.1:
resolution: {integrity: sha512-4Zvx99Q7d1uggYBUX/AIjvoyqXhluGbbKrRmG8SQTLprPFg6fa293tVJH1o1GQwNe3lUydd8ZHzn37OaSncgSQ==}
eslint-plugin-jsdoc@62.8.0:
resolution: {integrity: sha512-hu3r9/6JBmPG6wTcqtYzgZAnjEG2eqRUATfkFscokESg1VDxZM21ZaMire0KjeMwfj+SXvgB4Rvh5LBuesj92w==}
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
peerDependencies:
eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0
eslint-plugin-jsonc@3.1.1:
resolution: {integrity: sha512-7TSQO8ZyvOuXWb0sYke3KUSh0DJA4/QviKfuzD3/Cy3XDjtrIrTWQbjb7j/Yy2l/DgwuM+lCS2c/jqJifv5jhg==}
eslint-plugin-jsonc@3.1.2:
resolution: {integrity: sha512-dopTxdB22iuOkgKyJCupEC5IYBItUT4J/teq1H5ddUObcaYhOURxtJElZczdcYnnKCghNU/vccuyPkliy2Wxsg==}
engines: {node: ^20.19.0 || ^22.13.0 || >=24}
peerDependencies:
eslint: '>=9.38.0'
@ -5147,9 +5162,6 @@ packages:
fd-package-json@2.0.0:
resolution: {integrity: sha512-jKmm9YtsNXN789RS/0mSzOC1NUq9mkVd65vbSSVsKdjGvYXBuE4oWe2QOEoFeRmJg+lPuZxpmrfFclNhoRMneQ==}
fd-slicer@1.1.0:
resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==}
fdir@6.5.0:
resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
engines: {node: '>=12.0.0'}
@ -5895,8 +5907,8 @@ packages:
lowlight@1.20.0:
resolution: {integrity: sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==}
lru-cache@11.2.6:
resolution: {integrity: sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==}
lru-cache@11.2.7:
resolution: {integrity: sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==}
engines: {node: 20 || >=22}
lru-cache@5.1.1:
@ -6269,8 +6281,8 @@ packages:
resolution: {integrity: sha512-u5xUnYE+UOOBA6SpELJheMCtj2Laqx15Vl70QxKo43Wz/6nMHXS7PrEioXLjXAwhmawdEMNImwKCcPhBJWbKVw==}
engines: {node: '>=18.20.0 <20 || >=20.12.1'}
node-abi@3.88.0:
resolution: {integrity: sha512-At6b4UqIEVudaqPsXjmUO1r/N5BUr4yhDGs5PkBE8/oG5+TfLPhFechiskFsnT6Ql0VfUXbalUUCbfXxtj7K+w==}
node-abi@3.89.0:
resolution: {integrity: sha512-6u9UwL0HlAl21+agMN3YAMXcKByMqwGx+pq+P76vii5f7hTPtKDp08/H9py6DY+cfDw7kQNTGEj/rly3IgbNQA==}
engines: {node: '>=10'}
node-addon-api@7.1.1:
@ -6671,8 +6683,8 @@ packages:
peerDependencies:
typescript: '>= 4.3.x'
react-docgen@8.0.2:
resolution: {integrity: sha512-+NRMYs2DyTP4/tqWz371Oo50JqmWltR1h2gcdgUMAWZJIAvrd0/SqlCfx7tpzpl/s36rzw6qH2MjoNrxtRNYhA==}
react-docgen@8.0.3:
resolution: {integrity: sha512-aEZ9qP+/M+58x2qgfSFEWH1BxLyHe5+qkLNJOZQb5iGS017jpbRnoKhNRrXPeA6RfBrZO5wZrT9DMC1UqE1f1w==}
engines: {node: ^20.9.0 || >=22}
react-dom@19.2.4:
@ -7132,8 +7144,8 @@ packages:
spdx-license-ids@3.0.23:
resolution: {integrity: sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==}
srvx@0.11.9:
resolution: {integrity: sha512-97wWJS6F0KTKAhDlHVmBzMvlBOp5FiNp3XrLoodIgYJpXxgG5tE9rX4Pg7s46n2shI4wtEsMATTS1+rI3/ubzA==}
srvx@0.11.12:
resolution: {integrity: sha512-AQfrGqntqVPXgP03pvBDN1KyevHC+KmYVqb8vVf4N+aomQqdhaZxjvoVp+AOm4u6x+GgNQY3MVzAUIn+TqwkOA==}
engines: {node: '>=20.16.0'}
hasBin: true
@ -7341,8 +7353,8 @@ packages:
tinybench@2.9.0:
resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
tinyexec@1.0.2:
resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==}
tinyexec@1.0.4:
resolution: {integrity: sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==}
engines: {node: '>=18'}
tinyglobby@0.2.15:
@ -7357,16 +7369,16 @@ packages:
resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==}
engines: {node: '>=14.0.0'}
tinyrainbow@3.0.3:
resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==}
tinyrainbow@3.1.0:
resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==}
engines: {node: '>=14.0.0'}
tinyspy@4.0.4:
resolution: {integrity: sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==}
engines: {node: '>=14.0.0'}
tldts-core@7.0.25:
resolution: {integrity: sha512-ZjCZK0rppSBu7rjHYDYsEaMOIbbT+nWF57hKkv4IUmZWBNrBWBOjIElc0mKRgLM8bm7x/BBlof6t2gi/Oq/Asw==}
tldts-core@7.0.26:
resolution: {integrity: sha512-5WJ2SqFsv4G2Dwi7ZFVRnz6b2H1od39QME1lc2y5Ew3eWiZMAeqOAfWpRP9jHvhUl881406QtZTODvjttJs+ew==}
tldts@7.0.25:
resolution: {integrity: sha512-keinCnPbwXEUG3ilrWQZU+CqcTTzHq9m2HhoUP2l7Xmi8l1LuijAXLpAJ5zRW+ifKTNscs4NdCkfkDCBYm352w==}
@ -7391,8 +7403,8 @@ packages:
resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==}
engines: {node: '>=6'}
tough-cookie@6.0.0:
resolution: {integrity: sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==}
tough-cookie@6.0.1:
resolution: {integrity: sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==}
engines: {node: '>=16'}
tr46@6.0.0:
@ -7501,8 +7513,8 @@ packages:
undici-types@7.18.2:
resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==}
undici@7.22.0:
resolution: {integrity: sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg==}
undici@7.24.4:
resolution: {integrity: sha512-BM/JzwwaRXxrLdElV2Uo6cTLEjhSb3WXboncJamZ15NgUURmvlXvxa6xkwIOILIjPNo9i8ku136ZvWV0Uly8+w==}
engines: {node: '>=20.18.1'}
unicode-trie@2.0.0:
@ -7697,8 +7709,8 @@ packages:
'@nuxt/kit':
optional: true
vite-plugin-storybook-nextjs@3.2.2:
resolution: {integrity: sha512-ZJXCrhi9mW4jEJTKhJ5sUtpBe84mylU40me2aMuLSgIJo4gE/Rc559hZvMYLFTWta1gX7Rm8Co5EEHakPct+wA==}
vite-plugin-storybook-nextjs@3.2.3:
resolution: {integrity: sha512-NQvkiZKfbGmk0j3mYeTJnGiucV+VOcryCsm/CoE7rBVRrpVntg5lWj+CbosFwHhGPpWQ3I4HJ3nSRzDq0u74Ug==}
peerDependencies:
next: ^14.1.0 || ^15.0.0 || ^16.0.0
storybook: ^0.0.0-0 || ^9.0.0 || ^10.0.0 || ^10.0.0-0 || ^10.1.0-0 || ^10.2.0-0 || ^10.3.0-0
@ -7884,11 +7896,12 @@ packages:
engines: {node: '>= 14.6'}
hasBin: true
yauzl@2.10.0:
resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==}
yauzl@3.2.1:
resolution: {integrity: sha512-k1isifdbpNSFEHFJ1ZY4YDewv0IH9FR61lDetaRMD3j2ae3bIXGV+7c+LHCqtQGofSd8PIyV4X6+dHMAnSr60A==}
engines: {node: '>=12'}
yjs@13.6.29:
resolution: {integrity: sha512-kHqDPdltoXH+X4w1lVmMtddE3Oeqq48nM40FD5ojTd8xYhQpzIDcfE2keMSU5bAgRPJBe225WTUdyUgj1DtbiQ==}
yjs@13.6.30:
resolution: {integrity: sha512-vv/9h42eCMC81ZHDFswuu/MKzkl/vyq1BhaNGfHyOonwlG4CJbQF4oiBBJPvfdeCt/PlVDWh7Nov9D34YY09uQ==}
engines: {node: '>=16.0.0', npm: '>=8.0.0'}
yocto-queue@0.1.0:
@ -8113,7 +8126,7 @@ snapshots:
'@stylistic/eslint-plugin': 5.10.0(eslint@10.0.3(jiti@1.21.7))
'@typescript-eslint/eslint-plugin': 8.57.0(@typescript-eslint/parser@8.57.0(eslint@10.0.3(jiti@1.21.7))(typescript@5.9.3))(eslint@10.0.3(jiti@1.21.7))(typescript@5.9.3)
'@typescript-eslint/parser': 8.57.0(eslint@10.0.3(jiti@1.21.7))(typescript@5.9.3)
'@vitest/eslint-plugin': 1.6.10(@voidzero-dev/vite-plus-test@0.1.11(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.11(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2))(esbuild@0.27.2)(jiti@1.21.7)(jsdom@28.1.0(canvas@3.2.1))(sass@1.98.0)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2))(eslint@10.0.3(jiti@1.21.7))(typescript@5.9.3)
'@vitest/eslint-plugin': 1.6.12(@voidzero-dev/vite-plus-test@0.1.11(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.11(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2))(esbuild@0.27.2)(jiti@1.21.7)(jsdom@28.1.0(canvas@3.2.1))(sass@1.98.0)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2))(eslint@10.0.3(jiti@1.21.7))(typescript@5.9.3)
ansis: 4.2.0
cac: 7.0.0
eslint: 10.0.3(jiti@1.21.7)
@ -8123,8 +8136,8 @@ snapshots:
eslint-plugin-antfu: 3.2.2(eslint@10.0.3(jiti@1.21.7))
eslint-plugin-command: 3.5.2(@typescript-eslint/rule-tester@8.57.0(eslint@10.0.3(jiti@1.21.7))(typescript@5.9.3))(@typescript-eslint/typescript-estree@8.57.0(typescript@5.9.3))(@typescript-eslint/utils@8.57.0(eslint@10.0.3(jiti@1.21.7))(typescript@5.9.3))(eslint@10.0.3(jiti@1.21.7))
eslint-plugin-import-lite: 0.5.2(eslint@10.0.3(jiti@1.21.7))
eslint-plugin-jsdoc: 62.7.1(eslint@10.0.3(jiti@1.21.7))
eslint-plugin-jsonc: 3.1.1(eslint@10.0.3(jiti@1.21.7))
eslint-plugin-jsdoc: 62.8.0(eslint@10.0.3(jiti@1.21.7))
eslint-plugin-jsonc: 3.1.2(eslint@10.0.3(jiti@1.21.7))
eslint-plugin-n: 17.24.0(eslint@10.0.3(jiti@1.21.7))(typescript@5.9.3)
eslint-plugin-no-only-tests: 3.3.0
eslint-plugin-perfectionist: 5.6.0(eslint@10.0.3(jiti@1.21.7))(typescript@5.9.3)
@ -8161,14 +8174,14 @@ snapshots:
'@antfu/install-pkg@1.1.0':
dependencies:
package-manager-detector: 1.6.0
tinyexec: 1.0.2
tinyexec: 1.0.4
'@antfu/ni@28.3.0':
dependencies:
ansis: 4.2.0
fzf: 0.5.2
package-manager-detector: 1.6.0
tinyexec: 1.0.2
tinyexec: 1.0.4
tinyglobby: 0.2.15
'@antfu/utils@8.1.1': {}
@ -8179,7 +8192,7 @@ snapshots:
'@csstools/css-color-parser': 4.0.2(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)
'@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0)
'@csstools/css-tokenizer': 4.0.0
lru-cache: 11.2.6
lru-cache: 11.2.7
'@asamuzakjp/dom-selector@6.8.1':
dependencies:
@ -8187,7 +8200,7 @@ snapshots:
bidi-js: 1.0.3
css-tree: 3.2.1
is-potential-custom-element-name: 1.0.1
lru-cache: 11.2.6
lru-cache: 11.2.7
'@asamuzakjp/nwsapi@2.3.9': {}
@ -8389,7 +8402,7 @@ snapshots:
'@code-inspector/core@1.4.4':
dependencies:
'@vue/compiler-dom': 3.5.30
chalk: 4.1.2
chalk: 4.1.1
dotenv: 16.6.1
launch-ide: 1.4.3
portfinder: 1.0.38
@ -8446,7 +8459,9 @@ snapshots:
dependencies:
'@csstools/css-tokenizer': 4.0.0
'@csstools/css-syntax-patches-for-csstree@1.1.0': {}
'@csstools/css-syntax-patches-for-csstree@1.1.1(css-tree@3.2.1)':
optionalDependencies:
css-tree: 3.2.1
'@csstools/css-tokenizer@4.0.0': {}
@ -8462,18 +8477,18 @@ snapshots:
'@iconify/utils': 3.1.0
tailwindcss: 3.4.19(tsx@4.21.0)(yaml@2.8.2)
'@emnapi/core@1.8.1':
'@emnapi/core@1.9.0':
dependencies:
'@emnapi/wasi-threads': 1.1.0
'@emnapi/wasi-threads': 1.2.0
tslib: 2.8.1
optional: true
'@emnapi/runtime@1.8.1':
'@emnapi/runtime@1.9.0':
dependencies:
tslib: 2.8.1
optional: true
'@emnapi/wasi-threads@1.1.0':
'@emnapi/wasi-threads@1.2.0':
dependencies:
tslib: 2.8.1
optional: true
@ -8807,7 +8822,7 @@ snapshots:
'@floating-ui/react': 0.26.28(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@react-aria/focus': 3.21.5(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@react-aria/interactions': 3.27.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@tanstack/react-virtual': 3.13.21(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@tanstack/react-virtual': 3.13.23(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
react: 19.2.4
react-dom: 19.2.4(react@19.2.4)
use-sync-external-store: 1.6.0(react@19.2.4)
@ -8960,7 +8975,7 @@ snapshots:
'@img/sharp-wasm32@0.34.5':
dependencies:
'@emnapi/runtime': 1.8.1
'@emnapi/runtime': 1.9.0
optional: true
'@img/sharp-win32-arm64@0.34.5':
@ -9100,7 +9115,7 @@ snapshots:
'@lexical/utils': 0.41.0
lexical: 0.41.0
'@lexical/react@0.41.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(yjs@13.6.29)':
'@lexical/react@0.41.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(yjs@13.6.30)':
dependencies:
'@floating-ui/react': 0.27.19(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@lexical/devtools-core': 0.41.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
@ -9118,7 +9133,7 @@ snapshots:
'@lexical/table': 0.41.0
'@lexical/text': 0.41.0
'@lexical/utils': 0.41.0
'@lexical/yjs': 0.41.0(yjs@13.6.29)
'@lexical/yjs': 0.41.0(yjs@13.6.30)
lexical: 0.41.0
react: 19.2.4
react-dom: 19.2.4(react@19.2.4)
@ -9154,12 +9169,12 @@ snapshots:
'@lexical/selection': 0.41.0
lexical: 0.41.0
'@lexical/yjs@0.41.0(yjs@13.6.29)':
'@lexical/yjs@0.41.0(yjs@13.6.30)':
dependencies:
'@lexical/offset': 0.41.0
'@lexical/selection': 0.41.0
lexical: 0.41.0
yjs: 13.6.29
yjs: 13.6.30
'@mdx-js/loader@3.1.1(webpack@5.105.4(esbuild@0.27.2)(uglify-js@3.19.3))':
dependencies:
@ -9231,8 +9246,8 @@ snapshots:
'@napi-rs/wasm-runtime@1.1.1':
dependencies:
'@emnapi/core': 1.8.1
'@emnapi/runtime': 1.8.1
'@emnapi/core': 1.9.0
'@emnapi/runtime': 1.9.0
'@tybys/wasm-util': 0.10.1
optional: true
@ -10218,7 +10233,7 @@ snapshots:
storybook: 10.2.17(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
styled-jsx: 5.1.6(@babel/core@7.29.0)(react@19.2.4)
vite: '@voidzero-dev/vite-plus-core@0.1.11(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2)'
vite-plugin-storybook-nextjs: 3.2.2(@voidzero-dev/vite-plus-core@0.1.11(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2))(next@16.1.6(@babel/core@7.29.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0))(storybook@10.2.17(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)
vite-plugin-storybook-nextjs: 3.2.3(@voidzero-dev/vite-plus-core@0.1.11(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2))(next@16.1.6(@babel/core@7.29.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0))(storybook@10.2.17(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3)
optionalDependencies:
typescript: 5.9.3
transitivePeerDependencies:
@ -10244,7 +10259,7 @@ snapshots:
empathic: 2.0.0
magic-string: 0.30.21
react: 19.2.4
react-docgen: 8.0.2
react-docgen: 8.0.3
react-dom: 19.2.4(react@19.2.4)
resolve: 1.22.11
storybook: 10.2.17(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
@ -10262,7 +10277,7 @@ snapshots:
'@storybook/global': 5.0.0
'@storybook/react-dom-shim': 10.2.17(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@10.2.17(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))
react: 19.2.4
react-docgen: 8.0.2
react-docgen: 8.0.3
react-dom: 19.2.4(react@19.2.4)
storybook: 10.2.17(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
optionalDependencies:
@ -10320,7 +10335,7 @@ snapshots:
'@tanstack/devtools-client@0.0.6':
dependencies:
'@tanstack/devtools-event-client': 0.4.1
'@tanstack/devtools-event-client': 0.4.3
'@tanstack/devtools-event-bus@0.4.1':
dependencies:
@ -10329,7 +10344,7 @@ snapshots:
- bufferutil
- utf-8-validate
'@tanstack/devtools-event-client@0.4.1': {}
'@tanstack/devtools-event-client@0.4.3': {}
'@tanstack/devtools-ui@0.5.0(csstype@3.2.3)(solid-js@1.9.11)':
dependencies:
@ -10340,9 +10355,18 @@ snapshots:
transitivePeerDependencies:
- csstype
'@tanstack/devtools-utils@0.3.2(@types/react@19.2.14)(csstype@3.2.3)(react@19.2.4)(solid-js@1.9.11)':
'@tanstack/devtools-ui@0.5.1(csstype@3.2.3)(solid-js@1.9.11)':
dependencies:
'@tanstack/devtools-ui': 0.5.0(csstype@3.2.3)(solid-js@1.9.11)
clsx: 2.1.1
dayjs: 1.11.20
goober: 2.1.18(csstype@3.2.3)
solid-js: 1.9.11
transitivePeerDependencies:
- csstype
'@tanstack/devtools-utils@0.3.4(@types/react@19.2.14)(csstype@3.2.3)(react@19.2.4)(solid-js@1.9.11)':
dependencies:
'@tanstack/devtools-ui': 0.5.1(csstype@3.2.3)(solid-js@1.9.11)
optionalDependencies:
'@types/react': 19.2.14
react: 19.2.4
@ -10377,14 +10401,14 @@ snapshots:
'@tanstack/form-core@1.28.5':
dependencies:
'@tanstack/devtools-event-client': 0.4.1
'@tanstack/devtools-event-client': 0.4.3
'@tanstack/pacer-lite': 0.1.1
'@tanstack/store': 0.9.2
'@tanstack/form-devtools@0.2.18(@types/react@19.2.14)(csstype@3.2.3)(react@19.2.4)(solid-js@1.9.11)':
dependencies:
'@tanstack/devtools-ui': 0.5.0(csstype@3.2.3)(solid-js@1.9.11)
'@tanstack/devtools-utils': 0.3.2(@types/react@19.2.14)(csstype@3.2.3)(react@19.2.4)(solid-js@1.9.11)
'@tanstack/devtools-ui': 0.5.1(csstype@3.2.3)(solid-js@1.9.11)
'@tanstack/devtools-utils': 0.3.4(@types/react@19.2.14)(csstype@3.2.3)(react@19.2.4)(solid-js@1.9.11)
'@tanstack/form-core': 1.28.5
clsx: 2.1.1
dayjs: 1.11.20
@ -10418,7 +10442,7 @@ snapshots:
'@tanstack/react-form-devtools@0.2.18(@types/react@19.2.14)(csstype@3.2.3)(react@19.2.4)(solid-js@1.9.11)':
dependencies:
'@tanstack/devtools-utils': 0.3.2(@types/react@19.2.14)(csstype@3.2.3)(react@19.2.4)(solid-js@1.9.11)
'@tanstack/devtools-utils': 0.3.4(@types/react@19.2.14)(csstype@3.2.3)(react@19.2.4)(solid-js@1.9.11)
'@tanstack/form-devtools': 0.2.18(@types/react@19.2.14)(csstype@3.2.3)(react@19.2.4)(solid-js@1.9.11)
react: 19.2.4
transitivePeerDependencies:
@ -10454,15 +10478,15 @@ snapshots:
react-dom: 19.2.4(react@19.2.4)
use-sync-external-store: 1.6.0(react@19.2.4)
'@tanstack/react-virtual@3.13.21(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
'@tanstack/react-virtual@3.13.23(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
dependencies:
'@tanstack/virtual-core': 3.13.21
'@tanstack/virtual-core': 3.13.23
react: 19.2.4
react-dom: 19.2.4(react@19.2.4)
'@tanstack/store@0.9.2': {}
'@tanstack/virtual-core@3.13.21': {}
'@tanstack/virtual-core@3.13.23': {}
'@testing-library/dom@10.4.1':
dependencies:
@ -10975,7 +10999,7 @@ snapshots:
'@resvg/resvg-wasm': 2.4.0
satori: 0.16.0
'@vitejs/plugin-react@5.1.4(@voidzero-dev/vite-plus-core@0.1.11(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2))':
'@vitejs/plugin-react@5.2.0(@voidzero-dev/vite-plus-core@0.1.11(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2))':
dependencies:
'@babel/core': 7.29.0
'@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0)
@ -11001,7 +11025,7 @@ snapshots:
periscopic: 4.0.2
react: 19.2.4
react-dom: 19.2.4(react@19.2.4)
srvx: 0.11.9
srvx: 0.11.12
strip-literal: 3.1.0
turbo-stream: 3.2.0
vite: '@voidzero-dev/vite-plus-core@0.1.11(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2)'
@ -11020,10 +11044,10 @@ snapshots:
magicast: 0.5.2
obug: 2.1.1
std-env: 4.0.0
tinyrainbow: 3.0.3
tinyrainbow: 3.1.0
vitest: '@voidzero-dev/vite-plus-test@0.1.11(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.11(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2))(esbuild@0.27.2)(jiti@1.21.7)(jsdom@28.1.0(canvas@3.2.1))(sass@1.98.0)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2)'
'@vitest/eslint-plugin@1.6.10(@voidzero-dev/vite-plus-test@0.1.11(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.11(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2))(esbuild@0.27.2)(jiti@1.21.7)(jsdom@28.1.0(canvas@3.2.1))(sass@1.98.0)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2))(eslint@10.0.3(jiti@1.21.7))(typescript@5.9.3)':
'@vitest/eslint-plugin@1.6.12(@voidzero-dev/vite-plus-test@0.1.11(@types/node@25.5.0)(@voidzero-dev/vite-plus-core@0.1.11(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2))(esbuild@0.27.2)(jiti@1.21.7)(jsdom@28.1.0(canvas@3.2.1))(sass@1.98.0)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2))(eslint@10.0.3(jiti@1.21.7))(typescript@5.9.3)':
dependencies:
'@typescript-eslint/scope-manager': 8.57.0
'@typescript-eslint/utils': 8.57.0(eslint@10.0.3(jiti@1.21.7))(typescript@5.9.3)
@ -11048,7 +11072,7 @@ snapshots:
'@vitest/pretty-format@4.1.0':
dependencies:
tinyrainbow: 3.0.3
tinyrainbow: 3.1.0
'@vitest/spy@3.2.4':
dependencies:
@ -11064,7 +11088,7 @@ snapshots:
dependencies:
'@vitest/pretty-format': 4.1.0
convert-source-map: 2.0.0
tinyrainbow: 3.0.3
tinyrainbow: 3.1.0
'@voidzero-dev/vite-plus-core@0.1.11(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2)':
dependencies:
@ -11107,7 +11131,7 @@ snapshots:
sirv: 3.0.2
std-env: 4.0.0
tinybench: 2.9.0
tinyexec: 1.0.2
tinyexec: 1.0.4
tinyglobby: 0.2.15
vite: '@voidzero-dev/vite-plus-core@0.1.11(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2)'
ws: 8.19.0
@ -11390,7 +11414,7 @@ snapshots:
autoprefixer@10.4.27(postcss@8.5.8):
dependencies:
browserslist: 4.28.1
caniuse-lite: 1.0.30001777
caniuse-lite: 1.0.30001779
fraction.js: 5.3.4
picocolors: 1.1.1
postcss: 8.5.8
@ -11409,7 +11433,7 @@ snapshots:
base64-js@1.5.1:
optional: true
baseline-browser-mapping@2.10.0: {}
baseline-browser-mapping@2.10.8: {}
before-after-hook@4.0.0: {}
@ -11448,9 +11472,9 @@ snapshots:
browserslist@4.28.1:
dependencies:
baseline-browser-mapping: 2.10.0
caniuse-lite: 1.0.30001777
electron-to-chromium: 1.5.307
baseline-browser-mapping: 2.10.8
caniuse-lite: 1.0.30001779
electron-to-chromium: 1.5.313
node-releases: 2.0.36
update-browserslist-db: 1.2.3(browserslist@4.28.1)
@ -11484,7 +11508,7 @@ snapshots:
camelize@1.0.1: {}
caniuse-lite@1.0.30001777: {}
caniuse-lite@1.0.30001779: {}
canvas@3.2.1:
dependencies:
@ -11550,7 +11574,7 @@ snapshots:
parse5: 7.3.0
parse5-htmlparser2-tree-adapter: 7.1.0
parse5-parser-stream: 7.1.2
undici: 7.22.0
undici: 7.24.4
whatwg-mimetype: 4.0.0
chevrotain-allstar@0.3.1(chevrotain@11.1.2):
@ -11757,9 +11781,9 @@ snapshots:
cssstyle@6.2.0:
dependencies:
'@asamuzakjp/css-color': 5.0.1
'@csstools/css-syntax-patches-for-csstree': 1.1.0
'@csstools/css-syntax-patches-for-csstree': 1.1.1(css-tree@3.2.1)
css-tree: 3.2.1
lru-cache: 11.2.6
lru-cache: 11.2.7
csstype@3.2.3: {}
@ -12055,7 +12079,7 @@ snapshots:
tslib: 2.3.0
zrender: 6.0.0
electron-to-chromium@1.5.307: {}
electron-to-chromium@1.5.313: {}
elkjs@0.11.1: {}
@ -12179,7 +12203,7 @@ snapshots:
'@eslint/config-helpers': 0.5.3
pathe: 2.0.3
eslint-json-compat-utils@0.2.2(eslint@10.0.3(jiti@1.21.7))(jsonc-eslint-parser@3.1.0):
eslint-json-compat-utils@0.2.3(eslint@10.0.3(jiti@1.21.7))(jsonc-eslint-parser@3.1.0):
dependencies:
eslint: 10.0.3(jiti@1.21.7)
esquery: 1.7.0
@ -12240,7 +12264,7 @@ snapshots:
dependencies:
eslint: 10.0.3(jiti@1.21.7)
eslint-plugin-jsdoc@62.7.1(eslint@10.0.3(jiti@1.21.7)):
eslint-plugin-jsdoc@62.8.0(eslint@10.0.3(jiti@1.21.7)):
dependencies:
'@es-joy/jsdoccomment': 0.84.0
'@es-joy/resolve.exports': 1.2.0
@ -12260,7 +12284,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
eslint-plugin-jsonc@3.1.1(eslint@10.0.3(jiti@1.21.7)):
eslint-plugin-jsonc@3.1.2(eslint@10.0.3(jiti@1.21.7)):
dependencies:
'@eslint-community/eslint-utils': 4.9.1(eslint@10.0.3(jiti@1.21.7))
'@eslint/core': 1.1.1
@ -12268,7 +12292,7 @@ snapshots:
'@ota-meshi/ast-token-store': 0.3.0
diff-sequences: 29.6.3
eslint: 10.0.3(jiti@1.21.7)
eslint-json-compat-utils: 0.2.2(eslint@10.0.3(jiti@1.21.7))(jsonc-eslint-parser@3.1.0)
eslint-json-compat-utils: 0.2.3(eslint@10.0.3(jiti@1.21.7))(jsonc-eslint-parser@3.1.0)
jsonc-eslint-parser: 3.1.0
natural-compare: 1.4.0
synckit: 0.11.12
@ -12718,7 +12742,7 @@ snapshots:
dependencies:
debug: 4.4.3
get-stream: 5.2.0
yauzl: 2.10.0
yauzl: 3.2.1
optionalDependencies:
'@types/yauzl': 2.10.3
transitivePeerDependencies:
@ -12766,10 +12790,6 @@ snapshots:
dependencies:
walk-up-path: 4.0.0
fd-slicer@1.1.0:
dependencies:
pend: 1.2.0
fdir@6.5.0(picomatch@4.0.3):
optionalDependencies:
picomatch: 4.0.3
@ -13293,8 +13313,8 @@ snapshots:
parse5: 8.0.0
saxes: 6.0.0
symbol-tree: 3.2.4
tough-cookie: 6.0.0
undici: 7.22.0
tough-cookie: 6.0.1
undici: 7.24.4
w3c-xmlserializer: 5.0.0
webidl-conversions: 8.0.1
whatwg-mimetype: 5.0.0
@ -13386,7 +13406,7 @@ snapshots:
launch-ide@1.4.3:
dependencies:
chalk: 4.1.2
chalk: 4.1.1
dotenv: 16.6.1
layout-base@1.0.2: {}
@ -13473,7 +13493,7 @@ snapshots:
listr2: 9.0.5
micromatch: 4.0.8
string-argv: 0.3.2
tinyexec: 1.0.2
tinyexec: 1.0.4
yaml: 2.8.2
listr2@9.0.5:
@ -13524,7 +13544,7 @@ snapshots:
fault: 1.0.4
highlight.js: 10.7.3
lru-cache@11.2.6: {}
lru-cache@11.2.7: {}
lru-cache@5.1.1:
dependencies:
@ -14182,8 +14202,8 @@ snapshots:
dependencies:
'@next/env': 16.1.6
'@swc/helpers': 0.5.15
baseline-browser-mapping: 2.10.0
caniuse-lite: 1.0.30001777
baseline-browser-mapping: 2.10.8
caniuse-lite: 1.0.30001779
postcss: 8.4.31
react: 19.2.4
react-dom: 19.2.4(react@19.2.4)
@ -14209,7 +14229,7 @@ snapshots:
json-stringify-safe: 5.0.1
propagate: 2.0.1
node-abi@3.88.0:
node-abi@3.89.0:
dependencies:
semver: 7.7.4
optional: true
@ -14438,7 +14458,7 @@ snapshots:
path-scurry@2.0.2:
dependencies:
lru-cache: 11.2.6
lru-cache: 11.2.7
minipass: 7.1.3
path2d@0.2.2:
@ -14580,7 +14600,7 @@ snapshots:
minimist: 1.2.8
mkdirp-classic: 0.5.3
napi-build-utils: 2.0.0
node-abi: 3.88.0
node-abi: 3.89.0
pump: 3.0.4
rc: 1.2.8
simple-get: 4.0.1
@ -14657,7 +14677,7 @@ snapshots:
dependencies:
typescript: 5.9.3
react-docgen@8.0.2:
react-docgen@8.0.3:
dependencies:
'@babel/core': 7.29.0
'@babel/traverse': 7.29.0
@ -15259,7 +15279,7 @@ snapshots:
spdx-license-ids@3.0.23: {}
srvx@0.11.9: {}
srvx@0.11.12: {}
std-env@4.0.0: {}
@ -15481,7 +15501,7 @@ snapshots:
pathe: 2.0.3
pnpm-workspace-yaml: 1.6.0
restore-cursor: 5.1.0
tinyexec: 1.0.2
tinyexec: 1.0.4
tinyglobby: 0.2.15
unconfig: 7.5.0
yaml: 2.8.2
@ -15520,7 +15540,7 @@ snapshots:
tinybench@2.9.0: {}
tinyexec@1.0.2: {}
tinyexec@1.0.4: {}
tinyglobby@0.2.15:
dependencies:
@ -15531,15 +15551,15 @@ snapshots:
tinyrainbow@2.0.0: {}
tinyrainbow@3.0.3: {}
tinyrainbow@3.1.0: {}
tinyspy@4.0.4: {}
tldts-core@7.0.25: {}
tldts-core@7.0.26: {}
tldts@7.0.25:
dependencies:
tldts-core: 7.0.25
tldts-core: 7.0.26
to-regex-range@5.0.1:
dependencies:
@ -15558,7 +15578,7 @@ snapshots:
totalist@3.0.1: {}
tough-cookie@6.0.0:
tough-cookie@6.0.1:
dependencies:
tldts: 7.0.25
@ -15655,7 +15675,7 @@ snapshots:
undici-types@7.18.2: {}
undici@7.22.0: {}
undici@7.24.4: {}
unicode-trie@2.0.0:
dependencies:
@ -15811,7 +15831,7 @@ snapshots:
dependencies:
'@unpic/react': 1.0.2(next@16.1.6(@babel/core@7.29.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@vercel/og': 0.8.6
'@vitejs/plugin-react': 5.1.4(@voidzero-dev/vite-plus-core@0.1.11(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2))
'@vitejs/plugin-react': 5.2.0(@voidzero-dev/vite-plus-core@0.1.11(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2))
magic-string: 0.30.21
react: 19.2.4
react-dom: 19.2.4(react@19.2.4)
@ -15866,7 +15886,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
vite-plugin-storybook-nextjs@3.2.2(@voidzero-dev/vite-plus-core@0.1.11(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2))(next@16.1.6(@babel/core@7.29.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0))(storybook@10.2.17(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3):
vite-plugin-storybook-nextjs@3.2.3(@voidzero-dev/vite-plus-core@0.1.11(@types/node@25.5.0)(esbuild@0.27.2)(jiti@1.21.7)(sass@1.98.0)(terser@5.46.0)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2))(next@16.1.6(@babel/core@7.29.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.98.0))(storybook@10.2.17(@testing-library/dom@10.4.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(typescript@5.9.3):
dependencies:
'@next/env': 16.0.0
image-size: 2.0.2
@ -16097,12 +16117,12 @@ snapshots:
yaml@2.8.2: {}
yauzl@2.10.0:
yauzl@3.2.1:
dependencies:
buffer-crc32: 0.2.13
fd-slicer: 1.1.0
pend: 1.2.0
yjs@13.6.29:
yjs@13.6.30:
dependencies:
lib0: 0.2.117