import CSSStyleDeclarationValueParser from './CSSStyleDeclarationValueParser.js';
import CSSStyleDeclarationValueUtility from './CSSStyleDeclarationValueUtility.js';
const RECT_REGEXP = /^rect\((.*)\)$/i;
const SPLIT_COMMA_SEPARATED_WITH_PARANTHESES_REGEXP = /,(?=(?:(?:(?!\))[\s\S])*\()|[^\(\)]*$)/; // Split on commas that are outside of parentheses
const SPLIT_SPACE_SEPARATED_WITH_PARANTHESES_REGEXP = /\s+(?=(?:(?:(?!\))[\s\S])*\()|[^\(\)]*$)/; // Split on spaces that are outside of parentheses
const WHITE_SPACE_GLOBAL_REGEXP = /\s+/gm;
const BORDER_STYLE = [
    'none',
    'hidden',
    'dotted',
    'dashed',
    'solid',
    'double',
    'groove',
    'ridge',
    'inset',
    'outset'
];
const BORDER_WIDTH = ['thin', 'medium', 'thick'];
const BORDER_COLLAPSE = ['separate', 'collapse'];
const BACKGROUND_REPEAT = ['repeat', 'repeat-x', 'repeat-y', 'no-repeat'];
const BACKGROUND_ORIGIN = ['border-box', 'padding-box', 'content-box'];
const BACKGROUND_CLIP = ['border-box', 'padding-box', 'content-box'];
const BACKGROUND_ATTACHMENT = ['scroll', 'fixed'];
const FLEX_BASIS = ['auto', 'fill', 'content'];
const CLEAR = ['none', 'left', 'right', 'both'];
const FLOAT = ['none', 'left', 'right', 'inline-start', 'inline-end'];
const SYSTEM_FONT = ['caption', 'icon', 'menu', 'message-box', 'small-caption', 'status-bar'];
const FONT_WEIGHT = ['normal', 'bold', 'bolder', 'lighter'];
const FONT_STYLE = ['normal', 'italic', 'oblique'];
const FONT_SIZE = [
    'xx-small',
    'x-small',
    'small',
    'medium',
    'large',
    'x-large',
    'xx-large',
    'xxx-large',
    'smaller',
    'larger'
];
const FONT_STRETCH = [
    'ultra-condensed',
    'extra-condensed',
    'condensed',
    'semi-condensed',
    'normal',
    'semi-expanded',
    'expanded',
    'extra-expanded',
    'ultra-expanded'
];
const DISPLAY = [
    /* Legacy values */
    'block',
    'inline',
    'inline-block',
    'flex',
    'inline-flex',
    'grid',
    'inline-grid',
    'flow-root',
    /* Box generation */
    'none',
    'contents',
    /* Two-value syntax */
    'block flow',
    'inline flow',
    'inline flow-root',
    'block flex',
    'inline flex',
    'block grid',
    'inline grid',
    'block flow-root',
    /* Other values */
    'table',
    'table-row',
    'list-item'
];
const BORDER_IMAGE_REPEAT = ['stretch', 'repeat', 'round', 'space'];
const TEXT_TRANSFORM = [
    'capitalize',
    'uppercase',
    'lowercase',
    'none',
    'full-width',
    'full-size-kana'
];
const VISIBILITY = ['visible', 'hidden', 'collapse'];
/**
 * Computed style property parser.
 */
