HEX
Server: Apache/2.4.52 (Ubuntu)
System: Linux spn-python 5.15.0-89-generic #99-Ubuntu SMP Mon Oct 30 20:42:41 UTC 2023 x86_64
User: arjun (1000)
PHP: 8.1.2-1ubuntu2.20
Disabled: NONE
Upload Files
File: /var/www/html/insiders/wp-load/wp-content/plugins/gutenmate/lib/css.php
<?php

function gtm_css_hasValue( $val ) {
	return ! is_null( $val ) && $val !== "" && $val !== false && ( ! is_array( $val ) || ! empty( $val ) );
}

function gtm_css_cssProps( $name, $val, $unit = "" ) {
	$props = [];

	if ( is_array( $val ) ) {
		// Responsive attribute
		if ( isset( $val['lg'] ) && gtm_css_hasValue( $val['lg'] ) ) {
			$props[$name . "---lg"] = $val['lg'] . $unit;
		}

		if ( isset( $val['md'] ) && gtm_css_hasValue( $val['md'] ) ) {
			$props[$name . "---md"] = $val['md'] . $unit;
		}

		if ( isset( $val['sm'] ) && gtm_css_hasValue( $val['sm'] ) ) {
			$props[$name . "---sm"] = $val['sm'] . $unit;
		}

	} else {
		// Regular attribute
		if ( gtm_css_hasValue( $val ) ) {
			$props[$name] = $val . $unit;
		}
	}

	return $props;
}

function gtm_css_cssPropsIf( $theCondition, $name, $val, $unit = "" ) {
	if ( $theCondition ) {
		if ( is_string( $name ) ) {
			return gtm_css_cssProps( $name, $val, $unit );
		} else {
			return $name;
		}
	}

	return [];
}

function gtm_css_isCssUnitValue( $val ) {
	if ( is_null( $val ) ) {
		return false;
	}

	return preg_match( '/^[\-0-9.]+(px|%|em|rem|vh|vw)$/i', $val );
}

function gtm_css_isCssVariableValue( $val ) {
	if ( is_null( $val ) ) {
		return false;
	}

	return preg_match( '/^var\(/i', $val );
}

function gtm_css_isCustomShadowValue( $val ) {
	if ( is_null( $val ) ) {
		return false;
	}

	return preg_match( '/^[\-0-9.]+px [\-0-9.]+px/i', $val );
}

function gtm_css_isSingularValue( $val ) {
	return (
		! is_array( $val ) &&
		( is_string( $val ) || is_numeric( $val ) )
	);
}

function gtm_css_isResponsiveValue( $val ) {
	return (
		is_array( $val ) &&
		( isset( $val['lg'] ) ||
			isset( $val['md'] ) ||
			isset( $val['sm'] )
		)
	);
}

function gtm_css_parseResponsiveFontSizeValue( $value, $defaultValue = "" ) {
	if ( is_array( $value ) ) {
		$parsedValue = [];

		if ( isset( $value['lg'] ) ) {
			$parsedValue['lg'] = gtm_css_parseFontSizeValue( $value['lg'], $defaultValue );
		}

		if ( isset( $value['md'] ) ) {
			$parsedValue['md'] = gtm_css_parseFontSizeValue( $value['md'], $defaultValue );
		}

		if ( isset( $value['sm'] ) ) {
			$parsedValue['sm'] = gtm_css_parseFontSizeValue( $value['sm'], $defaultValue );
		}

		return $parsedValue;
	}

	return gtm_css_parseFontSizeValue( $value, $defaultValue );
}

function gtm_css_parseFontSizeValue( $value, $defaultValue = "" ) {
	if ( gtm_css_isCssUnitValue( $value ) ) {
		return $value;
	} else if ( gtm_css_isCssVariableValue( $value ) ) {
		return $value;
	} else if ( gtm_css_hasValue( $value ) ) {
		if ( gtm_startsWith( $value, GTM_PRESET_SLUG_VALUE_PREFIX ) ) {
			$varName = "--gtm--font-size--{$value}";
		} else {
			$varName = "--wp--preset--font-size--{$value}";
		}

		if ( $defaultValue ) {
			return "var({$varName}, {$defaultValue})";
		} else {
			return "var({$varName})";
		}
	}
}

