react-secure-captcha
Version:
A professional customizable React Captcha component with Canvas and Math modes, animations with Framer Motion, and toast notifications via Sonner.
1,506 lines (1,421 loc) • 289 kB
JavaScript
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var index_exports = {};
__export(index_exports, {
CanvasCaptcha: () => CanvasCaptcha_default,
Captcha: () => Captcha_default,
MathCaptcha: () => MathCaptcha_default,
useCaptcha: () => useCaptcha
});
module.exports = __toCommonJS(index_exports);
// src/components/Captcha.tsx
var import_react25 = require("react");
// src/components/CanvasCaptcha.tsx
var import_react = require("react");
var import_jsx_runtime = require("react/jsx-runtime");
var CanvasCaptcha = ({
text,
width = 180,
height = 50,
fontSize = 28,
fontFamily = "Arial",
backgroundColor = "#f9f9f9",
textColor = "#333",
noise = 30
}) => {
const canvasRef = (0, import_react.useRef)(null);
(0, import_react.useEffect)(() => {
const canvas = canvasRef.current;
if (!canvas) return;
const ctx = canvas.getContext("2d");
if (!ctx) return;
ctx.clearRect(0, 0, width, height);
ctx.fillStyle = backgroundColor;
ctx.fillRect(0, 0, width, height);
for (let i = 0; i < noise; i++) {
ctx.fillStyle = `rgba(0,0,0,${Math.random()})`;
ctx.beginPath();
ctx.arc(
Math.random() * width,
Math.random() * height,
Math.random() * 5,
0,
2 * Math.PI
);
ctx.fill();
}
ctx.font = `${fontSize}px ${fontFamily}`;
ctx.fillStyle = textColor;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText(text, width / 2, height / 2);
}, [
text,
width,
height,
fontSize,
fontFamily,
backgroundColor,
textColor,
noise
]);
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
"canvas",
{
ref: canvasRef,
width,
height,
className: "rounded-md border border-gray-300"
}
);
};
var CanvasCaptcha_default = CanvasCaptcha;
// src/components/MathCaptcha.tsx
var import_jsx_runtime2 = require("react/jsx-runtime");
var MathCaptcha = ({
question,
width = 180,
height = 50,
fontSize = 28,
fontFamily = "Arial",
backgroundColor = "#f9f9f9",
textColor = "#333",
className = ""
}) => {
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
"div",
{
style: { width, height, backgroundColor },
className: `flex items-center justify-center rounded-md border border-gray-300 select-none ${className}`,
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
"span",
{
style: { fontSize, fontFamily, color: textColor },
className: "font-bold",
children: question
}
)
}
);
};
var MathCaptcha_default = MathCaptcha;
// node_modules/framer-motion/dist/es/components/AnimatePresence/index.mjs
var import_jsx_runtime5 = require("react/jsx-runtime");
var import_react11 = require("react");
// node_modules/framer-motion/dist/es/context/LayoutGroupContext.mjs
var import_react2 = require("react");
var LayoutGroupContext = (0, import_react2.createContext)({});
// node_modules/framer-motion/dist/es/utils/use-constant.mjs
var import_react3 = require("react");
function useConstant(init) {
const ref = (0, import_react3.useRef)(null);
if (ref.current === null) {
ref.current = init();
}
return ref.current;
}
// node_modules/framer-motion/dist/es/utils/use-isomorphic-effect.mjs
var import_react4 = require("react");
// node_modules/framer-motion/dist/es/utils/is-browser.mjs
var isBrowser = typeof window !== "undefined";
// node_modules/framer-motion/dist/es/utils/use-isomorphic-effect.mjs
var useIsomorphicLayoutEffect = isBrowser ? import_react4.useLayoutEffect : import_react4.useEffect;
// node_modules/framer-motion/dist/es/components/AnimatePresence/PresenceChild.mjs
var import_jsx_runtime4 = require("react/jsx-runtime");
var React3 = __toESM(require("react"), 1);
var import_react8 = require("react");
// node_modules/framer-motion/dist/es/context/PresenceContext.mjs
var import_react5 = require("react");
var PresenceContext = /* @__PURE__ */ (0, import_react5.createContext)(null);
// node_modules/framer-motion/dist/es/components/AnimatePresence/PopChild.mjs
var import_jsx_runtime3 = require("react/jsx-runtime");
// node_modules/motion-utils/dist/es/array.mjs
function addUniqueItem(arr, item) {
if (arr.indexOf(item) === -1)
arr.push(item);
}
function removeItem(arr, item) {
const index = arr.indexOf(item);
if (index > -1)
arr.splice(index, 1);
}
// node_modules/motion-utils/dist/es/clamp.mjs
var clamp = (min, max, v) => {
if (v > max)
return max;
if (v < min)
return min;
return v;
};
// node_modules/motion-utils/dist/es/format-error-message.mjs
function formatErrorMessage(message, errorCode) {
return errorCode ? `${message}. For more information and steps for solving, visit https://motion.dev/troubleshooting/${errorCode}` : message;
}
// node_modules/motion-utils/dist/es/errors.mjs
var warning = () => {
};
var invariant = () => {
};
if (process.env.NODE_ENV !== "production") {
warning = (check, message, errorCode) => {
if (!check && typeof console !== "undefined") {
console.warn(formatErrorMessage(message, errorCode));
}
};
invariant = (check, message, errorCode) => {
if (!check) {
throw new Error(formatErrorMessage(message, errorCode));
}
};
}
// node_modules/motion-utils/dist/es/global-config.mjs
var MotionGlobalConfig = {};
// node_modules/motion-utils/dist/es/is-numerical-string.mjs
var isNumericalString = (v) => /^-?(?:\d+(?:\.\d+)?|\.\d+)$/u.test(v);
// node_modules/motion-utils/dist/es/is-object.mjs
function isObject(value) {
return typeof value === "object" && value !== null;
}
// node_modules/motion-utils/dist/es/is-zero-value-string.mjs
var isZeroValueString = (v) => /^0[^.\s]+$/u.test(v);
// node_modules/motion-utils/dist/es/memo.mjs
// @__NO_SIDE_EFFECTS__
function memo(callback) {
let result;
return () => {
if (result === void 0)
result = callback();
return result;
};
}
// node_modules/motion-utils/dist/es/noop.mjs
var noop = /* @__NO_SIDE_EFFECTS__ */ (any) => any;
// node_modules/motion-utils/dist/es/pipe.mjs
var combineFunctions = (a, b) => (v) => b(a(v));
var pipe = (...transformers) => transformers.reduce(combineFunctions);
// node_modules/motion-utils/dist/es/progress.mjs
var progress = /* @__NO_SIDE_EFFECTS__ */ (from, to, value) => {
const toFromDifference = to - from;
return toFromDifference === 0 ? 1 : (value - from) / toFromDifference;
};
// node_modules/motion-utils/dist/es/subscription-manager.mjs
var SubscriptionManager = class {
constructor() {
this.subscriptions = [];
}
add(handler) {
addUniqueItem(this.subscriptions, handler);
return () => removeItem(this.subscriptions, handler);
}
notify(a, b, c) {
const numSubscriptions = this.subscriptions.length;
if (!numSubscriptions)
return;
if (numSubscriptions === 1) {
this.subscriptions[0](a, b, c);
} else {
for (let i = 0; i < numSubscriptions; i++) {
const handler = this.subscriptions[i];
handler && handler(a, b, c);
}
}
}
getSize() {
return this.subscriptions.length;
}
clear() {
this.subscriptions.length = 0;
}
};
// node_modules/motion-utils/dist/es/time-conversion.mjs
var secondsToMilliseconds = /* @__NO_SIDE_EFFECTS__ */ (seconds) => seconds * 1e3;
var millisecondsToSeconds = /* @__NO_SIDE_EFFECTS__ */ (milliseconds) => milliseconds / 1e3;
// node_modules/motion-utils/dist/es/velocity-per-second.mjs
function velocityPerSecond(velocity, frameDuration) {
return frameDuration ? velocity * (1e3 / frameDuration) : 0;
}
// node_modules/motion-utils/dist/es/warn-once.mjs
var warned = /* @__PURE__ */ new Set();
function warnOnce(condition, message, errorCode) {
if (condition || warned.has(message))
return;
console.warn(formatErrorMessage(message, errorCode));
warned.add(message);
}
// node_modules/motion-utils/dist/es/easing/cubic-bezier.mjs
var calcBezier = (t, a1, a2) => (((1 - 3 * a2 + 3 * a1) * t + (3 * a2 - 6 * a1)) * t + 3 * a1) * t;
var subdivisionPrecision = 1e-7;
var subdivisionMaxIterations = 12;
function binarySubdivide(x, lowerBound, upperBound, mX1, mX2) {
let currentX;
let currentT;
let i = 0;
do {
currentT = lowerBound + (upperBound - lowerBound) / 2;
currentX = calcBezier(currentT, mX1, mX2) - x;
if (currentX > 0) {
upperBound = currentT;
} else {
lowerBound = currentT;
}
} while (Math.abs(currentX) > subdivisionPrecision && ++i < subdivisionMaxIterations);
return currentT;
}
function cubicBezier(mX1, mY1, mX2, mY2) {
if (mX1 === mY1 && mX2 === mY2)
return noop;
const getTForX = (aX) => binarySubdivide(aX, 0, 1, mX1, mX2);
return (t) => t === 0 || t === 1 ? t : calcBezier(getTForX(t), mY1, mY2);
}
// node_modules/motion-utils/dist/es/easing/modifiers/mirror.mjs
var mirrorEasing = (easing) => (p) => p <= 0.5 ? easing(2 * p) / 2 : (2 - easing(2 * (1 - p))) / 2;
// node_modules/motion-utils/dist/es/easing/modifiers/reverse.mjs
var reverseEasing = (easing) => (p) => 1 - easing(1 - p);
// node_modules/motion-utils/dist/es/easing/back.mjs
var backOut = /* @__PURE__ */ cubicBezier(0.33, 1.53, 0.69, 0.99);
var backIn = /* @__PURE__ */ reverseEasing(backOut);
var backInOut = /* @__PURE__ */ mirrorEasing(backIn);
// node_modules/motion-utils/dist/es/easing/anticipate.mjs
var anticipate = (p) => (p *= 2) < 1 ? 0.5 * backIn(p) : 0.5 * (2 - Math.pow(2, -10 * (p - 1)));
// node_modules/motion-utils/dist/es/easing/circ.mjs
var circIn = (p) => 1 - Math.sin(Math.acos(p));
var circOut = reverseEasing(circIn);
var circInOut = mirrorEasing(circIn);
// node_modules/motion-utils/dist/es/easing/ease.mjs
var easeIn = /* @__PURE__ */ cubicBezier(0.42, 0, 1, 1);
var easeOut = /* @__PURE__ */ cubicBezier(0, 0, 0.58, 1);
var easeInOut = /* @__PURE__ */ cubicBezier(0.42, 0, 0.58, 1);
// node_modules/motion-utils/dist/es/easing/utils/is-easing-array.mjs
var isEasingArray = (ease2) => {
return Array.isArray(ease2) && typeof ease2[0] !== "number";
};
// node_modules/motion-utils/dist/es/easing/utils/is-bezier-definition.mjs
var isBezierDefinition = (easing) => Array.isArray(easing) && typeof easing[0] === "number";
// node_modules/motion-utils/dist/es/easing/utils/map.mjs
var easingLookup = {
linear: noop,
easeIn,
easeInOut,
easeOut,
circIn,
circInOut,
circOut,
backIn,
backInOut,
backOut,
anticipate
};
var isValidEasing = (easing) => {
return typeof easing === "string";
};
var easingDefinitionToFunction = (definition) => {
if (isBezierDefinition(definition)) {
invariant(definition.length === 4, `Cubic bezier arrays must contain four numerical values.`, "cubic-bezier-length");
const [x1, y1, x2, y2] = definition;
return cubicBezier(x1, y1, x2, y2);
} else if (isValidEasing(definition)) {
invariant(easingLookup[definition] !== void 0, `Invalid easing type '${definition}'`, "invalid-easing-type");
return easingLookup[definition];
}
return definition;
};
// node_modules/motion-dom/dist/es/frameloop/order.mjs
var stepsOrder = [
"setup",
// Compute
"read",
// Read
"resolveKeyframes",
// Write/Read/Write/Read
"preUpdate",
// Compute
"update",
// Compute
"preRender",
// Compute
"render",
// Write
"postRender"
// Compute
];
// node_modules/motion-dom/dist/es/stats/buffer.mjs
var statsBuffer = {
value: null,
addProjectionMetrics: null
};
// node_modules/motion-dom/dist/es/frameloop/render-step.mjs
function createRenderStep(runNextFrame, stepName) {
let thisFrame = /* @__PURE__ */ new Set();
let nextFrame = /* @__PURE__ */ new Set();
let isProcessing = false;
let flushNextFrame = false;
const toKeepAlive = /* @__PURE__ */ new WeakSet();
let latestFrameData = {
delta: 0,
timestamp: 0,
isProcessing: false
};
let numCalls = 0;
function triggerCallback(callback) {
if (toKeepAlive.has(callback)) {
step.schedule(callback);
runNextFrame();
}
numCalls++;
callback(latestFrameData);
}
const step = {
/**
* Schedule a process to run on the next frame.
*/
schedule: (callback, keepAlive = false, immediate = false) => {
const addToCurrentFrame = immediate && isProcessing;
const queue = addToCurrentFrame ? thisFrame : nextFrame;
if (keepAlive)
toKeepAlive.add(callback);
if (!queue.has(callback))
queue.add(callback);
return callback;
},
/**
* Cancel the provided callback from running on the next frame.
*/
cancel: (callback) => {
nextFrame.delete(callback);
toKeepAlive.delete(callback);
},
/**
* Execute all schedule callbacks.
*/
process: (frameData2) => {
latestFrameData = frameData2;
if (isProcessing) {
flushNextFrame = true;
return;
}
isProcessing = true;
[thisFrame, nextFrame] = [nextFrame, thisFrame];
thisFrame.forEach(triggerCallback);
if (stepName && statsBuffer.value) {
statsBuffer.value.frameloop[stepName].push(numCalls);
}
numCalls = 0;
thisFrame.clear();
isProcessing = false;
if (flushNextFrame) {
flushNextFrame = false;
step.process(frameData2);
}
}
};
return step;
}
// node_modules/motion-dom/dist/es/frameloop/batcher.mjs
var maxElapsed = 40;
function createRenderBatcher(scheduleNextBatch, allowKeepAlive) {
let runNextFrame = false;
let useDefaultElapsed = true;
const state = {
delta: 0,
timestamp: 0,
isProcessing: false
};
const flagRunNextFrame = () => runNextFrame = true;
const steps = stepsOrder.reduce((acc, key) => {
acc[key] = createRenderStep(flagRunNextFrame, allowKeepAlive ? key : void 0);
return acc;
}, {});
const { setup, read, resolveKeyframes, preUpdate, update, preRender, render, postRender } = steps;
const processBatch = () => {
const timestamp = MotionGlobalConfig.useManualTiming ? state.timestamp : performance.now();
runNextFrame = false;
if (!MotionGlobalConfig.useManualTiming) {
state.delta = useDefaultElapsed ? 1e3 / 60 : Math.max(Math.min(timestamp - state.timestamp, maxElapsed), 1);
}
state.timestamp = timestamp;
state.isProcessing = true;
setup.process(state);
read.process(state);
resolveKeyframes.process(state);
preUpdate.process(state);
update.process(state);
preRender.process(state);
render.process(state);
postRender.process(state);
state.isProcessing = false;
if (runNextFrame && allowKeepAlive) {
useDefaultElapsed = false;
scheduleNextBatch(processBatch);
}
};
const wake = () => {
runNextFrame = true;
useDefaultElapsed = true;
if (!state.isProcessing) {
scheduleNextBatch(processBatch);
}
};
const schedule = stepsOrder.reduce((acc, key) => {
const step = steps[key];
acc[key] = (process2, keepAlive = false, immediate = false) => {
if (!runNextFrame)
wake();
return step.schedule(process2, keepAlive, immediate);
};
return acc;
}, {});
const cancel = (process2) => {
for (let i = 0; i < stepsOrder.length; i++) {
steps[stepsOrder[i]].cancel(process2);
}
};
return { schedule, cancel, state, steps };
}
// node_modules/motion-dom/dist/es/frameloop/frame.mjs
var { schedule: frame, cancel: cancelFrame, state: frameData, steps: frameSteps } = /* @__PURE__ */ createRenderBatcher(typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : noop, true);
// node_modules/motion-dom/dist/es/frameloop/sync-time.mjs
var now;
function clearTime() {
now = void 0;
}
var time = {
now: () => {
if (now === void 0) {
time.set(frameData.isProcessing || MotionGlobalConfig.useManualTiming ? frameData.timestamp : performance.now());
}
return now;
},
set: (newTime) => {
now = newTime;
queueMicrotask(clearTime);
}
};
// node_modules/motion-dom/dist/es/stats/animation-count.mjs
var activeAnimations = {
layout: 0,
mainThread: 0,
waapi: 0
};
// node_modules/motion-dom/dist/es/animation/utils/is-css-variable.mjs
var checkStringStartsWith = (token) => (key) => typeof key === "string" && key.startsWith(token);
var isCSSVariableName = /* @__PURE__ */ checkStringStartsWith("--");
var startsAsVariableToken = /* @__PURE__ */ checkStringStartsWith("var(--");
var isCSSVariableToken = (value) => {
const startsWithToken = startsAsVariableToken(value);
if (!startsWithToken)
return false;
return singleCssVariableRegex.test(value.split("/*")[0].trim());
};
var singleCssVariableRegex = /var\(--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)$/iu;
// node_modules/motion-dom/dist/es/value/types/numbers/index.mjs
var number = {
test: (v) => typeof v === "number",
parse: parseFloat,
transform: (v) => v
};
var alpha = {
...number,
transform: (v) => clamp(0, 1, v)
};
var scale = {
...number,
default: 1
};
// node_modules/motion-dom/dist/es/value/types/utils/sanitize.mjs
var sanitize = (v) => Math.round(v * 1e5) / 1e5;
// node_modules/motion-dom/dist/es/value/types/utils/float-regex.mjs
var floatRegex = /-?(?:\d+(?:\.\d+)?|\.\d+)/gu;
// node_modules/motion-dom/dist/es/value/types/utils/is-nullish.mjs
function isNullish(v) {
return v == null;
}
// node_modules/motion-dom/dist/es/value/types/utils/single-color-regex.mjs
var singleColorRegex = /^(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))$/iu;
// node_modules/motion-dom/dist/es/value/types/color/utils.mjs
var isColorString = (type, testProp) => (v) => {
return Boolean(typeof v === "string" && singleColorRegex.test(v) && v.startsWith(type) || testProp && !isNullish(v) && Object.prototype.hasOwnProperty.call(v, testProp));
};
var splitColor = (aName, bName, cName) => (v) => {
if (typeof v !== "string")
return v;
const [a, b, c, alpha2] = v.match(floatRegex);
return {
[aName]: parseFloat(a),
[bName]: parseFloat(b),
[cName]: parseFloat(c),
alpha: alpha2 !== void 0 ? parseFloat(alpha2) : 1
};
};
// node_modules/motion-dom/dist/es/value/types/color/rgba.mjs
var clampRgbUnit = (v) => clamp(0, 255, v);
var rgbUnit = {
...number,
transform: (v) => Math.round(clampRgbUnit(v))
};
var rgba = {
test: /* @__PURE__ */ isColorString("rgb", "red"),
parse: /* @__PURE__ */ splitColor("red", "green", "blue"),
transform: ({ red, green, blue, alpha: alpha$1 = 1 }) => "rgba(" + rgbUnit.transform(red) + ", " + rgbUnit.transform(green) + ", " + rgbUnit.transform(blue) + ", " + sanitize(alpha.transform(alpha$1)) + ")"
};
// node_modules/motion-dom/dist/es/value/types/color/hex.mjs
function parseHex(v) {
let r = "";
let g = "";
let b = "";
let a = "";
if (v.length > 5) {
r = v.substring(1, 3);
g = v.substring(3, 5);
b = v.substring(5, 7);
a = v.substring(7, 9);
} else {
r = v.substring(1, 2);
g = v.substring(2, 3);
b = v.substring(3, 4);
a = v.substring(4, 5);
r += r;
g += g;
b += b;
a += a;
}
return {
red: parseInt(r, 16),
green: parseInt(g, 16),
blue: parseInt(b, 16),
alpha: a ? parseInt(a, 16) / 255 : 1
};
}
var hex = {
test: /* @__PURE__ */ isColorString("#"),
parse: parseHex,
transform: rgba.transform
};
// node_modules/motion-dom/dist/es/value/types/numbers/units.mjs
var createUnitType = /* @__NO_SIDE_EFFECTS__ */ (unit) => ({
test: (v) => typeof v === "string" && v.endsWith(unit) && v.split(" ").length === 1,
parse: parseFloat,
transform: (v) => `${v}${unit}`
});
var degrees = /* @__PURE__ */ createUnitType("deg");
var percent = /* @__PURE__ */ createUnitType("%");
var px = /* @__PURE__ */ createUnitType("px");
var vh = /* @__PURE__ */ createUnitType("vh");
var vw = /* @__PURE__ */ createUnitType("vw");
var progressPercentage = /* @__PURE__ */ (() => ({
...percent,
parse: (v) => percent.parse(v) / 100,
transform: (v) => percent.transform(v * 100)
}))();
// node_modules/motion-dom/dist/es/value/types/color/hsla.mjs
var hsla = {
test: /* @__PURE__ */ isColorString("hsl", "hue"),
parse: /* @__PURE__ */ splitColor("hue", "saturation", "lightness"),
transform: ({ hue, saturation, lightness, alpha: alpha$1 = 1 }) => {
return "hsla(" + Math.round(hue) + ", " + percent.transform(sanitize(saturation)) + ", " + percent.transform(sanitize(lightness)) + ", " + sanitize(alpha.transform(alpha$1)) + ")";
}
};
// node_modules/motion-dom/dist/es/value/types/color/index.mjs
var color = {
test: (v) => rgba.test(v) || hex.test(v) || hsla.test(v),
parse: (v) => {
if (rgba.test(v)) {
return rgba.parse(v);
} else if (hsla.test(v)) {
return hsla.parse(v);
} else {
return hex.parse(v);
}
},
transform: (v) => {
return typeof v === "string" ? v : v.hasOwnProperty("red") ? rgba.transform(v) : hsla.transform(v);
},
getAnimatableNone: (v) => {
const parsed = color.parse(v);
parsed.alpha = 0;
return color.transform(parsed);
}
};
// node_modules/motion-dom/dist/es/value/types/utils/color-regex.mjs
var colorRegex = /(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))/giu;
// node_modules/motion-dom/dist/es/value/types/complex/index.mjs
function test(v) {
return isNaN(v) && typeof v === "string" && (v.match(floatRegex)?.length || 0) + (v.match(colorRegex)?.length || 0) > 0;
}
var NUMBER_TOKEN = "number";
var COLOR_TOKEN = "color";
var VAR_TOKEN = "var";
var VAR_FUNCTION_TOKEN = "var(";
var SPLIT_TOKEN = "${}";
var complexRegex = /var\s*\(\s*--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)|#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\)|-?(?:\d+(?:\.\d+)?|\.\d+)/giu;
function analyseComplexValue(value) {
const originalValue = value.toString();
const values = [];
const indexes = {
color: [],
number: [],
var: []
};
const types = [];
let i = 0;
const tokenised = originalValue.replace(complexRegex, (parsedValue) => {
if (color.test(parsedValue)) {
indexes.color.push(i);
types.push(COLOR_TOKEN);
values.push(color.parse(parsedValue));
} else if (parsedValue.startsWith(VAR_FUNCTION_TOKEN)) {
indexes.var.push(i);
types.push(VAR_TOKEN);
values.push(parsedValue);
} else {
indexes.number.push(i);
types.push(NUMBER_TOKEN);
values.push(parseFloat(parsedValue));
}
++i;
return SPLIT_TOKEN;
});
const split = tokenised.split(SPLIT_TOKEN);
return { values, split, indexes, types };
}
function parseComplexValue(v) {
return analyseComplexValue(v).values;
}
function createTransformer(source) {
const { split, types } = analyseComplexValue(source);
const numSections = split.length;
return (v) => {
let output = "";
for (let i = 0; i < numSections; i++) {
output += split[i];
if (v[i] !== void 0) {
const type = types[i];
if (type === NUMBER_TOKEN) {
output += sanitize(v[i]);
} else if (type === COLOR_TOKEN) {
output += color.transform(v[i]);
} else {
output += v[i];
}
}
}
return output;
};
}
var convertNumbersToZero = (v) => typeof v === "number" ? 0 : color.test(v) ? color.getAnimatableNone(v) : v;
function getAnimatableNone(v) {
const parsed = parseComplexValue(v);
const transformer = createTransformer(v);
return transformer(parsed.map(convertNumbersToZero));
}
var complex = {
test,
parse: parseComplexValue,
createTransformer,
getAnimatableNone
};
// node_modules/motion-dom/dist/es/value/types/color/hsla-to-rgba.mjs
function hueToRgb(p, q, t) {
if (t < 0)
t += 1;
if (t > 1)
t -= 1;
if (t < 1 / 6)
return p + (q - p) * 6 * t;
if (t < 1 / 2)
return q;
if (t < 2 / 3)
return p + (q - p) * (2 / 3 - t) * 6;
return p;
}
function hslaToRgba({ hue, saturation, lightness, alpha: alpha2 }) {
hue /= 360;
saturation /= 100;
lightness /= 100;
let red = 0;
let green = 0;
let blue = 0;
if (!saturation) {
red = green = blue = lightness;
} else {
const q = lightness < 0.5 ? lightness * (1 + saturation) : lightness + saturation - lightness * saturation;
const p = 2 * lightness - q;
red = hueToRgb(p, q, hue + 1 / 3);
green = hueToRgb(p, q, hue);
blue = hueToRgb(p, q, hue - 1 / 3);
}
return {
red: Math.round(red * 255),
green: Math.round(green * 255),
blue: Math.round(blue * 255),
alpha: alpha2
};
}
// node_modules/motion-dom/dist/es/utils/mix/immediate.mjs
function mixImmediate(a, b) {
return (p) => p > 0 ? b : a;
}
// node_modules/motion-dom/dist/es/utils/mix/number.mjs
var mixNumber = (from, to, progress2) => {
return from + (to - from) * progress2;
};
// node_modules/motion-dom/dist/es/utils/mix/color.mjs
var mixLinearColor = (from, to, v) => {
const fromExpo = from * from;
const expo = v * (to * to - fromExpo) + fromExpo;
return expo < 0 ? 0 : Math.sqrt(expo);
};
var colorTypes = [hex, rgba, hsla];
var getColorType = (v) => colorTypes.find((type) => type.test(v));
function asRGBA(color2) {
const type = getColorType(color2);
warning(Boolean(type), `'${color2}' is not an animatable color. Use the equivalent color code instead.`, "color-not-animatable");
if (!Boolean(type))
return false;
let model = type.parse(color2);
if (type === hsla) {
model = hslaToRgba(model);
}
return model;
}
var mixColor = (from, to) => {
const fromRGBA = asRGBA(from);
const toRGBA = asRGBA(to);
if (!fromRGBA || !toRGBA) {
return mixImmediate(from, to);
}
const blended = { ...fromRGBA };
return (v) => {
blended.red = mixLinearColor(fromRGBA.red, toRGBA.red, v);
blended.green = mixLinearColor(fromRGBA.green, toRGBA.green, v);
blended.blue = mixLinearColor(fromRGBA.blue, toRGBA.blue, v);
blended.alpha = mixNumber(fromRGBA.alpha, toRGBA.alpha, v);
return rgba.transform(blended);
};
};
// node_modules/motion-dom/dist/es/utils/mix/visibility.mjs
var invisibleValues = /* @__PURE__ */ new Set(["none", "hidden"]);
function mixVisibility(origin, target) {
if (invisibleValues.has(origin)) {
return (p) => p <= 0 ? origin : target;
} else {
return (p) => p >= 1 ? target : origin;
}
}
// node_modules/motion-dom/dist/es/utils/mix/complex.mjs
function mixNumber2(a, b) {
return (p) => mixNumber(a, b, p);
}
function getMixer(a) {
if (typeof a === "number") {
return mixNumber2;
} else if (typeof a === "string") {
return isCSSVariableToken(a) ? mixImmediate : color.test(a) ? mixColor : mixComplex;
} else if (Array.isArray(a)) {
return mixArray;
} else if (typeof a === "object") {
return color.test(a) ? mixColor : mixObject;
}
return mixImmediate;
}
function mixArray(a, b) {
const output = [...a];
const numValues = output.length;
const blendValue = a.map((v, i) => getMixer(v)(v, b[i]));
return (p) => {
for (let i = 0; i < numValues; i++) {
output[i] = blendValue[i](p);
}
return output;
};
}
function mixObject(a, b) {
const output = { ...a, ...b };
const blendValue = {};
for (const key in output) {
if (a[key] !== void 0 && b[key] !== void 0) {
blendValue[key] = getMixer(a[key])(a[key], b[key]);
}
}
return (v) => {
for (const key in blendValue) {
output[key] = blendValue[key](v);
}
return output;
};
}
function matchOrder(origin, target) {
const orderedOrigin = [];
const pointers = { color: 0, var: 0, number: 0 };
for (let i = 0; i < target.values.length; i++) {
const type = target.types[i];
const originIndex = origin.indexes[type][pointers[type]];
const originValue = origin.values[originIndex] ?? 0;
orderedOrigin[i] = originValue;
pointers[type]++;
}
return orderedOrigin;
}
var mixComplex = (origin, target) => {
const template = complex.createTransformer(target);
const originStats = analyseComplexValue(origin);
const targetStats = analyseComplexValue(target);
const canInterpolate = originStats.indexes.var.length === targetStats.indexes.var.length && originStats.indexes.color.length === targetStats.indexes.color.length && originStats.indexes.number.length >= targetStats.indexes.number.length;
if (canInterpolate) {
if (invisibleValues.has(origin) && !targetStats.values.length || invisibleValues.has(target) && !originStats.values.length) {
return mixVisibility(origin, target);
}
return pipe(mixArray(matchOrder(originStats, targetStats), targetStats.values), template);
} else {
warning(true, `Complex values '${origin}' and '${target}' too different to mix. Ensure all colors are of the same type, and that each contains the same quantity of number and color values. Falling back to instant transition.`, "complex-values-different");
return mixImmediate(origin, target);
}
};
// node_modules/motion-dom/dist/es/utils/mix/index.mjs
function mix(from, to, p) {
if (typeof from === "number" && typeof to === "number" && typeof p === "number") {
return mixNumber(from, to, p);
}
const mixer = getMixer(from);
return mixer(from, to);
}
// node_modules/motion-dom/dist/es/animation/drivers/frame.mjs
var frameloopDriver = (update) => {
const passTimestamp = ({ timestamp }) => update(timestamp);
return {
start: (keepAlive = true) => frame.update(passTimestamp, keepAlive),
stop: () => cancelFrame(passTimestamp),
/**
* If we're processing this frame we can use the
* framelocked timestamp to keep things in sync.
*/
now: () => frameData.isProcessing ? frameData.timestamp : time.now()
};
};
// node_modules/motion-dom/dist/es/animation/waapi/utils/linear.mjs
var generateLinearEasing = (easing, duration, resolution = 10) => {
let points = "";
const numPoints = Math.max(Math.round(duration / resolution), 2);
for (let i = 0; i < numPoints; i++) {
points += Math.round(easing(i / (numPoints - 1)) * 1e4) / 1e4 + ", ";
}
return `linear(${points.substring(0, points.length - 2)})`;
};
// node_modules/motion-dom/dist/es/animation/generators/utils/calc-duration.mjs
var maxGeneratorDuration = 2e4;
function calcGeneratorDuration(generator) {
let duration = 0;
const timeStep = 50;
let state = generator.next(duration);
while (!state.done && duration < maxGeneratorDuration) {
duration += timeStep;
state = generator.next(duration);
}
return duration >= maxGeneratorDuration ? Infinity : duration;
}
// node_modules/motion-dom/dist/es/animation/generators/utils/create-generator-easing.mjs
function createGeneratorEasing(options, scale2 = 100, createGenerator) {
const generator = createGenerator({ ...options, keyframes: [0, scale2] });
const duration = Math.min(calcGeneratorDuration(generator), maxGeneratorDuration);
return {
type: "keyframes",
ease: (progress2) => {
return generator.next(duration * progress2).value / scale2;
},
duration: millisecondsToSeconds(duration)
};
}
// node_modules/motion-dom/dist/es/animation/generators/utils/velocity.mjs
var velocitySampleDuration = 5;
function calcGeneratorVelocity(resolveValue, t, current) {
const prevT = Math.max(t - velocitySampleDuration, 0);
return velocityPerSecond(current - resolveValue(prevT), t - prevT);
}
// node_modules/motion-dom/dist/es/animation/generators/spring/defaults.mjs
var springDefaults = {
// Default spring physics
stiffness: 100,
damping: 10,
mass: 1,
velocity: 0,
// Default duration/bounce-based options
duration: 800,
// in ms
bounce: 0.3,
visualDuration: 0.3,
// in seconds
// Rest thresholds
restSpeed: {
granular: 0.01,
default: 2
},
restDelta: {
granular: 5e-3,
default: 0.5
},
// Limits
minDuration: 0.01,
// in seconds
maxDuration: 10,
// in seconds
minDamping: 0.05,
maxDamping: 1
};
// node_modules/motion-dom/dist/es/animation/generators/spring/find.mjs
var safeMin = 1e-3;
function findSpring({ duration = springDefaults.duration, bounce = springDefaults.bounce, velocity = springDefaults.velocity, mass = springDefaults.mass }) {
let envelope;
let derivative;
warning(duration <= secondsToMilliseconds(springDefaults.maxDuration), "Spring duration must be 10 seconds or less", "spring-duration-limit");
let dampingRatio = 1 - bounce;
dampingRatio = clamp(springDefaults.minDamping, springDefaults.maxDamping, dampingRatio);
duration = clamp(springDefaults.minDuration, springDefaults.maxDuration, millisecondsToSeconds(duration));
if (dampingRatio < 1) {
envelope = (undampedFreq2) => {
const exponentialDecay = undampedFreq2 * dampingRatio;
const delta = exponentialDecay * duration;
const a = exponentialDecay - velocity;
const b = calcAngularFreq(undampedFreq2, dampingRatio);
const c = Math.exp(-delta);
return safeMin - a / b * c;
};
derivative = (undampedFreq2) => {
const exponentialDecay = undampedFreq2 * dampingRatio;
const delta = exponentialDecay * duration;
const d = delta * velocity + velocity;
const e = Math.pow(dampingRatio, 2) * Math.pow(undampedFreq2, 2) * duration;
const f = Math.exp(-delta);
const g = calcAngularFreq(Math.pow(undampedFreq2, 2), dampingRatio);
const factor = -envelope(undampedFreq2) + safeMin > 0 ? -1 : 1;
return factor * ((d - e) * f) / g;
};
} else {
envelope = (undampedFreq2) => {
const a = Math.exp(-undampedFreq2 * duration);
const b = (undampedFreq2 - velocity) * duration + 1;
return -safeMin + a * b;
};
derivative = (undampedFreq2) => {
const a = Math.exp(-undampedFreq2 * duration);
const b = (velocity - undampedFreq2) * (duration * duration);
return a * b;
};
}
const initialGuess = 5 / duration;
const undampedFreq = approximateRoot(envelope, derivative, initialGuess);
duration = secondsToMilliseconds(duration);
if (isNaN(undampedFreq)) {
return {
stiffness: springDefaults.stiffness,
damping: springDefaults.damping,
duration
};
} else {
const stiffness = Math.pow(undampedFreq, 2) * mass;
return {
stiffness,
damping: dampingRatio * 2 * Math.sqrt(mass * stiffness),
duration
};
}
}
var rootIterations = 12;
function approximateRoot(envelope, derivative, initialGuess) {
let result = initialGuess;
for (let i = 1; i < rootIterations; i++) {
result = result - envelope(result) / derivative(result);
}
return result;
}
function calcAngularFreq(undampedFreq, dampingRatio) {
return undampedFreq * Math.sqrt(1 - dampingRatio * dampingRatio);
}
// node_modules/motion-dom/dist/es/animation/generators/spring/index.mjs
var durationKeys = ["duration", "bounce"];
var physicsKeys = ["stiffness", "damping", "mass"];
function isSpringType(options, keys) {
return keys.some((key) => options[key] !== void 0);
}
function getSpringOptions(options) {
let springOptions = {
velocity: springDefaults.velocity,
stiffness: springDefaults.stiffness,
damping: springDefaults.damping,
mass: springDefaults.mass,
isResolvedFromDuration: false,
...options
};
if (!isSpringType(options, physicsKeys) && isSpringType(options, durationKeys)) {
if (options.visualDuration) {
const visualDuration = options.visualDuration;
const root = 2 * Math.PI / (visualDuration * 1.2);
const stiffness = root * root;
const damping = 2 * clamp(0.05, 1, 1 - (options.bounce || 0)) * Math.sqrt(stiffness);
springOptions = {
...springOptions,
mass: springDefaults.mass,
stiffness,
damping
};
} else {
const derived = findSpring(options);
springOptions = {
...springOptions,
...derived,
mass: springDefaults.mass
};
springOptions.isResolvedFromDuration = true;
}
}
return springOptions;
}
function spring(optionsOrVisualDuration = springDefaults.visualDuration, bounce = springDefaults.bounce) {
const options = typeof optionsOrVisualDuration !== "object" ? {
visualDuration: optionsOrVisualDuration,
keyframes: [0, 1],
bounce
} : optionsOrVisualDuration;
let { restSpeed, restDelta } = options;
const origin = options.keyframes[0];
const target = options.keyframes[options.keyframes.length - 1];
const state = { done: false, value: origin };
const { stiffness, damping, mass, duration, velocity, isResolvedFromDuration } = getSpringOptions({
...options,
velocity: -millisecondsToSeconds(options.velocity || 0)
});
const initialVelocity = velocity || 0;
const dampingRatio = damping / (2 * Math.sqrt(stiffness * mass));
const initialDelta = target - origin;
const undampedAngularFreq = millisecondsToSeconds(Math.sqrt(stiffness / mass));
const isGranularScale = Math.abs(initialDelta) < 5;
restSpeed || (restSpeed = isGranularScale ? springDefaults.restSpeed.granular : springDefaults.restSpeed.default);
restDelta || (restDelta = isGranularScale ? springDefaults.restDelta.granular : springDefaults.restDelta.default);
let resolveSpring;
if (dampingRatio < 1) {
const angularFreq = calcAngularFreq(undampedAngularFreq, dampingRatio);
resolveSpring = (t) => {
const envelope = Math.exp(-dampingRatio * undampedAngularFreq * t);
return target - envelope * ((initialVelocity + dampingRatio * undampedAngularFreq * initialDelta) / angularFreq * Math.sin(angularFreq * t) + initialDelta * Math.cos(angularFreq * t));
};
} else if (dampingRatio === 1) {
resolveSpring = (t) => target - Math.exp(-undampedAngularFreq * t) * (initialDelta + (initialVelocity + undampedAngularFreq * initialDelta) * t);
} else {
const dampedAngularFreq = undampedAngularFreq * Math.sqrt(dampingRatio * dampingRatio - 1);
resolveSpring = (t) => {
const envelope = Math.exp(-dampingRatio * undampedAngularFreq * t);
const freqForT = Math.min(dampedAngularFreq * t, 300);
return target - envelope * ((initialVelocity + dampingRatio * undampedAngularFreq * initialDelta) * Math.sinh(freqForT) + dampedAngularFreq * initialDelta * Math.cosh(freqForT)) / dampedAngularFreq;
};
}
const generator = {
calculatedDuration: isResolvedFromDuration ? duration || null : null,
next: (t) => {
const current = resolveSpring(t);
if (!isResolvedFromDuration) {
let currentVelocity = t === 0 ? initialVelocity : 0;
if (dampingRatio < 1) {
currentVelocity = t === 0 ? secondsToMilliseconds(initialVelocity) : calcGeneratorVelocity(resolveSpring, t, current);
}
const isBelowVelocityThreshold = Math.abs(currentVelocity) <= restSpeed;
const isBelowDisplacementThreshold = Math.abs(target - current) <= restDelta;
state.done = isBelowVelocityThreshold && isBelowDisplacementThreshold;
} else {
state.done = t >= duration;
}
state.value = state.done ? target : current;
return state;
},
toString: () => {
const calculatedDuration = Math.min(calcGeneratorDuration(generator), maxGeneratorDuration);
const easing = generateLinearEasing((progress2) => generator.next(calculatedDuration * progress2).value, calculatedDuration, 30);
return calculatedDuration + "ms " + easing;
},
toTransition: () => {
}
};
return generator;
}
spring.applyToOptions = (options) => {
const generatorOptions = createGeneratorEasing(options, 100, spring);
options.ease = generatorOptions.ease;
options.duration = secondsToMilliseconds(generatorOptions.duration);
options.type = "keyframes";
return options;
};
// node_modules/motion-dom/dist/es/animation/generators/inertia.mjs
function inertia({ keyframes: keyframes2, velocity = 0, power = 0.8, timeConstant = 325, bounceDamping = 10, bounceStiffness = 500, modifyTarget, min, max, restDelta = 0.5, restSpeed }) {
const origin = keyframes2[0];
const state = {
done: false,
value: origin
};
const isOutOfBounds = (v) => min !== void 0 && v < min || max !== void 0 && v > max;
const nearestBoundary = (v) => {
if (min === void 0)
return max;
if (max === void 0)
return min;
return Math.abs(min - v) < Math.abs(max - v) ? min : max;
};
let amplitude = power * velocity;
const ideal = origin + amplitude;
const target = modifyTarget === void 0 ? ideal : modifyTarget(ideal);
if (target !== ideal)
amplitude = target - origin;
const calcDelta = (t) => -amplitude * Math.exp(-t / timeConstant);
const calcLatest = (t) => target + calcDelta(t);
const applyFriction = (t) => {
const delta = calcDelta(t);
const latest = calcLatest(t);
state.done = Math.abs(delta) <= restDelta;
state.value = state.done ? target : latest;
};
let timeReachedBoundary;
let spring$1;
const checkCatchBoundary = (t) => {
if (!isOutOfBounds(state.value))
return;
timeReachedBoundary = t;
spring$1 = spring({
keyframes: [state.value, nearestBoundary(state.value)],
velocity: calcGeneratorVelocity(calcLatest, t, state.value),
// TODO: This should be passing * 1000
damping: bounceDamping,
stiffness: bounceStiffness,
restDelta,
restSpeed
});
};
checkCatchBoundary(0);
return {
calculatedDuration: null,
next: (t) => {
let hasUpdatedFrame = false;
if (!spring$1 && timeReachedBoundary === void 0) {
hasUpdatedFrame = true;
applyFriction(t);
checkCatchBoundary(t);
}
if (timeReachedBoundary !== void 0 && t >= timeReachedBoundary) {
return spring$1.next(t - timeReachedBoundary);
} else {
!hasUpdatedFrame && applyFriction(t);
return state;
}
}
};
}
// node_modules/motion-dom/dist/es/utils/interpolate.mjs
function createMixers(output, ease2, customMixer) {
const mixers = [];
const mixerFactory = customMixer || MotionGlobalConfig.mix || mix;
const numMixers = output.length - 1;
for (let i = 0; i < numMixers; i++) {
let mixer = mixerFactory(output[i], output[i + 1]);
if (ease2) {
const easingFunction = Array.isArray(ease2) ? ease2[i] || noop : ease2;
mixer = pipe(easingFunction, mixer);
}
mixers.push(mixer);
}
return mixers;
}
function interpolate(input, output, { clamp: isClamp = true, ease: ease2, mixer } = {}) {
const inputLength = input.length;
invariant(inputLength === output.length, "Both input and output ranges must be the same length", "range-length");
if (inputLength === 1)
return () => output[0];
if (inputLength === 2 && output[0] === output[1])
return () => output[1];
const isZeroDeltaRange = input[0] === input[1];
if (input[0] > input[inputLength - 1]) {
input = [...input].reverse();
output = [...output].reverse();
}
const mixers = createMixers(output, ease2, mixer);
const numMixers = mixers.length;
const interpolator = (v) => {
if (isZeroDeltaRange && v < input[0])
return output[0];
let i = 0;
if (numMixers > 1) {
for (; i < input.length - 2; i++) {
if (v < input[i + 1])
break;
}
}
const progressInRange = progress(input[i], input[i + 1], v);
return mixers[i](progressInRange);
};
return isClamp ? (v) => interpolator(clamp(input[0], input[inputLength - 1], v)) : interpolator;
}
// node_modules/motion-dom/dist/es/animation/keyframes/offsets/fill.mjs
function fillOffset(offset, remaining) {
const min = offset[offset.length - 1];
for (let i = 1; i <= remaining; i++) {
const offsetProgress = progress(0, remaining, i);
offset.push(mixNumber(min, 1, offsetProgress));
}
}
// node_modules/motion-dom/dist/es/animation/keyframes/offsets/default.mjs
function defaultOffset(arr) {
const offset = [0];
fillOffset(offset, arr.length - 1);
return offset;
}
// node_modules/motion-dom/dist/es/animation/keyframes/offsets/time.mjs
function convertOffsetToTimes(offset, duration) {
return offset.map((o) => o * duration);
}
// node_modules/motion-dom/dist/es/animation/generators/keyframes.mjs
function defaultEasing(values, easing) {
return values.map(() => easing || easeInOut).splice(0, values.length - 1);
}
function keyframes({ duration = 300, keyframes: keyframeValues, times, ease: ease2 = "easeInOut" }) {
const easingFunctions = isEasingArray(ease2) ? ease2.map(easingDefinitionToFunction) : easingDefinitionToFunction(ease2);
const state = {
done: false,
value: keyframeValues[0]
};
const absoluteTimes = convertOffsetToTimes(
// Only use the provided offsets if they're the correct length
// TODO Maybe we should warn here if there's a length mismatch
times && times.length === keyframeValues.length ? times : defaultOffset(keyframeValues),
duration
);
const mapTimeToKeyframe = interpolate(absoluteTimes, keyframeValues, {
ease: Array.isArray(easingFunctions) ? easingFunctions : defaultEasing(keyframeValues, easingFunctions)
});
return {
calculatedDuration: duration,
next: (t) => {
state.value = mapTimeToKeyframe(t);
state.done = t >= duration;
return state;
}
};
}
// node_modules/motion-dom/dist/es/animation/keyframes/get-final.mjs
var isNotNull = (value) => value !== null;
function getFinalKeyframe(keyframes2, { repeat, repeatType = "loop" }, finalKeyframe, speed = 1) {
const resolvedKeyframes = keyframes2.filter(isNotNull);
const useFirstKeyframe = speed < 0 || repeat && repeatType !== "loop" && repeat % 2 === 1;
const index = useFirstKeyframe ? 0 : resolvedKeyframes.length - 1;
return !index || finalKeyframe === void 0 ? resolvedKeyframes[index] : finalKeyframe;
}
// node_modules/motion-dom/dist/es/animation/utils/replace-transition-type.mjs
var transitionTypeMap = {
decay: inertia,
inertia,
tween: keyframes,
keyframes,
spring
};
function replaceTransitionType(transition) {
if (typeof transition.type === "string") {
transition.type = transitionTypeMap[transition.type];
}
}
// node_modules/motion-dom/dist/es/animation/utils/WithPromise.mjs
var WithPromise = class {
constructor() {
this.updateFinished();
}
get finished() {
return this._finished;
}
updateFinished() {
this._finished = new Promise((resolve) => {
this.resolve = resolve;
});
}
notifyFinished() {
this.resolve();
}
/**
* Allows the animation to be awaited.
*
* @deprecated Use `finished` instead.
*/
then(onResolve, onReject) {
return this.finished.then(onResolve, onReject);
}
};
// node_modules/motion-dom/dist/es/animation/JSAnimation.mjs
var percentToProgress = (percent2) => percent2 / 100;
var JSAnimation = class extends WithPromise {
constructor(options) {
super();
this.state = "idle";
this.startTime = null;
this.isStopped = false;
this.currentTime = 0;
this.holdTime = null;
this.playbackSpeed = 1;
this.stop = () => {
const { motionValue: motionValue2 } = this.options;
if (motionValue2 && motionValue2.updatedAt !== time.now()) {
this.tick(time.now());
}
this.isStopped = true;
if (this.state === "idle")
return;
this.teardown();
this.options.onStop?.();
};
activeAnimations.mainThread++;
this.options = options;
this.initAnimation();
this.play();
if (options.autoplay === false)
this.pause();
}
initAnimation() {
const { options } = this;
replaceTransitionType(options);
const { type = keyframes, repeat = 0, repeatDelay = 0, repeatType, velocity = 0 } = options;
let { keyframes: keyframes$1 } = options;
const generatorFactory = type || keyframes;
if (process.env.NODE_ENV !== "production" && generatorFactory !== keyframes) {
invariant(keyframes$1.length <= 2, `Only two keyframes currently supported with spring and inertia animations. Trying to animate ${keyframes$1}`, "spring-two-frames");
}
if (generatorFactory !== keyframes && typeof keyframes$1[0] !== "number") {
this.mixKeyframes = pipe(percentToProgress, mix(keyframes$1[0], keyframes$1[1]));
keyframes$1 = [0, 100];
}
const generator = generatorFactory({ ...options, keyframes: keyframes$1 });
if (repeatType === "mirror") {
this.mirroredGenerator = generatorFactory({
...options,
keyframes: [...keyframes$1].reverse(),
velocity: -velocity
});
}
if (generator.calculatedDuration === null) {
generator.calculatedDuration = calcGen