export default class CSSStyleDeclarationPropertySetParser {
    /**
     * Returns border collapse.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getBorderCollapse(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'border-collapse': { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        if (CSSStyleDeclarationValueParser.getGlobal(lowerValue) ||
            BORDER_COLLAPSE.includes(lowerValue)) {
            return { 'border-collapse': { value: lowerValue, important } };
        }
        return null;
    }
    /**
     * Returns display.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getDisplay(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { display: { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        if (CSSStyleDeclarationValueParser.getGlobal(lowerValue) || DISPLAY.includes(lowerValue)) {
            return { display: { value: lowerValue, important } };
        }
        return null;
    }
    /**
     * Returns direction.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getDirection(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { direction: { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        if (CSSStyleDeclarationValueParser.getGlobal(lowerValue) ||
            lowerValue === 'ltr' ||
            lowerValue === 'rtl') {
            return { direction: { value: lowerValue, important } };
        }
        return null;
    }
    /**
     * Returns letter spacing.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getLetterSpacing(value, important) {
        const parsedValue = CSSStyleDeclarationValueParser.getVariable(value) ||
            CSSStyleDeclarationValueParser.getGlobal(value) ||
            CSSStyleDeclarationValueParser.getContentMeasurement(value);
        return parsedValue ? { 'letter-spacing': { value: parsedValue, important } } : null;
    }
    /**
     * Returns word spacing.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getWordSpacing(value, important) {
        const parsedValue = CSSStyleDeclarationValueParser.getVariable(value) ||
            CSSStyleDeclarationValueParser.getGlobal(value) ||
            CSSStyleDeclarationValueParser.getContentMeasurement(value);
        return parsedValue ? { 'word-spacing': { value: parsedValue, important } } : null;
    }
    /**
     * Returns text indent.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getTextIndent(value, important) {
        const parsedValue = CSSStyleDeclarationValueParser.getVariable(value) ||
            CSSStyleDeclarationValueParser.getGlobal(value) ||
            CSSStyleDeclarationValueParser.getContentMeasurement(value);
        return parsedValue ? { 'text-indent': { value: parsedValue, important } } : null;
    }
    /**
     * Returns width.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getWidth(value, important) {
        const parsedValue = CSSStyleDeclarationValueParser.getVariable(value) ||
            CSSStyleDeclarationValueParser.getGlobal(value) ||
            CSSStyleDeclarationValueParser.getContentMeasurement(value);
        return parsedValue ? { width: { value: parsedValue, important } } : null;
    }
    /**
     * Returns height.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getHeight(value, important) {
        const parsedValue = CSSStyleDeclarationValueParser.getVariable(value) ||
            CSSStyleDeclarationValueParser.getGlobal(value) ||
            CSSStyleDeclarationValueParser.getContentMeasurement(value);
        return parsedValue ? { height: { value: parsedValue, important } } : null;
    }
    /**
     * Returns top.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getTop(value, important) {
        const parsedValue = CSSStyleDeclarationValueParser.getVariable(value) ||
            CSSStyleDeclarationValueParser.getGlobal(value) ||
            CSSStyleDeclarationValueParser.getContentMeasurement(value);
        return parsedValue ? { top: { value: parsedValue, important } } : null;
    }
    /**
     * Returns top.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getRight(value, important) {
        const parsedValue = CSSStyleDeclarationValueParser.getVariable(value) ||
            CSSStyleDeclarationValueParser.getGlobal(value) ||
            CSSStyleDeclarationValueParser.getContentMeasurement(value);
        return parsedValue ? { right: { value: parsedValue, important } } : null;
    }
    /**
     * Returns top.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getBottom(value, important) {
        const parsedValue = CSSStyleDeclarationValueParser.getVariable(value) ||
            CSSStyleDeclarationValueParser.getGlobal(value) ||
            CSSStyleDeclarationValueParser.getContentMeasurement(value);
        return parsedValue ? { bottom: { value: parsedValue, important } } : null;
    }
    /**
     * Returns top.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getLeft(value, important) {
        const parsedValue = CSSStyleDeclarationValueParser.getVariable(value) ||
            CSSStyleDeclarationValueParser.getGlobal(value) ||
            CSSStyleDeclarationValueParser.getContentMeasurement(value);
        return parsedValue ? { left: { value: parsedValue, important } } : null;
    }
    /**
     * Returns clear.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getClear(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { clear: { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        if (CSSStyleDeclarationValueParser.getGlobal(lowerValue) || CLEAR.includes(lowerValue)) {
            return { clear: { value: lowerValue, important } };
        }
        return null;
    }
    /**
     * Returns clip
     *
     * Based on:
     * https://github.com/jsdom/cssstyle/blob/master/lib/properties/clip.js
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getClip(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { clip: { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        if (CSSStyleDeclarationValueParser.getGlobal(lowerValue) || lowerValue === 'auto') {
            return { clip: { value: lowerValue, important } };
        }
        const matches = lowerValue.match(RECT_REGEXP);
        if (!matches) {
            return null;
        }
        const parts = matches[1].split(/\s*,\s*/);
        if (parts.length !== 4) {
            return null;
        }
        for (const part of parts) {
            if (!CSSStyleDeclarationValueParser.getMeasurement(part)) {
                return null;
            }
        }
        return { clip: { value, important } };
    }
    /**
     * Returns float.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getFloat(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { float: { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        if (CSSStyleDeclarationValueParser.getGlobal(lowerValue) || FLOAT.includes(lowerValue)) {
            return { float: { value: lowerValue, important } };
        }
        return null;
    }
    /**
     * Returns float.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getCSSFloat(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'css-float': { value: variable, important } };
        }
        const float = this.getFloat(value, important);
        return float ? { 'css-float': float['float'] } : null;
    }
    /**
     * Returns outline.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values.
     */
    static getOutline(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { outline: { value: variable, important } };
        }
        const globalValue = CSSStyleDeclarationValueParser.getGlobal(value);
        if (globalValue) {
            return {
                ...this.getOutlineColor(globalValue, important),
                ...this.getOutlineStyle(globalValue, important),
                ...this.getOutlineWidth(globalValue, important)
            };
        }
        const properties = {
            ...this.getOutlineColor('initial', important),
            ...this.getOutlineStyle('initial', important),
            ...this.getOutlineWidth('initial', important)
        };
        const parts = value.split(SPLIT_SPACE_SEPARATED_WITH_PARANTHESES_REGEXP);
        for (const part of parts) {
            const width = this.getOutlineWidth(part, important);
            const style = this.getOutlineStyle(part, important);
            const color = this.getOutlineColor(part, important);
            if (width === null && style === null && color === null) {
                return null;
            }
            Object.assign(properties, width, style, color);
        }
        return properties;
    }
    /**
     * Returns outline color.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getOutlineColor(value, important) {
        const color = CSSStyleDeclarationValueParser.getVariable(value) ||
            CSSStyleDeclarationValueParser.getGlobal(value) ||
            CSSStyleDeclarationValueParser.getColor(value);
        return color
            ? {
                'outline-color': { value: color, important }
            }
            : null;
    }
    /**
     * Returns outline offset.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getOutlineOffset(value, important) {
        const parsedValue = CSSStyleDeclarationValueParser.getVariable(value) ||
            CSSStyleDeclarationValueParser.getLength(value);
        return parsedValue ? { 'outline-offset': { value: parsedValue, important } } : null;
    }
    /**
     * Returns outline style.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getOutlineStyle(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'outline-style': { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        if (CSSStyleDeclarationValueParser.getGlobal(lowerValue) || BORDER_STYLE.includes(lowerValue)) {
            return {
                'outline-style': { value: lowerValue, important }
            };
        }
        return null;
    }
    /**
     * Returns outline width.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getOutlineWidth(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'outline-width': { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        const parsedValue = BORDER_WIDTH.includes(lowerValue) || CSSStyleDeclarationValueParser.getGlobal(lowerValue)
            ? lowerValue
            : CSSStyleDeclarationValueParser.getLength(value);
        if (parsedValue) {
            return {
                'outline-width': { value: parsedValue, important }
            };
        }
        return null;
    }
    /**
     * Returns border.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values.
     */
    static getBorder(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { border: { value: variable, important } };
        }
        const globalValue = CSSStyleDeclarationValueParser.getGlobal(value);
        if (globalValue) {
            return {
                ...this.getBorderWidth(globalValue, important),
                ...this.getBorderStyle(globalValue, important),
                ...this.getBorderColor(globalValue, important),
                ...this.getBorderImage(globalValue, important)
            };
        }
        const properties = {
            ...this.getBorderWidth('initial', important),
            ...this.getBorderStyle('initial', important),
            ...this.getBorderColor('initial', important),
            ...this.getBorderImage('initial', important)
        };
        const parts = value
            .replace(/\s*,\s*/g, ',')
            .split(SPLIT_SPACE_SEPARATED_WITH_PARANTHESES_REGEXP);
        for (const part of parts) {
            const width = this.getBorderWidth(part, important);
            const style = this.getBorderStyle(part, important);
            const color = this.getBorderColor(part, important);
            if (width === null && style === null && color === null) {
                return null;
            }
            Object.assign(properties, width, style, color);
        }
        return properties;
    }
    /**
     * Returns border width.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getBorderWidth(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'border-width': { value: variable, important } };
        }
        const globalValue = CSSStyleDeclarationValueParser.getGlobal(value);
        if (globalValue) {
            return {
                ...this.getBorderTopWidth(globalValue, important),
                ...this.getBorderRightWidth(globalValue, important),
                ...this.getBorderBottomWidth(globalValue, important),
                ...this.getBorderLeftWidth(globalValue, important)
            };
        }
        const parts = value.split(SPLIT_SPACE_SEPARATED_WITH_PARANTHESES_REGEXP);
        const top = this.getBorderTopWidth(parts[0], important);
        const right = this.getBorderRightWidth(parts[1] || parts[0], important);
        const bottom = this.getBorderBottomWidth(parts[2] || parts[0], important);
        const left = this.getBorderLeftWidth(parts[3] || parts[1] || parts[0], important);
        if (!top || !right || !bottom || !left) {
            return null;
        }
        return {
            ...top,
            ...right,
            ...bottom,
            ...left
        };
    }
    /**
     * Returns border style.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getBorderStyle(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'border-style': { value: variable, important } };
        }
        const globalValue = CSSStyleDeclarationValueParser.getGlobal(value);
        if (globalValue) {
            return {
                ...this.getBorderTopStyle(globalValue, important),
                ...this.getBorderRightStyle(globalValue, important),
                ...this.getBorderBottomStyle(globalValue, important),
                ...this.getBorderLeftStyle(globalValue, important)
            };
        }
        const parts = value.split(SPLIT_SPACE_SEPARATED_WITH_PARANTHESES_REGEXP);
        const top = this.getBorderTopStyle(parts[0], important);
        const right = this.getBorderRightStyle(parts[1] || parts[0], important);
        const bottom = this.getBorderBottomStyle(parts[2] || parts[0], important);
        const left = this.getBorderLeftStyle(parts[3] || parts[1] || parts[0], important);
        if (!top || !right || !bottom || !left) {
            return null;
        }
        return {
            ...top,
            ...right,
            ...bottom,
            ...left
        };
    }
    /**
     * Returns border color.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getBorderColor(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'border-color': { value: variable, important } };
        }
        const globalValue = CSSStyleDeclarationValueParser.getGlobal(value);
        if (globalValue) {
            return {
                ...this.getBorderTopColor(globalValue, important),
                ...this.getBorderRightColor(globalValue, important),
                ...this.getBorderBottomColor(globalValue, important),
                ...this.getBorderLeftColor(globalValue, important)
            };
        }
        const parts = value.split(SPLIT_SPACE_SEPARATED_WITH_PARANTHESES_REGEXP);
        const top = this.getBorderTopColor(parts[0], important);
        const right = this.getBorderRightColor(parts[1] || parts[0], important);
        const bottom = this.getBorderBottomColor(parts[2] || parts[0], important);
        const left = this.getBorderLeftColor(parts[3] || parts[1] || parts[0], important);
        if (!top || !right || !bottom || !left) {
            return null;
        }
        return {
            ...top,
            ...right,
            ...bottom,
            ...left
        };
    }
    /**
     * Returns border image.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getBorderImage(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'border-image': { value: variable, important } };
        }
        const globalValue = CSSStyleDeclarationValueParser.getGlobal(value);
        if (globalValue) {
            return {
                ...this.getBorderImageSource(globalValue, important),
                ...this.getBorderImageSlice(globalValue, important),
                ...this.getBorderImageWidth(globalValue, important),
                ...this.getBorderImageOutset(globalValue, important),
                ...this.getBorderImageRepeat(globalValue, important)
            };
        }
        let parsedValue = value.replace(/\s\/\s/g, '/');
        const sourceMatch = parsedValue.match(/\s*([a-zA-Z-]+\([^)]*\))\s*/);
        if (sourceMatch) {
            parsedValue = parsedValue.replace(sourceMatch[0], '');
        }
        const parts = parsedValue.split(SPLIT_SPACE_SEPARATED_WITH_PARANTHESES_REGEXP);
        if (sourceMatch) {
            parts.push(sourceMatch[1]);
        }
        const properties = {
            ...this.getBorderImageSource('none', important),
            ...this.getBorderImageSlice('100%', important),
            ...this.getBorderImageWidth('1', important),
            ...this.getBorderImageOutset('0', important),
            ...this.getBorderImageRepeat('stretch', important)
        };
        for (let i = 0, max = parts.length; i < max; i++) {
            const part = parts[i];
            const previousPart = i > 0 ? parts[i - 1] : '';
            if (!part.startsWith('url') && part.includes('/')) {
                const [slice, width, outset] = part.split('/');
                const borderImageSlice = this.getBorderImageSlice(`${previousPart} ${slice}`, important) ||
                    this.getBorderImageSlice(slice, important);
                const borderImageWidth = this.getBorderImageWidth(width, important);
                const borderImageOutset = outset && this.getBorderImageOutset(outset, important);
                if (!borderImageSlice || !borderImageWidth || borderImageOutset === null) {
                    return null;
                }
                Object.assign(properties, borderImageSlice, borderImageWidth, borderImageOutset);
            }
            else {
                const slice = this.getBorderImageSlice(`${previousPart} ${part}`, important) ||
                    this.getBorderImageSlice(part, important);
                const source = this.getBorderImageSource(part, important);
                const repeat = this.getBorderImageRepeat(part, important);
                if (!slice && !source && !repeat) {
                    return null;
                }
                Object.assign(properties, slice, source, repeat);
            }
        }
        return properties;
    }
    /**
     * Returns border source.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getBorderImageSource(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'border-image-source': { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        if (CSSStyleDeclarationValueParser.getGlobal(lowerValue) || lowerValue === 'none') {
            return {
                'border-image-source': {
                    important,
                    value: lowerValue
                }
            };
        }
        const parsedValue = CSSStyleDeclarationValueParser.getURL(value) ||
            CSSStyleDeclarationValueParser.getGradient(value);
        if (!parsedValue) {
            return null;
        }
        return {
            'border-image-source': {
                important,
                value: parsedValue
            }
        };
    }
    /**
     * Returns border slice.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getBorderImageSlice(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'border-image-slice': { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        if (CSSStyleDeclarationValueParser.getGlobal(lowerValue)) {
            return {
                'border-image-slice': {
                    important,
                    value: lowerValue
                }
            };
        }
        if (lowerValue !== lowerValue.trim()) {
            return null;
        }
        const regexp = /(fill)|(calc\([^^)]+\))|([0-9]+%)|([0-9]+)/g;
        const values = [];
        let match;
        while ((match = regexp.exec(lowerValue))) {
            const previousCharacter = lowerValue[match.index - 1];
            const nextCharacter = lowerValue[match.index + match[0].length];
            if ((previousCharacter && previousCharacter !== ' ') ||
                (nextCharacter && nextCharacter !== ' ')) {
                return null;
            }
            const fill = match[1] && 'fill';
            const calc = match[2] && CSSStyleDeclarationValueParser.getCalc(match[2]);
            const percentage = match[3] && CSSStyleDeclarationValueParser.getPercentage(match[3]);
            const integer = match[4] && CSSStyleDeclarationValueParser.getInteger(match[4]);
            if (!fill && !calc && !percentage && !integer) {
                return null;
            }
            values.push(fill || calc || percentage || integer);
        }
        if (!values.length || values.length > 4) {
            return null;
        }
        return {
            'border-image-slice': {
                important,
                value: values.join(' ')
            }
        };
    }
    /**
     * Returns border width.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getBorderImageWidth(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'border-image-width': { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        if (CSSStyleDeclarationValueParser.getGlobal(lowerValue)) {
            return {
                'border-image-width': {
                    important,
                    value: lowerValue
                }
            };
        }
        const parts = lowerValue.split(SPLIT_SPACE_SEPARATED_WITH_PARANTHESES_REGEXP);
        if (parts.length > 4) {
            return null;
        }
        for (const part of parts) {
            if (!CSSStyleDeclarationValueParser.getInteger(part) &&
                !CSSStyleDeclarationValueParser.getAutoMeasurement(part)) {
                return null;
            }
        }
        return {
            'border-image-width': {
                important,
                value
            }
        };
    }
    /**
     * Returns border outset.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getBorderImageOutset(value, important) {
        if (value === '0') {
            return {
                'border-image-outset': {
                    important,
                    value
                }
            };
        }
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'border-image-outset': { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        if (CSSStyleDeclarationValueParser.getGlobal(lowerValue)) {
            return {
                'border-image-outset': {
                    important,
                    value: lowerValue
                }
            };
        }
        const parts = value.split(SPLIT_SPACE_SEPARATED_WITH_PARANTHESES_REGEXP);
        if (parts.length > 4) {
            return null;
        }
        const newParts = [];
        for (const part of parts) {
            const parsedValue = CSSStyleDeclarationValueParser.getLength(part) ||
                CSSStyleDeclarationValueParser.getFloat(part);
            if (!parsedValue) {
                return null;
            }
            newParts.push(parsedValue === '0px' ? '0' : parsedValue);
        }
        return {
            'border-image-outset': {
                important,
                value: newParts.join(' ')
            }
        };
    }
    /**
     * Returns border repeat.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getBorderImageRepeat(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'border-image-repeat': { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        if (CSSStyleDeclarationValueParser.getGlobal(lowerValue)) {
            return {
                'border-image-repeat': {
                    important,
                    value: lowerValue
                }
            };
        }
        const parts = lowerValue.split(SPLIT_SPACE_SEPARATED_WITH_PARANTHESES_REGEXP);
        if (parts.length > 2) {
            return null;
        }
        for (const part of parts) {
            if (!BORDER_IMAGE_REPEAT.includes(part)) {
                return null;
            }
        }
        return {
            'border-image-repeat': {
                important,
                value
            }
        };
    }
    /**
     * Returns border width.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getBorderTopWidth(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'border-top-width': { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        const parsedValue = BORDER_WIDTH.includes(lowerValue) || CSSStyleDeclarationValueParser.getGlobal(lowerValue)
            ? lowerValue
            : CSSStyleDeclarationValueParser.getLength(value);
        if (parsedValue) {
            return {
                'border-top-width': { value: parsedValue, important }
            };
        }
        return null;
    }
    /**
     * Returns border width.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getBorderRightWidth(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'border-right-width': { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        const parsedValue = BORDER_WIDTH.includes(lowerValue) || CSSStyleDeclarationValueParser.getGlobal(lowerValue)
            ? lowerValue
            : CSSStyleDeclarationValueParser.getLength(value);
        if (parsedValue) {
            return {
                'border-right-width': { value: parsedValue, important }
            };
        }
        return null;
    }
    /**
     * Returns border width.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getBorderBottomWidth(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'border-bottom-width': { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        const parsedValue = BORDER_WIDTH.includes(lowerValue) || CSSStyleDeclarationValueParser.getGlobal(lowerValue)
            ? lowerValue
            : CSSStyleDeclarationValueParser.getLength(value);
        if (parsedValue) {
            return {
                'border-bottom-width': { value: parsedValue, important }
            };
        }
        return null;
    }
    /**
     * Returns border width.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getBorderLeftWidth(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'border-left-width': { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        const parsedValue = BORDER_WIDTH.includes(lowerValue) || CSSStyleDeclarationValueParser.getGlobal(lowerValue)
            ? lowerValue
            : CSSStyleDeclarationValueParser.getLength(value);
        if (parsedValue) {
            return {
                'border-left-width': { value: parsedValue, important }
            };
        }
        return null;
    }
    /**
     * Returns border style.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getBorderTopStyle(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'border-top-style': { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        if (CSSStyleDeclarationValueParser.getGlobal(lowerValue) || BORDER_STYLE.includes(lowerValue)) {
            return {
                'border-top-style': { value: lowerValue, important }
            };
        }
        return null;
    }
    /**
     * Returns border style.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getBorderRightStyle(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'border-right-style': { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        if (CSSStyleDeclarationValueParser.getGlobal(lowerValue) || BORDER_STYLE.includes(lowerValue)) {
            return {
                'border-right-style': { value: lowerValue, important }
            };
        }
        return null;
    }
    /**
     * Returns border style.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getBorderBottomStyle(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'border-bottom-style': { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        if (CSSStyleDeclarationValueParser.getGlobal(lowerValue) || BORDER_STYLE.includes(lowerValue)) {
            return {
                'border-bottom-style': { value: lowerValue, important }
            };
        }
        return null;
    }
    /**
     * Returns border style.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getBorderLeftStyle(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'border-left-style': { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        if (CSSStyleDeclarationValueParser.getGlobal(lowerValue) || BORDER_STYLE.includes(lowerValue)) {
            return {
                'border-left-style': { value: lowerValue, important }
            };
        }
        return null;
    }
    /**
     * Returns border color.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getBorderTopColor(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'border-top-color': { value: variable, important } };
        }
        const color = CSSStyleDeclarationValueParser.getGlobal(value) ||
            CSSStyleDeclarationValueParser.getColor(value);
        return color
            ? {
                'border-top-color': { value: color, important }
            }
            : null;
    }
    /**
     * Returns border color.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getBorderRightColor(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'border-right-color': { value: variable, important } };
        }
        const color = CSSStyleDeclarationValueParser.getGlobal(value) ||
            CSSStyleDeclarationValueParser.getColor(value);
        return color
            ? {
                'border-right-color': { value: color, important }
            }
            : null;
    }
    /**
     * Returns border color.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getBorderBottomColor(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'border-bottom-color': { value: variable, important } };
        }
        const color = CSSStyleDeclarationValueParser.getGlobal(value) ||
            CSSStyleDeclarationValueParser.getColor(value);
        return color
            ? {
                'border-bottom-color': { value: color, important }
            }
            : null;
    }
    /**
     * Returns border color.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getBorderLeftColor(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'border-left-color': { value: variable, important } };
        }
        const color = CSSStyleDeclarationValueParser.getGlobal(value) ||
            CSSStyleDeclarationValueParser.getColor(value);
        return color
            ? {
                'border-left-color': { value: color, important }
            }
            : null;
    }
    /**
     * Returns border radius.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values.
     */
    static getBorderRadius(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'border-radius': { value: variable, important } };
        }
        const globalValue = CSSStyleDeclarationValueParser.getGlobal(value);
        if (globalValue) {
            return {
                ...this.getBorderTopLeftRadius(globalValue, important),
                ...this.getBorderTopRightRadius(globalValue, important),
                ...this.getBorderBottomRightRadius(globalValue, important),
                ...this.getBorderBottomLeftRadius(globalValue, important)
            };
        }
        const parts = value.split(SPLIT_SPACE_SEPARATED_WITH_PARANTHESES_REGEXP);
        const topLeft = this.getBorderTopLeftRadius(parts[0], important);
        const topRight = this.getBorderTopRightRadius(parts[1] || parts[0], important);
        const bottomRight = this.getBorderBottomRightRadius(parts[2] || parts[0], important);
        const bottomLeft = this.getBorderBottomLeftRadius(parts[3] || parts[1] || parts[0], important);
        if (!topLeft || !topRight || !bottomRight || !bottomLeft) {
            return null;
        }
        return {
            ...topLeft,
            ...topRight,
            ...bottomRight,
            ...bottomLeft
        };
    }
    /**
     * Returns border radius.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values.
     */
    static getBorderTopLeftRadius(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'border-top-left-radius': { value: variable, important } };
        }
        const radius = CSSStyleDeclarationValueParser.getGlobal(value) ||
            CSSStyleDeclarationValueParser.getMeasurement(value);
        return radius ? { 'border-top-left-radius': { important, value: radius } } : null;
    }
    /**
     * Returns border radius.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values.
     */
    static getBorderTopRightRadius(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'border-top-right-radius': { value: variable, important } };
        }
        const radius = CSSStyleDeclarationValueParser.getGlobal(value) ||
            CSSStyleDeclarationValueParser.getMeasurement(value);
        return radius ? { 'border-top-right-radius': { important, value: radius } } : null;
    }
    /**
     * Returns border radius.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values.
     */
    static getBorderBottomRightRadius(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'border-bottom-right-radius': { value: variable, important } };
        }
        const radius = CSSStyleDeclarationValueParser.getGlobal(value) ||
            CSSStyleDeclarationValueParser.getMeasurement(value);
        return radius ? { 'border-bottom-right-radius': { important, value: radius } } : null;
    }
    /**
     * Returns border radius.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values.
     */
    static getBorderBottomLeftRadius(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'border-bottom-left-radius': { value: variable, important } };
        }
        const radius = CSSStyleDeclarationValueParser.getGlobal(value) ||
            CSSStyleDeclarationValueParser.getMeasurement(value);
        return radius ? { 'border-bottom-left-radius': { important, value: radius } } : null;
    }
    /**
     * Returns border top, right, bottom or left.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values.
     */
    static getBorderTop(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'border-top': { value: variable, important } };
        }
        const globalValue = CSSStyleDeclarationValueParser.getGlobal(value);
        if (globalValue) {
            return {
                ...this.getBorderTopWidth(globalValue, important),
                ...this.getBorderTopStyle(globalValue, important),
                ...this.getBorderTopColor(globalValue, important)
            };
        }
        const properties = {
            ...this.getBorderTopWidth('initial', important),
            ...this.getBorderTopStyle('initial', important),
            ...this.getBorderTopColor('initial', important)
        };
        const parts = value.split(SPLIT_SPACE_SEPARATED_WITH_PARANTHESES_REGEXP);
        for (const part of parts) {
            const width = this.getBorderTopWidth(part, important);
            const style = this.getBorderTopStyle(part, important);
            const color = this.getBorderTopColor(part, important);
            if (width === null && style === null && color === null) {
                return null;
            }
            Object.assign(properties, width, style, color);
        }
        return properties;
    }
    /**
     * Returns border top, right, bottom or left.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values.
     */
    static getBorderRight(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'border-right': { value: variable, important } };
        }
        const globalValue = CSSStyleDeclarationValueParser.getGlobal(value);
        if (globalValue) {
            return {
                ...this.getBorderRightWidth(globalValue, important),
                ...this.getBorderRightStyle(globalValue, important),
                ...this.getBorderRightColor(globalValue, important)
            };
        }
        const properties = {
            ...this.getBorderRightWidth('initial', important),
            ...this.getBorderRightStyle('initial', important),
            ...this.getBorderRightColor('initial', important)
        };
        const parts = value.split(SPLIT_SPACE_SEPARATED_WITH_PARANTHESES_REGEXP);
        for (const part of parts) {
            const width = this.getBorderRightWidth(part, important);
            const style = this.getBorderRightStyle(part, important);
            const color = this.getBorderRightColor(part, important);
            if (width === null && style === null && color === null) {
                return null;
            }
            Object.assign(properties, width, style, color);
        }
        return properties;
    }
    /**
     * Returns border top, right, bottom or left.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values.
     */
    static getBorderBottom(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'border-bottom': { value: variable, important } };
        }
        const globalValue = CSSStyleDeclarationValueParser.getGlobal(value);
        if (globalValue) {
            return {
                ...this.getBorderBottomWidth(globalValue, important),
                ...this.getBorderBottomStyle(globalValue, important),
                ...this.getBorderBottomColor(globalValue, important)
            };
        }
        const properties = {
            ...this.getBorderBottomWidth('initial', important),
            ...this.getBorderBottomStyle('initial', important),
            ...this.getBorderBottomColor('initial', important)
        };
        const parts = value.split(SPLIT_SPACE_SEPARATED_WITH_PARANTHESES_REGEXP);
        for (const part of parts) {
            const width = this.getBorderBottomWidth(part, important);
            const style = this.getBorderBottomStyle(part, important);
            const color = this.getBorderBottomColor(part, important);
            if (width === null && style === null && color === null) {
                return null;
            }
            Object.assign(properties, width, style, color);
        }
        return properties;
    }
    /**
     * Returns border top, right, bottom or left.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values.
     */
    static getBorderLeft(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'border-left': { value: variable, important } };
        }
        const globalValue = CSSStyleDeclarationValueParser.getGlobal(value);
        if (globalValue) {
            return {
                ...this.getBorderLeftWidth(globalValue, important),
                ...this.getBorderLeftStyle(globalValue, important),
                ...this.getBorderLeftColor(globalValue, important)
            };
        }
        const properties = {
            ...this.getBorderLeftWidth('initial', important),
            ...this.getBorderLeftStyle('initial', important),
            ...this.getBorderLeftColor('initial', important)
        };
        const parts = value.split(SPLIT_SPACE_SEPARATED_WITH_PARANTHESES_REGEXP);
        for (const part of parts) {
            const width = this.getBorderLeftWidth(part, important);
            const style = this.getBorderLeftStyle(part, important);
            const color = this.getBorderLeftColor(part, important);
            if (width === null && style === null && color === null) {
                return null;
            }
            Object.assign(properties, width, style, color);
        }
        return properties;
    }
    /**
     * Returns padding.
     *
     * @param value Value.
     * @param important Important.
     */
    static getPadding(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { padding: { value: variable, important } };
        }
        const globalValue = CSSStyleDeclarationValueParser.getGlobal(value);
        if (globalValue) {
            return {
                ...this.getPaddingTop(globalValue, important),
                ...this.getPaddingRight(globalValue, important),
                ...this.getPaddingBottom(globalValue, important),
                ...this.getPaddingLeft(globalValue, important)
            };
        }
        const parts = value.split(SPLIT_SPACE_SEPARATED_WITH_PARANTHESES_REGEXP);
        const top = this.getPaddingTop(parts[0], important);
        const right = this.getPaddingRight(parts[1] || parts[0], important);
        const bottom = this.getPaddingBottom(parts[2] || parts[0], important);
        const left = this.getPaddingLeft(parts[3] || parts[1] || parts[0], important);
        if (!top || !right || !bottom || !left) {
            return null;
        }
        return {
            ...top,
            ...right,
            ...bottom,
            ...left
        };
    }
    /**
     * Returns padding top.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values.
     */
    static getPaddingTop(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'padding-top': { value: variable, important } };
        }
        const padding = CSSStyleDeclarationValueParser.getGlobal(value) ||
            CSSStyleDeclarationValueParser.getMeasurement(value);
        return padding ? { 'padding-top': { value: padding, important } } : null;
    }
    /**
     * Returns padding right.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values.
     */
    static getPaddingRight(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'padding-right': { value: variable, important } };
        }
        const padding = CSSStyleDeclarationValueParser.getGlobal(value) ||
            CSSStyleDeclarationValueParser.getMeasurement(value);
        return padding ? { 'padding-right': { value: padding, important } } : null;
    }
    /**
     * Returns padding bottom.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values.
     */
    static getPaddingBottom(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'padding-bottom': { value: variable, important } };
        }
        const padding = CSSStyleDeclarationValueParser.getGlobal(value) ||
            CSSStyleDeclarationValueParser.getMeasurement(value);
        return padding ? { 'padding-bottom': { value: padding, important } } : null;
    }
    /**
     * Returns padding left.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values.
     */
    static getPaddingLeft(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'padding-left': { value: variable, important } };
        }
        const padding = CSSStyleDeclarationValueParser.getGlobal(value) ||
            CSSStyleDeclarationValueParser.getMeasurement(value);
        return padding ? { 'padding-left': { value: padding, important } } : null;
    }
    /**
     * Returns margin.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values.
     */
    static getMargin(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { margin: { value: variable, important } };
        }
        const globalValue = CSSStyleDeclarationValueParser.getGlobal(value);
        if (globalValue) {
            return {
                ...this.getMarginTop(globalValue, important),
                ...this.getMarginRight(globalValue, important),
                ...this.getMarginBottom(globalValue, important),
                ...this.getMarginLeft(globalValue, important)
            };
        }
        const parts = value.split(SPLIT_SPACE_SEPARATED_WITH_PARANTHESES_REGEXP);
        const top = this.getMarginTop(parts[0], important);
        const right = this.getMarginRight(parts[1] || parts[0], important);
        const bottom = this.getMarginBottom(parts[2] || parts[0], important);
        const left = this.getMarginLeft(parts[3] || parts[1] || parts[0], important);
        if (!top || !right || !bottom || !left) {
            return null;
        }
        return {
            ...top,
            ...right,
            ...bottom,
            ...left
        };
    }
    /**
     * Returns margin top.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values.
     */
    static getMarginTop(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'margin-top': { value: variable, important } };
        }
        const margin = CSSStyleDeclarationValueParser.getGlobal(value) ||
            CSSStyleDeclarationValueParser.getAutoMeasurement(value);
        return margin ? { 'margin-top': { value: margin, important } } : null;
    }
    /**
     * Returns margin right.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values.
     */
    static getMarginRight(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'margin-right': { value: variable, important } };
        }
        const margin = CSSStyleDeclarationValueParser.getGlobal(value) ||
            CSSStyleDeclarationValueParser.getAutoMeasurement(value);
        return margin ? { 'margin-right': { value: margin, important } } : null;
    }
    /**
     * Returns margin right.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values.
     */
    static getMarginBottom(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'margin-bottom': { value: variable, important } };
        }
        const margin = CSSStyleDeclarationValueParser.getGlobal(value) ||
            CSSStyleDeclarationValueParser.getAutoMeasurement(value);
        return margin ? { 'margin-bottom': { value: margin, important } } : null;
    }
    /**
     * Returns margin left.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values.
     */
    static getMarginLeft(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'margin-left': { value: variable, important } };
        }
        const margin = CSSStyleDeclarationValueParser.getGlobal(value) ||
            CSSStyleDeclarationValueParser.getAutoMeasurement(value);
        return margin ? { 'margin-left': { value: margin, important } } : null;
    }
    /**
     * Returns flex.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values.
     */
    static getFlex(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { flex: { value: variable, important } };
        }
        const lowerValue = value.trim().toLowerCase();
        const globalValue = CSSStyleDeclarationValueParser.getGlobal(value);
        if (globalValue) {
            return {
                ...this.getFlexGrow(globalValue, important),
                ...this.getFlexShrink(globalValue, important),
                ...this.getFlexBasis(globalValue, important)
            };
        }
        switch (lowerValue) {
            case 'none':
                return {
                    ...this.getFlexGrow('0', important),
                    ...this.getFlexShrink('0', important),
                    ...this.getFlexBasis('auto', important)
                };
            case 'auto':
                return {
                    ...this.getFlexGrow('1', important),
                    ...this.getFlexShrink('1', important),
                    ...this.getFlexBasis('auto', important)
                };
        }
        const measurement = CSSStyleDeclarationValueParser.getContentMeasurement(lowerValue);
        if (measurement) {
            return {
                ...this.getFlexGrow('1', important),
                ...this.getFlexShrink('1', important),
                ...this.getFlexBasis(measurement, important)
            };
        }
        const parts = value.split(SPLIT_SPACE_SEPARATED_WITH_PARANTHESES_REGEXP);
        const flexGrow = this.getFlexGrow(parts[0], important);
        const flexShrink = this.getFlexShrink(parts[1] || '1', important);
        const flexBasis = this.getFlexBasis(parts[2] || '0%', important);
        if (!flexGrow || !flexShrink || !flexBasis) {
            return null;
        }
        return {
            ...flexGrow,
            ...flexShrink,
            ...flexBasis
        };
    }
    /**
     * Returns flex basis.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getFlexBasis(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'flex-basis': { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        if (CSSStyleDeclarationValueParser.getGlobal(lowerValue) || FLEX_BASIS.includes(lowerValue)) {
            return { 'flex-basis': { value: lowerValue, important } };
        }
        const measurement = CSSStyleDeclarationValueParser.getContentMeasurement(lowerValue);
        return measurement ? { 'flex-basis': { value: measurement, important } } : null;
    }
    /**
     * Returns flex shrink.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getFlexShrink(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'flex-shrink': { value: variable, important } };
        }
        const parsedValue = CSSStyleDeclarationValueParser.getGlobal(value) ||
            CSSStyleDeclarationValueParser.getFloat(value);
        return parsedValue ? { 'flex-shrink': { value: parsedValue, important } } : null;
    }
    /**
     * Returns flex grow.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getFlexGrow(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'flex-grow': { value: variable, important } };
        }
        const parsedValue = CSSStyleDeclarationValueParser.getGlobal(value) ||
            CSSStyleDeclarationValueParser.getFloat(value);
        return parsedValue ? { 'flex-grow': { value: parsedValue, important } } : null;
    }
    /**
     * Returns background.
     *
     * @param name Name.
     * @param value Value.
     * @param important Important.
     * @returns Property values.
     */
    static getBackground(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { background: { value: variable, important } };
        }
        const globalValue = CSSStyleDeclarationValueParser.getGlobal(value);
        if (globalValue) {
            return {
                ...this.getBackgroundImage(globalValue, important),
                ...this.getBackgroundPosition(globalValue, important),
                ...this.getBackgroundSize(globalValue, important),
                ...this.getBackgroundRepeat(globalValue, important),
                ...this.getBackgroundAttachment(globalValue, important),
                ...this.getBackgroundOrigin(globalValue, important),
                ...this.getBackgroundClip(globalValue, important),
                ...this.getBackgroundColor(globalValue, important)
            };
        }
        const properties = {
            ...this.getBackgroundImage('initial', important),
            ...this.getBackgroundPosition('initial', important),
            ...this.getBackgroundSize('initial', important),
            ...this.getBackgroundRepeat('initial', important),
            ...this.getBackgroundAttachment('initial', important),
            ...this.getBackgroundOrigin('initial', important),
            ...this.getBackgroundClip('initial', important),
            ...this.getBackgroundColor('initial', important)
        };
        const parts = CSSStyleDeclarationValueUtility.splitBySpace(value.replace(/\s+\/\s+/g, '/'));
        const backgroundPositions = [];
        for (const part of parts) {
            if (!part.startsWith('url') && part.includes('/')) {
                const [position, size] = part.split('/');
                const backgroundPositionX = this.getBackgroundPositionX(position, important);
                const backgroundPositionY = this.getBackgroundPositionY(position, important);
                const backgroundSize = this.getBackgroundSize(size, important);
                if ((!backgroundPositionX && !backgroundPositionY) || !backgroundSize) {
                    return null;
                }
                if (backgroundPositionY) {
                    backgroundPositions.push(backgroundPositionY['background-position-y'].value);
                }
                else if (backgroundPositionX) {
                    backgroundPositions.push(backgroundPositionX['background-position-x'].value);
                }
                Object.assign(properties, backgroundSize);
            }
            else {
                const backgroundImage = this.getBackgroundImage(part, important);
                const backgroundRepeat = this.getBackgroundRepeat(part, important);
                const backgroundAttachment = this.getBackgroundAttachment(part, important);
                const backgroundPositionX = this.getBackgroundPositionX(part, important);
                const backgroundPositionY = this.getBackgroundPositionY(part, important);
                const backgroundColor = this.getBackgroundColor(part, important);
                const backgroundOrigin = this.getBackgroundOrigin(part, important);
                const backgroundClip = this.getBackgroundClip(part, important);
                if (!backgroundImage &&
                    !backgroundRepeat &&
                    !backgroundAttachment &&
                    !backgroundPositionX &&
                    !backgroundPositionY &&
                    !backgroundColor &&
                    !backgroundOrigin &&
                    !backgroundClip) {
                    return null;
                }
                if (backgroundPositionX) {
                    backgroundPositions.push(backgroundPositionX['background-position-x'].value);
                }
                else if (backgroundPositionY) {
                    backgroundPositions.push(backgroundPositionY['background-position-y'].value);
                }
                Object.assign(properties, backgroundImage, backgroundRepeat, backgroundAttachment, backgroundColor, backgroundOrigin, backgroundClip);
            }
        }
        if (backgroundPositions.length) {
            Object.assign(properties, this.getBackgroundPosition(backgroundPositions.join(' '), important));
        }
        return properties;
    }
    /**
     * Returns background size.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getBackgroundSize(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'background-size': { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        if (CSSStyleDeclarationValueParser.getGlobal(lowerValue)) {
            return { 'background-size': { value: lowerValue, important } };
        }
        const imageParts = lowerValue.split(SPLIT_COMMA_SEPARATED_WITH_PARANTHESES_REGEXP);
        const parsed = [];
        for (const imagePart of imageParts) {
            const parts = imagePart.trim().split(' ');
            if (parts.length !== 1 && parts.length !== 2) {
                return null;
            }
            if (parts.length === 1) {
                if (parts[0] !== 'cover' &&
                    parts[0] !== 'contain' &&
                    !CSSStyleDeclarationValueParser.getAutoMeasurement(parts[0])) {
                    return null;
                }
                parsed.push(parts[0]);
            }
            else {
                if (!CSSStyleDeclarationValueParser.getAutoMeasurement(parts[0]) ||
                    !CSSStyleDeclarationValueParser.getAutoMeasurement(parts[1])) {
                    return null;
                }
                parsed.push(`${parts[0]} ${parts[1]}`);
            }
        }
        if (parsed.length === 1) {
            return { 'background-size': { value: parsed.join(', '), important } };
        }
        return null;
    }
    /**
     * Returns background origin.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getBackgroundOrigin(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'background-origin': { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        if (CSSStyleDeclarationValueParser.getGlobal(lowerValue) ||
            BACKGROUND_ORIGIN.includes(lowerValue)) {
            return { 'background-origin': { value: lowerValue, important } };
        }
        return null;
    }
    /**
     * Returns background clip.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getBackgroundClip(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'background-clip': { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        if (CSSStyleDeclarationValueParser.getGlobal(lowerValue) ||
            BACKGROUND_CLIP.includes(lowerValue)) {
            return { 'background-clip': { value: lowerValue, important } };
        }
        return null;
    }
    /**
     * Returns background repeat.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getBackgroundRepeat(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'background-repeat': { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        if (CSSStyleDeclarationValueParser.getGlobal(lowerValue) ||
            BACKGROUND_REPEAT.includes(lowerValue)) {
            return { 'background-repeat': { value: lowerValue, important } };
        }
        return null;
    }
    /**
     * Returns background attachment.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getBackgroundAttachment(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'background-attachment': { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        if (CSSStyleDeclarationValueParser.getGlobal(lowerValue) ||
            BACKGROUND_ATTACHMENT.includes(lowerValue)) {
            return { 'background-attachment': { value: lowerValue, important } };
        }
        return null;
    }
    /**
     * Returns background position.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getBackgroundPosition(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'background-position': { value: variable, important } };
        }
        const globalValue = CSSStyleDeclarationValueParser.getGlobal(value);
        if (globalValue) {
            return {
                ...this.getBackgroundPositionX(globalValue, important),
                ...this.getBackgroundPositionY(globalValue, important)
            };
        }
        const imageParts = value.split(SPLIT_COMMA_SEPARATED_WITH_PARANTHESES_REGEXP);
        let x = '';
        let y = '';
        for (const imagePart of imageParts) {
            const parts = imagePart.trim().split(SPLIT_SPACE_SEPARATED_WITH_PARANTHESES_REGEXP);
            if (x) {
                x += ',';
                y += ',';
            }
            switch (parts.length) {
                case 1:
                    if (parts[0] === 'top' || parts[0] === 'bottom') {
                        x += 'center';
                        y += parts[0];
                    }
                    else if (parts[0] === 'left' || parts[0] === 'right') {
                        x += parts[0];
                        y += 'center';
                    }
                    else if (parts[0] === 'center') {
                        x += 'center';
                        y += 'center';
                    }
                    break;
                case 2:
                    x += parts[0] === 'top' || parts[0] === 'bottom' ? parts[1] : parts[0];
                    y += parts[0] === 'top' || parts[0] === 'bottom' ? parts[0] : parts[1];
                    break;
                case 3:
                    if (parts[0] === 'top' ||
                        parts[0] === 'bottom' ||
                        parts[1] === 'left' ||
                        parts[1] === 'right' ||
                        parts[2] === 'left' ||
                        parts[2] === 'right') {
                        if (CSSStyleDeclarationValueParser.getMeasurement(parts[1])) {
                            x += parts[2];
                            y += `${parts[0]} ${parts[1]}`;
                        }
                        else {
                            x += `${parts[1]} ${parts[2]}`;
                            y += parts[0];
                        }
                    }
                    else {
                        if (CSSStyleDeclarationValueParser.getMeasurement(parts[1])) {
                            x += `${parts[0]} ${parts[1]}`;
                            y += parts[2];
                        }
                        else {
                            x += parts[0];
                            y += `${parts[1]} ${parts[2]}`;
                        }
                    }
                    break;
                case 4:
                    x +=
                        parts[0] === 'top' ||
                            parts[0] === 'bottom' ||
                            parts[1] === 'top' ||
                            parts[1] === 'bottom'
                            ? `${parts[2]} ${parts[3]}`
                            : `${parts[0]} ${parts[1]}`;
                    y +=
                        parts[0] === 'top' ||
                            parts[0] === 'bottom' ||
                            parts[1] === 'top' ||
                            parts[1] === 'bottom'
                            ? `${parts[0]} ${parts[1]}`
                            : `${parts[2]} ${parts[3]}`;
                    break;
                default:
                    return null;
            }
        }
        const xValue = this.getBackgroundPositionX(x, important);
        const yValue = this.getBackgroundPositionY(y, important);
        if (xValue && yValue) {
            return {
                ...xValue,
                ...yValue
            };
        }
        return null;
    }
    /**
     * Returns background position.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getBackgroundPositionX(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'background-position-x': { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        if (CSSStyleDeclarationValueParser.getGlobal(lowerValue)) {
            return { 'background-position-x': { value: lowerValue, important } };
        }
        const imageParts = lowerValue.split(SPLIT_COMMA_SEPARATED_WITH_PARANTHESES_REGEXP);
        let parsedValue = '';
        for (const imagePart of imageParts) {
            const parts = imagePart.trim().split(SPLIT_SPACE_SEPARATED_WITH_PARANTHESES_REGEXP);
            if (parsedValue) {
                parsedValue += ',';
            }
            for (const part of parts) {
                const measurement = CSSStyleDeclarationValueParser.getMeasurement(part);
                if (!measurement && part !== 'left' && part !== 'right' && part !== 'center') {
                    return null;
                }
                if (parsedValue) {
                    parsedValue += ' ';
                }
                parsedValue += measurement || part;
            }
        }
        return { 'background-position-x': { value: parsedValue, important } };
    }
    /**
     * Returns background position.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getBackgroundPositionY(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'background-position-y': { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        if (CSSStyleDeclarationValueParser.getGlobal(lowerValue)) {
            return { 'background-position-y': { value: lowerValue, important } };
        }
        const imageParts = lowerValue.split(SPLIT_COMMA_SEPARATED_WITH_PARANTHESES_REGEXP);
        let parsedValue = '';
        for (const imagePart of imageParts) {
            const parts = imagePart.trim().split(SPLIT_SPACE_SEPARATED_WITH_PARANTHESES_REGEXP);
            if (parsedValue) {
                parsedValue += ',';
            }
            for (const part of parts) {
                const measurement = CSSStyleDeclarationValueParser.getMeasurement(part);
                if (!measurement && part !== 'top' && part !== 'bottom' && part !== 'center') {
                    return null;
                }
                if (parsedValue) {
                    parsedValue += ' ';
                }
                parsedValue += measurement || part;
            }
        }
        return { 'background-position-y': { value: parsedValue, important } };
    }
    /**
     * Returns background color.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property value.
     */
    static getBackgroundColor(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'background-color': { value: variable, important } };
        }
        const color = CSSStyleDeclarationValueParser.getGlobal(value) ||
            CSSStyleDeclarationValueParser.getColor(value);
        return color
            ? {
                ['background-color']: { important, value: color }
            }
            : null;
    }
    /**
     * Returns background image.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property value.
     */
    static getBackgroundImage(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'background-image': { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        if (CSSStyleDeclarationValueParser.getGlobal(lowerValue) || lowerValue === 'none') {
            return { 'background-image': { value: lowerValue, important } };
        }
        const parts = CSSStyleDeclarationValueUtility.splitByComma(value);
        const parsed = [];
        for (const part of parts) {
            const parsedValue = CSSStyleDeclarationValueParser.getURL(part.trim()) ||
                CSSStyleDeclarationValueParser.getGradient(part.trim());
            if (!parsedValue) {
                return null;
            }
            parsed.push(parsedValue);
        }
        if (parsed.length) {
            return { 'background-image': { value: parsed.join(', '), important } };
        }
        return null;
    }
    /**
     * Returns color.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property value.
     */
    static getColor(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { color: { value: variable, important } };
        }
        const color = CSSStyleDeclarationValueParser.getGlobal(value) ||
            CSSStyleDeclarationValueParser.getColor(value);
        return color ? { color: { important, value: color } } : null;
    }
    /**
     * Returns color.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property value.
     */
    static getFloodColor(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'flood-color': { value: variable, important } };
        }
        const color = CSSStyleDeclarationValueParser.getGlobal(value) ||
            CSSStyleDeclarationValueParser.getColor(value);
        return color ? { 'flood-color': { important, value: color } } : null;
    }
    /**
     * Returns font.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getFont(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { font: { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        if (CSSStyleDeclarationValueParser.getGlobal(lowerValue)) {
            return {
                ...this.getFontStyle(lowerValue, important),
                ...this.getFontVariant(lowerValue, important),
                ...this.getFontWeight(lowerValue, important),
                ...this.getFontStretch(lowerValue, important),
                ...this.getFontSize(lowerValue, important),
                ...this.getLineHeight(lowerValue, important),
                ...this.getFontFamily(lowerValue, important)
            };
        }
        if (SYSTEM_FONT.includes(lowerValue)) {
            return { font: { value: lowerValue, important } };
        }
        const properties = {
            ...this.getFontStyle('normal', important),
            ...this.getFontVariant('normal', important),
            ...this.getFontWeight('normal', important),
            ...this.getFontStretch('normal', important),
            ...this.getLineHeight('normal', important)
        };
        const parts = value
            .replace(/\s*\/\s*/g, '/')
            .split(SPLIT_SPACE_SEPARATED_WITH_PARANTHESES_REGEXP);
        for (let i = 0, max = parts.length; i < max; i++) {
            const part = parts[i];
            if (part.includes('/')) {
                const [size, height] = part.split('/');
                const fontSize = this.getFontSize(size, important);
                const lineHeight = this.getLineHeight(height, important);
                if (!fontSize || !lineHeight) {
                    return null;
                }
                Object.assign(properties, fontSize, lineHeight);
            }
            else {
                const fontStyle = this.getFontStyle(part, important);
                const fontVariant = this.getFontVariant(part, important);
                const fontWeight = this.getFontWeight(part, important);
                const fontSize = this.getFontSize(part, important);
                const fontStretch = this.getFontStretch(part, important);
                if (fontStyle) {
                    Object.assign(properties, fontStyle);
                }
                else if (fontVariant) {
                    Object.assign(properties, fontVariant);
                }
                else if (fontWeight) {
                    Object.assign(properties, fontWeight);
                }
                else if (fontSize) {
                    Object.assign(properties, fontSize);
                }
                else if (fontStretch) {
                    Object.assign(properties, fontStretch);
                }
                else {
                    const fontFamilyValue = parts.slice(i).join(' ');
                    const fontFamily = this.getFontFamily(fontFamilyValue, important);
                    if (!fontFamily) {
                        return null;
                    }
                    Object.assign(properties, fontFamily);
                    break;
                }
            }
        }
        return properties;
    }
    /**
     * Returns font style.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getFontStyle(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'font-style': { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        if (CSSStyleDeclarationValueParser.getGlobal(lowerValue) || FONT_STYLE.includes(lowerValue)) {
            return { 'font-style': { value: lowerValue, important } };
        }
        const parts = value.split(SPLIT_SPACE_SEPARATED_WITH_PARANTHESES_REGEXP);
        if (parts.length === 2 && parts[0] === 'oblique') {
            const degree = CSSStyleDeclarationValueParser.getDegree(parts[1]);
            return degree ? { 'font-style': { value: lowerValue, important } } : null;
        }
        return null;
    }
    /**
     * Returns font variant.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getFontVariant(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'font-variant': { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        return CSSStyleDeclarationValueParser.getGlobal(lowerValue) ||
            lowerValue === 'normal' ||
            lowerValue === 'small-caps'
            ? { 'font-variant': { value: lowerValue, important } }
            : null;
    }
    /**
     * Returns font strech.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getFontStretch(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'font-stretch': { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        if (CSSStyleDeclarationValueParser.getGlobal(lowerValue) || FONT_STRETCH.includes(lowerValue)) {
            return { 'font-stretch': { value: lowerValue, important } };
        }
        const percentage = CSSStyleDeclarationValueParser.getPercentage(value);
        return percentage ? { 'font-stretch': { value: percentage, important } } : null;
    }
    /**
     * Returns font weight.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getFontWeight(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'font-weight': { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        if (CSSStyleDeclarationValueParser.getGlobal(lowerValue) || FONT_WEIGHT.includes(lowerValue)) {
            return { 'font-weight': { value: lowerValue, important } };
        }
        const integer = CSSStyleDeclarationValueParser.getInteger(value);
        return integer ? { 'font-weight': { value: integer, important } } : null;
    }
    /**
     * Returns font size.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getFontSize(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'font-size': { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        if (CSSStyleDeclarationValueParser.getGlobal(lowerValue) || FONT_SIZE.includes(lowerValue)) {
            return { 'font-size': { value: lowerValue, important } };
        }
        const measurement = CSSStyleDeclarationValueParser.getMeasurement(value);
        return measurement ? { 'font-size': { value: measurement, important } } : null;
    }
    /**
     * Returns line height.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getLineHeight(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'line-height': { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        if (CSSStyleDeclarationValueParser.getGlobal(lowerValue) || lowerValue === 'normal') {
            return { 'line-height': { value: lowerValue, important } };
        }
        const lineHeight = CSSStyleDeclarationValueParser.getFloat(value) ||
            CSSStyleDeclarationValueParser.getMeasurement(value);
        return lineHeight ? { 'line-height': { value: lineHeight, important } } : null;
    }
    /**
     * Returns font family.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getFontFamily(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'font-family': { value: variable, important } };
        }
        const globalValue = CSSStyleDeclarationValueParser.getGlobal(value);
        if (globalValue) {
            return { 'font-family': { value: globalValue, important } };
        }
        const parts = value.split(',');
        let parsedValue = '';
        let endWithApostroph = false;
        for (let i = 0, max = parts.length; i < max; i++) {
            let trimmedPart = parts[i].trim().replace(/'/g, '"');
            if (!trimmedPart) {
                return null;
            }
            if (trimmedPart.includes(' ')) {
                const apostrophCount = (trimmedPart.match(/"/g) || []).length;
                if ((trimmedPart[0] !== '"' || i !== 0) && apostrophCount !== 2 && apostrophCount !== 0) {
                    return null;
                }
                if (trimmedPart[0] === '"' && trimmedPart[trimmedPart.length - 1] !== '"') {
                    endWithApostroph = true;
                }
                else if (trimmedPart[0] !== '"' && trimmedPart[trimmedPart.length - 1] !== '"') {
                    trimmedPart = `"${trimmedPart}"`;
                }
            }
            else {
                trimmedPart = trimmedPart.replace(/"/g, '');
            }
            if (i > 0) {
                parsedValue += ', ';
            }
            parsedValue += trimmedPart;
        }
        if (endWithApostroph) {
            parsedValue += '"';
        }
        if (!parsedValue) {
            return null;
        }
        return {
            'font-family': {
                important,
                value: parsedValue
            }
        };
    }
    /**
     * Returns font family.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property values
     */
    static getTextTransform(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'text-transform': { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        const parsedValue = CSSStyleDeclarationValueParser.getGlobal(lowerValue) ||
            (TEXT_TRANSFORM.includes(lowerValue) && lowerValue);
        if (parsedValue) {
            return {
                'text-transform': { value: parsedValue, important }
            };
        }
        return null;
    }
    /**
     * Returns visibility.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property
     */
    static getVisibility(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { visibility: { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        const parsedValue = CSSStyleDeclarationValueParser.getGlobal(lowerValue) ||
            (VISIBILITY.includes(lowerValue) && lowerValue);
        if (parsedValue) {
            return {
                visibility: { value: parsedValue, important }
            };
        }
        return null;
    }
    /**
     * Returns aspect ratio.
     *
     * @param value Value.
     * @param important Important.
     * @returns Property
     */
    static getAspectRatio(value, important) {
        const variable = CSSStyleDeclarationValueParser.getVariable(value);
        if (variable) {
            return { 'aspect-ratio': { value: variable, important } };
        }
        const lowerValue = value.toLowerCase();
        if (CSSStyleDeclarationValueParser.getGlobal(lowerValue)) {
            return { 'aspect-ratio': { value: lowerValue, important } };
        }
        let parsedValue = value;
        const hasAuto = parsedValue.includes('auto');
        if (hasAuto) {
            parsedValue = parsedValue.replace('auto', '');
        }
        parsedValue = parsedValue.replace(WHITE_SPACE_GLOBAL_REGEXP, '');
        if (!parsedValue) {
            return { 'aspect-ratio': { value: 'auto', important } };
        }
        const aspectRatio = parsedValue.split('/');
        if (aspectRatio.length > 3) {
            return null;
        }
        const width = Number(aspectRatio[0]);
        const height = aspectRatio[1] ? Number(aspectRatio[1]) : 1;
        if (isNaN(width) || isNaN(height)) {
            return null;
        }
        if (hasAuto) {
            return { 'aspect-ratio': { value: `auto ${width} / ${height}`, important } };
        }
        return { 'aspect-ratio': { value: `${width} / ${height}`, important } };
    }
}
//# sourceMappingURL=CSSStyleDeclarationPropertySetParser.js.map