function gtm_css_presetCssParser( $attributes ) {
	$css  = [];
	$root = [];

	// Generate css for type scale
	if ( ! empty( $attributes['fontSizes'] ) ) {
		foreach ( $attributes['fontSizes'] as $fontSize ) {
			if ( $fontSize ) {
				$root += gtm_css_cssProps( "--gtm--font-size--{$fontSize['slug']}", $fontSize['size'] );
			}
		}
	}

	// Generate css for typography
	if ( ! empty( $attributes['typography'] ) ) {
		foreach ( $attributes['typography'] as $typo ) {
			$inlineImport = gtm_css_getImportGoogleFont( $typo );

			$root += $inlineImport;

			$family_stacks = '';
			if ( ! empty( $typo['fontFamily'] ) ) {
				$family_stacks = $typo['fontFamily'] . ', var(--gtm-typography-font-stacks, sans-serif)';
			}

			$root += gtm_css_cssProps( "--gtm--typography--{$typo['slug']}--font-family", $family_stacks );
			$root += gtm_css_cssProps( "--gtm--typography--{$typo['slug']}--font-weight", $typo['fontWeight'] ?? '' );
			$root += gtm_css_cssProps( "--gtm--typography--{$typo['slug']}--font-style", preg_match( '/i$/i', $typo['fontWeight'] ?? '' ) ? 'italic' : 'normal' );
			$root += gtm_css_cssProps( "--gtm--typography--{$typo['slug']}--font-size", gtm_css_parseResponsiveFontSizeValue( $typo['fontSize'] ?? '' ) );
			$root += gtm_css_cssProps( "--gtm--typography--{$typo['slug']}--line-height", $typo['lineHeight'] ?? '' );
			$root += gtm_css_cssProps( "--gtm--typography--{$typo['slug']}--letter-spacing", $typo['letterSpacing'] ?? '' );
			$root += gtm_css_cssProps( "--gtm--typography--{$typo['slug']}--text-transform", $typo['textTransform'] ?? '' );

			/* Generate has class */
			$has_typo = [];
			$has_typo += gtm_css_cssPropsIf( $family_stacks, 'font-family', "var( --gtm--typography--{$typo['slug']}--font-family )" );
			$has_typo += gtm_css_cssPropsIf( $typo['fontWeight'] ?? '', 'font-weight', "var( --gtm--typography--{$typo['slug']}--font-weight )" );
			$has_typo += gtm_css_cssPropsIf( preg_match( '/i$/i', $typo['fontWeight'] ?? '' ), 'font-style', "var( --gtm--typography--{$typo['slug']}--font-style )" );
			$has_typo += gtm_css_cssPropsIf( gtm_css_parseResponsiveFontSizeValue( $typo['fontSize'] ?? '' ) ?? '', 'font-size', "var( --gtm--typography--{$typo['slug']}--font-size )" );
			$has_typo += gtm_css_cssPropsIf( $typo['lineHeight'] ?? '', 'line-height', "var( --gtm--typography--{$typo['slug']}--line-height )" );
			$has_typo += gtm_css_cssPropsIf( $typo['letterSpacing'] ?? '', 'letter-spacing', "var( --gtm--typography--{$typo['slug']}--letter-spacing )" );
			$has_typo += gtm_css_cssPropsIf( $typo['textTransform'] ?? '', 'text-transform', "var( --gtm--typography--{$typo['slug']}--text-transform )" );

			$css[".gtm-has-typography-{$typo['slug']}"] = $has_typo;
		}
	}

	// Generate css for spacing
	if ( ! empty( $attributes['spacing'] ) ) {
		foreach ( $attributes['spacing'] as $space ) {
			if ( $space ) {
				$root += gtm_css_cssProps( "--gtm--space--{$space['slug']}", $space['size'] );
			}
		}
	}

	$css['body'] = $root;
	return $css;
}

