<commit_before>import { currentFrameTime } from 'framesync';
import { color, Color, hsla, HSLA } from 'style-value-types';
import { getProgressFromValue, getValueFromProgress, smooth as calcSmoothing, stepProgress } from './calc';
import { Easing } from './easing';

const noop = (v: any): any => v;

/**
 * Append Unit
 * A function that will append
 * appendUnit('px', 20) -> '20px'
 * @param  {string} unit)
 * @return {number}
 */
export const appendUnit = (unit: string) => (v: number) => `${v}${unit}`;

/**
 * Apply offset
 * A function that, given a value, will get the offset from `from`
 * and apply it to `to`
 * @param  {number} from
 * @param  {number} to
 * @return {function}
 */
export const applyOffset = (from: number, to?: number) => {
  let hasReceivedFrom = true;
  if (to === undefined) {
    to = from;
    hasReceivedFrom = false;
  }

  const getOffset = (v: number) => v - from;
  const applyOffsetTo = (v: number) => v + to;
  return (v: number) => {
    if (hasReceivedFrom) {
      return applyOffsetTo(getOffset(v));
    } else {
      from = v;
      hasReceivedFrom = true;
      return to;
    }
  };
};

const blend = (from: number, to: number, v: number) => {
  const fromExpo = from * from;
  const toExpo = to * to;
  return Math.sqrt(v * (toExpo - fromExpo) + fromExpo);
};

// http://codepen.io/osublake/pen/xGVVaN
export const blendColor = (from: Color | string, to: Color | string) => {
  const fromColor = (typeof from === 'string') ? color.parse(from) : from;
  const toColor = (typeof to === 'string') ? color.parse(to) : to;
  let blended = { ...fromColor };

  // Only use the sqrt blending function for rgba and hex
  const blendFunc = (
    (from as HSLA).hue !== undefined ||
    typeof from === 'string' && hsla.test(from as string)
  ) ? getValueFromProgress
    : blend;

  return (v: number) => {
    blended = { ...blended };
    for (const key in blended) {
      if (key !== 'alpha' && blended.hasOwnProperty(key)) {
        blended[key] = blendFunc(fromColor[key], toColor[key], v);
      }
    }

    blended.alpha = getValueFromProgress(fromColor.alpha, toColor.alpha, v);

    return blended;
  };
};

/**
 * Clamp value between
 * Creates a function that will restrict a given value between `min` and `max`
 * @param  {number} min
 * @param  {number} max
 * @return {number}
 */
export const clamp = (min: number, max: number) => (v: number) => Math.min(Math.max(v, min), max);

/**
 * Pipe
 * Compose other transformers to run linearily
 * pipe(min(20), max(40))
 * @param  {...functions} transformers
 * @return {function}
 */
const combineFunctions = (a: Function, b: Function) => (v: any) => b(a(v));
export const pipe = (...transformers: Function[]) => transformers.reduce(combineFunctions);

/**
 * Conditionally apply a transformer using the provided function when `check` returns `true`
 */
export type Check = (v: any) => boolean;
export type Apply = (v: any) => number;
export const conditional = (check: Check, apply: Apply) => (v: any): any => check(v) ? apply(v) : v;

/**
 * Interpolate from set of values to another
 */
