@underverse-ui/underverse 0.2.107 → 0.2.108

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -6935,6 +6935,14 @@ function WheelColumn({
6935
6935
  const wheelDeltaRef = React25.useRef(0);
6936
6936
  const scrollEndTimeoutRef = React25.useRef(null);
6937
6937
  const suppressScrollSelectUntilRef = React25.useRef(0);
6938
+ const suppressItemClickUntilRef = React25.useRef(0);
6939
+ const dragRef = React25.useRef(null);
6940
+ const draggingRef = React25.useRef(false);
6941
+ const inertialRef = React25.useRef(false);
6942
+ const inertiaRafRef = React25.useRef(null);
6943
+ const inertiaVelocityRef = React25.useRef(0);
6944
+ const inertiaLastTimeRef = React25.useRef(0);
6945
+ const moveSamplesRef = React25.useRef([]);
6938
6946
  const loop = true;
6939
6947
  const ui = React25.useMemo(() => {
6940
6948
  if (size === "sm") {
@@ -7005,6 +7013,10 @@ function WheelColumn({
7005
7013
  window.clearTimeout(scrollEndTimeoutRef.current);
7006
7014
  scrollEndTimeoutRef.current = null;
7007
7015
  }
7016
+ if (inertiaRafRef.current != null) {
7017
+ cancelAnimationFrame(inertiaRafRef.current);
7018
+ inertiaRafRef.current = null;
7019
+ }
7008
7020
  cancelAnimationFrame(rafRef.current);
7009
7021
  };
7010
7022
  }, [animate, baseOffset, extendedItems.length, getNearestVirtualIndex, itemHeight, loop, scrollRef, valueIndex]);
@@ -7102,6 +7114,138 @@ function WheelColumn({
7102
7114
  const from = lastVirtualIndexRef.current ?? fallback;
7103
7115
  return getNearestVirtualIndex(valueIndex, from);
7104
7116
  }, [baseOffset, getNearestVirtualIndex, items.length, loop, valueIndex]);
7117
+ const commitFromScrollTop = React25.useCallback(
7118
+ (behavior) => {
7119
+ const el = scrollRef.current;
7120
+ if (!el) return;
7121
+ if (items.length <= 0) return;
7122
+ const len = items.length;
7123
+ const maxVirtual = Math.max(0, extendedItems.length - 1);
7124
+ const idxVirtual = clamp3(Math.round(el.scrollTop / itemHeight), 0, maxVirtual);
7125
+ const realIndex = (idxVirtual % len + len) % len;
7126
+ const snappedVirtual = loop ? getNearestVirtualIndex(realIndex, idxVirtual) : realIndex;
7127
+ lastVirtualIndexRef.current = snappedVirtual;
7128
+ suppressScrollSelectUntilRef.current = Date.now() + 350;
7129
+ if (behavior === "auto") el.scrollTop = snappedVirtual * itemHeight;
7130
+ else el.scrollTo({ top: snappedVirtual * itemHeight, behavior });
7131
+ onSelect(items[realIndex]);
7132
+ if (loop) {
7133
+ const min = len;
7134
+ const max = len * 2 - 1;
7135
+ let centered = snappedVirtual;
7136
+ if (centered < min) centered += len;
7137
+ if (centered > max) centered -= len;
7138
+ if (centered !== snappedVirtual) {
7139
+ lastVirtualIndexRef.current = centered;
7140
+ el.scrollTop = centered * itemHeight;
7141
+ }
7142
+ }
7143
+ },
7144
+ [extendedItems.length, getNearestVirtualIndex, itemHeight, items, loop, onSelect, scrollRef]
7145
+ );
7146
+ const onPointerDown = (e) => {
7147
+ if (e.pointerType !== "mouse") return;
7148
+ if (e.button !== 0) return;
7149
+ const el = scrollRef.current;
7150
+ if (!el) return;
7151
+ e.preventDefault();
7152
+ setFocusedColumn(column);
7153
+ draggingRef.current = true;
7154
+ inertialRef.current = false;
7155
+ if (inertiaRafRef.current != null) {
7156
+ cancelAnimationFrame(inertiaRafRef.current);
7157
+ inertiaRafRef.current = null;
7158
+ }
7159
+ if (scrollEndTimeoutRef.current != null) {
7160
+ window.clearTimeout(scrollEndTimeoutRef.current);
7161
+ scrollEndTimeoutRef.current = null;
7162
+ }
7163
+ dragRef.current = { pointerId: e.pointerId, startY: e.clientY, startScrollTop: el.scrollTop, moved: false };
7164
+ moveSamplesRef.current = [{ t: performance.now(), top: el.scrollTop }];
7165
+ try {
7166
+ el.setPointerCapture(e.pointerId);
7167
+ } catch {
7168
+ }
7169
+ };
7170
+ const onPointerMove = (e) => {
7171
+ const el = scrollRef.current;
7172
+ const drag = dragRef.current;
7173
+ if (!el || !drag) return;
7174
+ if (e.pointerId !== drag.pointerId) return;
7175
+ e.preventDefault();
7176
+ const dy = e.clientY - drag.startY;
7177
+ if (!drag.moved && Math.abs(dy) < 4) return;
7178
+ if (!drag.moved) {
7179
+ drag.moved = true;
7180
+ suppressItemClickUntilRef.current = Date.now() + 400;
7181
+ }
7182
+ suppressScrollSelectUntilRef.current = Date.now() + 500;
7183
+ el.scrollTop = drag.startScrollTop - dy;
7184
+ const now = performance.now();
7185
+ const samples = moveSamplesRef.current;
7186
+ samples.push({ t: now, top: el.scrollTop });
7187
+ while (samples.length > 6 && samples[0] && now - samples[0].t > 120) samples.shift();
7188
+ while (samples.length > 8) samples.shift();
7189
+ if (samples.length >= 2) {
7190
+ const oldest = samples[0];
7191
+ const dt = now - oldest.t;
7192
+ if (dt > 0) inertiaVelocityRef.current = (el.scrollTop - oldest.top) / dt;
7193
+ }
7194
+ };
7195
+ const startInertia = React25.useCallback(() => {
7196
+ const el = scrollRef.current;
7197
+ if (!el) return;
7198
+ if (items.length <= 0) return;
7199
+ inertialRef.current = true;
7200
+ suppressItemClickUntilRef.current = Date.now() + 600;
7201
+ inertiaLastTimeRef.current = performance.now();
7202
+ const len = items.length;
7203
+ const cycle = len * itemHeight;
7204
+ const frictionPerFrame = 0.92;
7205
+ const tick = () => {
7206
+ const now = performance.now();
7207
+ const last = inertiaLastTimeRef.current || now;
7208
+ const dt = Math.min(48, Math.max(0, now - last));
7209
+ inertiaLastTimeRef.current = now;
7210
+ let v = inertiaVelocityRef.current;
7211
+ el.scrollTop += v * dt;
7212
+ if (loop && cycle > 0) {
7213
+ if (el.scrollTop < cycle * 0.5) el.scrollTop += cycle;
7214
+ else if (el.scrollTop > cycle * 2.5) el.scrollTop -= cycle;
7215
+ }
7216
+ const decay = Math.pow(frictionPerFrame, dt / 16);
7217
+ v *= decay;
7218
+ inertiaVelocityRef.current = v;
7219
+ if (Math.abs(v) < 0.03) {
7220
+ inertialRef.current = false;
7221
+ inertiaRafRef.current = null;
7222
+ commitFromScrollTop("smooth");
7223
+ return;
7224
+ }
7225
+ inertiaRafRef.current = requestAnimationFrame(tick);
7226
+ };
7227
+ inertiaRafRef.current = requestAnimationFrame(tick);
7228
+ }, [commitFromScrollTop, itemHeight, items.length, loop, scrollRef]);
7229
+ const endDrag = (pointerId) => {
7230
+ const el = scrollRef.current;
7231
+ const drag = dragRef.current;
7232
+ if (!el || !drag) return;
7233
+ if (pointerId !== drag.pointerId) return;
7234
+ dragRef.current = null;
7235
+ draggingRef.current = false;
7236
+ try {
7237
+ el.releasePointerCapture(pointerId);
7238
+ } catch {
7239
+ }
7240
+ const v = inertiaVelocityRef.current;
7241
+ const shouldFlick = drag.moved && Math.abs(v) >= 0.35;
7242
+ if (shouldFlick) {
7243
+ startInertia();
7244
+ } else {
7245
+ inertialRef.current = false;
7246
+ commitFromScrollTop("smooth");
7247
+ }
7248
+ };
7105
7249
  return /* @__PURE__ */ jsxs26("div", { className: cn("flex-1", ui.columnWidth), children: [
7106
7250
  /* @__PURE__ */ jsx31("div", { className: cn(ui.label, "font-bold uppercase tracking-wider text-muted-foreground/70 text-center"), children: labelText }),
7107
7251
  /* @__PURE__ */ jsxs26("div", { className: "relative rounded-xl bg-muted/30 overflow-hidden", style: { height }, children: [
@@ -7121,6 +7265,7 @@ function WheelColumn({
7121
7265
  className: cn(
7122
7266
  "h-full overflow-y-auto overscroll-contain snap-y snap-mandatory",
7123
7267
  "scrollbar-none",
7268
+ "select-none cursor-grab active:cursor-grabbing",
7124
7269
  "focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-2 focus-visible:ring-offset-background rounded-xl"
7125
7270
  ),
7126
7271
  style: { paddingTop: paddingY, paddingBottom: paddingY },
@@ -7129,7 +7274,15 @@ function WheelColumn({
7129
7274
  tabIndex: focused ? 0 : -1,
7130
7275
  onKeyDown: (e) => onKeyDown(e, column),
7131
7276
  onFocus: () => setFocusedColumn(column),
7132
- onScroll: handleScroll,
7277
+ onScroll: () => {
7278
+ if (draggingRef.current) return;
7279
+ if (inertialRef.current) return;
7280
+ handleScroll();
7281
+ },
7282
+ onPointerDown,
7283
+ onPointerMove,
7284
+ onPointerUp: (e) => endDrag(e.pointerId),
7285
+ onPointerCancel: (e) => endDrag(e.pointerId),
7133
7286
  children: /* @__PURE__ */ jsx31("div", { children: extendedItems.map((n, index) => {
7134
7287
  const dist = Math.abs(index - currentVirtual);
7135
7288
  const distForVisual = Math.min(dist, 2);
@@ -7154,6 +7307,7 @@ function WheelColumn({
7154
7307
  opacity
7155
7308
  },
7156
7309
  onClick: () => {
7310
+ if (Date.now() < suppressItemClickUntilRef.current) return;
7157
7311
  const el = scrollRef.current;
7158
7312
  if (!el) return;
7159
7313
  suppressScrollSelectUntilRef.current = Date.now() + 350;
@@ -11127,7 +11281,7 @@ RadioGroupItem.displayName = "RadioGroupItem";
11127
11281
 
11128
11282
  // ../../components/ui/Slider.tsx
11129
11283
  import * as React34 from "react";
11130
- import { jsx as jsx41, jsxs as jsxs36 } from "react/jsx-runtime";
11284
+ import { Fragment as Fragment14, jsx as jsx41, jsxs as jsxs36 } from "react/jsx-runtime";
11131
11285
  var SIZE_STYLES = {
11132
11286
  sm: {
11133
11287
  track: "h-1",
@@ -11145,16 +11299,22 @@ var SIZE_STYLES = {
11145
11299
  container: "py-3"
11146
11300
  }
11147
11301
  };
11302
+ var clamp5 = (n, min, max) => Math.min(max, Math.max(min, n));
11148
11303
  var Slider = React34.forwardRef(
11149
11304
  ({
11150
11305
  className,
11306
+ mode = "single",
11151
11307
  value,
11152
11308
  defaultValue = 0,
11309
+ rangeValue,
11310
+ defaultRangeValue,
11153
11311
  min = 0,
11154
11312
  max = 100,
11155
11313
  step = 1,
11156
11314
  onChange,
11157
11315
  onValueChange,
11316
+ onRangeChange,
11317
+ onRangeValueChange,
11158
11318
  onMouseUp,
11159
11319
  onTouchEnd,
11160
11320
  label,
@@ -11171,20 +11331,125 @@ var Slider = React34.forwardRef(
11171
11331
  noFocus = true,
11172
11332
  ...props
11173
11333
  }, ref) => {
11334
+ const isRange = mode === "range";
11335
+ const trackRef = React34.useRef(null);
11174
11336
  const [internalValue, setInternalValue] = React34.useState(defaultValue);
11337
+ const [internalRange, setInternalRange] = React34.useState(() => {
11338
+ if (defaultRangeValue) return defaultRangeValue;
11339
+ const v = clamp5(defaultValue, min, max);
11340
+ return [min, v];
11341
+ });
11342
+ const [activeThumb, setActiveThumb] = React34.useState(null);
11343
+ const dragRef = React34.useRef(null);
11175
11344
  const isControlled = value !== void 0;
11176
11345
  const currentValue = isControlled ? value : internalValue;
11177
- const handleChange = (e) => {
11178
- const newValue = Number(e.target.value);
11179
- if (!isControlled) {
11180
- setInternalValue(newValue);
11346
+ const isRangeControlled = rangeValue !== void 0;
11347
+ const currentRange = isRangeControlled ? rangeValue : internalRange;
11348
+ const rangeMin = clamp5(currentRange[0] ?? min, min, max);
11349
+ const rangeMax = clamp5(currentRange[1] ?? max, min, max);
11350
+ const normalizedRange = rangeMin <= rangeMax ? [rangeMin, rangeMax] : [rangeMax, rangeMin];
11351
+ const handleSingleChange = React34.useCallback(
11352
+ (e) => {
11353
+ const newValue = Number(e.target.value);
11354
+ if (!isControlled) {
11355
+ setInternalValue(newValue);
11356
+ }
11357
+ onChange?.(newValue);
11358
+ onValueChange?.(newValue);
11359
+ },
11360
+ [isControlled, onChange, onValueChange]
11361
+ );
11362
+ const emitRange = React34.useCallback(
11363
+ (next) => {
11364
+ onRangeChange?.(next);
11365
+ onRangeValueChange?.(next);
11366
+ },
11367
+ [onRangeChange, onRangeValueChange]
11368
+ );
11369
+ const handleRangeChange = React34.useCallback(
11370
+ (thumb) => (e) => {
11371
+ const nextVal = Number(e.target.value);
11372
+ const [curMin, curMax] = normalizedRange;
11373
+ const next = thumb === "min" ? [Math.min(nextVal, curMax), curMax] : [curMin, Math.max(nextVal, curMin)];
11374
+ if (!isRangeControlled) setInternalRange(next);
11375
+ emitRange(next);
11376
+ },
11377
+ [emitRange, isRangeControlled, normalizedRange]
11378
+ );
11379
+ const denom = Math.max(1e-9, max - min);
11380
+ const percentage = (currentValue - min) / denom * 100;
11381
+ const rangeStartPct = (normalizedRange[0] - min) / denom * 100;
11382
+ const rangeEndPct = (normalizedRange[1] - min) / denom * 100;
11383
+ const sizeStyles8 = SIZE_STYLES[size];
11384
+ const displayValue = React34.useMemo(() => {
11385
+ if (isRange) {
11386
+ const a = formatValue ? formatValue(normalizedRange[0]) : normalizedRange[0].toString();
11387
+ const b = formatValue ? formatValue(normalizedRange[1]) : normalizedRange[1].toString();
11388
+ return `${a} \u2013 ${b}`;
11389
+ }
11390
+ return formatValue ? formatValue(currentValue) : currentValue.toString();
11391
+ }, [currentValue, formatValue, isRange, normalizedRange]);
11392
+ const quantize = React34.useCallback(
11393
+ (v) => {
11394
+ const stepped = Math.round((v - min) / step) * step + min;
11395
+ const fixed = Number(stepped.toFixed(10));
11396
+ return clamp5(fixed, min, max);
11397
+ },
11398
+ [max, min, step]
11399
+ );
11400
+ const valueFromClientX = React34.useCallback(
11401
+ (clientX) => {
11402
+ const el = trackRef.current;
11403
+ if (!el) return min;
11404
+ const rect = el.getBoundingClientRect();
11405
+ const x = clamp5(clientX - rect.left, 0, rect.width);
11406
+ const ratio = rect.width <= 0 ? 0 : x / rect.width;
11407
+ return quantize(min + ratio * (max - min));
11408
+ },
11409
+ [max, min, quantize]
11410
+ );
11411
+ const startRangeDrag = (e) => {
11412
+ if (!isRange) return;
11413
+ if (disabled) return;
11414
+ if (orientation !== "horizontal") return;
11415
+ if (e.button !== 0) return;
11416
+ const nextValue = valueFromClientX(e.clientX);
11417
+ const [curMin, curMax] = normalizedRange;
11418
+ const distToMin = Math.abs(nextValue - curMin);
11419
+ const distToMax = Math.abs(nextValue - curMax);
11420
+ const thumb = distToMin <= distToMax ? "min" : "max";
11421
+ setActiveThumb(thumb);
11422
+ dragRef.current = { pointerId: e.pointerId, thumb };
11423
+ try {
11424
+ e.currentTarget.setPointerCapture(e.pointerId);
11425
+ } catch {
11426
+ }
11427
+ const next = thumb === "min" ? [Math.min(nextValue, curMax), curMax] : [curMin, Math.max(nextValue, curMin)];
11428
+ if (!isRangeControlled) setInternalRange(next);
11429
+ emitRange(next);
11430
+ };
11431
+ const moveRangeDrag = (e) => {
11432
+ const drag = dragRef.current;
11433
+ if (!drag) return;
11434
+ if (e.pointerId !== drag.pointerId) return;
11435
+ const nextValue = valueFromClientX(e.clientX);
11436
+ const [curMin, curMax] = normalizedRange;
11437
+ const next = drag.thumb === "min" ? [Math.min(nextValue, curMax), curMax] : [curMin, Math.max(nextValue, curMin)];
11438
+ if (!isRangeControlled) setInternalRange(next);
11439
+ emitRange(next);
11440
+ };
11441
+ const endRangeDrag = (e) => {
11442
+ const drag = dragRef.current;
11443
+ if (!drag) return;
11444
+ if (e.pointerId !== drag.pointerId) return;
11445
+ dragRef.current = null;
11446
+ onMouseUp?.();
11447
+ onTouchEnd?.();
11448
+ try {
11449
+ e.currentTarget.releasePointerCapture(e.pointerId);
11450
+ } catch {
11181
11451
  }
11182
- onChange?.(newValue);
11183
- onValueChange?.(newValue);
11184
11452
  };
11185
- const percentage = (currentValue - min) / (max - min) * 100;
11186
- const sizeStyles8 = SIZE_STYLES[size];
11187
- const displayValue = formatValue ? formatValue(currentValue) : currentValue.toString();
11188
11453
  if (orientation === "vertical") {
11189
11454
  }
11190
11455
  return /* @__PURE__ */ jsxs36("div", { className: cn("w-full space-y-2", containerClassName), children: [
@@ -11192,65 +11457,129 @@ var Slider = React34.forwardRef(
11192
11457
  label && /* @__PURE__ */ jsx41("label", { className: cn("text-sm font-medium text-foreground", labelClassName), children: label }),
11193
11458
  showValue && /* @__PURE__ */ jsx41("span", { className: cn("text-xs font-mono text-muted-foreground min-w-8 text-right", valueClassName), children: displayValue })
11194
11459
  ] }),
11195
- /* @__PURE__ */ jsxs36("div", { className: cn("relative flex items-center", sizeStyles8.container), children: [
11196
- /* @__PURE__ */ jsx41("div", { className: cn("w-full rounded-full bg-secondary relative overflow-hidden", sizeStyles8.track, trackClassName), children: /* @__PURE__ */ jsx41("div", { className: "absolute left-0 top-0 h-full bg-primary rounded-full", style: { width: `${percentage}%` } }) }),
11197
- /* @__PURE__ */ jsx41(
11198
- "input",
11460
+ /* @__PURE__ */ jsxs36("div", { ref: trackRef, className: cn("relative flex items-center", sizeStyles8.container), children: [
11461
+ /* @__PURE__ */ jsx41("div", { className: cn("w-full rounded-full bg-secondary relative overflow-hidden", sizeStyles8.track, trackClassName), children: isRange ? /* @__PURE__ */ jsx41(
11462
+ "div",
11199
11463
  {
11200
- ref,
11201
- type: "range",
11202
- min,
11203
- max,
11204
- step,
11205
- value: currentValue,
11206
- onChange: handleChange,
11207
- onMouseUp,
11208
- onTouchEnd,
11209
- disabled,
11210
- className: cn(
11211
- // Base styles
11212
- "absolute w-full h-full appearance-none bg-transparent cursor-pointer",
11213
- !noFocus && "focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 focus:ring-offset-background rounded-full",
11214
- noFocus && "outline-none ring-0 focus:outline-none focus:ring-0 focus-visible:outline-none",
11215
- // Webkit styles for thumb
11216
- "[&::-webkit-slider-thumb]:appearance-none",
11217
- "[&::-webkit-slider-thumb]:bg-primary",
11218
- "[&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-background",
11219
- "[&::-webkit-slider-thumb]:rounded-full",
11220
- "[&::-webkit-slider-thumb]:shadow-md",
11221
- "[&::-webkit-slider-thumb]:cursor-pointer",
11222
- "[&::-webkit-slider-thumb]:transition-all [&::-webkit-slider-thumb]:duration-150",
11223
- size === "sm" && "[&::-webkit-slider-thumb]:w-3 [&::-webkit-slider-thumb]:h-3",
11224
- size === "md" && "[&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:h-4",
11225
- size === "lg" && "[&::-webkit-slider-thumb]:w-5 [&::-webkit-slider-thumb]:h-5",
11226
- // Firefox styles for thumb
11227
- "[&::-moz-range-thumb]:bg-primary",
11228
- "[&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-background",
11229
- "[&::-moz-range-thumb]:rounded-full",
11230
- "[&::-moz-range-thumb]:shadow-md",
11231
- "[&::-moz-range-thumb]:cursor-pointer",
11232
- "[&::-moz-range-thumb]:transition-all [&::-moz-range-thumb]:duration-150",
11233
- size === "sm" && "[&::-moz-range-thumb]:w-3 [&::-moz-range-thumb]:h-3",
11234
- size === "md" && "[&::-moz-range-thumb]:w-4 [&::-moz-range-thumb]:h-4",
11235
- size === "lg" && "[&::-moz-range-thumb]:w-5 [&::-moz-range-thumb]:h-5",
11236
- // Remove default track in Firefox
11237
- "[&::-moz-range-track]:bg-transparent",
11238
- "[&::-moz-range-track]:border-transparent",
11239
- // Hover effects
11240
- "hover:[&::-webkit-slider-thumb]:scale-110 hover:[&::-webkit-slider-thumb]:shadow-lg",
11241
- "hover:[&::-moz-range-thumb]:scale-110 hover:[&::-moz-range-thumb]:shadow-lg",
11242
- // Disabled styles
11243
- disabled && [
11244
- "cursor-not-allowed opacity-50",
11245
- "[&::-webkit-slider-thumb]:cursor-not-allowed [&::-webkit-slider-thumb]:opacity-50",
11246
- "[&::-moz-range-thumb]:cursor-not-allowed [&::-moz-range-thumb]:opacity-50"
11247
- ],
11248
- className,
11249
- thumbClassName
11250
- ),
11251
- ...props
11464
+ className: "absolute top-0 h-full bg-primary rounded-full",
11465
+ style: { left: `${rangeStartPct}%`, width: `${Math.max(0, rangeEndPct - rangeStartPct)}%` }
11252
11466
  }
11253
- )
11467
+ ) : /* @__PURE__ */ jsx41("div", { className: "absolute left-0 top-0 h-full bg-primary rounded-full", style: { width: `${percentage}%` } }) }),
11468
+ (() => {
11469
+ const baseInputClassName = cn(
11470
+ // Base styles
11471
+ "absolute w-full h-full appearance-none bg-transparent cursor-pointer",
11472
+ !noFocus && "focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 focus:ring-offset-background rounded-full",
11473
+ noFocus && "outline-none ring-0 focus:outline-none focus:ring-0 focus-visible:outline-none",
11474
+ // Webkit styles for thumb
11475
+ "[&::-webkit-slider-thumb]:appearance-none",
11476
+ "[&::-webkit-slider-thumb]:bg-primary",
11477
+ "[&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-background",
11478
+ "[&::-webkit-slider-thumb]:rounded-full",
11479
+ "[&::-webkit-slider-thumb]:shadow-md",
11480
+ "[&::-webkit-slider-thumb]:cursor-pointer",
11481
+ "[&::-webkit-slider-thumb]:transition-all [&::-webkit-slider-thumb]:duration-150",
11482
+ size === "sm" && "[&::-webkit-slider-thumb]:w-3 [&::-webkit-slider-thumb]:h-3",
11483
+ size === "md" && "[&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:h-4",
11484
+ size === "lg" && "[&::-webkit-slider-thumb]:w-5 [&::-webkit-slider-thumb]:h-5",
11485
+ // Firefox styles for thumb
11486
+ "[&::-moz-range-thumb]:bg-primary",
11487
+ "[&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-background",
11488
+ "[&::-moz-range-thumb]:rounded-full",
11489
+ "[&::-moz-range-thumb]:shadow-md",
11490
+ "[&::-moz-range-thumb]:cursor-pointer",
11491
+ "[&::-moz-range-thumb]:transition-all [&::-moz-range-thumb]:duration-150",
11492
+ size === "sm" && "[&::-moz-range-thumb]:w-3 [&::-moz-range-thumb]:h-3",
11493
+ size === "md" && "[&::-moz-range-thumb]:w-4 [&::-moz-range-thumb]:h-4",
11494
+ size === "lg" && "[&::-moz-range-thumb]:w-5 [&::-moz-range-thumb]:h-5",
11495
+ // Remove default track in Firefox
11496
+ "[&::-moz-range-track]:bg-transparent",
11497
+ "[&::-moz-range-track]:border-transparent",
11498
+ // Hover effects
11499
+ "hover:[&::-webkit-slider-thumb]:scale-110 hover:[&::-webkit-slider-thumb]:shadow-lg",
11500
+ "hover:[&::-moz-range-thumb]:scale-110 hover:[&::-moz-range-thumb]:shadow-lg",
11501
+ // Disabled styles
11502
+ disabled && [
11503
+ "cursor-not-allowed opacity-50",
11504
+ "[&::-webkit-slider-thumb]:cursor-not-allowed [&::-webkit-slider-thumb]:opacity-50",
11505
+ "[&::-moz-range-thumb]:cursor-not-allowed [&::-moz-range-thumb]:opacity-50"
11506
+ ],
11507
+ className,
11508
+ thumbClassName
11509
+ );
11510
+ if (!isRange) {
11511
+ return /* @__PURE__ */ jsx41(
11512
+ "input",
11513
+ {
11514
+ ref,
11515
+ type: "range",
11516
+ min,
11517
+ max,
11518
+ step,
11519
+ value: currentValue,
11520
+ onChange: handleSingleChange,
11521
+ onMouseUp,
11522
+ onTouchEnd,
11523
+ disabled,
11524
+ className: baseInputClassName,
11525
+ ...props
11526
+ }
11527
+ );
11528
+ }
11529
+ const minZ = activeThumb === "min" ? "z-20" : "z-10";
11530
+ const maxZ = activeThumb === "max" ? "z-20" : "z-10";
11531
+ return /* @__PURE__ */ jsxs36(Fragment14, { children: [
11532
+ /* @__PURE__ */ jsx41(
11533
+ "div",
11534
+ {
11535
+ className: cn("absolute inset-0 z-30", disabled ? "cursor-not-allowed" : "cursor-pointer"),
11536
+ onPointerDown: startRangeDrag,
11537
+ onPointerMove: moveRangeDrag,
11538
+ onPointerUp: endRangeDrag,
11539
+ onPointerCancel: endRangeDrag
11540
+ }
11541
+ ),
11542
+ /* @__PURE__ */ jsx41(
11543
+ "input",
11544
+ {
11545
+ ref,
11546
+ type: "range",
11547
+ min,
11548
+ max,
11549
+ step,
11550
+ value: normalizedRange[0],
11551
+ onChange: handleRangeChange("min"),
11552
+ onMouseUp,
11553
+ onTouchEnd,
11554
+ disabled,
11555
+ "aria-label": "Minimum value",
11556
+ onPointerDown: () => setActiveThumb("min"),
11557
+ onFocus: () => setActiveThumb("min"),
11558
+ className: cn(baseInputClassName, minZ, "pointer-events-none"),
11559
+ ...props
11560
+ }
11561
+ ),
11562
+ /* @__PURE__ */ jsx41(
11563
+ "input",
11564
+ {
11565
+ type: "range",
11566
+ min,
11567
+ max,
11568
+ step,
11569
+ value: normalizedRange[1],
11570
+ onChange: handleRangeChange("max"),
11571
+ onMouseUp,
11572
+ onTouchEnd,
11573
+ disabled,
11574
+ "aria-label": "Maximum value",
11575
+ onPointerDown: () => setActiveThumb("max"),
11576
+ onFocus: () => setActiveThumb("max"),
11577
+ className: cn(baseInputClassName, maxZ, "pointer-events-none"),
11578
+ ...props
11579
+ }
11580
+ )
11581
+ ] });
11582
+ })()
11254
11583
  ] })
11255
11584
  ] });
11256
11585
  }
@@ -11260,7 +11589,7 @@ Slider.displayName = "Slider";
11260
11589
  // ../../components/ui/OverlayControls.tsx
11261
11590
  import { Dot as Dot2, Maximize2, Pause, Play, RotateCcw, RotateCw, Volume2, VolumeX } from "lucide-react";
11262
11591
  import React35 from "react";
11263
- import { Fragment as Fragment14, jsx as jsx42, jsxs as jsxs37 } from "react/jsx-runtime";
11592
+ import { Fragment as Fragment15, jsx as jsx42, jsxs as jsxs37 } from "react/jsx-runtime";
11264
11593
  function OverlayControls({
11265
11594
  mode,
11266
11595
  value,
@@ -11483,7 +11812,7 @@ function OverlayControls({
11483
11812
  const handleSliderMouseLeave = () => {
11484
11813
  setPreviewData(null);
11485
11814
  };
11486
- return /* @__PURE__ */ jsxs37(Fragment14, { children: [
11815
+ return /* @__PURE__ */ jsxs37(Fragment15, { children: [
11487
11816
  keyboardFeedback && /* @__PURE__ */ jsx42(
11488
11817
  "div",
11489
11818
  {
@@ -11693,7 +12022,7 @@ function OverlayControls({
11693
12022
  // ../../components/ui/CategoryTreeSelect.tsx
11694
12023
  import { useState as useState29, useEffect as useEffect19 } from "react";
11695
12024
  import { ChevronRight as ChevronRight6, ChevronDown as ChevronDown4, Check as Check6, FolderTree, Layers } from "lucide-react";
11696
- import { Fragment as Fragment15, jsx as jsx43, jsxs as jsxs38 } from "react/jsx-runtime";
12025
+ import { Fragment as Fragment16, jsx as jsx43, jsxs as jsxs38 } from "react/jsx-runtime";
11697
12026
  var defaultLabels = {
11698
12027
  emptyText: "No categories",
11699
12028
  selectedText: (count) => `${count} selected`
@@ -11930,7 +12259,7 @@ function CategoryTreeSelect(props) {
11930
12259
  ]
11931
12260
  }
11932
12261
  ),
11933
- isOpen && !disabled && /* @__PURE__ */ jsxs38(Fragment15, { children: [
12262
+ isOpen && !disabled && /* @__PURE__ */ jsxs38(Fragment16, { children: [
11934
12263
  /* @__PURE__ */ jsx43("div", { className: "fixed inset-0 z-10", onClick: () => setIsOpen(false) }),
11935
12264
  /* @__PURE__ */ jsx43(
11936
12265
  "div",
@@ -11950,7 +12279,7 @@ function CategoryTreeSelect(props) {
11950
12279
  }
11951
12280
 
11952
12281
  // ../../components/ui/ImageUpload.tsx
11953
- import { useState as useState30, useRef as useRef13, useCallback as useCallback10 } from "react";
12282
+ import { useState as useState30, useRef as useRef14, useCallback as useCallback11 } from "react";
11954
12283
  import { Upload, X as X12, Image as ImageIcon, Loader2 as Loader25, Check as Check7 } from "lucide-react";
11955
12284
  import { jsx as jsx44, jsxs as jsxs39 } from "react/jsx-runtime";
11956
12285
  function ImageUpload({
@@ -11971,7 +12300,7 @@ function ImageUpload({
11971
12300
  const [isDragging, setIsDragging] = useState30(false);
11972
12301
  const [uploading, setUploading] = useState30(false);
11973
12302
  const [uploadedImages, setUploadedImages] = useState30([]);
11974
- const fileInputRef = useRef13(null);
12303
+ const fileInputRef = useRef14(null);
11975
12304
  const { addToast } = useToast();
11976
12305
  const t = useTranslations("OCR.imageUpload");
11977
12306
  const previewSizes = {
@@ -11979,7 +12308,7 @@ function ImageUpload({
11979
12308
  md: "w-24 h-24",
11980
12309
  lg: "w-32 h-32"
11981
12310
  };
11982
- const handleDragOver = useCallback10(
12311
+ const handleDragOver = useCallback11(
11983
12312
  (e) => {
11984
12313
  e.preventDefault();
11985
12314
  if (!disabled) {
@@ -11988,11 +12317,11 @@ function ImageUpload({
11988
12317
  },
11989
12318
  [disabled]
11990
12319
  );
11991
- const handleDragLeave = useCallback10((e) => {
12320
+ const handleDragLeave = useCallback11((e) => {
11992
12321
  e.preventDefault();
11993
12322
  setIsDragging(false);
11994
12323
  }, []);
11995
- const handleFiles = useCallback10(
12324
+ const handleFiles = useCallback11(
11996
12325
  async (files) => {
11997
12326
  if (files.length === 0) return;
11998
12327
  const validFiles = files.filter((file) => {
@@ -12059,7 +12388,7 @@ function ImageUpload({
12059
12388
  },
12060
12389
  [maxSize, addToast, onUpload]
12061
12390
  );
12062
- const handleDrop = useCallback10(
12391
+ const handleDrop = useCallback11(
12063
12392
  (e) => {
12064
12393
  e.preventDefault();
12065
12394
  setIsDragging(false);
@@ -12069,7 +12398,7 @@ function ImageUpload({
12069
12398
  },
12070
12399
  [disabled, handleFiles]
12071
12400
  );
12072
- const handleFileSelect = useCallback10(
12401
+ const handleFileSelect = useCallback11(
12073
12402
  (e) => {
12074
12403
  const files = Array.from(e.target.files || []);
12075
12404
  handleFiles(files);
@@ -12174,7 +12503,7 @@ function ImageUpload({
12174
12503
  // ../../components/ui/Carousel.tsx
12175
12504
  import * as React37 from "react";
12176
12505
  import { ChevronLeft as ChevronLeft5, ChevronRight as ChevronRight7 } from "lucide-react";
12177
- import { Fragment as Fragment16, jsx as jsx45, jsxs as jsxs40 } from "react/jsx-runtime";
12506
+ import { Fragment as Fragment17, jsx as jsx45, jsxs as jsxs40 } from "react/jsx-runtime";
12178
12507
  function Carousel({
12179
12508
  children,
12180
12509
  autoScroll = true,
@@ -12386,7 +12715,7 @@ function Carousel({
12386
12715
  ))
12387
12716
  }
12388
12717
  ),
12389
- showArrows && totalSlides > slidesToShow && /* @__PURE__ */ jsxs40(Fragment16, { children: [
12718
+ showArrows && totalSlides > slidesToShow && /* @__PURE__ */ jsxs40(Fragment17, { children: [
12390
12719
  /* @__PURE__ */ jsx45(
12391
12720
  Button_default,
12392
12721
  {
@@ -12748,7 +13077,7 @@ function FallingIcons({
12748
13077
  // ../../components/ui/List.tsx
12749
13078
  import * as React39 from "react";
12750
13079
  import { ChevronRight as ChevronRight8 } from "lucide-react";
12751
- import { Fragment as Fragment17, jsx as jsx47, jsxs as jsxs42 } from "react/jsx-runtime";
13080
+ import { Fragment as Fragment18, jsx as jsx47, jsxs as jsxs42 } from "react/jsx-runtime";
12752
13081
  var SIZE_STYLES2 = {
12753
13082
  xs: { label: "text-xs", desc: "text-[11px]", icon: "h-3.5 w-3.5", avatar: "h-6 w-6" },
12754
13083
  sm: { label: "text-[13px]", desc: "text-[12px]", icon: "h-4 w-4", avatar: "h-8 w-8" },
@@ -12900,7 +13229,7 @@ var ListItem = React39.forwardRef(
12900
13229
  }
12901
13230
  }
12902
13231
  } : {};
12903
- const inner = /* @__PURE__ */ jsxs42(Fragment17, { children: [
13232
+ const inner = /* @__PURE__ */ jsxs42(Fragment18, { children: [
12904
13233
  /* @__PURE__ */ jsxs42("div", { className: cn("flex items-center gap-3", contentClassName, "group/item relative"), ...headerProps, children: [
12905
13234
  avatar && /* @__PURE__ */ jsx47("div", { className: cn("shrink-0", sz.avatar), children: typeof avatar === "string" ? /* @__PURE__ */ jsx47("img", { src: avatar, alt: "", className: cn("rounded-full object-cover", sz.avatar) }) : avatar }),
12906
13235
  Left && !avatar && /* @__PURE__ */ jsx47("span", { className: cn("text-muted-foreground shrink-0", sz.icon), children: /* @__PURE__ */ jsx47(Left, { className: cn(sz.icon) }) }),
@@ -12945,7 +13274,7 @@ var List_default = List;
12945
13274
  // ../../components/ui/Watermark.tsx
12946
13275
  import * as React40 from "react";
12947
13276
  import { createPortal as createPortal5 } from "react-dom";
12948
- import { Fragment as Fragment18, jsx as jsx48, jsxs as jsxs43 } from "react/jsx-runtime";
13277
+ import { Fragment as Fragment19, jsx as jsx48, jsxs as jsxs43 } from "react/jsx-runtime";
12949
13278
  var PRESETS2 = {
12950
13279
  confidential: { text: "CONFIDENTIAL", color: "rgba(220, 38, 38, 0.15)", rotate: -22, fontSize: 16, fontWeight: "bold" },
12951
13280
  draft: { text: "DRAFT", color: "rgba(59, 130, 246, 0.15)", rotate: -22, fontSize: 18, fontWeight: "bold" },
@@ -13224,7 +13553,7 @@ var Watermark = ({
13224
13553
  }
13225
13554
  );
13226
13555
  if (fullPage) {
13227
- return /* @__PURE__ */ jsxs43(Fragment18, { children: [
13556
+ return /* @__PURE__ */ jsxs43(Fragment19, { children: [
13228
13557
  children,
13229
13558
  typeof window !== "undefined" ? createPortal5(overlay, document.body) : null
13230
13559
  ] });
@@ -13516,7 +13845,7 @@ var Timeline_default = Timeline;
13516
13845
  import * as React42 from "react";
13517
13846
  import { Pipette, X as X13, Copy, Check as Check8, Palette, History } from "lucide-react";
13518
13847
  import { jsx as jsx50, jsxs as jsxs45 } from "react/jsx-runtime";
13519
- var clamp5 = (n, min, max) => Math.max(min, Math.min(max, n));
13848
+ var clamp6 = (n, min, max) => Math.max(min, Math.min(max, n));
13520
13849
  function hexToRgb(hex) {
13521
13850
  const str = hex.replace(/^#/, "").trim();
13522
13851
  if (str.length === 3) {
@@ -13534,7 +13863,7 @@ function hexToRgb(hex) {
13534
13863
  return null;
13535
13864
  }
13536
13865
  function rgbToHex(r, g, b) {
13537
- return `#${[r, g, b].map((v) => clamp5(Math.round(v), 0, 255).toString(16).padStart(2, "0")).join("")}`;
13866
+ return `#${[r, g, b].map((v) => clamp6(Math.round(v), 0, 255).toString(16).padStart(2, "0")).join("")}`;
13538
13867
  }
13539
13868
  function rgbToHsl(r, g, b) {
13540
13869
  r /= 255;
@@ -13595,10 +13924,10 @@ function parseAnyColor(input) {
13595
13924
  }
13596
13925
  const rgbaMatch = s.match(/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})(?:\s*,\s*(\d*\.?\d+))?\s*\)/i);
13597
13926
  if (rgbaMatch) {
13598
- const r = clamp5(parseInt(rgbaMatch[1], 10), 0, 255);
13599
- const g = clamp5(parseInt(rgbaMatch[2], 10), 0, 255);
13600
- const b = clamp5(parseInt(rgbaMatch[3], 10), 0, 255);
13601
- const a = rgbaMatch[4] != null ? clamp5(parseFloat(rgbaMatch[4]), 0, 1) : 1;
13927
+ const r = clamp6(parseInt(rgbaMatch[1], 10), 0, 255);
13928
+ const g = clamp6(parseInt(rgbaMatch[2], 10), 0, 255);
13929
+ const b = clamp6(parseInt(rgbaMatch[3], 10), 0, 255);
13930
+ const a = rgbaMatch[4] != null ? clamp6(parseFloat(rgbaMatch[4]), 0, 1) : 1;
13602
13931
  return { r, g, b, a };
13603
13932
  }
13604
13933
  const hslaMatch = s.match(/hsla?\(\s*(\d{1,3}(?:\.\d+)?)\s*,?\s*(\d{1,3}(?:\.\d+)?)%?\s*,?\s*(\d{1,3}(?:\.\d+)?)%?(?:\s*,?\s*(\d*\.?\d+))?\s*\)/i);
@@ -13606,7 +13935,7 @@ function parseAnyColor(input) {
13606
13935
  const h = parseFloat(hslaMatch[1]);
13607
13936
  const sl = parseFloat(hslaMatch[2]);
13608
13937
  const l = parseFloat(hslaMatch[3]);
13609
- const a = hslaMatch[4] != null ? clamp5(parseFloat(hslaMatch[4]), 0, 1) : 1;
13938
+ const a = hslaMatch[4] != null ? clamp6(parseFloat(hslaMatch[4]), 0, 1) : 1;
13610
13939
  const rgb = hslToRgb(h, sl, l);
13611
13940
  return { ...rgb, a };
13612
13941
  }
@@ -13619,12 +13948,12 @@ function formatOutput({ r, g, b, a }, withAlpha, format) {
13619
13948
  if (format === "hsl" || format === "hsla") {
13620
13949
  const hsl = rgbToHsl(r, g, b);
13621
13950
  if (format === "hsla" || withAlpha) {
13622
- return `hsla(${Math.round(hsl.h)}, ${Math.round(hsl.s)}%, ${Math.round(hsl.l)}%, ${clamp5(a, 0, 1)})`;
13951
+ return `hsla(${Math.round(hsl.h)}, ${Math.round(hsl.s)}%, ${Math.round(hsl.l)}%, ${clamp6(a, 0, 1)})`;
13623
13952
  }
13624
13953
  return `hsl(${Math.round(hsl.h)}, ${Math.round(hsl.s)}%, ${Math.round(hsl.l)}%)`;
13625
13954
  }
13626
13955
  if (withAlpha || a !== 1) {
13627
- return `rgba(${clamp5(r, 0, 255)}, ${clamp5(g, 0, 255)}, ${clamp5(b, 0, 255)}, ${clamp5(a, 0, 1)})`;
13956
+ return `rgba(${clamp6(r, 0, 255)}, ${clamp6(g, 0, 255)}, ${clamp6(b, 0, 255)}, ${clamp6(a, 0, 1)})`;
13628
13957
  }
13629
13958
  return rgbToHex(r, g, b);
13630
13959
  }
@@ -13758,7 +14087,7 @@ function ColorPicker({
13758
14087
  emit(next);
13759
14088
  };
13760
14089
  const setAlpha = (aPct) => {
13761
- const a = clamp5(aPct / 100, 0, 1);
14090
+ const a = clamp6(aPct / 100, 0, 1);
13762
14091
  const next = { ...rgba, a };
13763
14092
  setRgba(next);
13764
14093
  emit(next);
@@ -14036,7 +14365,7 @@ function ColorPicker({
14036
14365
 
14037
14366
  // ../../components/ui/Grid.tsx
14038
14367
  import React43, { useId as useId7 } from "react";
14039
- import { Fragment as Fragment19, jsx as jsx51, jsxs as jsxs46 } from "react/jsx-runtime";
14368
+ import { Fragment as Fragment20, jsx as jsx51, jsxs as jsxs46 } from "react/jsx-runtime";
14040
14369
  var BP_MIN = {
14041
14370
  sm: 640,
14042
14371
  md: 768,
@@ -14193,7 +14522,7 @@ var GridItem = React43.forwardRef(
14193
14522
  st.opacity = 0;
14194
14523
  st.animation = `uvGridItemFadeIn 0.5s ease-out forwards`;
14195
14524
  }
14196
- return /* @__PURE__ */ jsxs46(Fragment19, { children: [
14525
+ return /* @__PURE__ */ jsxs46(Fragment20, { children: [
14197
14526
  animationDelay != null && /* @__PURE__ */ jsx51(
14198
14527
  "style",
14199
14528
  {
@@ -14223,12 +14552,12 @@ var Grid = Object.assign(GridRoot, { Item: GridItem });
14223
14552
  var Grid_default = Grid;
14224
14553
 
14225
14554
  // ../../components/ui/LineChart.tsx
14226
- import { useMemo as useMemo13, useState as useState37, useRef as useRef15 } from "react";
14555
+ import { useMemo as useMemo14, useState as useState37, useRef as useRef16 } from "react";
14227
14556
 
14228
14557
  // ../../components/ui/ChartTooltip.tsx
14229
14558
  import { useEffect as useEffect23, useState as useState36 } from "react";
14230
14559
  import { createPortal as createPortal6 } from "react-dom";
14231
- import { Fragment as Fragment20, jsx as jsx52, jsxs as jsxs47 } from "react/jsx-runtime";
14560
+ import { Fragment as Fragment21, jsx as jsx52, jsxs as jsxs47 } from "react/jsx-runtime";
14232
14561
  function ChartTooltip({ x, y, visible, label, value, color, secondaryLabel, secondaryValue, items, containerRef }) {
14233
14562
  const [isMounted, setIsMounted] = useState36(false);
14234
14563
  const [position, setPosition] = useState36(null);
@@ -14275,7 +14604,7 @@ function ChartTooltip({ x, y, visible, label, value, color, secondaryLabel, seco
14275
14604
  ":"
14276
14605
  ] }),
14277
14606
  /* @__PURE__ */ jsx52("span", { className: "font-semibold ml-auto", children: item.value })
14278
- ] }, i)) }) : /* @__PURE__ */ jsxs47(Fragment20, { children: [
14607
+ ] }, i)) }) : /* @__PURE__ */ jsxs47(Fragment21, { children: [
14279
14608
  /* @__PURE__ */ jsxs47("div", { className: "flex items-center gap-2", children: [
14280
14609
  color && /* @__PURE__ */ jsx52("div", { className: "w-2 h-2 rounded-full shrink-0", style: { backgroundColor: color } }),
14281
14610
  /* @__PURE__ */ jsx52("span", { className: "font-semibold", children: value })
@@ -14302,7 +14631,7 @@ function ChartTooltip({ x, y, visible, label, value, color, secondaryLabel, seco
14302
14631
  }
14303
14632
 
14304
14633
  // ../../components/ui/LineChart.tsx
14305
- import { Fragment as Fragment21, jsx as jsx53, jsxs as jsxs48 } from "react/jsx-runtime";
14634
+ import { Fragment as Fragment22, jsx as jsx53, jsxs as jsxs48 } from "react/jsx-runtime";
14306
14635
  function LineChart({
14307
14636
  data,
14308
14637
  width = 400,
@@ -14317,12 +14646,12 @@ function LineChart({
14317
14646
  curved = true,
14318
14647
  className = ""
14319
14648
  }) {
14320
- const svgRef = useRef15(null);
14649
+ const svgRef = useRef16(null);
14321
14650
  const padding = { top: 20, right: 20, bottom: 40, left: 40 };
14322
14651
  const chartWidth = width - padding.left - padding.right;
14323
14652
  const chartHeight = height - padding.top - padding.bottom;
14324
14653
  const [hoveredPoint, setHoveredPoint] = useState37(null);
14325
- const { minValue, maxValue, points, linePath, areaPath } = useMemo13(() => {
14654
+ const { minValue, maxValue, points, linePath, areaPath } = useMemo14(() => {
14326
14655
  if (!data.length) return { minValue: 0, maxValue: 0, points: [], linePath: "", areaPath: "" };
14327
14656
  const values = data.map((d) => d.value);
14328
14657
  const min = Math.min(...values);
@@ -14357,7 +14686,7 @@ function LineChart({
14357
14686
  }
14358
14687
  return { minValue: min, maxValue: max, points: pts, linePath: path, areaPath: area };
14359
14688
  }, [data, chartWidth, chartHeight, curved, padding.left, padding.top]);
14360
- const gridLines = useMemo13(() => {
14689
+ const gridLines = useMemo14(() => {
14361
14690
  const lines = [];
14362
14691
  const steps = 5;
14363
14692
  for (let i = 0; i <= steps; i++) {
@@ -14367,7 +14696,7 @@ function LineChart({
14367
14696
  }
14368
14697
  return lines;
14369
14698
  }, [minValue, maxValue, chartHeight, padding.top]);
14370
- return /* @__PURE__ */ jsxs48(Fragment21, { children: [
14699
+ return /* @__PURE__ */ jsxs48(Fragment22, { children: [
14371
14700
  /* @__PURE__ */ jsxs48("svg", { ref: svgRef, width, height, className: `overflow-visible ${className}`, style: { fontFamily: "inherit" }, children: [
14372
14701
  showGrid && /* @__PURE__ */ jsx53("g", { className: "text-muted-foreground/20", children: gridLines.map((line, i) => /* @__PURE__ */ jsxs48("g", { children: [
14373
14702
  /* @__PURE__ */ jsx53("line", { x1: padding.left, y1: line.y, x2: width - padding.right, y2: line.y, stroke: "currentColor", strokeDasharray: "4 4" }),
@@ -14475,8 +14804,8 @@ function LineChart({
14475
14804
  }
14476
14805
 
14477
14806
  // ../../components/ui/BarChart.tsx
14478
- import { useMemo as useMemo14, useState as useState38, useRef as useRef16 } from "react";
14479
- import { Fragment as Fragment22, jsx as jsx54, jsxs as jsxs49 } from "react/jsx-runtime";
14807
+ import { useMemo as useMemo15, useState as useState38, useRef as useRef17 } from "react";
14808
+ import { Fragment as Fragment23, jsx as jsx54, jsxs as jsxs49 } from "react/jsx-runtime";
14480
14809
  function BarChart({
14481
14810
  data,
14482
14811
  width = 400,
@@ -14491,12 +14820,12 @@ function BarChart({
14491
14820
  barGap = 0.3,
14492
14821
  className = ""
14493
14822
  }) {
14494
- const svgRef = useRef16(null);
14823
+ const svgRef = useRef17(null);
14495
14824
  const padding = horizontal ? { top: 20, right: 40, bottom: 20, left: 80 } : { top: 20, right: 20, bottom: 40, left: 40 };
14496
14825
  const chartWidth = width - padding.left - padding.right;
14497
14826
  const chartHeight = height - padding.top - padding.bottom;
14498
14827
  const [hoveredBar, setHoveredBar] = useState38(null);
14499
- const { maxValue, bars, gridLines } = useMemo14(() => {
14828
+ const { maxValue, bars, gridLines } = useMemo15(() => {
14500
14829
  if (!data.length) return { maxValue: 0, bars: [], gridLines: [] };
14501
14830
  const max = Math.max(...data.map((d) => d.value));
14502
14831
  const barCount = data.length;
@@ -14545,12 +14874,12 @@ function BarChart({
14545
14874
  }
14546
14875
  return { maxValue: max, bars: barsData, gridLines: lines };
14547
14876
  }, [data, chartWidth, chartHeight, horizontal, barGap, padding, width, height]);
14548
- return /* @__PURE__ */ jsxs49(Fragment22, { children: [
14877
+ return /* @__PURE__ */ jsxs49(Fragment23, { children: [
14549
14878
  /* @__PURE__ */ jsxs49("svg", { ref: svgRef, width, height, className: `overflow-visible ${className}`, style: { fontFamily: "inherit" }, children: [
14550
- showGrid && /* @__PURE__ */ jsx54("g", { className: "text-muted-foreground/20", children: gridLines.map((line, i) => /* @__PURE__ */ jsx54("g", { children: horizontal ? /* @__PURE__ */ jsxs49(Fragment22, { children: [
14879
+ showGrid && /* @__PURE__ */ jsx54("g", { className: "text-muted-foreground/20", children: gridLines.map((line, i) => /* @__PURE__ */ jsx54("g", { children: horizontal ? /* @__PURE__ */ jsxs49(Fragment23, { children: [
14551
14880
  /* @__PURE__ */ jsx54("line", { x1: line.x, y1: line.y1, x2: line.x, y2: line.y2, stroke: "currentColor", strokeDasharray: "4 4" }),
14552
14881
  /* @__PURE__ */ jsx54("text", { x: line.x, y: height - 8, textAnchor: "middle", fontSize: "10", className: "text-muted-foreground", fill: "currentColor", children: line.value.toFixed(0) })
14553
- ] }) : /* @__PURE__ */ jsxs49(Fragment22, { children: [
14882
+ ] }) : /* @__PURE__ */ jsxs49(Fragment23, { children: [
14554
14883
  /* @__PURE__ */ jsx54("line", { x1: line.x1, y1: line.y, x2: line.x2, y2: line.y, stroke: "currentColor", strokeDasharray: "4 4" }),
14555
14884
  /* @__PURE__ */ jsx54("text", { x: padding.left - 8, y: line.y + 4, textAnchor: "end", fontSize: "10", className: "text-muted-foreground", fill: "currentColor", children: line.value.toFixed(0) })
14556
14885
  ] }) }, i)) }),
@@ -14657,7 +14986,7 @@ function BarChart({
14657
14986
  }
14658
14987
 
14659
14988
  // ../../components/ui/PieChart.tsx
14660
- import { useMemo as useMemo15, useState as useState39, useRef as useRef17 } from "react";
14989
+ import { useMemo as useMemo16, useState as useState39, useRef as useRef18 } from "react";
14661
14990
  import { jsx as jsx55, jsxs as jsxs50 } from "react/jsx-runtime";
14662
14991
  function PieChart({
14663
14992
  data,
@@ -14671,11 +15000,11 @@ function PieChart({
14671
15000
  startAngle = -90,
14672
15001
  className = ""
14673
15002
  }) {
14674
- const containerRef = useRef17(null);
15003
+ const containerRef = useRef18(null);
14675
15004
  const center = size / 2;
14676
15005
  const radius = size / 2 - 10;
14677
15006
  const innerRadius = donut ? radius - donutWidth : 0;
14678
- const { segments, total } = useMemo15(() => {
15007
+ const { segments, total } = useMemo16(() => {
14679
15008
  if (!data.length) return { segments: [], total: 0 };
14680
15009
  const sum = data.reduce((acc, d) => acc + d.value, 0);
14681
15010
  let currentAngle = startAngle;
@@ -14822,7 +15151,7 @@ function PieChart({
14822
15151
  }
14823
15152
 
14824
15153
  // ../../components/ui/AreaChart.tsx
14825
- import { useMemo as useMemo16, useState as useState40, useRef as useRef18 } from "react";
15154
+ import { useMemo as useMemo17, useState as useState40, useRef as useRef19 } from "react";
14826
15155
  import { jsx as jsx56, jsxs as jsxs51 } from "react/jsx-runtime";
14827
15156
  function getCatmullRomSpline(points) {
14828
15157
  if (points.length < 2) return "";
@@ -14857,12 +15186,12 @@ function AreaChart({
14857
15186
  curved = true,
14858
15187
  className = ""
14859
15188
  }) {
14860
- const containerRef = useRef18(null);
15189
+ const containerRef = useRef19(null);
14861
15190
  const padding = { top: 20, right: 20, bottom: 40, left: 50 };
14862
15191
  const chartWidth = width - padding.left - padding.right;
14863
15192
  const chartHeight = height - padding.top - padding.bottom;
14864
15193
  const [hoveredPoint, setHoveredPoint] = useState40(null);
14865
- const { processedSeries, gridLines, maxValue, labels } = useMemo16(() => {
15194
+ const { processedSeries, gridLines, maxValue, labels } = useMemo17(() => {
14866
15195
  if (!series.length || !series[0]?.data?.length) {
14867
15196
  return { processedSeries: [], gridLines: [], maxValue: 0, labels: [] };
14868
15197
  }
@@ -15076,7 +15405,7 @@ function AreaChart({
15076
15405
  }
15077
15406
 
15078
15407
  // ../../components/ui/Sparkline.tsx
15079
- import { useMemo as useMemo17 } from "react";
15408
+ import { useMemo as useMemo18 } from "react";
15080
15409
  import { jsx as jsx57, jsxs as jsxs52 } from "react/jsx-runtime";
15081
15410
  function getCatmullRomSpline2(points) {
15082
15411
  if (points.length < 2) return "";
@@ -15115,7 +15444,7 @@ function Sparkline({
15115
15444
  const padding = 4;
15116
15445
  const chartWidth = width - padding * 2;
15117
15446
  const chartHeight = height - padding * 2;
15118
- const { points, linePath, areaPath, lineLength, trend } = useMemo17(() => {
15447
+ const { points, linePath, areaPath, lineLength, trend } = useMemo18(() => {
15119
15448
  const normalizedData = data.map((d) => typeof d === "number" ? d : d.value);
15120
15449
  if (!normalizedData.length) {
15121
15450
  return { points: [], linePath: "", areaPath: "", lineLength: 0, trend: 0 };
@@ -15219,7 +15548,7 @@ function Sparkline({
15219
15548
  }
15220
15549
 
15221
15550
  // ../../components/ui/RadarChart.tsx
15222
- import { useMemo as useMemo18, useState as useState41, useRef as useRef19 } from "react";
15551
+ import { useMemo as useMemo19, useState as useState41, useRef as useRef20 } from "react";
15223
15552
  import { jsx as jsx58, jsxs as jsxs53 } from "react/jsx-runtime";
15224
15553
  function RadarChart({
15225
15554
  series,
@@ -15231,11 +15560,11 @@ function RadarChart({
15231
15560
  animated = true,
15232
15561
  className = ""
15233
15562
  }) {
15234
- const containerRef = useRef19(null);
15563
+ const containerRef = useRef20(null);
15235
15564
  const center = size / 2;
15236
15565
  const radius = size / 2 - 40;
15237
15566
  const [hoveredPoint, setHoveredPoint] = useState41(null);
15238
- const { axes, processedSeries, levelPaths } = useMemo18(() => {
15567
+ const { axes, processedSeries, levelPaths } = useMemo19(() => {
15239
15568
  if (!series.length || !series[0]?.data?.length) {
15240
15569
  return { axes: [], processedSeries: [], levelPaths: [] };
15241
15570
  }
@@ -15419,7 +15748,7 @@ function RadarChart({
15419
15748
  }
15420
15749
 
15421
15750
  // ../../components/ui/GaugeChart.tsx
15422
- import { useMemo as useMemo19 } from "react";
15751
+ import { useMemo as useMemo20 } from "react";
15423
15752
  import { jsx as jsx59, jsxs as jsxs54 } from "react/jsx-runtime";
15424
15753
  function GaugeChart({
15425
15754
  value,
@@ -15439,7 +15768,7 @@ function GaugeChart({
15439
15768
  }) {
15440
15769
  const center = size / 2;
15441
15770
  const radius = center - thickness / 2 - 10;
15442
- const { backgroundPath, valuePath, percentage, needleAngle } = useMemo19(() => {
15771
+ const { backgroundPath, valuePath, percentage, needleAngle } = useMemo20(() => {
15443
15772
  const normalizedValue = Math.min(Math.max(value, min), max);
15444
15773
  const pct = (normalizedValue - min) / (max - min);
15445
15774
  const totalAngle = endAngle - startAngle;
@@ -15588,16 +15917,16 @@ function GaugeChart({
15588
15917
 
15589
15918
  // ../../components/ui/ClientOnly.tsx
15590
15919
  import { useEffect as useEffect24, useState as useState42 } from "react";
15591
- import { Fragment as Fragment23, jsx as jsx60 } from "react/jsx-runtime";
15920
+ import { Fragment as Fragment24, jsx as jsx60 } from "react/jsx-runtime";
15592
15921
  function ClientOnly({ children, fallback = null }) {
15593
15922
  const [hasMounted, setHasMounted] = useState42(false);
15594
15923
  useEffect24(() => {
15595
15924
  setHasMounted(true);
15596
15925
  }, []);
15597
15926
  if (!hasMounted) {
15598
- return /* @__PURE__ */ jsx60(Fragment23, { children: fallback });
15927
+ return /* @__PURE__ */ jsx60(Fragment24, { children: fallback });
15599
15928
  }
15600
- return /* @__PURE__ */ jsx60(Fragment23, { children });
15929
+ return /* @__PURE__ */ jsx60(Fragment24, { children });
15601
15930
  }
15602
15931
 
15603
15932
  // ../../components/ui/Loading.tsx
@@ -16239,7 +16568,7 @@ function validateColumns(columns) {
16239
16568
  }
16240
16569
 
16241
16570
  // ../../components/ui/DataTable/DataTable.tsx
16242
- import { Fragment as Fragment24, jsx as jsx65, jsxs as jsxs59 } from "react/jsx-runtime";
16571
+ import { Fragment as Fragment25, jsx as jsx65, jsxs as jsxs59 } from "react/jsx-runtime";
16243
16572
  function DataTable({
16244
16573
  columns,
16245
16574
  data,
@@ -16477,17 +16806,17 @@ function DataTable({
16477
16806
  isCenterAlign && "justify-center",
16478
16807
  !isRightAlign && !isCenterAlign && "justify-start"
16479
16808
  ),
16480
- children: isRightAlign ? /* @__PURE__ */ jsxs59(Fragment24, { children: [
16809
+ children: isRightAlign ? /* @__PURE__ */ jsxs59(Fragment25, { children: [
16481
16810
  filterContent,
16482
16811
  titleContent
16483
- ] }) : /* @__PURE__ */ jsxs59(Fragment24, { children: [
16812
+ ] }) : /* @__PURE__ */ jsxs59(Fragment25, { children: [
16484
16813
  titleContent,
16485
16814
  filterContent
16486
16815
  ] })
16487
16816
  }
16488
16817
  );
16489
16818
  };
16490
- const renderHeader = /* @__PURE__ */ jsx65(Fragment24, { children: headerRows.map((row, rowIndex) => /* @__PURE__ */ jsx65(TableRow, { children: row.map((headerCell, cellIndex) => {
16819
+ const renderHeader = /* @__PURE__ */ jsx65(Fragment25, { children: headerRows.map((row, rowIndex) => /* @__PURE__ */ jsx65(TableRow, { children: row.map((headerCell, cellIndex) => {
16491
16820
  const { column: col, colSpan, rowSpan, isLeaf } = headerCell;
16492
16821
  const prevCell = cellIndex > 0 ? row[cellIndex - 1] : null;
16493
16822
  const prevCol = prevCell?.column;
@@ -16976,9 +17305,9 @@ function AccessDenied({
16976
17305
 
16977
17306
  // ../../components/ui/ThemeToggleHeadless.tsx
16978
17307
  import { Moon as Moon2, Sun as Sun2, Monitor } from "lucide-react";
16979
- import { useEffect as useEffect26, useRef as useRef20, useState as useState43 } from "react";
17308
+ import { useEffect as useEffect26, useRef as useRef21, useState as useState43 } from "react";
16980
17309
  import { createPortal as createPortal7 } from "react-dom";
16981
- import { Fragment as Fragment25, jsx as jsx70, jsxs as jsxs64 } from "react/jsx-runtime";
17310
+ import { Fragment as Fragment26, jsx as jsx70, jsxs as jsxs64 } from "react/jsx-runtime";
16982
17311
  function ThemeToggleHeadless({
16983
17312
  theme,
16984
17313
  onChange,
@@ -16987,7 +17316,7 @@ function ThemeToggleHeadless({
16987
17316
  }) {
16988
17317
  const [isOpen, setIsOpen] = useState43(false);
16989
17318
  const [mounted, setMounted] = useState43(false);
16990
- const triggerRef = useRef20(null);
17319
+ const triggerRef = useRef21(null);
16991
17320
  const [dropdownPosition, setDropdownPosition] = useState43(null);
16992
17321
  useEffect26(() => setMounted(true), []);
16993
17322
  const themes = [
@@ -17029,7 +17358,7 @@ function ThemeToggleHeadless({
17029
17358
  children: /* @__PURE__ */ jsx70(CurrentIcon, { className: "h-5 w-5" })
17030
17359
  }
17031
17360
  ),
17032
- isOpen && /* @__PURE__ */ jsxs64(Fragment25, { children: [
17361
+ isOpen && /* @__PURE__ */ jsxs64(Fragment26, { children: [
17033
17362
  typeof window !== "undefined" && createPortal7(/* @__PURE__ */ jsx70("div", { className: "fixed inset-0 z-9998", onClick: () => setIsOpen(false) }), document.body),
17034
17363
  typeof window !== "undefined" && dropdownPosition && createPortal7(
17035
17364
  /* @__PURE__ */ jsx70(
@@ -17078,10 +17407,10 @@ function ThemeToggleHeadless({
17078
17407
  }
17079
17408
 
17080
17409
  // ../../components/ui/LanguageSwitcherHeadless.tsx
17081
- import { useRef as useRef21, useState as useState44 } from "react";
17410
+ import { useRef as useRef22, useState as useState44 } from "react";
17082
17411
  import { createPortal as createPortal8 } from "react-dom";
17083
17412
  import { Globe } from "lucide-react";
17084
- import { Fragment as Fragment26, jsx as jsx71, jsxs as jsxs65 } from "react/jsx-runtime";
17413
+ import { Fragment as Fragment27, jsx as jsx71, jsxs as jsxs65 } from "react/jsx-runtime";
17085
17414
  function LanguageSwitcherHeadless({
17086
17415
  locales,
17087
17416
  currentLocale,
@@ -17091,7 +17420,7 @@ function LanguageSwitcherHeadless({
17091
17420
  }) {
17092
17421
  const [isOpen, setIsOpen] = useState44(false);
17093
17422
  const [dropdownPosition, setDropdownPosition] = useState44(null);
17094
- const triggerButtonRef = useRef21(null);
17423
+ const triggerButtonRef = useRef22(null);
17095
17424
  const currentLanguage = locales.find((l) => l.code === currentLocale) || locales[0];
17096
17425
  const calculatePosition = () => {
17097
17426
  const rect = triggerButtonRef.current?.getBoundingClientRect();
@@ -17126,7 +17455,7 @@ function LanguageSwitcherHeadless({
17126
17455
  children: /* @__PURE__ */ jsx71(Globe, { className: "h-5 w-5" })
17127
17456
  }
17128
17457
  ),
17129
- isOpen && /* @__PURE__ */ jsxs65(Fragment26, { children: [
17458
+ isOpen && /* @__PURE__ */ jsxs65(Fragment27, { children: [
17130
17459
  typeof window !== "undefined" && createPortal8(/* @__PURE__ */ jsx71("div", { className: "fixed inset-0 z-9998", onClick: () => setIsOpen(false) }), document.body),
17131
17460
  typeof window !== "undefined" && dropdownPosition && createPortal8(
17132
17461
  /* @__PURE__ */ jsx71(
@@ -18042,7 +18371,7 @@ function useSmartLocale() {
18042
18371
  }
18043
18372
 
18044
18373
  // ../../components/ui/UEditor/UEditor.tsx
18045
- import { useEffect as useEffect31, useMemo as useMemo22 } from "react";
18374
+ import { useEffect as useEffect31, useMemo as useMemo23 } from "react";
18046
18375
  import { useTranslations as useTranslations7 } from "next-intl";
18047
18376
  import { useEditor, EditorContent } from "@tiptap/react";
18048
18377
 
@@ -18085,7 +18414,7 @@ import { common, createLowlight } from "lowlight";
18085
18414
  import { Extension } from "@tiptap/core";
18086
18415
  import Suggestion from "@tiptap/suggestion";
18087
18416
  import { ReactRenderer } from "@tiptap/react";
18088
- import { forwardRef as forwardRef13, useEffect as useEffect27, useImperativeHandle, useRef as useRef22, useState as useState45 } from "react";
18417
+ import { forwardRef as forwardRef13, useEffect as useEffect27, useImperativeHandle, useRef as useRef23, useState as useState45 } from "react";
18089
18418
  import {
18090
18419
  FileCode,
18091
18420
  Heading1,
@@ -18103,7 +18432,7 @@ import tippy from "tippy.js";
18103
18432
  import { jsx as jsx74, jsxs as jsxs66 } from "react/jsx-runtime";
18104
18433
  var CommandList = forwardRef13((props, ref) => {
18105
18434
  const [selectedIndex, setSelectedIndex] = useState45(0);
18106
- const listRef = useRef22(null);
18435
+ const listRef = useRef23(null);
18107
18436
  useEffect27(() => {
18108
18437
  setSelectedIndex(0);
18109
18438
  }, [props.items]);
@@ -18416,7 +18745,7 @@ var ClipboardImages = Extension2.create({
18416
18745
  });
18417
18746
 
18418
18747
  // ../../components/ui/UEditor/resizable-image.tsx
18419
- import { useEffect as useEffect28, useRef as useRef23, useState as useState46 } from "react";
18748
+ import { useEffect as useEffect28, useRef as useRef24, useState as useState46 } from "react";
18420
18749
  import Image3 from "@tiptap/extension-image";
18421
18750
  import { mergeAttributes } from "@tiptap/core";
18422
18751
  import { NodeViewWrapper, ReactNodeViewRenderer } from "@tiptap/react";
@@ -18431,19 +18760,19 @@ function toNullableNumber(value) {
18431
18760
  }
18432
18761
  return null;
18433
18762
  }
18434
- function clamp6(value, min, max) {
18763
+ function clamp7(value, min, max) {
18435
18764
  return Math.min(max, Math.max(min, value));
18436
18765
  }
18437
18766
  function ResizableImageNodeView(props) {
18438
18767
  const { node, selected, updateAttributes, editor, getPos } = props;
18439
- const wrapperRef = useRef23(null);
18440
- const imgRef = useRef23(null);
18768
+ const wrapperRef = useRef24(null);
18769
+ const imgRef = useRef24(null);
18441
18770
  const [isHovered, setIsHovered] = useState46(false);
18442
18771
  const [isResizing, setIsResizing] = useState46(false);
18443
18772
  const widthAttr = toNullableNumber(node.attrs["width"]);
18444
18773
  const heightAttr = toNullableNumber(node.attrs["height"]);
18445
18774
  const textAlign = String(node.attrs["textAlign"] ?? "");
18446
- const dragStateRef = useRef23(null);
18775
+ const dragStateRef = useRef24(null);
18447
18776
  useEffect28(() => {
18448
18777
  const img = imgRef.current;
18449
18778
  if (!img) return;
@@ -18493,18 +18822,18 @@ function ResizableImageNodeView(props) {
18493
18822
  let nextH = drag.startH;
18494
18823
  if (event.ctrlKey) {
18495
18824
  if (Math.abs(dx) >= Math.abs(dy)) {
18496
- nextW = clamp6(drag.startW + dx, MIN_IMAGE_SIZE_PX, drag.maxW);
18497
- nextH = clamp6(nextW / drag.aspect, MIN_IMAGE_SIZE_PX, Number.POSITIVE_INFINITY);
18825
+ nextW = clamp7(drag.startW + dx, MIN_IMAGE_SIZE_PX, drag.maxW);
18826
+ nextH = clamp7(nextW / drag.aspect, MIN_IMAGE_SIZE_PX, Number.POSITIVE_INFINITY);
18498
18827
  } else {
18499
- nextH = clamp6(drag.startH + dy, MIN_IMAGE_SIZE_PX, Number.POSITIVE_INFINITY);
18500
- nextW = clamp6(nextH * drag.aspect, MIN_IMAGE_SIZE_PX, drag.maxW);
18828
+ nextH = clamp7(drag.startH + dy, MIN_IMAGE_SIZE_PX, Number.POSITIVE_INFINITY);
18829
+ nextW = clamp7(nextH * drag.aspect, MIN_IMAGE_SIZE_PX, drag.maxW);
18501
18830
  }
18502
18831
  } else {
18503
18832
  if (!drag.axis && (Math.abs(dx) > AXIS_LOCK_THRESHOLD_PX || Math.abs(dy) > AXIS_LOCK_THRESHOLD_PX)) {
18504
18833
  drag.axis = Math.abs(dx) >= Math.abs(dy) ? "x" : "y";
18505
18834
  }
18506
- if (drag.axis === "x") nextW = clamp6(drag.startW + dx, MIN_IMAGE_SIZE_PX, drag.maxW);
18507
- if (drag.axis === "y") nextH = clamp6(drag.startH + dy, MIN_IMAGE_SIZE_PX, Number.POSITIVE_INFINITY);
18835
+ if (drag.axis === "x") nextW = clamp7(drag.startW + dx, MIN_IMAGE_SIZE_PX, drag.maxW);
18836
+ if (drag.axis === "y") nextH = clamp7(drag.startH + dy, MIN_IMAGE_SIZE_PX, Number.POSITIVE_INFINITY);
18508
18837
  }
18509
18838
  drag.lastW = nextW;
18510
18839
  drag.lastH = nextH;
@@ -18736,7 +19065,7 @@ function buildUEditorExtensions({
18736
19065
  }
18737
19066
 
18738
19067
  // ../../components/ui/UEditor/toolbar.tsx
18739
- import React65, { useRef as useRef25, useState as useState48 } from "react";
19068
+ import React65, { useRef as useRef26, useState as useState48 } from "react";
18740
19069
  import { useTranslations as useTranslations4 } from "next-intl";
18741
19070
  import {
18742
19071
  AlignCenter,
@@ -18774,13 +19103,13 @@ import {
18774
19103
  } from "lucide-react";
18775
19104
 
18776
19105
  // ../../components/ui/UEditor/colors.tsx
18777
- import { useMemo as useMemo20 } from "react";
19106
+ import { useMemo as useMemo21 } from "react";
18778
19107
  import { useTranslations as useTranslations2 } from "next-intl";
18779
19108
  import { X as X14 } from "lucide-react";
18780
19109
  import { jsx as jsx76, jsxs as jsxs68 } from "react/jsx-runtime";
18781
19110
  var useEditorColors = () => {
18782
19111
  const t = useTranslations2("UEditor");
18783
- const textColors = useMemo20(
19112
+ const textColors = useMemo21(
18784
19113
  () => [
18785
19114
  { name: t("colors.default"), color: "inherit", cssClass: "text-foreground" },
18786
19115
  { name: t("colors.muted"), color: "var(--muted-foreground)", cssClass: "text-muted-foreground" },
@@ -18793,7 +19122,7 @@ var useEditorColors = () => {
18793
19122
  ],
18794
19123
  [t]
18795
19124
  );
18796
- const highlightColors = useMemo20(
19125
+ const highlightColors = useMemo21(
18797
19126
  () => [
18798
19127
  { name: t("colors.default"), color: "", cssClass: "" },
18799
19128
  { name: t("colors.muted"), color: "var(--muted)", cssClass: "bg-muted" },
@@ -18838,7 +19167,7 @@ var EditorColorPalette = ({
18838
19167
  ] });
18839
19168
 
18840
19169
  // ../../components/ui/UEditor/inputs.tsx
18841
- import { useEffect as useEffect29, useRef as useRef24, useState as useState47 } from "react";
19170
+ import { useEffect as useEffect29, useRef as useRef25, useState as useState47 } from "react";
18842
19171
  import { useTranslations as useTranslations3 } from "next-intl";
18843
19172
  import { Check as Check9, X as X15 } from "lucide-react";
18844
19173
  import { jsx as jsx77, jsxs as jsxs69 } from "react/jsx-runtime";
@@ -18856,7 +19185,7 @@ var LinkInput = ({
18856
19185
  }) => {
18857
19186
  const t = useTranslations3("UEditor");
18858
19187
  const [url, setUrl] = useState47(initialUrl);
18859
- const inputRef = useRef24(null);
19188
+ const inputRef = useRef25(null);
18860
19189
  useEffect29(() => {
18861
19190
  inputRef.current?.focus();
18862
19191
  inputRef.current?.select();
@@ -18886,7 +19215,7 @@ var ImageInput = ({ onSubmit, onCancel }) => {
18886
19215
  const t = useTranslations3("UEditor");
18887
19216
  const [url, setUrl] = useState47("");
18888
19217
  const [alt, setAlt] = useState47("");
18889
- const inputRef = useRef24(null);
19218
+ const inputRef = useRef25(null);
18890
19219
  useEffect29(() => {
18891
19220
  inputRef.current?.focus();
18892
19221
  }, []);
@@ -18940,7 +19269,7 @@ var ImageInput = ({ onSubmit, onCancel }) => {
18940
19269
  };
18941
19270
 
18942
19271
  // ../../components/ui/UEditor/toolbar.tsx
18943
- import { Fragment as Fragment27, jsx as jsx78, jsxs as jsxs70 } from "react/jsx-runtime";
19272
+ import { Fragment as Fragment28, jsx as jsx78, jsxs as jsxs70 } from "react/jsx-runtime";
18944
19273
  function fileToDataUrl2(file) {
18945
19274
  return new Promise((resolve, reject) => {
18946
19275
  const reader = new FileReader();
@@ -18988,7 +19317,7 @@ var EditorToolbar = ({
18988
19317
  const t = useTranslations4("UEditor");
18989
19318
  const { textColors, highlightColors } = useEditorColors();
18990
19319
  const [showImageInput, setShowImageInput] = useState48(false);
18991
- const fileInputRef = useRef25(null);
19320
+ const fileInputRef = useRef26(null);
18992
19321
  const [isUploadingImage, setIsUploadingImage] = useState48(false);
18993
19322
  const [imageUploadError, setImageUploadError] = useState48(null);
18994
19323
  const insertImageFiles = async (files) => {
@@ -19297,7 +19626,7 @@ var EditorToolbar = ({
19297
19626
  },
19298
19627
  onCancel: () => setShowImageInput(false)
19299
19628
  }
19300
- ) : /* @__PURE__ */ jsxs70(Fragment27, { children: [
19629
+ ) : /* @__PURE__ */ jsxs70(Fragment28, { children: [
19301
19630
  /* @__PURE__ */ jsx78(DropdownMenuItem, { icon: LinkIcon, label: t("imageInput.addFromUrl"), onClick: () => setShowImageInput(true) }),
19302
19631
  /* @__PURE__ */ jsx78(
19303
19632
  DropdownMenuItem,
@@ -19407,7 +19736,7 @@ var EditorToolbar = ({
19407
19736
  };
19408
19737
 
19409
19738
  // ../../components/ui/UEditor/menus.tsx
19410
- import { useCallback as useCallback13, useEffect as useEffect30, useMemo as useMemo21, useRef as useRef26, useState as useState49 } from "react";
19739
+ import { useCallback as useCallback14, useEffect as useEffect30, useMemo as useMemo22, useRef as useRef27, useState as useState49 } from "react";
19411
19740
  import { createPortal as createPortal9 } from "react-dom";
19412
19741
  import { useTranslations as useTranslations5 } from "next-intl";
19413
19742
  import {
@@ -19437,8 +19766,8 @@ import { jsx as jsx79, jsxs as jsxs71 } from "react/jsx-runtime";
19437
19766
  var SlashCommandMenu = ({ editor, onClose, filterText = "" }) => {
19438
19767
  const t = useTranslations5("UEditor");
19439
19768
  const [selectedIndex, setSelectedIndex] = useState49(0);
19440
- const menuRef = useRef26(null);
19441
- const allCommands = useMemo21(
19769
+ const menuRef = useRef27(null);
19770
+ const allCommands = useMemo22(
19442
19771
  () => [
19443
19772
  {
19444
19773
  icon: Type3,
@@ -19509,7 +19838,7 @@ var SlashCommandMenu = ({ editor, onClose, filterText = "" }) => {
19509
19838
  ],
19510
19839
  [editor, t]
19511
19840
  );
19512
- const commands = useMemo21(() => {
19841
+ const commands = useMemo22(() => {
19513
19842
  if (!filterText) return allCommands;
19514
19843
  const lowerFilter = filterText.toLowerCase();
19515
19844
  return allCommands.filter((cmd) => cmd.label.toLowerCase().includes(lowerFilter) || cmd.description.toLowerCase().includes(lowerFilter));
@@ -19521,7 +19850,7 @@ var SlashCommandMenu = ({ editor, onClose, filterText = "" }) => {
19521
19850
  const selectedElement = menuRef.current?.querySelector(`[data-index="${selectedIndex}"]`);
19522
19851
  selectedElement?.scrollIntoView({ block: "nearest" });
19523
19852
  }, [selectedIndex]);
19524
- const selectCommand = useCallback13(
19853
+ const selectCommand = useCallback14(
19525
19854
  (index) => {
19526
19855
  const command = commands[index];
19527
19856
  if (command) {
@@ -19744,9 +20073,9 @@ var BubbleMenuContent = ({
19744
20073
  var CustomBubbleMenu = ({ editor }) => {
19745
20074
  const [isVisible, setIsVisible] = useState49(false);
19746
20075
  const [position, setPosition] = useState49({ top: 0, left: 0 });
19747
- const menuRef = useRef26(null);
19748
- const keepOpenRef = useRef26(false);
19749
- const setKeepOpen = useCallback13((next) => {
20076
+ const menuRef = useRef27(null);
20077
+ const keepOpenRef = useRef27(false);
20078
+ const setKeepOpen = useCallback14((next) => {
19750
20079
  keepOpenRef.current = next;
19751
20080
  if (next) setIsVisible(true);
19752
20081
  }, []);
@@ -19901,7 +20230,7 @@ var UEditor = ({
19901
20230
  }) => {
19902
20231
  const t = useTranslations7("UEditor");
19903
20232
  const effectivePlaceholder = placeholder ?? t("placeholder");
19904
- const extensions = useMemo22(
20233
+ const extensions = useMemo23(
19905
20234
  () => buildUEditorExtensions({ placeholder: effectivePlaceholder, maxCharacters, uploadImage, imageInsertMode, editable }),
19906
20235
  [effectivePlaceholder, maxCharacters, uploadImage, imageInsertMode, editable]
19907
20236
  );