function gtm_css_getImportGoogleFont( $typo ) {
	$inlineImport = [];

	if ( ! empty( $typo['fontFamily'] ) && gtm_css_isGoogleFont( $typo['fontFamily'] ) ) {
		$weight = $typo['fontWeight'] ?? '400';

		$slug = ! empty( $typo['slug'] ) ? $typo['slug'] : $typo['fontFamily'];

		/* php only */
		$handle = gtm_generate_web_font_handle( $slug, $weight );

		if ( ! gtm_is_block_editor_screen() ) {
			Gtm_Webfont_Loader::get_instance()->add( $typo['fontFamily'], $weight );
		} else {
			$handle                             = gtm_generate_web_font_handle( $typo['fontFamily'], $weight );
			$inlineImport['@import ' . $handle] = gtm_generate_web_font_url( $typo['fontFamily'], $weight );
		}
		/* end php only */

		/* Support preloadFontWeight */
		if ( ! empty( $typo['preloadFontWeight'] ) ) {
			$weights = explode( ',', $typo['preloadFontWeight'] );

			foreach ( $weights as $weight ) {
				if ( ! empty( $weight ) ) {
					/* php only */
					if ( ! gtm_is_block_editor_screen() ) {
						Gtm_Webfont_Loader::get_instance()->add( $typo['fontFamily'], $weight );
					} else {
						$handle                             = gtm_generate_web_font_handle( $typo['fontFamily'], $weight );
						$inlineImport['@import ' . $handle] = gtm_generate_web_font_url( $typo['fontFamily'], $weight );
					}
					/* end php only */
				}
			}
		}

		/* Support fontWeightBold and fontWeightItalic */
		if ( ! empty( $typo['fontWeight'] ) ) {
			$additionalWeights = ['Bold', 'Italic'];
			foreach ( $additionalWeights as $weightName ) {
				$weight = $typo['fontWeight' . $weightName];
				if ( ! empty( $weight ) ) {
					/* php only */
					if ( ! gtm_is_block_editor_screen() ) {
						Gtm_Webfont_Loader::get_instance()->add( $typo['fontFamily'], $weight );
					} else {
						$handle                             = gtm_generate_web_font_handle( $typo['fontFamily'], $weight );
						$inlineImport['@import ' . $handle] = gtm_generate_web_font_url( $typo['fontFamily'], $weight );
					}
					/* end php only */
				}
			}
		}
	}

	return $inlineImport;
}

function gtm_css_isGoogleFont( $fontName ) {
	$list = include GTM_LIB_DIR . 'google-font-list.php';
	return array_key_exists( $fontName, $list );
}

function gtm_css_generateCss( $compiledCssTemplate, $options = [] ) {
	$options = wp_parse_args( $options, [
		'suppress-import' => false,
	] );

	$supported_media = [
		'lg' => '',
		'md' => '(max-width: 1199.98px)',
		'sm' => '(max-width: 767.98px)',
	];

	$rawCss = '';

	foreach ( ['import', 'all', 'lg', 'md', 'sm'] as $media ) {
		if ( ! isset( $compiledCssTemplate[$media] ) ) {
			continue;
		}

		if ( 'import' == $media ) {
			if ( ! $options['suppress-import'] ) {
				$import = $compiledCssTemplate[$media];
				foreach ( $import as $url ) {
					$rawCss .= ' @import ' . ' url("' . $url . '");';
				}
			}
		} else {
			$css = $compiledCssTemplate[$media];

			// Open media query
			if ( ! empty( $supported_media[$media] ) ) {
				$rawCss .= sprintf( ' @media %s {', $supported_media[$media] );
			}

			foreach ( $css as $selector => $props ) {

				// Move root to editor
				if ( is_admin() ) {
					$selector = ( 'body' === $selector ) ? str_replace( 'body', '.editor-styles-wrapper', $selector ) : $selector;
					$selector = str_replace( 'body ', '.editor-styles-wrapper ', $selector );
					$selector = str_replace( 'body, ', '.editor-styles-wrapper, ', $selector );
				}

				// Open selector
				$rawCss .= sprintf( '%s{', $selector );

				// Props
				foreach ( $props as $property => $value ) {
					$rawCss .= sprintf( '%s:%s;', $property, $value );
				}

				// Close selector
				$rawCss .= '}';
			}

			// Close media query
			if ( ! empty( $supported_media[$media] ) ) {
				$rawCss .= '}';
			}
		}
	}

	return $rawCss;
}

