@function breakpoint-infix-jtl($name, $breakpoints: $grid-breakpoints) {
	@return if(breakpoint-min($name, $breakpoints) == null, '', #{$name}-);
}

@function rem($pixels, $default: 16px) {
	@if (unitless($pixels)) {
		$pixels: $pixels * 1px;
	}
	@if (unitless($default)) {
		$default: $default * 1px;
	}
	@return $pixels / $default * 1rem;
}

@function pow($number, $exp) {
	$value: 1;

	@if $exp > 0 {
		@for $i from 1 through $exp {
			$value: $value * $number;
		}
	}
	@else if $exp < 0 {
		@for $i from 1 through -$exp {
			$value: $value / $number;
		}
	}

	@return $value;
}

@function fact($number) {
	$value: 1;

	@if $number > 0 {
		@for $i from 1 through $number {
			$value: $value * $i;
		}
	}

	@return $value;
}

@function pi() {
	@return 3.14159265359;
}

@function rad($angle) {
	$unit: unit($angle);
	$unitless: $angle / ($angle * 0 + 1);

	@if $unit == deg {
		$unitless: $unitless / 180 * pi();
	}

	@return $unitless;
}

@function sin($angle) {
	$sin: 0;
	$angle: rad($angle);

	@for $i from 0 through 10 {
		$sin: $sin + pow(-1, $i) * pow($angle, (2 * $i + 1)) / fact(2 * $i + 1);
	}

	@return $sin;
}

@function cos($angle) {
	$cos: 0;
	$angle: rad($angle);

	@for $i from 0 through 10 {
		$cos: $cos + pow(-1, $i) * pow($angle, 2 * $i) / fact(2 * $i);
	}

	@return $cos;
}

@function tan($angle) {
	@return sin($angle) / cos($angle);
}

@function str-replace($string, $search, $replace: "") {
	$index: str-index($string, $search);

	@if $index {
		@return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
	}

	@return $string;
}

@function header-height($breakpoint) {
	@if $breakpoint == lg {
		@return $navbar-image-height-lg + 2 * $navbar-padding-y-lg;
	}
	@return $navbar-image-height + 2 * $navbar-padding-y;
}

/* This function only exists to allow abstracs/_variables to use yiq-logic, as well, without having Bootstrap functions (which contain the "real" color-yiq) loaded before. It essentially works the same but has no optional parameters. */
$et-yiq-contrasted-threshold: 150 !default;
// Color contrast
@function et-color-yiq($color, $dark, $light) {
	$r: red($color);
	$g: green($color);
	$b: blue($color);

	$yiq: (($r * 299) + ($g * 587) + ($b * 114)) / 1000;

	@if ($yiq >= $et-yiq-contrasted-threshold) {
		@return $dark;
	} @else {
		@return $light;
	}
}

/*
The following is code for the WCAG conforming computation of colors.
It is based on https://github.com/jhogue/automated-a11y-sass but reduced to assuming 4.5 contrast ratio all round.
*/

// @function et-pow($base, $exponents)
// Helper: Raise a number the power of another number
// Adapted from: https://gist.github.com/hail2u/1964056
@function et-pow($base, $exponents) {
	$raised: 1;
	@for $i from 1 through $exponents {
		$raised: $raised * $base;
	}
	@return $raised;
}

// @function et-luminance($color)
// Helper: Calculate Luminance of a single color
@function et-luminance($color) {
	$rgba: red($color), green($color), blue($color);
	$rgba2: ();
	@for $i from 1 through 3 {
		$rgb: nth($rgba, $i);
		$rgb: $rgb / 255;
		$rgb: if($rgb < .03928, $rgb / 12.92, et-pow(($rgb + .055) / 1.055, 2));
		$rgba2: append($rgba2, $rgb);
	}
	@return .2126 * nth($rgba2, 1) + .7152 * nth($rgba2, 2) + 0.0722 * nth($rgba2, 3);
}

// @function et-contrast-ratio($fg, $bg)
// Helper: Calculate "readability" as defined by WCAG 2.1
@function et-contrast-ratio($fg, $bg) {
	$luminance1: et-luminance($fg) + 0.05;
	$luminance2: et-luminance($bg) + 0.05;
	$ratio: $luminance1 / $luminance2;
	@if $luminance2 > $luminance1 {
		$ratio: 1 / $ratio;
	}
	// Round to a hundreth because 6.96 should not pass a ratio of 7.0
	$ratio: round($ratio * 100) / 100;
	@return $ratio;
}

// @function et-light-or-dark($color)
// Helper: Use contrast against white or black to determine if a color is "light" or "dark"
@function et-light-or-dark($color) {
	$light-contrast: et-contrast-ratio($color, #fff);
	$dark-contrast: et-contrast-ratio($color, #000);
	@if $light-contrast > $dark-contrast {
		@return "dark";
	} @else {
		@return "light";
	}
}

// @function et-a11y-color($fg, $bg)
// Goal: Return a color that passes for the chosen WCAG level without changing the Hue of the color
@function et-a11y-color($fg, $bg) {
	$ratio: 4.5;
	$original-contrast: et-contrast-ratio($fg, $bg);
	@if $original-contrast >= $ratio {
		@return $fg;
	} @else {
		$fg-lod: et-light-or-dark($fg);
		$bg-lod: et-light-or-dark($bg);
		$adjustmentFunction: "lighten";
		@if $fg-lod == 'light' and $bg-lod == 'light' {
			// Both are light colors, darken the fg
			$adjustmentFunction: "darken";
		} @else if $fg-lod == 'dark' and $bg-lod == 'light' {
			// bg is light, fg is dark but does not pass, darken more
			$adjustmentFunction: "darken";
		}

		// Loop through with a @while statement until the color combination passes our required ratio.
		$limit: 100;
		$counter: 1;
		@while et-contrast-ratio($fg, $bg) < $ratio and $counter < $limit {
			@if $adjustmentFunction == "lighten" {
				$fg: lighten($fg, 1%);
			} @else {
				$fg: darken($fg, 1%);
			}
			$counter: $counter + 1;
		}
		@return $fg;
	}
}