{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "gpuix-motion",
  "type": "registry:lib",
  "title": "Runtime: motion",
  "description": "The `@gpuixui/motion` modules the component items import. Installed automatically with the component; not a component itself.",
  "author": "Cyberistic <https://github.com/Cyberistic>",
  "dependencies": [
    "@gpuix/native@0.11.0",
    "@gpuix/react@0.11.0",
    "react@^19.2.4"
  ],
  "files": [
    {
      "path": "packages/motion/src/duration.ts",
      "target": "@ui/gpuixui/motion/duration.ts",
      "type": "registry:lib",
      "content": "const SCHEDULABLE_SECONDS = Number.MAX_SAFE_INTEGER;\n\nexport const schedulableSeconds = (\n  value: number | null | undefined,\n): number | undefined =>\n  value !== null &&\n  value !== undefined &&\n  Number.isFinite(value) &&\n  value > 0 &&\n  value <= SCHEDULABLE_SECONDS\n    ? value\n    : undefined;\n"
    },
    {
      "path": "packages/motion/src/easing.ts",
      "target": "@ui/gpuixui/motion/easing.ts",
      "type": "registry:lib",
      "content": "import { clamp01 } from \"./progress.js\";\nimport { isMotionEasingName, type MotionEasingName } from \"./timing.js\";\n\nexport type Easing = (t: number) => number;\n\nexport const bezier = (\n  x1: number,\n  y1: number,\n  x2: number,\n  y2: number,\n): Easing => {\n  if (![x1, y1, x2, y2].every(Number.isFinite)) return linear;\n  const cx1 = clamp01(x1);\n  const cx2 = clamp01(x2);\n  const x = (u: number) =>\n    3 * (1 - u) * (1 - u) * u * cx1 + 3 * (1 - u) * u * u * cx2 + u * u * u;\n  const y = (u: number) =>\n    3 * (1 - u) * (1 - u) * u * y1 + 3 * (1 - u) * u * u * y2 + u * u * u;\n  return (t) => {\n    const target = clamp01(t);\n    let low = 0;\n    let high = 1;\n    let u = target;\n    for (let i = 0; i < 32; i += 1) {\n      const actual = x(u);\n      if (Math.abs(actual - target) < 1e-9) break;\n      if (actual < target) low = u;\n      else high = u;\n      u = (low + high) / 2;\n    }\n    return y(u);\n  };\n};\n\nconst namedCurves: Readonly<Record<MotionEasingName, Easing>> = {\n  linear: (t) => clamp01(t),\n  ease: bezier(0.25, 0.1, 0.25, 1),\n  easeIn: bezier(0.42, 0, 1, 1),\n  easeOut: bezier(0, 0, 0.58, 1),\n  easeInOut: bezier(0.42, 0, 0.58, 1),\n};\n\nexport const linear: Easing = namedCurves.linear;\n\nexport const ease: Easing = namedCurves.ease;\n\nexport const easeIn: Easing = namedCurves.easeIn;\n\nexport const easeOut: Easing = namedCurves.easeOut;\n\nexport const easeInOut: Easing = namedCurves.easeInOut;\n\nexport const motionCurve = (name: unknown): Easing =>\n  isMotionEasingName(name) ? namedCurves[name] : linear;\n\nexport const circIn: Easing = (t) => {\n  const u = clamp01(t);\n  return 1 - Math.sqrt(Math.max(1 - u * u, 0));\n};\n\nexport const circOut: Easing = (t) => {\n  const u = clamp01(t);\n  return Math.sqrt(Math.max(1 - (u - 1) * (u - 1), 0));\n};\n\nexport const circInOut: Easing = (t) =>\n  clamp01(t) < 0.5\n    ? circIn(clamp01(t) * 2) / 2\n    : 0.5 + circOut(clamp01(t) * 2 - 1) / 2;\n\nexport const backOut: Easing = (t) => {\n  const u = clamp01(t) - 1;\n  return 1 + 2.70158 * u * u * u + 1.70158 * u * u;\n};\n\nexport const backIn: Easing = (t) => 1 - backOut(1 - clamp01(t));\n\nexport const backInOut: Easing = (t) =>\n  clamp01(t) < 0.5\n    ? backIn(clamp01(t) * 2) / 2\n    : 0.5 + backOut(clamp01(t) * 2 - 1) / 2;\n\nexport const anticipate: Easing = (t) => {\n  const u = clamp01(t);\n  if (u < 0.5) return backIn(u * 2) / 2;\n  if (u === 1) return 1;\n  return 1 - 0.5 * 2 ** (-20 * (u - 0.5));\n};\n"
    },
    {
      "path": "packages/motion/src/hook-read.ts",
      "target": "@ui/gpuixui/motion/hook-read.ts",
      "type": "registry:lib",
      "content": "import type { Inertia } from \"./inertia.js\";\nimport { sameInertia } from \"./inertia-read.js\";\nimport { easeOut, type Easing } from \"./easing.js\";\nimport { isCurve } from \"./progress.js\";\nimport {\n  DEFAULT_TWEEN_MS,\n  transitionEquals,\n  type MotionFrame,\n  type Transition,\n} from \"./motion.js\";\n\nexport const retainTransition = (\n  previous: Transition,\n  next: Transition,\n): Transition => (transitionEquals(previous, next) ? previous : next);\n\nexport interface CoastDeclaration {\n  readonly inertia: Inertia;\n  readonly velocity: number;\n}\n\nexport interface TweenSpec {\n  readonly durationMs?: number | null;\n\n  readonly easing?: unknown;\n}\n\nexport const tweenSpecOf = (\n  spec: TweenSpec | null | undefined,\n): { readonly durationMs: number; readonly easing: Easing } => {\n  const easing = spec?.easing;\n  return {\n    durationMs: spec?.durationMs ?? DEFAULT_TWEEN_MS,\n    easing: isCurve(easing) ? easing : easeOut,\n  };\n};\n\nconst releaseOf = (velocity: number): number =>\n  Number.isFinite(velocity) ? velocity : 0;\n\nexport const sameCoast = (\n  left: CoastDeclaration,\n  right: CoastDeclaration,\n): boolean =>\n  releaseOf(left.velocity) === releaseOf(right.velocity) &&\n  sameInertia(left.inertia, right.inertia);\n\nexport const retainCoast = (\n  previous: CoastDeclaration,\n  next: CoastDeclaration,\n): CoastDeclaration => (sameCoast(previous, next) ? previous : next);\n\nexport const sameFrame = (left: MotionFrame, right: MotionFrame): boolean =>\n  left.value === right.value &&\n  left.velocity === right.velocity &&\n  left.complete === right.complete;\n"
    },
    {
      "path": "packages/motion/src/inertia-read.ts",
      "target": "@ui/gpuixui/motion/inertia-read.ts",
      "type": "registry:lib",
      "content": "import { schedulableSeconds } from \"./duration.js\";\nimport type { Inertia } from \"./inertia.js\";\n\nexport const DEFAULT_TAU_MS = 350;\n\nexport interface Bounds {\n  readonly min: number | null;\n  readonly max: number | null;\n}\n\nexport const tauOf = (tau: number | undefined): number =>\n  schedulableSeconds(tau) ?? DEFAULT_TAU_MS / 1000;\n\nexport const boundsOf = (min: number | null, max: number | null): Bounds => {\n  const low = min !== null && Number.isFinite(min) ? min : null;\n  const high = max !== null && Number.isFinite(max) ? max : null;\n  return low !== null && high !== null && low > high\n    ? { min: high, max: low }\n    : { min: low, max: high };\n};\n\nexport const inertiaOf = (fields: Inertia | null | undefined): Inertia => ({\n  tau: tauOf(fields?.tau),\n  ...boundsOf(fields?.min ?? null, fields?.max ?? null),\n});\n\nexport const sameInertia = (left: Inertia, right: Inertia): boolean => {\n  const a = inertiaOf(left);\n  const b = inertiaOf(right);\n  return a.tau === b.tau && a.min === b.min && a.max === b.max;\n};\n"
    },
    {
      "path": "packages/motion/src/inertia.ts",
      "target": "@ui/gpuixui/motion/inertia.ts",
      "type": "registry:lib",
      "content": "import { DEFAULT_TAU_MS, inertiaOf, type Bounds } from \"./inertia-read.js\";\n\nexport interface Inertia {\n  readonly tau: number;\n  readonly min: number | null;\n  readonly max: number | null;\n}\n\nexport interface InertiaSample {\n  readonly value: number;\n  readonly velocity: number;\n  readonly settled: boolean;\n}\n\nconst REST_SPEED = 0.001;\n\nconst clampTo = (value: number, { min, max }: Bounds): number => {\n  if (min !== null && value < min) return min;\n  if (max !== null && value > max) return max;\n  return value;\n};\n\nconst destinationOf = (\n  start: number,\n  speed: number,\n  tau: number,\n  limits: Bounds,\n): number => {\n  const rest = start + speed * tau;\n  if (Number.isFinite(rest)) return clampTo(rest, limits);\n  return (rest > 0 ? limits.max : limits.min) ?? clampTo(start, limits);\n};\n\nexport const inertia = (\n  tauMs = DEFAULT_TAU_MS,\n  bounds?: { readonly min?: number; readonly max?: number },\n): Inertia =>\n  inertiaOf({\n    tau: tauMs / 1000,\n    min: bounds?.min ?? null,\n    max: bounds?.max ?? null,\n  });\n\nconst finiteOr = (value: number, fallback: number): number =>\n  Number.isFinite(value) ? value : fallback;\n\nexport const project = (\n  inertia: Inertia,\n  position: number,\n  velocity: number,\n): number => {\n  const read = inertiaOf(inertia);\n  return destinationOf(\n    finiteOr(position, 0),\n    finiteOr(velocity, 0),\n    read.tau,\n    read,\n  );\n};\n\nexport const sampleInertia = (\n  inertia: Inertia,\n  from: number,\n  velocity: number,\n  elapsedMs: number,\n): InertiaSample => {\n  const t = (Number.isNaN(elapsedMs) ? 0 : Math.max(elapsedMs, 0)) / 1000;\n  const position = finiteOr(from, 0);\n  const speed = finiteOr(velocity, 0);\n  const read = inertiaOf(inertia);\n  const tau = read.tau;\n  const rest = position + speed * tau;\n  if (!Number.isFinite(rest)) {\n    return {\n      value: destinationOf(position, speed, tau, read),\n      velocity: 0,\n      settled: true,\n    };\n  }\n  const decay = Math.exp(-t / tau);\n  const value = clampTo(position + (rest - position) * (1 - decay), read);\n  const outVelocity = speed * decay;\n  const intoWall =\n    (read.min !== null && value <= read.min && outVelocity <= 0) ||\n    (read.max !== null && value >= read.max && outVelocity >= 0);\n  const settled = intoWall || Math.abs(outVelocity) <= REST_SPEED;\n  return { value, velocity: intoWall ? 0 : outVelocity, settled };\n};\n"
    },
    {
      "path": "packages/motion/src/motion.ts",
      "target": "@ui/gpuixui/motion/motion.ts",
      "type": "registry:lib",
      "content": "import { easeOut, type Easing } from \"./easing.js\";\nimport { sameInertia } from \"./inertia-read.js\";\nimport { sampleInertia, type Inertia, project } from \"./inertia.js\";\nimport { eased, mix } from \"./progress.js\";\nimport { sampleSpring, springPhysics, type SpringPhysics } from \"./spring.js\";\n\nexport type Transition =\n  | { readonly kind: \"instant\" }\n  | {\n      readonly kind: \"tween\";\n      readonly durationMs: number;\n      readonly easing: Easing;\n    }\n  | { readonly kind: \"spring\"; readonly physics: SpringPhysics };\n\nexport interface MotionFrame {\n  readonly value: number;\n  readonly velocity: number;\n  readonly active: boolean;\n\n  readonly complete: boolean;\n}\n\ntype Mode =\n  | { readonly kind: \"transition\"; readonly transition: Transition }\n  | { readonly kind: \"inertia\"; readonly inertia: Inertia };\n\nexport const DEFAULT_TWEEN_MS = 300;\n\nexport const instant: Transition = { kind: \"instant\" };\n\nconst runDurationMs = (durationMs: number): number =>\n  Number.isFinite(durationMs) && durationMs <= Number.MAX_SAFE_INTEGER\n    ? Math.max(durationMs, 0)\n    : DEFAULT_TWEEN_MS;\n\nexport const tween = (\n  durationMs = DEFAULT_TWEEN_MS,\n  easing: Easing = easeOut,\n): Transition => ({\n  kind: \"tween\",\n  durationMs: runDurationMs(durationMs),\n  easing,\n});\n\nexport const springTransition = (physics: SpringPhysics): Transition => ({\n  kind: \"spring\",\n  physics,\n});\n\nconst houseTransition: Transition = tween();\n\nconst isTransition = (value: unknown): value is Transition => {\n  if (typeof value !== \"object\" || value === null) return false;\n  if (!(\"kind\" in value)) return false;\n  return (\n    value.kind === \"instant\" ||\n    value.kind === \"tween\" ||\n    value.kind === \"spring\"\n  );\n};\n\nconst transitionOf = (declaration: Transition | null | undefined): Transition =>\n  isTransition(declaration) ? declaration : houseTransition;\n\nconst easingEquals = (left: Easing, right: Easing): boolean => left === right;\n\nconst physicsEquals = (left: SpringPhysics, right: SpringPhysics): boolean => {\n  const a = springPhysics(left);\n  const b = springPhysics(right);\n  return (\n    a.mass === b.mass &&\n    a.stiffness === b.stiffness &&\n    a.damping === b.damping &&\n    a.restDelta === b.restDelta &&\n    a.restSpeed === b.restSpeed\n  );\n};\n\nexport const transitionEquals = (\n  left: Transition,\n  right: Transition,\n): boolean => {\n  const a = transitionOf(left);\n  const b = transitionOf(right);\n  if (a.kind !== b.kind) return false;\n  if (a.kind === \"instant\") return true;\n  if (a.kind === \"tween\" && b.kind === \"tween\") {\n    return (\n      runDurationMs(a.durationMs) === runDurationMs(b.durationMs) &&\n      easingEquals(a.easing, b.easing)\n    );\n  }\n  return (\n    a.kind === \"spring\" &&\n    b.kind === \"spring\" &&\n    physicsEquals(a.physics, b.physics)\n  );\n};\n\nconst finite = (value: number, fallback: number): number =>\n  Number.isFinite(value) ? value : fallback;\n\nexport class MotionValue {\n  private value: number;\n  private velocity: number;\n  private from: number;\n  private initialVelocity: number;\n  private target: number;\n  private mode: Mode;\n  private startedMs: number;\n  private lastMs: number;\n  private active: boolean;\n  private completed: boolean;\n\n  constructor(initial: number) {\n    const value = finite(initial, 0);\n    this.value = value;\n    this.velocity = 0;\n    this.from = value;\n    this.initialVelocity = 0;\n    this.target = value;\n    this.mode = { kind: \"transition\", transition: instant };\n    this.startedMs = 0;\n    this.lastMs = 0;\n    this.active = false;\n    this.completed = false;\n  }\n\n  get current(): number {\n    return this.value;\n  }\n\n  get speed(): number {\n    return this.velocity;\n  }\n\n  set(value: number): void {\n    const safe = finite(value, this.value);\n    this.value = safe;\n    this.velocity = 0;\n    this.initialVelocity = 0;\n    this.from = safe;\n    this.target = safe;\n    this.mode = { kind: \"transition\", transition: instant };\n    this.active = false;\n    this.completed = false;\n  }\n\n  animate(target: number, transition: Transition = tween()): void {\n    const safeTarget = finite(target, this.target);\n    const declared = transitionOf(transition);\n    if (\n      this.mode.kind === \"transition\" &&\n      this.target === safeTarget &&\n      transitionEquals(this.mode.transition, declared)\n    ) {\n      return;\n    }\n    this.from = this.value;\n    this.initialVelocity = this.velocity;\n    this.target = safeTarget;\n    this.mode = { kind: \"transition\", transition: declared };\n    this.startedMs = this.lastMs;\n    this.active = this.from !== safeTarget || this.velocity !== 0;\n    this.completed = false;\n  }\n\n  coast(inertia: Inertia, velocity?: number): void {\n    const release = finite(velocity ?? this.velocity, 0);\n    if (\n      this.mode.kind === \"inertia\" &&\n      this.initialVelocity === release &&\n      sameInertia(this.mode.inertia, inertia)\n    ) {\n      return;\n    }\n    this.from = this.value;\n    this.initialVelocity = release;\n    this.target = project(inertia, this.value, this.initialVelocity);\n    this.mode = { kind: \"inertia\", inertia };\n    this.startedMs = this.lastMs;\n    this.active = this.from !== this.target || this.velocity !== 0;\n    this.completed = false;\n  }\n\n  sample(elapsedMs: number, reducedMotion = false): MotionFrame {\n    const now = Number.isFinite(elapsedMs)\n      ? Math.max(elapsedMs, this.lastMs)\n      : this.lastMs;\n    if (this.active && reducedMotion) {\n      this.finish();\n    } else if (this.active) {\n      this.advance(now);\n    }\n    this.lastMs = now;\n    const frame: MotionFrame = {\n      value: this.value,\n      velocity: this.velocity,\n      active: this.active,\n      complete: this.completed,\n    };\n    this.completed = false;\n    return frame;\n  }\n\n  private finish(): void {\n    this.value = this.target;\n    this.velocity = 0;\n    this.completed = true;\n    this.active = false;\n  }\n\n  private advance(now: number): void {\n    const t = (now - this.startedMs) / 1000;\n    if (this.mode.kind === \"inertia\") {\n      const sample = sampleInertia(\n        this.mode.inertia,\n        this.from,\n        this.initialVelocity,\n        t * 1000,\n      );\n      this.value = sample.value;\n      this.velocity = sample.velocity;\n      if (sample.settled) this.finish();\n      return;\n    }\n\n    const transition = this.mode.transition;\n    if (transition.kind === \"instant\") {\n      this.finish();\n      return;\n    }\n\n    if (transition.kind === \"tween\") {\n      const durationSec = runDurationMs(transition.durationMs) / 1000;\n      if (durationSec <= 0 || t >= durationSec) {\n        this.finish();\n        return;\n      }\n      const progress = eased(transition.easing, t / durationSec);\n      this.value = mix(this.from, this.target, progress);\n      this.velocity = finite((this.target - this.from) / durationSec, 0);\n      return;\n    }\n\n    const sample = sampleSpring(\n      transition.physics,\n      this.from,\n      this.target,\n      this.initialVelocity,\n      t * 1000,\n    );\n    this.value = sample.value;\n    this.velocity = sample.velocity;\n    if (sample.settled) this.finish();\n  }\n}\n"
    },
    {
      "path": "packages/motion/src/presence.ts",
      "target": "@ui/gpuixui/motion/presence.ts",
      "type": "registry:lib",
      "content": "import { schedulableSeconds } from \"./duration.js\";\nimport {\n  isMotionEasing,\n  motionTiming,\n  type MotionEasing,\n  type MotionLevel,\n} from \"./timing.js\";\n\nexport type PresenceSide = \"top\" | \"right\" | \"bottom\" | \"left\";\n\nexport interface PresenceFrame {\n  readonly opacity?: number;\n  readonly height?: number;\n  readonly top?: number;\n  readonly left?: number;\n}\n\nexport interface PresenceFrames {\n  readonly initial: PresenceFrame;\n  readonly animate: PresenceFrame;\n  readonly exit: PresenceFrame;\n}\n\nexport interface PresenceFrameInput {\n  readonly opacity?: number | null;\n  readonly height?: number | null;\n  readonly top?: number | null;\n  readonly left?: number | null;\n}\n\nexport interface PresenceFramesInput {\n  readonly initial?: PresenceFrameInput | null;\n  readonly animate?: PresenceFrameInput | null;\n  readonly exit?: PresenceFrameInput | null;\n}\n\nexport interface PresenceTransition {\n  readonly duration?: number;\n\n  readonly delay?: number;\n  readonly ease?: MotionEasing;\n}\n\nexport interface PresenceTransitionInput {\n  readonly duration?: number | null;\n  readonly delay?: number | null;\n\n  readonly ease?: unknown;\n}\n\nexport interface PresenceTiming {\n  readonly enter: PresenceTransition;\n  readonly exit: PresenceTransition;\n}\n\nexport interface PresenceTimingInput {\n  readonly enter?: PresenceTransitionInput | null;\n  readonly exit?: PresenceTransitionInput | null;\n}\n\nexport interface PresenceHitRule {\n  readonly pointerEvents?: \"auto\" | \"none\";\n}\n\nconst RENDERABLE_MAX = 3.402_823_466_385_288_6e38;\n\nconst readInset = (value: number | null | undefined): number | undefined =>\n  value !== null &&\n  value !== undefined &&\n  Number.isFinite(value) &&\n  Math.abs(value) <= RENDERABLE_MAX\n    ? value\n    : undefined;\n\nconst readOpacity = (value: number | null | undefined): number | undefined => {\n  const share = readInset(value);\n  return share !== undefined && share >= 0 && share <= 1 ? share : undefined;\n};\n\nconst readSize = (value: number | null | undefined): number | undefined => {\n  const size = readInset(value);\n  return size !== undefined && size >= 0 ? size : undefined;\n};\n\nconst travelOf = (offset: number): number => readInset(offset) ?? 0;\n\nconst axisOf = (axis: \"top\" | \"left\"): \"top\" | \"left\" =>\n  axis === \"left\" ? \"left\" : \"top\";\n\nexport const fadeFrom = (\n  axis: \"top\" | \"left\",\n  offset: number,\n): PresenceFrames => {\n  const travel = travelOf(offset);\n  return axisOf(axis) === \"top\"\n    ? {\n        initial: { opacity: 0, top: travel },\n        animate: { opacity: 1, top: 0 },\n        exit: { opacity: 0, top: travel },\n      }\n    : {\n        initial: { opacity: 0, left: travel },\n        animate: { opacity: 1, left: 0 },\n        exit: { opacity: 0, left: travel },\n      };\n};\n\nexport const fadeOnly: PresenceFrames = {\n  initial: { opacity: 0 },\n  animate: { opacity: 1 },\n  exit: { opacity: 0 },\n};\n\nconst sideOf = (side: PresenceSide): PresenceSide =>\n  side === \"top\" || side === \"right\" || side === \"left\" ? side : \"bottom\";\n\nexport const fadeFromSide = (\n  side: PresenceSide,\n  offset: number,\n): PresenceFrames => {\n  const named = sideOf(side);\n  return named === \"top\"\n    ? fadeFrom(\"top\", -offset)\n    : named === \"bottom\"\n      ? fadeFrom(\"top\", offset)\n      : named === \"left\"\n        ? fadeFrom(\"left\", -offset)\n        : fadeFrom(\"left\", offset);\n};\n\nexport const fadeFromAnchor = (\n  side: PresenceSide,\n  offset: number,\n): PresenceFrames => {\n  const named = sideOf(side);\n  return named === \"top\"\n    ? fadeFrom(\"top\", offset)\n    : named === \"bottom\"\n      ? fadeFrom(\"top\", -offset)\n      : named === \"left\"\n        ? fadeFrom(\"left\", offset)\n        : fadeFrom(\"left\", -offset);\n};\n\nconst frameOf = (\n  frame: PresenceFrameInput | null | undefined,\n): PresenceFrame => {\n  if (typeof frame !== \"object\" || frame === null) return {};\n  const opacity = readOpacity(frame.opacity);\n  const height = readSize(frame.height);\n  const top = readInset(frame.top);\n  const left = readInset(frame.left);\n  return {\n    ...(opacity === undefined ? {} : { opacity }),\n    ...(height === undefined ? {} : { height }),\n    ...(top === undefined ? {} : { top }),\n    ...(left === undefined ? {} : { left }),\n  };\n};\n\nconst framesOf = (\n  frames: PresenceFramesInput | null | undefined,\n): PresenceFrames => ({\n  initial: frameOf(frames?.initial),\n  animate: frameOf(frames?.animate),\n  exit: frameOf(frames?.exit),\n});\n\nconst transitionOf = (\n  transition: PresenceTransitionInput | null | undefined,\n): PresenceTransition => {\n  const duration = schedulableSeconds(transition?.duration);\n  if (duration === undefined) return { duration: 0 };\n  const delay = schedulableSeconds(transition?.delay);\n  const ease = transition?.ease;\n  return {\n    duration,\n    ...(delay === undefined ? {} : { delay }),\n    ...(ease === null || ease === undefined || !isMotionEasing(ease)\n      ? {}\n      : { ease }),\n  };\n};\n\nexport const presenceTimingOf = (\n  timing: PresenceTimingInput | null | undefined,\n): PresenceTiming => ({\n  enter: transitionOf(timing?.enter),\n  exit: transitionOf(timing?.exit),\n});\n\nexport const presenceTiming = (\n  level: MotionLevel,\n  preference: unknown = \"animated\",\n): PresenceTiming => ({\n  enter: motionTiming(level, { phase: \"enter\", preference }),\n  exit: motionTiming(level, { phase: \"exit\", preference }),\n});\n\nconst milliseconds = (seconds: number | null | undefined): number =>\n  (schedulableSeconds(seconds) ?? 0) * 1000;\n\nconst SCHEDULABLE_WINDOW_MS = 2_147_483_647;\n\nexport const transitionWindowMs = (\n  timing: PresenceTransition | null | undefined,\n): number => {\n  const total = Math.round(\n    milliseconds(timing?.duration) + milliseconds(timing?.delay),\n  );\n  return Number.isFinite(total) && total <= SCHEDULABLE_WINDOW_MS ? total : 0;\n};\n\nexport const exitWindowMs = (\n  timing: PresenceTimingInput | null | undefined,\n): number => transitionWindowMs(presenceTimingOf(timing).exit);\n\nconst waitSeconds = (delayMs: number): number | undefined =>\n  schedulableSeconds(delayMs / 1000);\n\nexport const delayedTiming = (\n  timing: PresenceTransition | null | undefined,\n  delayMs: number,\n): PresenceTransition => {\n  const wait = waitSeconds(delayMs);\n  return milliseconds(timing?.duration) === 0 || wait === undefined\n    ? (timing ?? {})\n    : { ...timing, delay: wait };\n};\n\nexport const presenceMotion = (\n  frames: PresenceFramesInput | null | undefined,\n  present: boolean,\n  timing: PresenceTimingInput | null | undefined,\n): {\n  readonly initial: PresenceFrame;\n  readonly animate: PresenceFrame;\n  readonly transition: PresenceTransition;\n} => {\n  const phases = presenceTimingOf(timing);\n  const read = framesOf(frames);\n  return {\n    initial: read.initial,\n    animate: present ? read.animate : read.exit,\n    transition: present ? phases.enter : phases.exit,\n  };\n};\n\nexport const presenceStyle = (\n  present: boolean,\n  rest: \"target\" | \"wrapper\" = \"target\",\n): PresenceHitRule =>\n  present && rest === \"wrapper\"\n    ? {}\n    : { pointerEvents: present ? \"auto\" : \"none\" };\n"
    },
    {
      "path": "packages/motion/src/progress.ts",
      "target": "@ui/gpuixui/motion/progress.ts",
      "type": "registry:lib",
      "content": "export const clamp01 = (value: number): number =>\n  Number.isNaN(value) ? 0 : value < 0 ? 0 : value > 1 ? 1 : value;\n\nexport const isCurve = (\n  value: unknown,\n): value is (progress: number) => number => typeof value === \"function\";\n\nexport const eased = (curve: unknown, progress: number): number => {\n  const unit = clamp01(progress);\n  if (!isCurve(curve)) return unit;\n  const value = curve(unit);\n  return Number.isFinite(value) ? value : unit;\n};\n\nexport const mix = (from: number, to: number, progress: number): number => {\n  const value = from * (1 - progress) + to * progress;\n  if (Number.isFinite(value)) return value;\n  return progress < 0.5 ? from : to;\n};\n"
    },
    {
      "path": "packages/motion/src/provider.ts",
      "target": "@ui/gpuixui/motion/provider.ts",
      "type": "registry:lib",
      "content": "import {\n  createContext,\n  createElement,\n  useContext,\n  type ReactNode,\n} from \"react\";\nimport { preferenceOf, type MotionPreference } from \"./timing.js\";\n\nconst MotionPreferenceContext = createContext<MotionPreference>(\"animated\");\n\nexport interface MotionProviderProps {\n  readonly preference?: unknown;\n  readonly children?: ReactNode;\n}\n\nexport const MotionProvider = ({ preference, children }: MotionProviderProps) =>\n  createElement(\n    MotionPreferenceContext.Provider,\n    { value: preferenceOf(preference) },\n    children,\n  );\n\nexport const useMotionPreference = (): MotionPreference =>\n  useContext(MotionPreferenceContext);\n"
    },
    {
      "path": "packages/motion/src/react.ts",
      "target": "@ui/gpuixui/motion/react.ts",
      "type": "registry:lib",
      "content": "import {\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n  type Dispatch,\n  type SetStateAction,\n} from \"react\";\nimport {\n  retainCoast,\n  retainTransition,\n  sameCoast,\n  sameFrame,\n  tweenSpecOf,\n  type CoastDeclaration,\n  type TweenSpec,\n} from \"./hook-read.js\";\nimport { project, type Inertia } from \"./inertia.js\";\nimport {\n  MotionValue,\n  springTransition,\n  tween,\n  type MotionFrame,\n  type Transition,\n} from \"./motion.js\";\nimport { useMotionPreference } from \"./provider.js\";\nimport { layoutSpring, type SpringPhysics } from \"./spring.js\";\nimport { reducedMotionOf } from \"./timing.js\";\n\nexport {\n  MotionProvider,\n  useMotionPreference,\n  useSurfacePresence,\n  useSurfaceTiming,\n  type MotionProviderProps,\n  type SurfacePresence,\n} from \"./react/presence.js\";\n\nexport interface MotionState {\n  readonly value: number;\n  readonly velocity: number;\n  readonly complete: boolean;\n}\n\nconst restingFrame = (value: number, complete: boolean): MotionState => ({\n  value,\n  velocity: 0,\n  complete,\n});\n\nexport interface MotionOptions {\n  readonly reducedMotion?: boolean;\n\n  readonly initial?: number;\n}\n\nexport type { TweenSpec } from \"./hook-read.js\";\n\nconst FRAME_MS = 16;\n\nconst initialFrame = (value: number): MotionFrame => ({\n  value,\n  velocity: 0,\n  active: false,\n  complete: false,\n});\n\nconst optionsOf = (options: MotionOptions | null | undefined): MotionOptions =>\n  options ?? {};\n\nconst useReducedMotion = (options: MotionOptions): boolean =>\n  reducedMotionOf(options.reducedMotion, useMotionPreference());\n\nconst publish = (\n  setFrame: Dispatch<SetStateAction<MotionFrame>>,\n  frame: MotionFrame,\n): void =>\n  setFrame((previous) => (sameFrame(previous, frame) ? previous : frame));\n\nconst settleBefore = (\n  motion: MotionValue,\n  origin: number,\n  reducedMotion: boolean,\n): MotionFrame => motion.sample(performance.now() - origin, reducedMotion);\n\nconst startValue = (target: number, initial: number | undefined): number => {\n  if (initial !== undefined && Number.isFinite(initial)) return initial;\n  return Number.isFinite(target) ? target : 0;\n};\n\nconst firstValue = (\n  target: number,\n  initial: number | undefined,\n  reducedMotion: boolean,\n): number => startValue(target, reducedMotion ? undefined : initial);\n\nconst skipsJourney = (\n  target: number,\n  initial: number | undefined,\n  reducedMotion: boolean,\n): boolean =>\n  reducedMotion &&\n  Number.isFinite(target) &&\n  initial !== undefined &&\n  Number.isFinite(initial) &&\n  initial !== startValue(target, undefined);\n\nconst restingValue = (named: number, current: number): number =>\n  Number.isFinite(named) ? named : current;\n\nconst coastRest = (declaration: CoastDeclaration, position: number): number =>\n  Number.isFinite(declaration.velocity)\n    ? project(declaration.inertia, position, declaration.velocity)\n    : position;\n\nexport const useMotion = (\n  target: number,\n  transition: Transition,\n  options: MotionOptions | null = {},\n): MotionState => {\n  const settings = optionsOf(options);\n  const reducedMotion = useReducedMotion(settings);\n  const [start] = useState(() =>\n    firstValue(target, settings.initial, reducedMotion),\n  );\n  const [motion] = useState(() => new MotionValue(start));\n  const [origin] = useState(() => performance.now());\n  const [frame, setFrame] = useState<MotionFrame>(() => {\n    const first = initialFrame(start);\n    return skipsJourney(target, settings.initial, reducedMotion)\n      ? { ...first, complete: true }\n      : first;\n  });\n\n  const skipped = useRef(skipsJourney(target, settings.initial, reducedMotion));\n\n  const declared = useRef(transition);\n  declared.current = retainTransition(declared.current, transition);\n  const running = declared.current;\n\n  const resting = restingValue(target, motion.current);\n\n  useEffect(() => {\n    if (skipped.current) {\n      skipped.current = false;\n      return;\n    }\n    if (reducedMotion) {\n      if (resting === motion.current) return;\n      motion.set(resting);\n      publish(setFrame, {\n        value: resting,\n        velocity: 0,\n        active: false,\n        complete: true,\n      });\n      return;\n    }\n    publish(setFrame, settleBefore(motion, origin, reducedMotion));\n    motion.animate(target, running);\n    let handle: ReturnType<typeof setTimeout> | undefined;\n    const tick = (): void => {\n      const next = motion.sample(performance.now() - origin, reducedMotion);\n      publish(setFrame, next);\n      if (next.active) handle = setTimeout(tick, FRAME_MS);\n    };\n    handle = setTimeout(tick, 0);\n    return () => {\n      if (handle !== undefined) clearTimeout(handle);\n    };\n  }, [motion, target, resting, running, origin, reducedMotion]);\n\n  return reducedMotion\n    ? restingFrame(\n        resting,\n\n        frame.complete || resting !== motion.current,\n      )\n    : {\n        value: frame.value,\n        velocity: frame.velocity,\n        complete: frame.complete,\n      };\n};\n\nexport const useSpring = (\n  target: number,\n  physics: SpringPhysics = layoutSpring,\n  options: MotionOptions | null = {},\n): MotionState => {\n  const transition = useMemo(() => springTransition(physics), [physics]);\n  return useMotion(target, transition, options);\n};\n\nexport const useTransition = (\n  target: number,\n  spec: TweenSpec | null = {},\n  options: MotionOptions | null = {},\n): MotionState => {\n  const { durationMs, easing } = tweenSpecOf(spec);\n  const transition = useMemo(\n    () => tween(durationMs, easing),\n    [durationMs, easing],\n  );\n  return useMotion(target, transition, options);\n};\n\nexport const useInertia = (\n  velocity: number,\n  inertia: Inertia,\n  options: MotionOptions | null = {},\n): MotionState => {\n  const settings = optionsOf(options);\n  const reducedMotion = useReducedMotion(settings);\n  const [offset] = useState(() => startValue(0, settings.initial));\n  const [rest] = useState(() => coastRest({ inertia, velocity }, offset));\n  const [motion] = useState(() => new MotionValue(offset));\n  const [start] = useState(() => performance.now());\n  const [frame, setFrame] = useState<MotionFrame>(() => {\n    if (reducedMotion && rest !== offset) {\n      return { ...initialFrame(rest), complete: true };\n    }\n    return initialFrame(reducedMotion ? rest : offset);\n  });\n\n  const skippingStart = useRef(reducedMotion);\n\n  const retired = useRef<CoastDeclaration | undefined>(undefined);\n\n  const declared = useRef<CoastDeclaration>({ inertia, velocity });\n  declared.current = retainCoast(declared.current, { inertia, velocity });\n  const running = declared.current;\n\n  const ended =\n    retired.current !== undefined && sameCoast(retired.current, running);\n\n  useEffect(() => {\n    if (reducedMotion) {\n      retired.current = running;\n\n      const destination = coastRest(running, motion.current);\n\n      if (ended) return;\n      if (destination === motion.current) return;\n      motion.set(destination);\n      skippingStart.current = false;\n      publish(setFrame, {\n        value: destination,\n        velocity: 0,\n        active: false,\n        complete: true,\n      });\n      return;\n    }\n    if (ended) {\n      publish(setFrame, settleBefore(motion, start, false));\n      return;\n    }\n    retired.current = undefined;\n    const sampled = settleBefore(motion, start, reducedMotion);\n    if (skippingStart.current && sampled.value === offset) {\n    } else {\n      skippingStart.current = false;\n      publish(setFrame, sampled);\n    }\n    motion.coast(running.inertia, running.velocity);\n    let handle: ReturnType<typeof setTimeout> | undefined;\n    const tick = (): void => {\n      const next = motion.sample(performance.now() - start, reducedMotion);\n      publish(setFrame, next);\n      if (next.active) handle = setTimeout(tick, FRAME_MS);\n    };\n    handle = setTimeout(tick, 0);\n    return () => {\n      if (handle !== undefined) clearTimeout(handle);\n    };\n  }, [motion, running, start, offset, reducedMotion]);\n\n  const resting = ended ? motion.current : coastRest(running, motion.current);\n  return reducedMotion\n    ? restingFrame(\n        resting,\n\n        frame.complete || resting !== motion.current,\n      )\n    : {\n        value: frame.value,\n        velocity: frame.velocity,\n        complete: frame.complete,\n      };\n};\n"
    },
    {
      "path": "packages/motion/src/react/presence.ts",
      "target": "@ui/gpuixui/motion/react/presence.ts",
      "type": "registry:lib",
      "content": "import { useEffect, useLayoutEffect, useState } from \"react\";\nimport {\n  exitWindowMs,\n  presenceTiming,\n  presenceTimingOf,\n  type PresenceTiming,\n  type PresenceTimingInput,\n} from \"../presence.js\";\nimport { useMotionPreference } from \"../provider.js\";\nimport type { MotionLevel } from \"../timing.js\";\n\nexport {\n  MotionProvider,\n  useMotionPreference,\n  type MotionProviderProps,\n} from \"../provider.js\";\n\nexport const useSurfaceTiming = (level: MotionLevel): PresenceTiming =>\n  presenceTiming(level, useMotionPreference());\n\nexport interface SurfacePresence {\n  readonly mounted: boolean;\n\n  readonly present: boolean;\n  readonly timing: PresenceTiming;\n}\n\nexport const useSurfacePresence = (\n  open: boolean,\n  timing: PresenceTimingInput | null | undefined,\n): SurfacePresence => {\n  const [mounted, setMounted] = useState(open);\n\n  const phases = presenceTimingOf(timing);\n  const windowMs = exitWindowMs(phases);\n\n  useLayoutEffect(() => {\n    if (open) setMounted(true);\n  }, [open]);\n\n  useEffect(() => {\n    if (open || !mounted) return;\n    if (windowMs === 0) {\n      setMounted(false);\n      return;\n    }\n    const handle = setTimeout(() => setMounted(false), windowMs);\n    return () => clearTimeout(handle);\n  }, [mounted, open, windowMs]);\n\n  return { mounted, present: open, timing: phases };\n};\n"
    },
    {
      "path": "packages/motion/src/spring.ts",
      "target": "@ui/gpuixui/motion/spring.ts",
      "type": "registry:lib",
      "content": "import { mix } from \"./progress.js\";\n\nexport interface SpringPhysics {\n  readonly mass: number;\n  readonly stiffness: number;\n  readonly damping: number;\n  readonly restDelta: number;\n  readonly restSpeed: number;\n}\n\nexport interface SpringSample {\n  readonly value: number;\n  readonly velocity: number;\n  readonly target: number;\n  readonly settled: boolean;\n}\n\nexport interface SpringPhysicsParams {\n  readonly mass?: number;\n  readonly stiffness?: number;\n  readonly damping?: number;\n  readonly restDelta?: number;\n  readonly restSpeed?: number;\n}\n\nconst DEFAULT_MASS = 1;\nconst DEFAULT_STIFFNESS = 260;\nconst DEFAULT_DAMPING = 28;\nconst DEFAULT_REST_DELTA = 0.001;\nconst DEFAULT_REST_SPEED = 0.01;\nconst MIN_POSITIVE = 1e-6;\nconst MAX_PHYSICS_VALUE = 1e6;\nconst EPSILON = 1.192_092_9e-7;\n\nconst sanitizeNumber = (value: number | undefined, fallback: number): number =>\n  value !== undefined && Number.isFinite(value) ? value : fallback;\n\nconst sanitizePositive = (\n  value: number | undefined,\n  fallback: number,\n): number =>\n  value !== undefined && Number.isFinite(value) && value > 0\n    ? Math.min(Math.max(value, MIN_POSITIVE), MAX_PHYSICS_VALUE)\n    : fallback;\n\nconst sanitizeNonNegative = (\n  value: number | undefined,\n  fallback: number,\n): number =>\n  value !== undefined && Number.isFinite(value) && value >= 0\n    ? Math.min(value, MAX_PHYSICS_VALUE)\n    : fallback;\n\nconst physicsOf = (\n  fields: SpringPhysicsParams | null | undefined,\n): SpringPhysics => ({\n  mass: sanitizePositive(fields?.mass, DEFAULT_MASS),\n  stiffness: sanitizePositive(fields?.stiffness, DEFAULT_STIFFNESS),\n  damping: sanitizeNonNegative(fields?.damping, DEFAULT_DAMPING),\n  restDelta: sanitizePositive(fields?.restDelta, DEFAULT_REST_DELTA),\n  restSpeed: sanitizePositive(fields?.restSpeed, DEFAULT_REST_SPEED),\n});\n\nexport const springPhysics = (\n  params: SpringPhysicsParams = {},\n): SpringPhysics => physicsOf(params);\n\nexport const affordanceSpring: SpringPhysics = springPhysics({\n  stiffness: 320,\n  damping: 34,\n});\n\nexport const layoutSpring: SpringPhysics = springPhysics({\n  stiffness: 260,\n  damping: 28,\n});\n\nexport const continuitySpring: SpringPhysics = springPhysics({\n  stiffness: 190,\n  damping: 23,\n});\n\nconst withinRest = (\n  rest: SpringPhysics,\n  value: number,\n  target: number,\n  velocity: number,\n): boolean =>\n  Math.abs(value - target) <= rest.restDelta &&\n  Math.abs(velocity) <= rest.restSpeed;\n\nexport const atRest = (\n  physics: SpringPhysics,\n  value: number,\n  target: number,\n  velocity: number,\n): boolean => withinRest(physicsOf(physics), value, target, velocity);\n\nexport const retarget = (\n  sample: SpringSample | null | undefined,\n  target: number,\n): SpringSample => {\n  const value = sanitizeNumber(sample?.value, 0);\n  return {\n    value,\n    velocity: sanitizeNumber(sample?.velocity, 0),\n    target: sanitizeNumber(target, value),\n    settled: false,\n  };\n};\n\nexport const sampleSpring = (\n  physics: SpringPhysics,\n  from: number,\n  target: number,\n  velocity: number,\n  elapsedMs: number,\n): SpringSample => {\n  const rest = physicsOf(physics);\n  const safeFrom = sanitizeNumber(from, 0);\n  const safeTarget = sanitizeNumber(target, safeFrom);\n  const safeVelocity = sanitizeNumber(velocity, 0);\n  const t = (Number.isNaN(elapsedMs) ? 0 : Math.max(elapsedMs, 0)) / 1000;\n\n  if (t === 0) {\n    const settled = withinRest(rest, safeFrom, safeTarget, safeVelocity);\n    return {\n      value: settled ? safeTarget : safeFrom,\n      velocity: settled ? 0 : safeVelocity,\n      target: safeTarget,\n      settled,\n    };\n  }\n\n  const angularFrequency = Math.sqrt(rest.stiffness / rest.mass);\n  const criticalDamping = 2 * Math.sqrt(rest.stiffness * rest.mass);\n  const dampingRatio = criticalDamping > 0 ? rest.damping / criticalDamping : 1;\n  const regime = (\n    displacement: number,\n    speed: number,\n  ): readonly [number, number] =>\n    dampingRatio < 1\n      ? underdamped(displacement, speed, angularFrequency, dampingRatio, t)\n      : Math.abs(dampingRatio - 1) <= EPSILON\n        ? criticallyDamped(displacement, speed, angularFrequency, t)\n        : overdamped(displacement, speed, angularFrequency, dampingRatio, t);\n\n  const displacement = safeFrom - safeTarget;\n  let value: number;\n  let outVelocity: number;\n  if (Number.isFinite(displacement)) {\n    const [sampledDisplacement, sampledVelocity] = regime(\n      displacement,\n      safeVelocity,\n    );\n    value = safeTarget + sampledDisplacement;\n    outVelocity = sampledVelocity;\n  } else {\n    const scale = Math.max(Math.abs(safeFrom), Math.abs(safeTarget));\n    const [position, positionSpeed] = regime(1, 0);\n    const [response, responseSpeed] = regime(0, 1);\n    value = mix(safeFrom, safeTarget, 1 - position) + response * safeVelocity;\n    outVelocity =\n      scale *\n      (positionSpeed * (safeFrom / scale - safeTarget / scale) +\n        responseSpeed * (safeVelocity / scale));\n  }\n  value = sanitizeNumber(value, safeTarget);\n  outVelocity = sanitizeNumber(outVelocity, 0);\n  if (withinRest(rest, value, safeTarget, outVelocity)) {\n    return {\n      value: safeTarget,\n      velocity: 0,\n      target: safeTarget,\n      settled: true,\n    };\n  }\n  return {\n    value,\n    velocity: outVelocity,\n    target: safeTarget,\n    settled: false,\n  };\n};\n\nconst underdamped = (\n  displacement: number,\n  velocity: number,\n  angularFrequency: number,\n  dampingRatio: number,\n  time: number,\n): readonly [number, number] => {\n  const dampedFrequency =\n    angularFrequency * Math.sqrt(1 - dampingRatio * dampingRatio);\n  if (dampedFrequency <= MIN_POSITIVE) {\n    return criticallyDamped(displacement, velocity, angularFrequency, time);\n  }\n\n  const decay = Math.exp(-dampingRatio * angularFrequency * time);\n  const sin = Math.sin(dampedFrequency * time);\n  const cos = Math.cos(dampedFrequency * time);\n  const a = displacement;\n  const b =\n    (velocity + dampingRatio * angularFrequency * displacement) /\n    dampedFrequency;\n  const oscillation = a * cos + b * sin;\n  const sampledDisplacement = decay * oscillation;\n  const sampledVelocity =\n    decay *\n    (-a * dampedFrequency * sin +\n      b * dampedFrequency * cos -\n      dampingRatio * angularFrequency * oscillation);\n  return [sampledDisplacement, sampledVelocity];\n};\n\nconst criticallyDamped = (\n  displacement: number,\n  velocity: number,\n  angularFrequency: number,\n  time: number,\n): readonly [number, number] => {\n  const decay = Math.exp(-angularFrequency * time);\n  const c = velocity + angularFrequency * displacement;\n  const displacementTerm = displacement + c * time;\n  return [\n    decay * displacementTerm,\n    decay * (c - angularFrequency * displacementTerm),\n  ];\n};\n\nconst overdamped = (\n  displacement: number,\n  velocity: number,\n  angularFrequency: number,\n  dampingRatio: number,\n  time: number,\n): readonly [number, number] => {\n  const ratioDelta = Math.sqrt(dampingRatio * dampingRatio - 1);\n  const r1 = -angularFrequency * (dampingRatio - ratioDelta);\n  const r2 = -angularFrequency * (dampingRatio + ratioDelta);\n  if (Math.abs(r1 - r2) <= MIN_POSITIVE) {\n    return criticallyDamped(displacement, velocity, angularFrequency, time);\n  }\n  const c1 = (velocity - r2 * displacement) / (r1 - r2);\n  const c2 = displacement - c1;\n  const e1 = Math.exp(r1 * time);\n  const e2 = Math.exp(r2 * time);\n  return [c1 * e1 + c2 * e2, c1 * r1 * e1 + c2 * r2 * e2];\n};\n"
    },
    {
      "path": "packages/motion/src/timeline.ts",
      "target": "@ui/gpuixui/motion/timeline.ts",
      "type": "registry:lib",
      "content": "import { linear, type Easing } from \"./easing.js\";\nimport { clamp01, eased, mix } from \"./progress.js\";\n\nconst finiteOr = (value: number, fallback: number): number =>\n  Number.isFinite(value) ? value : fallback;\n\nconst durationOf = (durationMs: number): number =>\n  Number.isFinite(durationMs) && durationMs > 0 ? durationMs : 0;\n\nconst endOf = (startMs: number, durationMs: number): number => {\n  const duration = durationOf(durationMs);\n  const end = startMs + duration;\n  return Number.isFinite(end) && end > startMs ? duration : 0;\n};\n\nconst placedAt = (startMs: number, waitMs: number): number => {\n  const placed = startMs + waitMs;\n  return Number.isFinite(placed) ? placed : startMs;\n};\n\nexport interface Keyframe {\n  readonly at: number;\n  readonly value: number;\n  readonly easing?: Easing;\n}\n\nexport const keyframe = (\n  at: number,\n  value: number,\n  easing?: Easing,\n): Keyframe => ({ at, value, easing });\n\nconst isFrame = (frame: Keyframe | null | undefined): frame is Keyframe =>\n  typeof frame === \"object\" &&\n  frame !== null &&\n  Number.isFinite(frame.at) &&\n  Number.isFinite(frame.value);\n\nconst stopsOf = (\n  frames: readonly (Keyframe | null | undefined)[] | null | undefined,\n): ReadonlyArray<Keyframe> =>\n  Array.isArray(frames) ? frames.filter(isFrame) : [];\n\nconst firstStop = (stops: ReadonlyArray<Keyframe>): Keyframe =>\n  stops.reduce((first, frame) => (frame.at < first.at ? frame : first));\n\nconst lowerStop = (\n  stops: ReadonlyArray<Keyframe>,\n  progress: number,\n): Keyframe | undefined =>\n  stops.reduce<Keyframe | undefined>(\n    (lower, frame) =>\n      frame.at > progress\n        ? lower\n        : lower === undefined || frame.at >= lower.at\n          ? frame\n          : lower,\n    undefined,\n  );\n\nconst upperStop = (\n  stops: ReadonlyArray<Keyframe>,\n  progress: number,\n): Keyframe | undefined =>\n  stops.reduce<Keyframe | undefined>(\n    (upper, frame) =>\n      frame.at <= progress || (upper !== undefined && frame.at >= upper.at)\n        ? upper\n        : frame,\n    undefined,\n  );\n\nexport const sampleKeyframes = (\n  frames: readonly (Keyframe | null | undefined)[] | null | undefined,\n  progress: number,\n): number => {\n  const stops = stopsOf(frames);\n  if (stops.length === 0) return 0;\n  const t = clamp01(progress);\n  const lo = lowerStop(stops, t);\n  if (lo === undefined) return firstStop(stops).value;\n  const hi = upperStop(stops, t);\n  if (hi === undefined) return lo.value;\n\n  const local = (t - lo.at) / (hi.at - lo.at);\n  const easing = hi.easing ?? linear;\n  return mix(lo.value, hi.value, eased(easing, local));\n};\n\nexport type StaggerFrom = \"start\" | \"end\" | \"center\";\n\nconst staggerFromOf = (from: StaggerFrom): StaggerFrom =>\n  from === \"start\" || from === \"end\" || from === \"center\" ? from : \"start\";\n\nconst staggerDelay = (\n  stepMs: number,\n  index: number,\n  count: number,\n  from: StaggerFrom,\n): number => {\n  if (!Number.isFinite(index) || !Number.isFinite(count)) return 0;\n  if (count <= 0 || index < 0 || index >= count) return 0;\n  const direction = staggerFromOf(from);\n  const distance =\n    direction === \"start\"\n      ? index\n      : direction === \"end\"\n        ? count - 1 - index\n        : Math.abs(index - (count - 1) / 2);\n  const step = Number.isFinite(stepMs) && stepMs > 0 ? stepMs : 0;\n  const delay = step * distance;\n  return Number.isFinite(delay) ? delay : 0;\n};\n\nexport const stagger = (\n  stepMs: number,\n  index: number,\n  count: number,\n  from: StaggerFrom = \"start\",\n): number => staggerDelay(stepMs, index, count, from);\n\nexport type SequenceStepState = \"pending\" | \"active\" | \"completed\";\n\nexport interface SequenceStepSample<K> {\n  readonly key: K;\n  readonly state: SequenceStepState;\n\n  readonly value: number;\n}\n\ninterface Step<K> {\n  readonly key: K;\n  readonly startMs: number;\n  readonly durationMs: number;\n  readonly easing: Easing;\n}\n\nconst clockOf = (elapsedMs: number): number =>\n  Number.isNaN(elapsedMs) ? 0 : Math.max(elapsedMs, 0);\n\nconst keysOf = <K>(keys: readonly K[] | null | undefined): ReadonlyArray<K> =>\n  Array.isArray(keys) ? keys : [];\n\nexport class Sequence<K> {\n  private readonly steps: Step<K>[] = [];\n\n  at(\n    key: K,\n    startMs: number,\n    durationMs: number,\n    easing: Easing = linear,\n  ): this {\n    const start = finiteOr(startMs, 0);\n    this.steps.push({\n      key,\n      startMs: start,\n      durationMs: endOf(start, durationMs),\n      easing,\n    });\n    return this;\n  }\n\n  append(key: K, durationMs: number, easing: Easing = linear): this {\n    return this.at(key, this.duration(), durationMs, easing);\n  }\n\n  stagger(\n    keys: readonly K[] | null | undefined,\n    startMs: number,\n    stepMs: number,\n    durationMs: number,\n    easing: Easing = linear,\n  ): this {\n    const start = finiteOr(startMs, 0);\n    const list = keysOf(keys);\n    const count = list.length;\n    list.forEach((key, index) => {\n      this.at(\n        key,\n        placedAt(start, staggerDelay(stepMs, index, count, \"start\")),\n        durationMs,\n        easing,\n      );\n    });\n    return this;\n  }\n\n  duration(): number {\n    return this.steps.reduce(\n      (max, step) => Math.max(max, step.startMs + step.durationMs),\n      0,\n    );\n  }\n\n  sample(elapsedMs: number): readonly SequenceStepSample<K>[] {\n    const elapsed = clockOf(elapsedMs);\n    return this.steps.map((step) => {\n      if (elapsed < step.startMs)\n        return { key: step.key, state: \"pending\", value: 0 };\n      const local = elapsed - step.startMs;\n      if (step.durationMs <= 0 || local >= step.durationMs) {\n        return { key: step.key, state: \"completed\", value: 1 };\n      }\n      return {\n        key: step.key,\n        state: \"active\",\n        value: eased(step.easing, local / step.durationMs),\n      };\n    });\n  }\n\n  complete(elapsedMs: number): boolean {\n    return clockOf(elapsedMs) >= this.duration();\n  }\n}\n"
    },
    {
      "path": "packages/motion/src/timing.ts",
      "target": "@ui/gpuixui/motion/timing.ts",
      "type": "registry:lib",
      "content": "import { schedulableSeconds } from \"./duration.js\";\n\nexport const motionLevels = {\n  step: 120,\n\n  fast: 160,\n\n  normal: 200,\n\n  slow: 320,\n\n  notice: 500,\n} as const;\n\nexport type MotionLevel = keyof typeof motionLevels;\n\nexport type MotionPhase = \"enter\" | \"exit\" | \"standard\";\n\nexport type MotionCurve = [number, number, number, number];\n\nexport const motionEasingNames = [\n  \"linear\",\n  \"ease\",\n  \"easeIn\",\n  \"easeOut\",\n  \"easeInOut\",\n] as const;\n\nexport type MotionEasingName = (typeof motionEasingNames)[number];\n\nexport type MotionEasing = MotionEasingName | MotionCurve;\n\nexport const isMotionEasingName = (value: unknown): value is MotionEasingName =>\n  motionEasingNames.some((name) => name === value);\n\nconst isFiniteNumber = (value: unknown): value is number =>\n  typeof value === \"number\" && Number.isFinite(value);\n\nconst isUnitControl = (value: unknown): boolean =>\n  isFiniteNumber(value) && value >= 0 && value <= 1;\n\nexport const isMotionEasing = (value: unknown): value is MotionEasing => {\n  if (typeof value === \"string\") return isMotionEasingName(value);\n  const curve: ReadonlyArray<unknown> = Array.isArray(value) ? value : [];\n  if (curve.length !== 4) return false;\n  const [x1, y1, x2, y2] = curve;\n  return (\n    isUnitControl(x1) &&\n    isFiniteNumber(y1) &&\n    isUnitControl(x2) &&\n    isFiniteNumber(y2)\n  );\n};\n\nexport const motionEasings: Readonly<Record<MotionPhase, MotionEasingName>> = {\n  enter: \"easeOut\",\n  exit: \"easeIn\",\n  standard: \"easeInOut\",\n};\n\nexport type MotionPreference = \"animated\" | \"reduced\";\n\nexport const preferenceOf = (value: unknown): MotionPreference =>\n  value === \"reduced\" || value === \"animated\"\n    ? value\n    : value === null || value === undefined\n      ? \"animated\"\n      : \"reduced\";\n\nexport const reducedMotionOf = (\n  override: boolean | undefined,\n  preference: unknown,\n): boolean => override ?? preferenceOf(preference) === \"reduced\";\n\nexport interface MotionTiming {\n  readonly duration: number;\n  readonly delay?: number;\n  readonly ease?: MotionEasing;\n}\n\nexport interface MotionTimingOptions {\n  readonly phase?: unknown;\n\n  readonly preference?: unknown;\n\n  readonly ease?: unknown;\n}\n\nexport const isMotionLevel = (value: unknown): value is MotionLevel =>\n  typeof value === \"string\" && Object.hasOwn(motionLevels, value);\n\nconst namesPhase = (phase: string): phase is MotionPhase =>\n  Object.hasOwn(motionEasings, phase);\n\nexport const motionLevelOf = (value: unknown): MotionLevel =>\n  isMotionLevel(value) ? value : \"normal\";\n\nconst phaseOf = (phase: unknown): MotionPhase =>\n  typeof phase === \"string\" && namesPhase(phase) ? phase : \"standard\";\n\nconst runnableMs = (durationMs: number): number =>\n  schedulableSeconds(durationMs / 1000) === undefined\n    ? motionLevels.normal\n    : durationMs;\n\nexport const motionTimingOf = (\n  durationMs: number,\n  options: MotionTimingOptions | null = {},\n): MotionTiming => {\n  const phase = options?.phase ?? \"standard\";\n  if (preferenceOf(options?.preference) === \"reduced\") return { duration: 0 };\n  const named = options?.ease;\n  return {\n    duration: runnableMs(durationMs) / 1000,\n    ease: isMotionEasing(named) ? named : motionEasings[phaseOf(phase)],\n  };\n};\n\nexport const motionTiming = (\n  level: MotionLevel,\n  options: MotionTimingOptions | null = {},\n): MotionTiming => motionTimingOf(motionLevels[motionLevelOf(level)], options);\n"
    }
  ],
  "docs": "[Runtime: motion](https://gpuixui.sudokw.com/registry) — These are GPUix native components: the files render through GPUix's reconciler against `@gpuix/react`, not the DOM, and need the per-platform `@gpuix/native` binding. The CLI installs the `@gpuixui/*` runtime the components import as registry items, so the copied tree resolves on its own; wrap it in `ThemeProvider` before it renders.",
  "meta": {
    "url": "/registry",
    "kind": "runtime",
    "runtime": "gpuix",
    "registry": "gpuixui"
  }
}