/**
 * Example input
 * $cssTemplate = [
 * 		'{{BLOCK}} .block-selector' => [
 *			'@import-font'  => 'https://example.com/font.css',
 * 			'my-block-prop-name#font-size---lg' => '24px',
 * 		],
 * ];
 *
 * Example output
 * $css = [
 * 		'import' => [
 * 			'https://fonts.googleapis.com/css',
 * 			'https://fonts.googleapis.com/css',
 * 		],
 * 		'md' => [
 * 			'.gtm-style-1 .wp-block-gtm-post-title__title' => [
 * 				'font-weight' => '300',
 * 			],
 * 		],
 * 		'all' => [
 * 			'.gtm-style-1 .wp-block-gtm-post-title__title' => [
 * 				'font-weight' => '400',
 * 			],
 * 		],
 * ];
 */
function gtm_css_compileCssTemplate( $cssTemplate ) {
	$css = [];

	foreach ( $cssTemplate as $selector => $properties ) {
		foreach ( $properties as $property => $value ) {
			if ( gtm_css_hasValue( $value ) ) {

				if ( gtm_startsWith( $property, '@import' ) ) {
					$css['import'][] = $value;
				} else {
					$prop_name = '';
					$media     = 'all';

					// Suffix in -has- class
					$prop_media_suffix = '';

					// Extract prop name
					if ( preg_match( '/^(.+)#/', $property, $match ) ) {
						$prop_name = $match[1];

						//Remove from original string
						$property = str_replace( $match[0], '', $property );
					}

					// Extract media
					if ( preg_match( '/@(.+)$/', $property, $match ) ) {
						$media = $match[1];

						$prop_media_suffix = '---' . $media;

						//Remove from original string
						$property = str_replace( $match[0], '', $property );
					}

					$new_selector = $selector;

					// Insert prop name class
					// Try disabling has-class to reduce css
					if ( FALSE && ! empty( $prop_name ) ) {
						$new_selector = str_replace( '{{BLOCK}}', sprintf( '{{BLOCK}}.gtm-has-%s%s', $prop_name, $prop_media_suffix ), $new_selector );
					}

					// Remove all {{BLOCK}}, No more needed.
					$new_selector = str_replace( '{{BLOCK}}', '', $new_selector );

					$css[$media][$new_selector][$property] = $value;
				}
			}
		}
	}

	return $css;
}

/*//////////////////////////////////////
// Classnames lib for php
// Thanks to https://github.com/cstro/classnames-php
//////////////////////////////////////*/

if ( ! function_exists( 'gtm_classNames' ) ) {
	function gtm_classNames() {
		$args = func_get_args();

		$data = array_reduce( $args, function ( $carry, $arg ) {
			if ( is_array( $arg ) ) {
				return array_merge( $carry, $arg );
			}

			$carry[] = $arg;
			return $carry;
		}, [] );

		$classes = array_map( function ( $key, $value ) {
			$condition = $value;
			$return    = $key;

			if ( is_int( $key ) ) {
				$condition = null;
				$return    = $value;
			}

			$isArray          = is_array( $return );
			$isObject         = is_object( $return );
			$isStringableType = ! $isArray && ! $isObject;

			$isStringableObject = $isObject && method_exists( $return, '__toString' );

			if ( ! $isStringableType && ! $isStringableObject ) {
				return null;
			}

			if ( $condition === null ) {
				return $return;
			}

			return $condition ? $return : null;

		}, array_keys( $data ), array_values( $data ) );

		$classes = array_filter( $classes );

		return implode( ' ', $classes );
	}
}

function gtm_css_compileCssVarClass( &$output, $name, $val ) {
	if ( ! gtm_css_hasValue( $val ) ) {
		return $output;
	}

	if ( gtm_css_isSingularValue( $val ) && is_string( $val ) ) {
		$output['classes'][] = "gtm-has-$name-$val";
	}

	return $output;
}