export const interpolate = (input: number[], output: number[], rangeEasing: Easing[]) => {
  const rangeLength = input.length;
  const finalIndex = rangeLength - 1;

  // If input runs highest -> lowest, reverse both arrays
  if (input[0] > input[finalIndex]) {
    input.reverse();
    output.reverse();
  }

  return (v: number) => {
    // If value outside minimum range, quickly return
    if (v <= input[0]) {
      return output[0];
    }

    // If value outside maximum range, quickly return
    if (v >= input[finalIndex]) {
      return output[finalIndex];<commit_msg>the Apply function should return type any<commit_after>import { currentFrameTime } from 'framesync';
import { color, Color, hsla, HSLA } from 'style-value-types';
import { getProgressFromValue, getValueFromProgress, smooth as calcSmoothing, stepProgress } from './calc';
import { Easing } from './easing';

const noop = (v: any): any => v;

/**
 * Append Unit
 * A function that will append
 * appendUnit('px', 20) -> '20px'
 * @param  {string} unit)
 * @return {number}
 */
export const appendUnit = (unit: string) => (v: number) => `${v}${unit}`;

/**
 * Apply offset
 * A function that, given a value, will get the offset from `from`
 * and apply it to `to`
 * @param  {number} from
 * @param  {number} to
 * @return {function}
 */
export const applyOffset = (from: number, to?: number) => {
  let hasReceivedFrom = true;
  if (to === undefined) {
    to = from;
    hasReceivedFrom = false;
  }

  const getOffset = (v: number) => v - from;
  const applyOffsetTo = (v: number) => v + to;
  return (v: number) => {
    if (hasReceivedFrom) {
      return applyOffsetTo(getOffset(v));
    } else {
      from = v;
      hasReceivedFrom = true;
      return to;
    }
  };
};

const blend = (from: number, to: number, v: number) => {
  const fromExpo = from * from;
  const toExpo = to * to;
  return Math.sqrt(v * (toExpo - fromExpo) + fromExpo);
};

// http://codepen.io/osublake/pen/xGVVaN
export const blendColor = (from: Color | string, to: Color | string) => {
  const fromColor = (typeof from === 'string') ? color.parse(from) : from;
  const toColor = (typeof to === 'string') ? color.parse(to) : to;
  let blended = { ...fromColor };

  // Only use the sqrt blending function for rgba and hex
  const blendFunc = (
    (from as HSLA).hue !== undefined ||
    typeof from === 'string' && hsla.test(from as string)
  ) ? getValueFromProgress
    : blend;

  return (v: number) => {
    blended = { ...blended };
    for (const key in blended) {
      if (key !== 'alpha' && blended.hasOwnProperty(key)) {
        blended[key] = blendFunc(fromColor[key], toColor[key], v);
      }
    }

    blended.alpha = getValueFromProgress(fromColor.alpha, toColor.alpha, v);

    return blended;
  };
};

/**
 * Clamp value between
 * Creates a function that will restrict a given value between `min` and `max`
 * @param  {number} min
 * @param  {number} max
 * @return {number}
 */
export const clamp = (min: number, max: number) => (v: number) => Math.min(Math.max(v, min), max);

/**
 * Pipe
 * Compose other transformers to run linearily
 * pipe(min(20), max(40))
 * @param  {...functions} transformers
 * @return {function}
 */
const combineFunctions = (a: Function, b: Function) => (v: any) => b(a(v));
export const pipe = (...transformers: Function[]) => transformers.reduce(combineFunctions);

/**
 * Conditionally apply a transformer using the provided function when `check` returns `true`
 */
export type Check = (v: any) => boolean;
export type Apply = (v: any) => any;
export const conditional = (check: Check, apply: Apply) => (v: any): any => check(v) ? apply(v) : v;

/**
 * Interpolate from set of values to another
 */
export const interpolate = (input: number[], output: number[], rangeEasing: Easing[]) => {
  const rangeLength = input.length;
  const finalIndex = rangeLength - 1;

  // If input runs highest -> lowest, reverse both arrays
  if (input[0] > input[finalIndex]) {
    input.reverse();
    output.reverse();
  }

  return (v: number) => {
    // If value outside minimum range, quickly return
    if (v <= input[0]) {
      return output[0];
    }

    // If value outside maximum range, quickly return
    if (v >= input[finalIndex]) {
      return output[finalIndex];
{'fraction_non_alphanumeric': 0.15705954157059543, 'fraction_numerical': 0.0032551200325512003, 'mean_word_length': 3.3249266862170086, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2750261', 'n_tokens_mistral': 2397, 'n_tokens_neox': 2350, 'n_words': 773}