export function cssVar(expression, el) {
    const match = /var\((--[\w-]+)(?:,\s*([^)]+))?\)/.exec(expression);
    if (!match)
        return expression;
    const [, variable, fallback] = match;
    const value = getComputedStyle(el).getPropertyValue(variable).trim();
    return value || fallback || null;
}
export function animateTo(el, keyframes, options) {
    return new Promise(resolve => {
        if (options?.duration === Infinity) {
            throw new Error('Promise-based animations must be finite.');
        }
        const reducedMotion = prefersReducedMotion();
        const duration = typeof options.duration === 'string' ? parseDuration(cssVar(options.duration, el) ?? '') : options.duration;
        const animation = el.animate(keyframes, {
            ...options,
            duration: reducedMotion && options?.reducedMotion !== 'allow' ? 0 : duration
        });
        animation.addEventListener('cancel', resolve, { once: true });
        animation.addEventListener('finish', resolve, { once: true });
    });
}
export function parseDuration(delay) {
    delay = delay.toString().toLowerCase();
    if (delay.indexOf('ms') > -1) {
        return parseFloat(delay);
    }
    if (delay.indexOf('s') > -1) {
        return parseFloat(delay) * 1000;
    }
    return parseFloat(delay);
}
export function prefersReducedMotion() {
    const query = window.matchMedia('(prefers-reduced-motion: reduce)');
    return query.matches;
}
export function stopAnimations(el) {
    return Promise.all(el.getAnimations().map(animation => {
        return new Promise(resolve => {
            const handleAnimationEvent = requestAnimationFrame(resolve);
            animation.addEventListener('cancel', () => handleAnimationEvent, { once: true });
            animation.addEventListener('finish', () => handleAnimationEvent, { once: true });
            animation.cancel();
        });
    }));
}
export function shimKeyframesHeightAuto(keyframes, calculatedHeight) {
    return keyframes.map(keyframe => ({
        ...keyframe,
        height: keyframe.height === 'auto' ? `${calculatedHeight}px` : keyframe.height
    }));
}