function gtm_css_compileCssVar( &$output, $name, $val, $unit = "" ) {
	if ( ! gtm_css_hasValue( $val ) ) {
		return $output;
	}

	if ( gtm_css_isSingularValue( $val ) ) {
		$output['classes'][]                  = "gtm-has-$name";
		$output['style']["$name#--gtm-$name"] = $val;

	} else if ( is_array( $val ) ) {
		foreach ( $val as $propName => $v ) {
			if ( ! empty( $propName ) ) {

				if ( 'lg' == $propName && gtm_css_hasValue( $val['lg'] ?? '' ) ) {
					$output['classes'][]                          = "gtm-has-$name---lg";
					$output['style']["$name#--gtm-$name---lg@lg"] = $val['lg'] . $unit;
				} else if ( 'md' == $propName && gtm_css_hasValue( $val['md'] ?? '' ) ) {
					$output['classes'][]                          = "gtm-has-$name---md";
					$output['style']["$name#--gtm-$name---md@md"] = $val['md'] . $unit;
				} else if ( 'sm' == $propName && gtm_css_hasValue( $val['sm'] ?? '' ) ) {
					$output['classes'][]                          = "gtm-has-$name---sm";
					$output['style']["$name#--gtm-$name---sm@sm"] = $val['sm'] . $unit;
				} else {
					// To support subfields such as typography field
					gtm_css_compileCssVar( $output, "{$name}-{$propName}", $v );
				}
			}
		}
	}

	return $output;
}

/*
New function is allow customize the selector
 */
function gtm_css_compileCssVarNEW( &$output, $selector, $name, $val, $unit = "" ) {
	if ( ! gtm_css_hasValue( $val ) ) {
		return $output;
	}

	if ( gtm_css_isSingularValue( $val ) ) {
		$output['classes'][]                             = "gtm-has-$name";
		$output['style'][$selector]["$name#--gtm-$name"] = $val;

	} else if ( is_array( $val ) ) {
		foreach ( $val as $propName => $v ) {
			if ( ! empty( $propName ) ) {
				if ( in_array( $propName, ['lg', 'md', 'sm'] ) ) {
					if ( gtm_css_hasValue( $val[$propName] ?? '' ) ) {
						$output['classes'][]                                                   = "gtm-has-$name---$propName";
						$output['style'][$selector]["$name#--gtm-$name---$propName@$propName"] = $val[$propName] . $unit;
					}

				} else {
					// To support subfields such as typography field
					gtm_css_compileCssVarNEW( $output, $selector, "{$name}-{$propName}", $v );
				}
			}
		}
	}

	return $output;
}

function gtm_css_parseFlexAlignValue( $value ) {
	if ( 'left' == $value || "top" == $value ) {
		return "flex-start";
	} else if ( "right" == $value || "bottom" == $value ) {
		return "flex-end";
	}

	return $value;
}

function gtm_css_parseFlexMatrixPositionValue( $value, $prefix = "" ) {
	if ( ! is_string( $value ) ) {
		return [];
	}

	if ( $prefix ) {
		$prefix += '-';
	}

	// Split from format "center left"
	$splitvalue = explode( ' ', $value );
	$y          = $splitvalue[0];
	$x          = $splitvalue[1] ?? false;

	// Make sure x has value in case "center"
	if ( ! $x ) {
		$x = 'center';
	}

	// Flex value
	$x = $x == "left" ? "flex-start" : $x;
	$x = $x == "right" ? "flex-end" : $x;

	$y = $y == "top" ? "flex-start" : $y;
	$y = $y == "bottom" ? "flex-end" : $y;

	return [
		$prefix . 'x' => $x,
		$prefix . 'y' => $y,
	];
}

function gtm_css_serialize_style( $style_arr ) {
	if ( ! is_array( $style_arr ) ) {
		return $style_arr;
	}

	$output = '';
	foreach ( $style_arr as $prop => $val ) {
		if ( ! empty( $prop ) ) {
			$output .= sprintf( '%s: %s;', $prop, $val );
		}
	}

	return $output;
}

function gtm_css_parseResponsiveBoxProps( $attributes, $propPrefix = "" ) {
	$props = [];

	if ( ! empty( $propPrefix ) ) {
		$propPrefix .= '-';
	}

	if ( $attributes ) {
		foreach ( ['lg', 'md', 'sm'] as $device ) {
			foreach ( ['top', 'left', 'bottom', 'right'] as $side ) {
				if ( isset( $attributes[$device][$side] ) ) {
					$props[$propPrefix . $side][$device] = gtm_css_parseSpacingValue( $attributes[$device][$side] );
				}
			}
		}
	}

	return $props;
}

function gtm_css_parseBorderRadiusValue( $values ) {
	if ( gtm_css_hasValue( $values ) ) {
		if ( is_string( $values ) ) {
			return $values;

		} else {
			$corners = [
				'topLeft'     => "border-top-left-radius",
				'topRight'    => "border-top-right-radius",
				'bottomLeft'  => "border-bottom-left-radius",
				'bottomRight' => "border-bottom-right-radius",
			];
			$outValue = [];

			foreach ( $corners as $corner => $propName ) {
				if ( gtm_css_hasValue( $values[$corner] ) ) {
					$outValue[$propName] = $values[$corner];
				}
			}

			return $outValue;
		}
	}
}

function gtm_css_parseFocalPointValue( $value, $prefix = "" ) {
	$outValue = [];

	if ( ! empty( $prefix ) ) {
		$prefix += "-";
	}

	if ( isset( $value['x'] ) ) {
		$outValue[$prefix . 'x'] = ( floatval( $value['x'] ) * 100 ) . '%';
	}

	if ( isset( $value['y'] ) ) {
		$outValue[$prefix . 'y'] = ( floatval( $value['y'] ) * 100 ) . '%';
	}

	return $outValue;
}

function gtm_css_parseSpacingValue( $value, $defaultValue = "" ) {
	// To cache the created function
	static $parseValueFunc;

	if ( empty( $parseValueFunc ) ) {
		$parseValueFunc = gtm_css_createResponsiveValueParser( 'gtm_css_parseSpacingValue_single' );
	}

	return $parseValueFunc( $value, $defaultValue );
}

function gtm_css_parseSpacingValue_single( $value, $defaultValue = "" ) {
	if ( gtm_css_isCssUnitValue( $value ) ) {
		return $value;
	} else if ( $value ) {
		if ( $defaultValue ) {
			return "var(--gtm--space--{$value}, {$defaultValue})";
		} else {
			return "var(--gtm--space--{$value})";
		}
	}
}

function gtm_css_parseGapValue( $value, $defaultValue = '' ) {
	// Use gtm_css_parseSpacingValue to parse
	$output = gtm_css_parseSpacingValue( $value, $defaultValue );

	if ( is_array( $output ) && ! empty( $output ) ) {
		$new_output = [];

		// Remap as a css property
		foreach ( $output as $key => $val ) {
			if ( 'col' == $key ) {
				$key = 'column-gap';
			} else if ( 'row' == $key ) {
				$key = 'row-gap';
			}

			$new_output[$key] = $val;

		}

		return $new_output;
	}

	return $output;
}

function gtm_css_parseShadowValue( $value, $defaultValue = "" ) {
	if ( gtm_css_isCustomShadowValue( $value ) ) {
		return $value;
	} else if ( $value ) {
		if ( $defaultValue ) {
			return "var(--gtm-shadow--{$value}, {$defaultValue})";
		} else {
			return "var(--gtm-shadow--{$value})";
		}
	}
}

function gtm_css_isRawColorValue( $value ) {
	if ( ! is_array( $value ) ) {
		if ( strpos( $value, '#' ) !== false || strpos( $value, 'gradient(' ) !== false ) {
			return true;
		}
	}

	return false;
}

function gtm_css_parseColorValue( $value ) {
	if ( is_array( $value ) ) {
		$actualVal = '';

		if ( ! empty( $value['solid'] ) ) {
			if ( gtm_css_isRawColorValue( $value['solid'] ) ) {
				$actualVal = $value['solid'];
			} else {
				$actualVal = "var(--wp--preset--color--{$value['solid']})";
			}
		}

		if ( ! empty( $value['gradient'] ) ) {
			if ( gtm_css_isRawColorValue( $value['gradient'] ) ) {
				$actualVal = $value['gradient'];
			} else {
				$actualVal = "var(--wp--preset--gradient--{$value['gradient']})";
			}
		}

		return $actualVal;
	} else if ( is_string( $value ) && ! empty( $value ) ) {
		if ( gtm_css_isRawColorValue( $value ) ) {
			return $value;
		} else {
			// Treat as a solid color
			return "var(--wp--preset--color--{$value})";
		}
	}

	return $value;
}

function gtm_css_parseTypographyProps( $attributes ) {
	$css = [];
	if ( ! empty( $attributes['preset'] ) ) {
		if ( $attributes['preset'] == "custom" ) {
			$css = gtm_css_parseCustomTypographyProps( $attributes );
		} else {
			$props = [
				"font-family",
				"font-weight",
				"font-style",
				"font-size",
				"line-height",
				"letter-spacing",
				"text-transform",
			];

			foreach ( $props as $prop ) {
				$css[$prop] = "var(--gtm--typography--{$attributes['preset']}--{$prop})";
			}
		}
	}

	return $css;
}

function gtm_css_parseCustomTypographyProps( $attributes ) {
	$css = [];

	if ( $attributes['preset'] == "custom" ) {
		$attributes = wp_parse_args( $attributes, [
			'fontFamily'    => '',
			'fontWeight'    => '',
			'fontSize'      => '',
			'lineHeight'    => '',
			'letterSpacing' => '',
			'textTransform' => '',
		] );
		unset( $attributes['preset'] );

		$fontFamily = $attributes['fontFamily'];

		// Quote font family name if not a variable
		if ( $fontFamily && ! preg_match( '|var\(|i', $fontFamily ) ) {
			$attributes['fontFamily'] = '"' . $fontFamily . '"';
		}

		// New
		if ( gtm_css_hasValue( $attributes['fontFamily'] ) ) {
			$css['font-family'] = $attributes['fontFamily'];
		}

		if ( gtm_css_hasValue( $attributes['fontWeight'] ) ) {
			if ( preg_match( '|i$|i', $attributes['fontWeight'] ) ) {
				$css['font-weight'] = str_replace( 'i', '', $attributes['fontWeight'] );
				$css['font-style']  = 'italic';
			} else {
				$css['font-weight'] = $attributes['fontWeight'];
			}
		}

		if ( gtm_css_hasValue( $attributes['fontSize'] ) ) {
			$css['font-size'] = gtm_css_parseResponsiveFontSizeValue( $attributes['fontSize'] );
		}

		if ( gtm_css_hasValue( $attributes['lineHeight'] ) ) {
			$css['line-height'] = $attributes['lineHeight'];
		}

		if ( gtm_css_hasValue( $attributes['letterSpacing'] ) ) {
			$css['letter-spacing'] = $attributes['letterSpacing'];
		}

		if ( gtm_css_hasValue( $attributes['textTransform'] ) ) {
			$css['text-transform'] = $attributes['textTransform'];
		}
	}

	return $css;
}

function gtm_css_createResponsiveValueParser( $parseValueFunction ) {
	return function ( $value, $defaultValue = "" ) use ( $parseValueFunction ) {

		if ( is_array( $value ) ) {
			$parsedValue = [];

			foreach ( ['lg', 'md', 'sm'] as $device ) {
				if ( isset( $value[$device] ) ) {
					if ( is_array( $value[$device] ) ) {
						// To support subfields
						foreach ( $value[$device] as $propName => $propVal ) {
							$parsedValue[$propName][$device] = call_user_func( $parseValueFunction, $value[$device][$propName], $defaultValue );
						}
					} else {
						// To support regular value, such as a value from GapControl
						$parsedValue[$device] = call_user_func( $parseValueFunction, $value[$device], $defaultValue );
					}
				}
			}

			return $parsedValue;
		}

		return call_user_func( $parseValueFunction, $value, $defaultValue );
	};

}