gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

handlers.go (63670B)


      1 // Copyright (c) 2019, David Kitchen <david@buro9.com>
      2 //
      3 // All rights reserved.
      4 //
      5 // Redistribution and use in source and binary forms, with or without
      6 // modification, are permitted provided that the following conditions are met:
      7 //
      8 // * Redistributions of source code must retain the above copyright notice, this
      9 //   list of conditions and the following disclaimer.
     10 //
     11 // * Redistributions in binary form must reproduce the above copyright notice,
     12 //   this list of conditions and the following disclaimer in the documentation
     13 //   and/or other materials provided with the distribution.
     14 //
     15 // * Neither the name of the organisation (Microcosm) nor the names of its
     16 //   contributors may be used to endorse or promote products derived from
     17 //   this software without specific prior written permission.
     18 //
     19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     22 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
     23 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     25 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     26 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     27 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29 
     30 package css
     31 
     32 import (
     33 	"regexp"
     34 	"strings"
     35 )
     36 
     37 var (
     38 	defaultStyleHandlers = map[string]func(string) bool{
     39 		"align-content":              AlignContentHandler,
     40 		"align-items":                AlignItemsHandler,
     41 		"align-self":                 AlignSelfHandler,
     42 		"all":                        AllHandler,
     43 		"animation":                  AnimationHandler,
     44 		"animation-delay":            AnimationDelayHandler,
     45 		"animation-direction":        AnimationDirectionHandler,
     46 		"animation-duration":         AnimationDurationHandler,
     47 		"animation-fill-mode":        AnimationFillModeHandler,
     48 		"animation-iteration-count":  AnimationIterationCountHandler,
     49 		"animation-name":             AnimationNameHandler,
     50 		"animation-play-state":       AnimationPlayStateHandler,
     51 		"animation-timing-function":  TimingFunctionHandler,
     52 		"backface-visibility":        BackfaceVisibilityHandler,
     53 		"background":                 BackgroundHandler,
     54 		"background-attachment":      BackgroundAttachmentHandler,
     55 		"background-blend-mode":      BackgroundBlendModeHandler,
     56 		"background-clip":            BackgroundClipHandler,
     57 		"background-color":           ColorHandler,
     58 		"background-image":           ImageHandler,
     59 		"background-origin":          BackgroundOriginHandler,
     60 		"background-position":        BackgroundPositionHandler,
     61 		"background-repeat":          BackgroundRepeatHandler,
     62 		"background-size":            BackgroundSizeHandler,
     63 		"border":                     BorderHandler,
     64 		"border-bottom":              BorderSideHandler,
     65 		"border-bottom-color":        ColorHandler,
     66 		"border-bottom-left-radius":  BorderSideRadiusHandler,
     67 		"border-bottom-right-radius": BorderSideRadiusHandler,
     68 		"border-bottom-style":        BorderSideStyleHandler,
     69 		"border-bottom-width":        BorderSideWidthHandler,
     70 		"border-collapse":            BorderCollapseHandler,
     71 		"border-color":               ColorHandler,
     72 		"border-image":               BorderImageHandler,
     73 		"border-image-outset":        BorderImageOutsetHandler,
     74 		"border-image-repeat":        BorderImageRepeatHandler,
     75 		"border-image-slice":         BorderImageSliceHandler,
     76 		"border-image-source":        ImageHandler,
     77 		"border-image-width":         BorderImageWidthHandler,
     78 		"border-left":                BorderSideHandler,
     79 		"border-left-color":          ColorHandler,
     80 		"border-left-style":          BorderSideStyleHandler,
     81 		"border-left-width":          BorderSideWidthHandler,
     82 		"border-radius":              BorderRadiusHandler,
     83 		"border-right":               BorderSideHandler,
     84 		"border-right-color":         ColorHandler,
     85 		"border-right-style":         BorderSideStyleHandler,
     86 		"border-right-width":         BorderSideWidthHandler,
     87 		"border-spacing":             BorderSpacingHandler,
     88 		"border-style":               BorderStyleHandler,
     89 		"border-top":                 BorderSideHandler,
     90 		"border-top-color":           ColorHandler,
     91 		"border-top-left-radius":     BorderSideRadiusHandler,
     92 		"border-top-right-radius":    BorderSideRadiusHandler,
     93 		"border-top-style":           BorderSideStyleHandler,
     94 		"border-top-width":           BorderSideWidthHandler,
     95 		"border-width":               BorderWidthHandler,
     96 		"bottom":                     SideHandler,
     97 		"box-decoration-break":       BoxDecorationBreakHandler,
     98 		"box-shadow":                 BoxShadowHandler,
     99 		"box-sizing":                 BoxSizingHandler,
    100 		"break-after":                BreakBeforeAfterHandler,
    101 		"break-before":               BreakBeforeAfterHandler,
    102 		"break-inside":               BreakInsideHandler,
    103 		"caption-side":               CaptionSideHandler,
    104 		"caret-color":                CaretColorHandler,
    105 		"clear":                      ClearHandler,
    106 		"clip":                       ClipHandler,
    107 		"color":                      ColorHandler,
    108 		"column-count":               ColumnCountHandler,
    109 		"column-fill":                ColumnFillHandler,
    110 		"column-gap":                 ColumnGapHandler,
    111 		"column-rule":                ColumnRuleHandler,
    112 		"column-rule-color":          ColorHandler,
    113 		"column-rule-style":          BorderSideStyleHandler,
    114 		"column-rule-width":          ColumnRuleWidthHandler,
    115 		"column-span":                ColumnSpanHandler,
    116 		"column-width":               ColumnWidthHandler,
    117 		"columns":                    ColumnsHandler,
    118 		"cursor":                     CursorHandler,
    119 		"direction":                  DirectionHandler,
    120 		"display":                    DisplayHandler,
    121 		"empty-cells":                EmptyCellsHandler,
    122 		"filter":                     FilterHandler,
    123 		"flex":                       FlexHandler,
    124 		"flex-basis":                 FlexBasisHandler,
    125 		"flex-direction":             FlexDirectionHandler,
    126 		"flex-flow":                  FlexFlowHandler,
    127 		"flex-grow":                  FlexGrowHandler,
    128 		"flex-shrink":                FlexGrowHandler,
    129 		"flex-wrap":                  FlexWrapHandler,
    130 		"float":                      FloatHandler,
    131 		"font":                       FontHandler,
    132 		"font-family":                FontFamilyHandler,
    133 		"font-kerning":               FontKerningHandler,
    134 		"font-language-override":     FontLanguageOverrideHandler,
    135 		"font-size":                  FontSizeHandler,
    136 		"font-size-adjust":           FontSizeAdjustHandler,
    137 		"font-stretch":               FontStretchHandler,
    138 		"font-style":                 FontStyleHandler,
    139 		"font-synthesis":             FontSynthesisHandler,
    140 		"font-variant":               FontVariantHandler,
    141 		"font-variant-caps":          FontVariantCapsHandler,
    142 		"font-variant-position":      FontVariantPositionHandler,
    143 		"font-weight":                FontWeightHandler,
    144 		"grid":                       GridHandler,
    145 		"grid-area":                  GridAreaHandler,
    146 		"grid-auto-columns":          GridAutoColumnsHandler,
    147 		"grid-auto-flow":             GridAutoFlowHandler,
    148 		"grid-auto-rows":             GridAutoColumnsHandler,
    149 		"grid-column":                GridColumnHandler,
    150 		"grid-column-end":            GridAxisStartEndHandler,
    151 		"grid-column-gap":            LengthHandler,
    152 		"grid-column-start":          GridAxisStartEndHandler,
    153 		"grid-gap":                   GridGapHandler,
    154 		"grid-row":                   GridRowHandler,
    155 		"grid-row-end":               GridAxisStartEndHandler,
    156 		"grid-row-gap":               LengthHandler,
    157 		"grid-row-start":             GridAxisStartEndHandler,
    158 		"grid-template":              GridTemplateHandler,
    159 		"grid-template-areas":        GridTemplateAreasHandler,
    160 		"grid-template-columns":      GridTemplateColumnsHandler,
    161 		"grid-template-rows":         GridTemplateRowsHandler,
    162 		"hanging-punctuation":        HangingPunctuationHandler,
    163 		"height":                     HeightHandler,
    164 		"hyphens":                    HyphensHandler,
    165 		"image-rendering":            ImageRenderingHandler,
    166 		"isolation":                  IsolationHandler,
    167 		"justify-content":            JustifyContentHandler,
    168 		"left":                       SideHandler,
    169 		"letter-spacing":             LetterSpacingHandler,
    170 		"line-break":                 LineBreakHandler,
    171 		"line-height":                LineHeightHandler,
    172 		"list-style":                 ListStyleHandler,
    173 		"list-style-image":           ImageHandler,
    174 		"list-style-position":        ListStylePositionHandler,
    175 		"list-style-type":            ListStyleTypeHandler,
    176 		"margin":                     MarginHandler,
    177 		"margin-bottom":              MarginSideHandler,
    178 		"margin-left":                MarginSideHandler,
    179 		"margin-right":               MarginSideHandler,
    180 		"margin-top":                 MarginSideHandler,
    181 		"max-height":                 MaxHeightWidthHandler,
    182 		"max-width":                  MaxHeightWidthHandler,
    183 		"min-height":                 MinHeightWidthHandler,
    184 		"min-width":                  MinHeightWidthHandler,
    185 		"mix-blend-mode":             MixBlendModeHandler,
    186 		"object-fit":                 ObjectFitHandler,
    187 		"object-position":            ObjectPositionHandler,
    188 		"opacity":                    OpacityHandler,
    189 		"order":                      OrderHandler,
    190 		"orphans":                    OrphansHandler,
    191 		"outline":                    OutlineHandler,
    192 		"outline-color":              ColorHandler,
    193 		"outline-offset":             OutlineOffsetHandler,
    194 		"outline-style":              OutlineStyleHandler,
    195 		"outline-width":              OutlineWidthHandler,
    196 		"overflow":                   OverflowHandler,
    197 		"overflow-wrap":              OverflowWrapHandler,
    198 		"overflow-x":                 OverflowXYHandler,
    199 		"overflow-y":                 OverflowXYHandler,
    200 		"padding":                    PaddingHandler,
    201 		"padding-bottom":             PaddingSideHandler,
    202 		"padding-left":               PaddingSideHandler,
    203 		"padding-right":              PaddingSideHandler,
    204 		"padding-top":                PaddingSideHandler,
    205 		"page-break-after":           PageBreakBeforeAfterHandler,
    206 		"page-break-before":          PageBreakBeforeAfterHandler,
    207 		"page-break-inside":          PageBreakInsideHandler,
    208 		"perspective":                PerspectiveHandler,
    209 		"perspective-origin":         PerspectiveOriginHandler,
    210 		"pointer-events":             PointerEventsHandler,
    211 		"position":                   PositionHandler,
    212 		"quotes":                     QuotesHandler,
    213 		"resize":                     ResizeHandler,
    214 		"right":                      SideHandler,
    215 		"scroll-behavior":            ScrollBehaviorHandler,
    216 		"tab-size":                   TabSizeHandler,
    217 		"table-layout":               TableLayoutHandler,
    218 		"text-align":                 TextAlignHandler,
    219 		"text-align-last":            TextAlignLastHandler,
    220 		"text-combine-upright":       TextCombineUprightHandler,
    221 		"text-decoration":            TextDecorationHandler,
    222 		"text-decoration-color":      ColorHandler,
    223 		"text-decoration-line":       TextDecorationLineHandler,
    224 		"text-decoration-style":      TextDecorationStyleHandler,
    225 		"text-indent":                TextIndentHandler,
    226 		"text-justify":               TextJustifyHandler,
    227 		"text-orientation":           TextOrientationHandler,
    228 		"text-overflow":              TextOverflowHandler,
    229 		"text-shadow":                TextShadowHandler,
    230 		"text-transform":             TextTransformHandler,
    231 		"top":                        SideHandler,
    232 		"transform":                  TransformHandler,
    233 		"transform-origin":           TransformOriginHandler,
    234 		"transform-style":            TransformStyleHandler,
    235 		"transition":                 TransitionHandler,
    236 		"transition-delay":           TransitionDelayHandler,
    237 		"transition-duration":        TransitionDurationHandler,
    238 		"transition-property":        TransitionPropertyHandler,
    239 		"transition-timing-function": TimingFunctionHandler,
    240 		"unicode-bidi":               UnicodeBidiHandler,
    241 		"user-select":                UserSelectHandler,
    242 		"vertical-align":             VerticalAlignHandler,
    243 		"visibility":                 VisiblityHandler,
    244 		"white-space":                WhiteSpaceHandler,
    245 		"widows":                     OrphansHandler,
    246 		"width":                      WidthHandler,
    247 		"word-break":                 WordBreakHandler,
    248 		"word-spacing":               WordSpacingHandler,
    249 		"word-wrap":                  WordWrapHandler,
    250 		"writing-mode":               WritingModeHandler,
    251 		"z-index":                    ZIndexHandler,
    252 	}
    253 	colorValues = []string{"initial", "inherit", "aliceblue", "antiquewhite",
    254 		"aqua", "aquamarine", "azure", "beige", "bisque", "black",
    255 		"blanchedalmond", "blue", "blueviolet", "brown", "burlywood",
    256 		"cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue",
    257 		"cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod",
    258 		"darkgray", "darkgrey", "darkgreen", "darkkhaki", "darkmagenta",
    259 		"darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon",
    260 		"darkseagreen", "darkslateblue", "darkslategrey", "darkslategray",
    261 		"darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray",
    262 		"dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen",
    263 		"fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray",
    264 		"grey", "green", "greenyellow", "honeydew", "hotpink", "indianred",
    265 		"indigo", "ivory", "khaki", "lavender", "lavenderblush",
    266 		"lemonchiffon", "lightblue", "lightcoral", "lightcyan",
    267 		"lightgoldenrodyellow", "lightgray", "lightgrey", "lightgreen",
    268 		"lightpink", "lightsalmon", "lightseagreen", "lightskyblue",
    269 		"lightslategray", "lightslategrey", "lightsteeelblue", "lightyellow",
    270 		"lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine",
    271 		"mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen",
    272 		"mediumslateblue", "mediumspringgreen", "mediumturquoise",
    273 		"mediumvioletred", "midnightblue", "mintcream", "mistyrose",
    274 		"moccasin", "navajowhite", "navy", "oldlace", "olive", "olivedrab",
    275 		"orange", "orangered", "orchid", "palegoldenrod", "palegreen",
    276 		"paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru",
    277 		"pink", "plum", "powderblue", "purple", "rebeccapurple", "red",
    278 		"rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown",
    279 		"seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue",
    280 		"slategray", "slategrey", "snow", "springgreen", "steelblue", "tan",
    281 		"teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white",
    282 		"whitesmoke", "yellow", "yellowgreen"}
    283 
    284 	Alpha             = regexp.MustCompile(`^[a-z]+$`)
    285 	Blur              = regexp.MustCompile(`^blur\([0-9]+px\)$`)
    286 	BrightnessCont    = regexp.MustCompile(`^(brightness|contrast)\([0-9]+\%\)$`)
    287 	Count             = regexp.MustCompile(`^[0-9]+[\.]?[0-9]*$`)
    288 	CubicBezier       = regexp.MustCompile(`^cubic-bezier\(([ ]*(0(.[0-9]+)?|1(.0)?),){3}[ ]*(0(.[0-9]+)?|1)\)$`)
    289 	Digits            = regexp.MustCompile(`^digits [2-4]$`)
    290 	DropShadow        = regexp.MustCompile(`drop-shadow\(([-]?[0-9]+px) ([-]?[0-9]+px)( [-]?[0-9]+px)?( ([-]?[0-9]+px))?`)
    291 	Font              = regexp.MustCompile(`^('[a-z \-]+'|[a-z \-]+)$`)
    292 	Grayscale         = regexp.MustCompile(`^grayscale\(([0-9]{1,2}|100)%\)$`)
    293 	GridTemplateAreas = regexp.MustCompile(`^['"]?[a-z ]+['"]?$`)
    294 	HexRGB            = regexp.MustCompile(`^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$`)
    295 	HSL               = regexp.MustCompile(`^hsl\([ ]*([012]?[0-9]{1,2}|3[0-5][0-9]|360),[ ]*([0-9]{0,2}|100)\%,[ ]*([0-9]{0,2}|100)\%\)$`)
    296 	HSLA              = regexp.MustCompile(`^hsla\(([ ]*[012]?[0-9]{1,2}|3[0-5][0-9]|360),[ ]*([0-9]{0,2}|100)\%,[ ]*([0-9]{0,2}|100)\%,[ ]*(1|1\.0|0|(0\.[0-9]+))\)$`)
    297 	HueRotate         = regexp.MustCompile(`^hue-rotate\(([12]?[0-9]{1,2}|3[0-5][0-9]|360)?\)$`)
    298 	Invert            = regexp.MustCompile(`^invert\(([0-9]{1,2}|100)%\)$`)
    299 	Length            = regexp.MustCompile(`^[\-]?([0-9]+|[0-9]*[\.][0-9]+)(%|cm|mm|in|px|pt|pc|em|ex|ch|rem|vw|vh|vmin|vmax|deg|rad|turn)?$`)
    300 	Matrix            = regexp.MustCompile(`^matrix\(([ ]*[0-9]+[\.]?[0-9]*,){5}([ ]*[0-9]+[\.]?[0-9]*)\)$`)
    301 	Matrix3D          = regexp.MustCompile(`^matrix3d\(([ ]*[0-9]+[\.]?[0-9]*,){15}([ ]*[0-9]+[\.]?[0-9]*)\)$`)
    302 	NegTime           = regexp.MustCompile(`^[\-]?[0-9]+[\.]?[0-9]*(s|ms)?$`)
    303 	Numeric           = regexp.MustCompile(`^[0-9]+$`)
    304 	NumericDecimal    = regexp.MustCompile(`^[0-9\.]+$`)
    305 	Opactiy           = regexp.MustCompile(`^opacity\(([0-9]{1,2}|100)%\)$`)
    306 	Perspective       = regexp.MustCompile(`perspective\(`)
    307 	Position          = regexp.MustCompile(`^[\-]*[0-9]+[cm|mm|in|px|pt|pc\%]* [[\-]*[0-9]+[cm|mm|in|px|pt|pc\%]*]*$`)
    308 	Opacity           = regexp.MustCompile(`^(0[.]?[0-9]*)|(1.0)$`)
    309 	QuotedAlpha       = regexp.MustCompile(`^["'][a-z]+["']$`)
    310 	Quotes            = regexp.MustCompile(`^([ ]*["'][\x{0022}\x{0027}\x{2039}\x{2039}\x{203A}\x{00AB}\x{00BB}\x{2018}\x{2019}\x{201C}-\x{201E}]["'] ["'][\x{0022}\x{0027}\x{2039}\x{2039}\x{203A}\x{00AB}\x{00BB}\x{2018}\x{2019}\x{201C}-\x{201E}]["'])+$`)
    311 	Rect              = regexp.MustCompile(`^rect\([0-9]+px,[ ]*[0-9]+px,[ ]*[0-9]+px,[ ]*[0-9]+px\)$`)
    312 	RGB               = regexp.MustCompile(`^rgb\(([ ]*((([0-9]{1,2}|100)\%)|(([01]?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5]))),){2}([ ]*((([0-9]{1,2}|100)\%)|(([01]?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5]))))\)$`)
    313 	RGBA              = regexp.MustCompile(`^rgba\(([ ]*((([0-9]{1,2}|100)\%)|(([01]?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5]))),){3}[ ]*(1(\.0)?|0|(0\.[0-9]+))\)$`)
    314 	Rotate            = regexp.MustCompile(`^rotate(x|y|z)?\(([12]?|3[0-5][0-9]|360)\)$`)
    315 	Rotate3D          = regexp.MustCompile(`^rotate3d\(([ ]?(1(\.0)?|0\.[0-9]+),){3}([12]?|3[0-5][0-9]|360)\)$`)
    316 	Saturate          = regexp.MustCompile(`^saturate\([0-9]+%\)$`)
    317 	Sepia             = regexp.MustCompile(`^sepia\(([0-9]{1,2}|100)%\)$`)
    318 	Skew              = regexp.MustCompile(`skew(x|y)?\(`)
    319 	Span              = regexp.MustCompile(`^span [0-9]+$`)
    320 	Steps             = regexp.MustCompile(`^steps\([ ]*[0-9]+([ ]*,[ ]*(start|end)?)\)$`)
    321 	Time              = regexp.MustCompile(`^[0-9]+[\.]?[0-9]*(s|ms)?$`)
    322 	TransitionProp    = regexp.MustCompile(`^([a-zA-Z]+,[ ]?)*[a-zA-Z]+$`)
    323 	TranslateScale    = regexp.MustCompile(`(translate|translate3d|translatex|translatey|translatez|scale|scale3d|scalex|scaley|scalez)\(`)
    324 	URL               = regexp.MustCompile(`^url\([\"\']?((https|http)[a-z0-9\.\\/_:]+[\"\']?)\)$`)
    325 	ZIndex            = regexp.MustCompile(`^[\-]?[0-9]+$`)
    326 )
    327 
    328 func multiSplit(value string, seps ...string) []string {
    329 	curArray := []string{value}
    330 	for _, i := range seps {
    331 		newArray := []string{}
    332 		for _, j := range curArray {
    333 			newArray = append(newArray, strings.Split(j, i)...)
    334 		}
    335 		curArray = newArray
    336 	}
    337 	return curArray
    338 }
    339 
    340 func recursiveCheck(value []string, funcs []func(string) bool) bool {
    341 	for i := 0; i < len(value); i++ {
    342 		tempVal := strings.Join(value[:i+1], " ")
    343 		for _, j := range funcs {
    344 			if j(tempVal) && (len(value[i+1:]) == 0 || recursiveCheck(value[i+1:], funcs)) {
    345 				return true
    346 			}
    347 		}
    348 	}
    349 	return false
    350 }
    351 
    352 func in(value []string, arr []string) bool {
    353 	for _, i := range value {
    354 		foundString := false
    355 		for _, j := range arr {
    356 			if j == i {
    357 				foundString = true
    358 			}
    359 		}
    360 		if !foundString {
    361 			return false
    362 		}
    363 	}
    364 	return true
    365 }
    366 
    367 func splitValues(value string) []string {
    368 	values := strings.Split(value, ",")
    369 	for _, strippedValue := range values {
    370 		strippedValue = strings.ToLower(strings.TrimSpace(strippedValue))
    371 	}
    372 	return values
    373 }
    374 
    375 func GetDefaultHandler(attr string) func(string) bool {
    376 
    377 	if defaultStyleHandlers[attr] != nil {
    378 		return defaultStyleHandlers[attr]
    379 	}
    380 	return BaseHandler
    381 }
    382 
    383 func BaseHandler(value string) bool {
    384 	return false
    385 }
    386 
    387 func AlignContentHandler(value string) bool {
    388 	values := []string{"stretch", "center", "flex-start",
    389 		"flex-end", "space-between", "space-around", "initial", "inherit"}
    390 	splitVals := splitValues(value)
    391 	return in(splitVals, values)
    392 }
    393 
    394 func AlignItemsHandler(value string) bool {
    395 	values := []string{"stretch", "center", "flex-start",
    396 		"flex-end", "baseline", "initial", "inherit"}
    397 	splitVals := splitValues(value)
    398 	return in(splitVals, values)
    399 }
    400 
    401 func AlignSelfHandler(value string) bool {
    402 	values := []string{"auto", "stretch", "center", "flex-start",
    403 		"flex-end", "baseline", "initial", "inherit"}
    404 	splitVals := splitValues(value)
    405 	return in(splitVals, values)
    406 }
    407 
    408 func AllHandler(value string) bool {
    409 	values := []string{"initial", "inherit", "unset"}
    410 	splitVals := splitValues(value)
    411 	return in(splitVals, values)
    412 }
    413 
    414 func AnimationHandler(value string) bool {
    415 	values := []string{"initial", "inherit"}
    416 	if in([]string{value}, values) {
    417 		return true
    418 	}
    419 	splitVals := strings.Split(value, " ")
    420 	usedFunctions := []func(string) bool{
    421 		AnimationNameHandler,
    422 		AnimationDurationHandler,
    423 		TimingFunctionHandler,
    424 		AnimationDelayHandler,
    425 		AnimationIterationCountHandler,
    426 		AnimationDirectionHandler,
    427 		AnimationFillModeHandler,
    428 		AnimationPlayStateHandler,
    429 	}
    430 	return recursiveCheck(splitVals, usedFunctions)
    431 }
    432 
    433 func AnimationDelayHandler(value string) bool {
    434 	if NegTime.MatchString(value) {
    435 		return true
    436 	}
    437 	values := []string{"initial", "inherit"}
    438 	splitVals := splitValues(value)
    439 	return in(splitVals, values)
    440 }
    441 
    442 func AnimationDirectionHandler(value string) bool {
    443 	values := []string{"normal", "reverse", "alternate", "alternate-reverse", "initial", "inherit"}
    444 	splitVals := splitValues(value)
    445 	return in(splitVals, values)
    446 }
    447 
    448 func AnimationDurationHandler(value string) bool {
    449 	if Time.MatchString(value) {
    450 		return true
    451 	}
    452 	values := []string{"initial", "inherit"}
    453 	splitVals := splitValues(value)
    454 	return in(splitVals, values)
    455 }
    456 
    457 func AnimationFillModeHandler(value string) bool {
    458 	values := []string{"none", "forwards", "backwards", "both", "initial", "inherit"}
    459 	splitVals := splitValues(value)
    460 	return in(splitVals, values)
    461 }
    462 
    463 func AnimationIterationCountHandler(value string) bool {
    464 	if Count.MatchString(value) {
    465 		return true
    466 	}
    467 	values := []string{"infinite", "initial", "inherit"}
    468 	splitVals := splitValues(value)
    469 	return in(splitVals, values)
    470 }
    471 
    472 func AnimationNameHandler(value string) bool {
    473 	return Alpha.MatchString(value)
    474 }
    475 
    476 func AnimationPlayStateHandler(value string) bool {
    477 	values := []string{"paused", "running", "initial", "inherit"}
    478 	splitVals := splitValues(value)
    479 	return in(splitVals, values)
    480 }
    481 
    482 func TimingFunctionHandler(value string) bool {
    483 	values := []string{"linear", "ease", "ease-in", "ease-out", "ease-in-out", "step-start", "step-end", "initial", "inherit"}
    484 	splitVals := splitValues(value)
    485 	if in(splitVals, values) {
    486 		return true
    487 	}
    488 	if CubicBezier.MatchString(value) {
    489 		return true
    490 	}
    491 	return Steps.MatchString(value)
    492 }
    493 
    494 func BackfaceVisibilityHandler(value string) bool {
    495 	values := []string{"visible", "hidden", "initial", "inherit"}
    496 	splitVals := splitValues(value)
    497 	return in(splitVals, values)
    498 }
    499 
    500 func BackgroundHandler(value string) bool {
    501 	values := []string{"initial", "inherit"}
    502 	if in([]string{value}, values) {
    503 		return true
    504 	}
    505 	splitVals := strings.Split(value, " ")
    506 	newSplitVals := []string{}
    507 	for _, i := range splitVals {
    508 		if len(strings.Split(i, "/")) == 2 {
    509 			newSplitVals = append(newSplitVals, strings.Split(i, "/")...)
    510 		} else {
    511 			newSplitVals = append(newSplitVals, i)
    512 		}
    513 	}
    514 	usedFunctions := []func(string) bool{
    515 		ColorHandler,
    516 		ImageHandler,
    517 		BackgroundPositionHandler,
    518 		BackgroundSizeHandler,
    519 		BackgroundRepeatHandler,
    520 		BackgroundOriginHandler,
    521 		BackgroundClipHandler,
    522 		BackgroundAttachmentHandler,
    523 	}
    524 	return recursiveCheck(newSplitVals, usedFunctions)
    525 }
    526 
    527 func BackgroundAttachmentHandler(value string) bool {
    528 	values := []string{"scroll", "fixed", "local", "initial", "inherit"}
    529 	splitVals := splitValues(value)
    530 	return in(splitVals, values)
    531 }
    532 
    533 func BackgroundClipHandler(value string) bool {
    534 	values := []string{"border-box", "padding-box", "content-box", "initial", "inherit"}
    535 	splitVals := splitValues(value)
    536 	return in(splitVals, values)
    537 }
    538 
    539 func BackgroundBlendModeHandler(value string) bool {
    540 	values := []string{"normal", "multiply", "screen", "overlay", "darken",
    541 		"lighten", "color-dodge", "saturation", "color", "luminosity"}
    542 	splitVals := splitValues(value)
    543 	return in(splitVals, values)
    544 }
    545 
    546 func ImageHandler(value string) bool {
    547 	values := []string{"none", "initial", "inherit"}
    548 	splitVals := splitValues(value)
    549 	if in(splitVals, values) {
    550 		return true
    551 	}
    552 	return URL.MatchString(value)
    553 }
    554 
    555 func BackgroundOriginHandler(value string) bool {
    556 	values := []string{"padding-box", "border-box", "content-box", "initial", "inherit"}
    557 	splitVals := splitValues(value)
    558 	return in(splitVals, values)
    559 }
    560 
    561 func BackgroundPositionHandler(value string) bool {
    562 	splitVals := strings.Split(value, ";")
    563 	values := []string{"left", "left top", "left bottom", "right", "right top", "right bottom", "right center", "center top", "center center", "center bottom", "center", "top", "bottom", "initial", "inherit"}
    564 	if in(splitVals, values) {
    565 		return true
    566 	}
    567 	return Position.MatchString(value)
    568 }
    569 
    570 func BackgroundRepeatHandler(value string) bool {
    571 	values := []string{"repeat", "repeat-x", "repeat-y", "no-repeat", "space", "round", "initial", "inherit"}
    572 	splitVals := splitValues(value)
    573 	return in(splitVals, values)
    574 }
    575 
    576 func BackgroundSizeHandler(value string) bool {
    577 	splitVals := strings.Split(value, " ")
    578 	values := []string{"auto", "cover", "contain", "initial", "inherit"}
    579 	if in(splitVals, values) {
    580 		return true
    581 	}
    582 	if len(splitVals) > 0 && LengthHandler(splitVals[0]) {
    583 		if len(splitVals) < 2 || (len(splitVals) == 2 && LengthHandler(splitVals[1])) {
    584 			return true
    585 		}
    586 	}
    587 	return false
    588 }
    589 
    590 func BorderHandler(value string) bool {
    591 	values := []string{"initial", "inherit"}
    592 	if in([]string{value}, values) {
    593 		return true
    594 	}
    595 	splitVals := multiSplit(value, " ", "/")
    596 	usedFunctions := []func(string) bool{
    597 		BorderWidthHandler,
    598 		BorderStyleHandler,
    599 		ColorHandler,
    600 	}
    601 	return recursiveCheck(splitVals, usedFunctions)
    602 }
    603 
    604 func BorderSideHandler(value string) bool {
    605 	values := []string{"initial", "inherit"}
    606 	if in([]string{value}, values) {
    607 		return true
    608 	}
    609 	splitVals := strings.Split(value, " ")
    610 	usedFunctions := []func(string) bool{
    611 		BorderSideWidthHandler,
    612 		BorderSideStyleHandler,
    613 		ColorHandler,
    614 	}
    615 	return recursiveCheck(splitVals, usedFunctions)
    616 }
    617 
    618 func BorderSideRadiusHandler(value string) bool {
    619 	splitVals := strings.Split(value, " ")
    620 	valid := true
    621 	for _, i := range splitVals {
    622 		if !LengthHandler(i) {
    623 			valid = false
    624 			break
    625 		}
    626 	}
    627 	if valid {
    628 		return true
    629 	}
    630 	splitVals = splitValues(value)
    631 	values := []string{"initial", "inherit"}
    632 	return in(splitVals, values)
    633 }
    634 
    635 func BorderSideStyleHandler(value string) bool {
    636 	values := []string{"none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset", "initial", "inherit"}
    637 	splitVals := splitValues(value)
    638 	return in(splitVals, values)
    639 }
    640 
    641 func BorderSideWidthHandler(value string) bool {
    642 	if LengthHandler(value) {
    643 		return true
    644 	}
    645 	splitVals := strings.Split(value, ";")
    646 	values := []string{"medium", "thin", "thick", "initial", "inherit"}
    647 	return in(splitVals, values)
    648 }
    649 
    650 func BorderCollapseHandler(value string) bool {
    651 	values := []string{"separate", "collapse", "initial", "inherit"}
    652 	splitVals := splitValues(value)
    653 	return in(splitVals, values)
    654 }
    655 
    656 func BorderImageHandler(value string) bool {
    657 	values := []string{"initial", "inherit"}
    658 	if in([]string{value}, values) {
    659 		return true
    660 	}
    661 	splitVals := multiSplit(value, " ", " / ")
    662 	usedFunctions := []func(string) bool{
    663 		ImageHandler,
    664 		BorderImageSliceHandler,
    665 		BorderImageWidthHandler,
    666 		BorderImageOutsetHandler,
    667 		BorderImageRepeatHandler,
    668 	}
    669 	return recursiveCheck(splitVals, usedFunctions)
    670 }
    671 
    672 func BorderImageOutsetHandler(value string) bool {
    673 	if LengthHandler(value) {
    674 		return true
    675 	}
    676 	values := []string{"initial", "inherit"}
    677 	splitVals := splitValues(value)
    678 	return in(splitVals, values)
    679 }
    680 
    681 func BorderImageRepeatHandler(value string) bool {
    682 	values := []string{"stretch", "repeat", "round", "space", "initial", "inherit"}
    683 	splitVals := splitValues(value)
    684 	return in(splitVals, values)
    685 }
    686 
    687 func BorderImageSliceHandler(value string) bool {
    688 	values := []string{"fill", "initial", "inherit"}
    689 	if in([]string{value}, values) {
    690 		return true
    691 	}
    692 	splitVals := strings.Split(value, " ")
    693 	if len(splitVals) > 4 {
    694 		return false
    695 	}
    696 	usedFunctions := []func(string) bool{
    697 		LengthHandler,
    698 	}
    699 	return recursiveCheck(splitVals, usedFunctions)
    700 }
    701 
    702 func BorderImageWidthHandler(value string) bool {
    703 	if LengthHandler(value) {
    704 		return true
    705 	}
    706 	values := []string{"auto", "initial", "inherit"}
    707 	splitVals := splitValues(value)
    708 	return in(splitVals, values)
    709 }
    710 
    711 func BorderRadiusHandler(value string) bool {
    712 	values := []string{"initial", "inherit"}
    713 	if in([]string{value}, values) {
    714 		return true
    715 	}
    716 	splitVals := strings.Split(value, " ")
    717 	if len(splitVals) > 4 {
    718 		return false
    719 	}
    720 	usedFunctions := []func(string) bool{
    721 		LengthHandler,
    722 	}
    723 	return recursiveCheck(splitVals, usedFunctions)
    724 }
    725 
    726 func BorderSpacingHandler(value string) bool {
    727 	values := []string{"initial", "inherit"}
    728 	if in([]string{value}, values) {
    729 		return true
    730 	}
    731 	splitVals := strings.Split(value, " ")
    732 	if len(splitVals) > 2 {
    733 		return false
    734 	}
    735 	usedFunctions := []func(string) bool{
    736 		LengthHandler,
    737 	}
    738 	return recursiveCheck(splitVals, usedFunctions)
    739 }
    740 
    741 func BorderStyleHandler(value string) bool {
    742 	values := []string{"initial", "inherit"}
    743 	if in([]string{value}, values) {
    744 		return true
    745 	}
    746 	splitVals := strings.Split(value, " ")
    747 	if len(splitVals) > 4 {
    748 		return false
    749 	}
    750 	usedFunctions := []func(string) bool{
    751 		BorderSideStyleHandler,
    752 	}
    753 	return recursiveCheck(splitVals, usedFunctions)
    754 }
    755 
    756 func BorderWidthHandler(value string) bool {
    757 	values := []string{"initial", "inherit"}
    758 	if in([]string{value}, values) {
    759 		return true
    760 	}
    761 	splitVals := strings.Split(value, " ")
    762 	if len(splitVals) > 4 {
    763 		return false
    764 	}
    765 	usedFunctions := []func(string) bool{
    766 		BorderSideWidthHandler,
    767 	}
    768 	return recursiveCheck(splitVals, usedFunctions)
    769 }
    770 
    771 func SideHandler(value string) bool {
    772 	if LengthHandler(value) {
    773 		return true
    774 	}
    775 	values := []string{"auto", "inherit", "unset"}
    776 	splitVals := splitValues(value)
    777 	return in(splitVals, values)
    778 }
    779 
    780 func BoxDecorationBreakHandler(value string) bool {
    781 	values := []string{"slice", "clone", "initial", "initial", "inherit", "unset"}
    782 	splitVals := splitValues(value)
    783 	return in(splitVals, values)
    784 }
    785 
    786 func BoxShadowHandler(value string) bool {
    787 	values := []string{"none", "initial", "inherit"}
    788 	if in([]string{value}, values) {
    789 		return true
    790 	}
    791 	commaSplitVals := strings.Split(value, ",")
    792 	for _, val := range commaSplitVals {
    793 		splitVals := strings.Split(val, " ")
    794 		if len(splitVals) > 6 || len(splitVals) < 2 {
    795 			return false
    796 		}
    797 		if !LengthHandler(splitVals[0]) {
    798 			return false
    799 		}
    800 		if !LengthHandler(splitVals[1]) {
    801 			return false
    802 		}
    803 		usedFunctions := []func(string) bool{
    804 			LengthHandler,
    805 			ColorHandler,
    806 		}
    807 		if len(splitVals) > 2 && !recursiveCheck(splitVals[2:], usedFunctions) {
    808 			return false
    809 		}
    810 	}
    811 	return true
    812 }
    813 
    814 func BoxSizingHandler(value string) bool {
    815 	values := []string{"slicontent-box", "border-box", "initial", "inherit"}
    816 	splitVals := splitValues(value)
    817 	return in(splitVals, values)
    818 }
    819 
    820 func BreakBeforeAfterHandler(value string) bool {
    821 	values := []string{"auto", "avoid", "always", "all", "avoid-page", "page", "left", "right", "recto", "verso", "avoid-column", "column", "avoid-region", "region"}
    822 	splitVals := splitValues(value)
    823 	return in(splitVals, values)
    824 }
    825 
    826 func BreakInsideHandler(value string) bool {
    827 	values := []string{"auto", "avoid", "avoid-page", "avoid-column", "avoid-region"}
    828 	splitVals := splitValues(value)
    829 	return in(splitVals, values)
    830 }
    831 
    832 func CaptionSideHandler(value string) bool {
    833 	values := []string{"top", "bottom", "initial", "inherit"}
    834 	splitVals := splitValues(value)
    835 	return in(splitVals, values)
    836 }
    837 
    838 func CaretColorHandler(value string) bool {
    839 	splitVals := splitValues(value)
    840 	if in(splitVals, colorValues) {
    841 		return true
    842 	}
    843 	if HexRGB.MatchString(value) {
    844 		return true
    845 	}
    846 	if RGB.MatchString(value) {
    847 		return true
    848 	}
    849 	if RGBA.MatchString(value) {
    850 		return true
    851 	}
    852 	if HSL.MatchString(value) {
    853 		return true
    854 	}
    855 	return HSLA.MatchString(value)
    856 }
    857 
    858 func ClearHandler(value string) bool {
    859 	values := []string{"none", "left", "right", "both", "initial", "inherit"}
    860 	splitVals := splitValues(value)
    861 	return in(splitVals, values)
    862 }
    863 
    864 func ClipHandler(value string) bool {
    865 	if Rect.MatchString(value) {
    866 		return true
    867 	}
    868 	values := []string{"auto", "initial", "inherit"}
    869 	splitVals := splitValues(value)
    870 	return in(splitVals, values)
    871 }
    872 
    873 func ColorHandler(value string) bool {
    874 	splitVals := splitValues(value)
    875 	if in(splitVals, colorValues) {
    876 		return true
    877 	}
    878 	if HexRGB.MatchString(value) {
    879 		return true
    880 	}
    881 	if RGB.MatchString(value) {
    882 		return true
    883 	}
    884 	if RGBA.MatchString(value) {
    885 		return true
    886 	}
    887 	if HSL.MatchString(value) {
    888 		return true
    889 	}
    890 	return HSLA.MatchString(value)
    891 }
    892 
    893 func ColumnCountHandler(value string) bool {
    894 	if Numeric.MatchString(value) {
    895 		return true
    896 	}
    897 	values := []string{"auto", "initial", "inherit"}
    898 	splitVals := splitValues(value)
    899 	return in(splitVals, values)
    900 }
    901 
    902 func ColumnFillHandler(value string) bool {
    903 	values := []string{"balance", "auto", "initial", "inherit"}
    904 	splitVals := splitValues(value)
    905 	return in(splitVals, values)
    906 }
    907 
    908 func ColumnGapHandler(value string) bool {
    909 	if LengthHandler(value) {
    910 		return true
    911 	}
    912 	values := []string{"normal", "initial", "inherit"}
    913 	splitVals := splitValues(value)
    914 	return in(splitVals, values)
    915 }
    916 
    917 func ColumnRuleHandler(value string) bool {
    918 	values := []string{"initial", "inherit"}
    919 	if in([]string{value}, values) {
    920 		return true
    921 	}
    922 	splitVals := strings.Split(value, " ")
    923 	usedFunctions := []func(string) bool{
    924 		ColumnRuleWidthHandler,
    925 		BorderSideStyleHandler,
    926 		ColorHandler,
    927 	}
    928 	return recursiveCheck(splitVals, usedFunctions)
    929 }
    930 
    931 func ColumnRuleWidthHandler(value string) bool {
    932 	if LengthHandler(value) {
    933 		return true
    934 	}
    935 	splitVals := strings.Split(value, ";")
    936 	values := []string{"medium", "thin", "thick", "initial", "inherit"}
    937 	return in(splitVals, values)
    938 }
    939 
    940 func ColumnSpanHandler(value string) bool {
    941 	values := []string{"none", "all", "initial", "inherit"}
    942 	splitVals := splitValues(value)
    943 	return in(splitVals, values)
    944 }
    945 
    946 func ColumnWidthHandler(value string) bool {
    947 	if LengthHandler(value) {
    948 		return true
    949 	}
    950 	splitVals := strings.Split(value, ";")
    951 	values := []string{"auto", "initial", "inherit"}
    952 	return in(splitVals, values)
    953 }
    954 
    955 func ColumnsHandler(value string) bool {
    956 	values := []string{"auto", "initial", "inherit"}
    957 	if in([]string{value}, values) {
    958 		return true
    959 	}
    960 	splitVals := strings.Split(value, " ")
    961 	usedFunctions := []func(string) bool{
    962 		ColumnWidthHandler,
    963 		ColumnCountHandler,
    964 	}
    965 	return recursiveCheck(splitVals, usedFunctions)
    966 }
    967 
    968 func CursorHandler(value string) bool {
    969 	values := []string{"alias", "all-scroll", "auto", "cell", "context-menu", "col-resize", "copy", "crosshair", "default", "e-resize", "ew-resize", "grab", "grabbing", "help", "move", "n-resize", "ne-resize", "nesw-resize", "ns-resize", "nw-resize", "nwse-resize", "no-drop", "none", "not-allowed", "pointer", "progress", "row-resize", "s-resize", "se-resize", "sw-resize", "text", "vertical-text", "w-resize", "wait", "zoom-in", "zoom-out", "initial", "inherit"}
    970 	splitVals := splitValues(value)
    971 	return in(splitVals, values)
    972 }
    973 
    974 func DirectionHandler(value string) bool {
    975 	values := []string{"ltr", "rtl", "initial", "inherit"}
    976 	splitVals := splitValues(value)
    977 	return in(splitVals, values)
    978 }
    979 
    980 func DisplayHandler(value string) bool {
    981 	values := []string{"inline", "block", "contents", "flex", "grid", "inline-block", "inline-flex", "inline-grid", "inline-table", "list-item", "run-in", "table", "table-caption", "table-column-group", "table-header-group", "table-footer-group", "table-row-group", "table-cell", "table-column", "table-row", "none", "initial", "inherit"}
    982 	splitVals := splitValues(value)
    983 	return in(splitVals, values)
    984 }
    985 
    986 func EmptyCellsHandler(value string) bool {
    987 	values := []string{"show", "hide", "initial", "inherit"}
    988 	splitVals := splitValues(value)
    989 	return in(splitVals, values)
    990 }
    991 
    992 func FilterHandler(value string) bool {
    993 	values := []string{"none", "initial", "inherit"}
    994 	splitVals := splitValues(value)
    995 	if in(splitVals, values) {
    996 		return true
    997 	}
    998 	if Blur.MatchString(value) {
    999 		return true
   1000 	}
   1001 	if BrightnessCont.MatchString(value) {
   1002 		return true
   1003 	}
   1004 	if DropShadow.MatchString(value) {
   1005 		return true
   1006 	}
   1007 	colorValue := strings.TrimSuffix(string(DropShadow.ReplaceAll([]byte(value), []byte{})), ")")
   1008 	if ColorHandler(colorValue) {
   1009 		return true
   1010 	}
   1011 	if Grayscale.MatchString(value) {
   1012 		return true
   1013 	}
   1014 	if HueRotate.MatchString(value) {
   1015 		return true
   1016 	}
   1017 	if Invert.MatchString(value) {
   1018 		return true
   1019 	}
   1020 	if Opacity.MatchString(value) {
   1021 		return true
   1022 	}
   1023 	if Saturate.MatchString(value) {
   1024 		return true
   1025 	}
   1026 	return Sepia.MatchString(value)
   1027 }
   1028 
   1029 func FlexHandler(value string) bool {
   1030 	values := []string{"auto", "initial", "initial", "inherit"}
   1031 	if in([]string{value}, values) {
   1032 		return true
   1033 	}
   1034 	splitVals := strings.Split(value, " ")
   1035 	usedFunctions := []func(string) bool{
   1036 		FlexGrowHandler,
   1037 		FlexBasisHandler,
   1038 	}
   1039 	return recursiveCheck(splitVals, usedFunctions)
   1040 }
   1041 
   1042 func FlexBasisHandler(value string) bool {
   1043 	if LengthHandler(value) {
   1044 		return true
   1045 	}
   1046 	splitVals := strings.Split(value, ";")
   1047 	values := []string{"auto", "initial", "inherit"}
   1048 	return in(splitVals, values)
   1049 }
   1050 
   1051 func FlexDirectionHandler(value string) bool {
   1052 	values := []string{"row", "row-reverse", "column", "column-reverse", "initial", "inherit"}
   1053 	splitVals := splitValues(value)
   1054 	return in(splitVals, values)
   1055 }
   1056 
   1057 func FlexFlowHandler(value string) bool {
   1058 	values := []string{"initial", "inherit"}
   1059 	if in([]string{value}, values) {
   1060 		return true
   1061 	}
   1062 	splitVals := strings.Split(value, " ")
   1063 	usedFunctions := []func(string) bool{
   1064 		FlexDirectionHandler,
   1065 		FlexWrapHandler,
   1066 	}
   1067 	return recursiveCheck(splitVals, usedFunctions)
   1068 }
   1069 
   1070 func FlexGrowHandler(value string) bool {
   1071 	if NumericDecimal.MatchString(value) {
   1072 		return true
   1073 	}
   1074 	splitVals := strings.Split(value, ";")
   1075 	values := []string{"initial", "inherit"}
   1076 	return in(splitVals, values)
   1077 }
   1078 
   1079 func FlexWrapHandler(value string) bool {
   1080 	values := []string{"nowrap", "wrap", "wrap-reverse", "initial", "inherit"}
   1081 	splitVals := splitValues(value)
   1082 	return in(splitVals, values)
   1083 }
   1084 
   1085 func FloatHandler(value string) bool {
   1086 	values := []string{"none", "left", "right", "initial", "inherit"}
   1087 	splitVals := splitValues(value)
   1088 	return in(splitVals, values)
   1089 }
   1090 
   1091 func FontHandler(value string) bool {
   1092 	values := []string{"caption", "icon", "menu", "message-box", "small-caption", "status-bar", "initial", "inherit"}
   1093 	if in([]string{value}, values) {
   1094 		return true
   1095 	}
   1096 	splitVals := strings.Split(value, " ")
   1097 	newSplitVals := []string{}
   1098 	for _, i := range splitVals {
   1099 		if len(strings.Split(i, "/")) == 2 {
   1100 			newSplitVals = append(newSplitVals, strings.Split(i, "/")...)
   1101 		} else {
   1102 			newSplitVals = append(newSplitVals, i)
   1103 		}
   1104 	}
   1105 	usedFunctions := []func(string) bool{
   1106 		FontStyleHandler,
   1107 		FontVariantHandler,
   1108 		FontWeightHandler,
   1109 		FontSizeHandler,
   1110 		FontFamilyHandler,
   1111 	}
   1112 	return recursiveCheck(newSplitVals, usedFunctions)
   1113 }
   1114 
   1115 func FontFamilyHandler(value string) bool {
   1116 	values := []string{"initial", "inherit"}
   1117 	splitVals := splitValues(value)
   1118 	if in(splitVals, values) {
   1119 		return true
   1120 	}
   1121 	for _, i := range splitVals {
   1122 		i = strings.TrimSpace(i)
   1123 		if Font.FindString(i) != i {
   1124 			return false
   1125 		}
   1126 	}
   1127 	return true
   1128 }
   1129 
   1130 func FontKerningHandler(value string) bool {
   1131 	values := []string{"auto", "normal", "none"}
   1132 	splitVals := splitValues(value)
   1133 	return in(splitVals, values)
   1134 }
   1135 
   1136 func FontLanguageOverrideHandler(value string) bool {
   1137 	return Alpha.MatchString(value)
   1138 }
   1139 
   1140 func FontSizeHandler(value string) bool {
   1141 	if LengthHandler(value) {
   1142 		return true
   1143 	}
   1144 	values := []string{"medium", "xx-small", "x-small", "small", "large", "x-large", "xx-large", "smaller", "larger", "initial", "inherit"}
   1145 	splitVals := splitValues(value)
   1146 	return in(splitVals, values)
   1147 }
   1148 
   1149 func FontSizeAdjustHandler(value string) bool {
   1150 	if Count.MatchString(value) {
   1151 		return true
   1152 	}
   1153 	values := []string{"auto", "initial", "inherit"}
   1154 	splitVals := splitValues(value)
   1155 	return in(splitVals, values)
   1156 }
   1157 
   1158 func FontStretchHandler(value string) bool {
   1159 	values := []string{"ultra-condensed", "extra-condensed", "condensed", "semi-condensed", "normal", "semi-expanded", "expanded", "extra-expanded", "ultra-expanded", "initial", "inherit"}
   1160 	splitVals := splitValues(value)
   1161 	return in(splitVals, values)
   1162 }
   1163 
   1164 func FontStyleHandler(value string) bool {
   1165 	values := []string{"normal", "italic", "oblique", "initial", "inherit"}
   1166 	splitVals := splitValues(value)
   1167 	return in(splitVals, values)
   1168 }
   1169 
   1170 func FontSynthesisHandler(value string) bool {
   1171 	values := []string{"none", "style", "weight"}
   1172 	splitVals := splitValues(value)
   1173 	return in(splitVals, values)
   1174 }
   1175 
   1176 func FontVariantCapsHandler(value string) bool {
   1177 	values := []string{"normal", "small-caps", "all-small-caps", "petite-caps", "all-petite-caps", "unicase", "titling-caps"}
   1178 	splitVals := splitValues(value)
   1179 	return in(splitVals, values)
   1180 }
   1181 
   1182 func FontVariantHandler(value string) bool {
   1183 	values := []string{"normal", "small-caps", "initial", "inherit"}
   1184 	splitVals := splitValues(value)
   1185 	return in(splitVals, values)
   1186 }
   1187 
   1188 func FontVariantPositionHandler(value string) bool {
   1189 	values := []string{"normal", "sub", "super"}
   1190 	splitVals := splitValues(value)
   1191 	return in(splitVals, values)
   1192 }
   1193 
   1194 func FontWeightHandler(value string) bool {
   1195 	values := []string{"normal", "bold", "bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900", "initial", "inherit"}
   1196 	splitVals := splitValues(value)
   1197 	return in(splitVals, values)
   1198 }
   1199 
   1200 func GridHandler(value string) bool {
   1201 	values := []string{"none", "initial", "inherit"}
   1202 	if in([]string{value}, values) {
   1203 		return true
   1204 	}
   1205 	splitVals := strings.Split(value, " ")
   1206 	newSplitVals := []string{}
   1207 	for _, i := range splitVals {
   1208 		if i != "/" {
   1209 			newSplitVals = append(newSplitVals, i)
   1210 		}
   1211 	}
   1212 	usedFunctions := []func(string) bool{
   1213 		GridTemplateRowsHandler,
   1214 		GridTemplateColumnsHandler,
   1215 		GridTemplateAreasHandler,
   1216 		GridAutoColumnsHandler,
   1217 		GridAutoFlowHandler,
   1218 	}
   1219 	return recursiveCheck(newSplitVals, usedFunctions)
   1220 }
   1221 
   1222 func GridAreaHandler(value string) bool {
   1223 	values := []string{"none", "initial", "inherit"}
   1224 	if in([]string{value}, values) {
   1225 		return true
   1226 	}
   1227 	splitVals := strings.Split(value, " / ")
   1228 	usedFunctions := []func(string) bool{
   1229 		GridAxisStartEndHandler,
   1230 	}
   1231 	return recursiveCheck(splitVals, usedFunctions)
   1232 }
   1233 
   1234 func GridAutoColumnsHandler(value string) bool {
   1235 	if LengthHandler(value) {
   1236 		return true
   1237 	}
   1238 	values := []string{"auto", "max-content", "min-content", "initial", "inherit"}
   1239 	splitVals := splitValues(value)
   1240 	return in(splitVals, values)
   1241 }
   1242 
   1243 func GridAutoFlowHandler(value string) bool {
   1244 	values := []string{"row", "column", "dense", "row dense", "column dense"}
   1245 	splitVals := splitValues(value)
   1246 	return in(splitVals, values)
   1247 }
   1248 
   1249 func GridColumnHandler(value string) bool {
   1250 	values := []string{"none", "initial", "inherit"}
   1251 	if in([]string{value}, values) {
   1252 		return true
   1253 	}
   1254 	splitVals := strings.Split(value, " / ")
   1255 	if len(splitVals) > 2 {
   1256 		return false
   1257 	}
   1258 	usedFunctions := []func(string) bool{
   1259 		GridAxisStartEndHandler,
   1260 	}
   1261 	return recursiveCheck(splitVals, usedFunctions)
   1262 }
   1263 
   1264 func GridColumnGapHandler(value string) bool {
   1265 	return LengthHandler(value)
   1266 }
   1267 
   1268 func LengthHandler(value string) bool {
   1269 	return Length.MatchString(value)
   1270 }
   1271 
   1272 func LineBreakHandler(value string) bool {
   1273 	values := []string{"auto", "loose", "normal", "strict"}
   1274 	splitVals := splitValues(value)
   1275 	return in(splitVals, values)
   1276 }
   1277 
   1278 func GridAxisStartEndHandler(value string) bool {
   1279 	if Numeric.MatchString(value) {
   1280 		return true
   1281 	}
   1282 	if Span.MatchString(value) {
   1283 		return true
   1284 	}
   1285 	values := []string{"auto"}
   1286 	splitVals := splitValues(value)
   1287 	return in(splitVals, values)
   1288 }
   1289 
   1290 func GridGapHandler(value string) bool {
   1291 	splitVals := strings.Split(value, " ")
   1292 	if len(splitVals) > 2 {
   1293 		return false
   1294 	}
   1295 	usedFunctions := []func(string) bool{
   1296 		GridColumnGapHandler,
   1297 	}
   1298 	return recursiveCheck(splitVals, usedFunctions)
   1299 }
   1300 
   1301 func GridRowHandler(value string) bool {
   1302 	splitVals := strings.Split(value, " / ")
   1303 	if len(splitVals) > 2 {
   1304 		return false
   1305 	}
   1306 	usedFunctions := []func(string) bool{
   1307 		GridAxisStartEndHandler,
   1308 	}
   1309 	return recursiveCheck(splitVals, usedFunctions)
   1310 }
   1311 
   1312 func GridTemplateHandler(value string) bool {
   1313 	values := []string{"none", "initial", "inherit"}
   1314 	if in([]string{value}, values) {
   1315 		return true
   1316 	}
   1317 	splitVals := strings.Split(value, " / ")
   1318 	if len(splitVals) > 2 {
   1319 		return false
   1320 	}
   1321 	usedFunctions := []func(string) bool{
   1322 		GridTemplateColumnsHandler,
   1323 		GridTemplateRowsHandler,
   1324 	}
   1325 	return recursiveCheck(splitVals, usedFunctions)
   1326 }
   1327 
   1328 func GridTemplateAreasHandler(value string) bool {
   1329 	values := []string{"none"}
   1330 	if in([]string{value}, values) {
   1331 		return true
   1332 	}
   1333 	return GridTemplateAreas.MatchString(value)
   1334 }
   1335 
   1336 func GridTemplateColumnsHandler(value string) bool {
   1337 	splitVals := strings.Split(value, " ")
   1338 	values := []string{"none", "auto", "max-content", "min-content", "initial", "inherit"}
   1339 	for _, val := range splitVals {
   1340 		if LengthHandler(val) {
   1341 			continue
   1342 		}
   1343 		valArr := []string{val}
   1344 		if !in(valArr, values) {
   1345 			return false
   1346 		}
   1347 	}
   1348 	return true
   1349 }
   1350 
   1351 func GridTemplateRowsHandler(value string) bool {
   1352 	splitVals := strings.Split(value, " ")
   1353 	values := []string{"none", "auto", "max-content", "min-content"}
   1354 	for _, val := range splitVals {
   1355 		if LengthHandler(val) {
   1356 			continue
   1357 		}
   1358 		valArr := []string{val}
   1359 		if !in(valArr, values) {
   1360 			return false
   1361 		}
   1362 	}
   1363 	return true
   1364 }
   1365 
   1366 func HangingPunctuationHandler(value string) bool {
   1367 	values := []string{"none", "first", "last", "allow-end", "force-end", "initial", "inherit"}
   1368 	splitVals := splitValues(value)
   1369 	return in(splitVals, values)
   1370 }
   1371 
   1372 func HeightHandler(value string) bool {
   1373 	if LengthHandler(value) {
   1374 		return true
   1375 	}
   1376 	values := []string{"auto", "initial", "inherit"}
   1377 	splitVals := splitValues(value)
   1378 	return in(splitVals, values)
   1379 }
   1380 
   1381 func HyphensHandler(value string) bool {
   1382 	values := []string{"none", "manual", "auto", "initial", "inherit"}
   1383 	splitVals := splitValues(value)
   1384 	return in(splitVals, values)
   1385 }
   1386 
   1387 func ImageRenderingHandler(value string) bool {
   1388 	values := []string{"auto", "smooth", "high-quality", "crisp-edges", "pixelated"}
   1389 	splitVals := splitValues(value)
   1390 	return in(splitVals, values)
   1391 }
   1392 
   1393 func IsolationHandler(value string) bool {
   1394 	values := []string{"auto", "isolate", "initial", "inherit"}
   1395 	splitVals := splitValues(value)
   1396 	return in(splitVals, values)
   1397 }
   1398 
   1399 func JustifyContentHandler(value string) bool {
   1400 	values := []string{"flex-start", "flex-end", "center", "space-between", "space-around", "initial", "inherit"}
   1401 	splitVals := splitValues(value)
   1402 	return in(splitVals, values)
   1403 }
   1404 
   1405 func LetterSpacingHandler(value string) bool {
   1406 	if LengthHandler(value) {
   1407 		return true
   1408 	}
   1409 	values := []string{"normal", "initial", "inherit"}
   1410 	splitVals := splitValues(value)
   1411 	return in(splitVals, values)
   1412 }
   1413 
   1414 func LineHeightHandler(value string) bool {
   1415 	if LengthHandler(value) {
   1416 		return true
   1417 	}
   1418 	values := []string{"normal", "initial", "inherit"}
   1419 	splitVals := splitValues(value)
   1420 	return in(splitVals, values)
   1421 }
   1422 
   1423 func ListStyleHandler(value string) bool {
   1424 	values := []string{"initial", "inherit"}
   1425 	if in([]string{value}, values) {
   1426 		return true
   1427 	}
   1428 	splitVals := strings.Split(value, " ")
   1429 	usedFunctions := []func(string) bool{
   1430 		ListStyleTypeHandler,
   1431 		ListStylePositionHandler,
   1432 		ImageHandler,
   1433 	}
   1434 	return recursiveCheck(splitVals, usedFunctions)
   1435 }
   1436 
   1437 func ListStylePositionHandler(value string) bool {
   1438 	values := []string{"inside", "outside", "initial", "inherit"}
   1439 	splitVals := splitValues(value)
   1440 	return in(splitVals, values)
   1441 }
   1442 
   1443 func ListStyleTypeHandler(value string) bool {
   1444 	values := []string{"disc", "armenian", "circle", "cjk-ideographic", "decimal", "decimal-leading-zero", "georgian", "hebrew", "hiragana", "hiragana-iroha", "katakana", "katakana-iroha", "lower-alpha", "lower-greek", "lower-latin", "lower-roman", "none", "square", "upper-alpha", "upper-greek", "upper-latin", "upper-roman", "initial", "inherit"}
   1445 	splitVals := splitValues(value)
   1446 	return in(splitVals, values)
   1447 }
   1448 
   1449 func MarginHandler(value string) bool {
   1450 	values := []string{"auto", "initial", "inherit"}
   1451 	if in([]string{value}, values) {
   1452 		return true
   1453 	}
   1454 	splitVals := strings.Split(value, " ")
   1455 	usedFunctions := []func(string) bool{
   1456 		MarginSideHandler,
   1457 	}
   1458 	return recursiveCheck(splitVals, usedFunctions)
   1459 }
   1460 
   1461 func MarginSideHandler(value string) bool {
   1462 	if LengthHandler(value) {
   1463 		return true
   1464 	}
   1465 	values := []string{"auto", "initial", "inherit"}
   1466 	splitVals := splitValues(value)
   1467 	return in(splitVals, values)
   1468 }
   1469 
   1470 func MaxHeightWidthHandler(value string) bool {
   1471 	if LengthHandler(value) {
   1472 		return true
   1473 	}
   1474 	values := []string{"none", "initial", "inherit"}
   1475 	splitVals := splitValues(value)
   1476 	return in(splitVals, values)
   1477 }
   1478 
   1479 func MinHeightWidthHandler(value string) bool {
   1480 	if LengthHandler(value) {
   1481 		return true
   1482 	}
   1483 	values := []string{"initial", "inherit"}
   1484 	splitVals := splitValues(value)
   1485 	return in(splitVals, values)
   1486 }
   1487 
   1488 func MixBlendModeHandler(value string) bool {
   1489 	values := []string{"normal", "multiply", "screen", "overlay", "darken", "lighten", "color-dodge", "color-burn", "difference", "exclusion", "hue", "saturation", "color", "luminosity"}
   1490 	splitVals := splitValues(value)
   1491 	return in(splitVals, values)
   1492 }
   1493 
   1494 func ObjectFitHandler(value string) bool {
   1495 	values := []string{"fill", "contain", "cover", "none", "scale-down", "initial", "inherit"}
   1496 	splitVals := splitValues(value)
   1497 	return in(splitVals, values)
   1498 }
   1499 
   1500 func ObjectPositionHandler(value string) bool {
   1501 	values := []string{"initial", "inherit"}
   1502 	if in([]string{value}, values) {
   1503 		return true
   1504 	}
   1505 	splitVals := strings.Split(value, " ")
   1506 	if len(splitVals) > 2 {
   1507 		return false
   1508 	}
   1509 	usedFunctions := []func(string) bool{
   1510 		LengthHandler,
   1511 	}
   1512 	return recursiveCheck(splitVals, usedFunctions)
   1513 }
   1514 
   1515 func OpacityHandler(value string) bool {
   1516 	if Opacity.MatchString(value) {
   1517 		return true
   1518 	}
   1519 	values := []string{"initial", "inherit"}
   1520 	splitVals := splitValues(value)
   1521 	return in(splitVals, values)
   1522 }
   1523 
   1524 func OrderHandler(value string) bool {
   1525 	if Numeric.MatchString(value) {
   1526 		return true
   1527 	}
   1528 	values := []string{"initial", "inherit"}
   1529 	splitVals := splitValues(value)
   1530 	return in(splitVals, values)
   1531 }
   1532 
   1533 func OutlineHandler(value string) bool {
   1534 	values := []string{"initial", "inherit"}
   1535 	if in([]string{value}, values) {
   1536 		return true
   1537 	}
   1538 	splitVals := strings.Split(value, " ")
   1539 	usedFunctions := []func(string) bool{
   1540 		ColorHandler,
   1541 		OutlineWidthHandler,
   1542 		OutlineStyleHandler,
   1543 	}
   1544 	return recursiveCheck(splitVals, usedFunctions)
   1545 }
   1546 
   1547 func OutlineOffsetHandler(value string) bool {
   1548 	if LengthHandler(value) {
   1549 		return true
   1550 	}
   1551 	values := []string{"initial", "inherit"}
   1552 	splitVals := splitValues(value)
   1553 	return in(splitVals, values)
   1554 }
   1555 
   1556 func OutlineStyleHandler(value string) bool {
   1557 	values := []string{"none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset", "initial", "inherit"}
   1558 	splitVals := splitValues(value)
   1559 	return in(splitVals, values)
   1560 }
   1561 
   1562 func OutlineWidthHandler(value string) bool {
   1563 	if LengthHandler(value) {
   1564 		return true
   1565 	}
   1566 	values := []string{"medium", "thin", "thick", "initial", "inherit"}
   1567 	splitVals := splitValues(value)
   1568 	return in(splitVals, values)
   1569 }
   1570 
   1571 func OverflowHandler(value string) bool {
   1572 	values := []string{"visible", "hidden", "scroll", "auto", "initial", "inherit"}
   1573 	splitVals := splitValues(value)
   1574 	return in(splitVals, values)
   1575 }
   1576 
   1577 func OverflowXYHandler(value string) bool {
   1578 	values := []string{"visible", "hidden", "scroll", "auto", "initial", "inherit"}
   1579 	splitVals := splitValues(value)
   1580 	return in(splitVals, values)
   1581 }
   1582 
   1583 func OverflowWrapHandler(value string) bool {
   1584 	values := []string{"normal", "break-word", "anywhere"}
   1585 	splitVals := splitValues(value)
   1586 	return in(splitVals, values)
   1587 }
   1588 
   1589 func OrphansHandler(value string) bool {
   1590 	return Numeric.MatchString(value)
   1591 }
   1592 
   1593 func PaddingHandler(value string) bool {
   1594 	values := []string{"initial", "inherit"}
   1595 	if in([]string{value}, values) {
   1596 		return true
   1597 	}
   1598 	splitVals := strings.Split(value, " ")
   1599 	if len(splitVals) > 4 {
   1600 		return false
   1601 	}
   1602 	usedFunctions := []func(string) bool{
   1603 		PaddingSideHandler,
   1604 	}
   1605 	return recursiveCheck(splitVals, usedFunctions)
   1606 }
   1607 
   1608 func PaddingSideHandler(value string) bool {
   1609 	if LengthHandler(value) {
   1610 		return true
   1611 	}
   1612 	values := []string{"initial", "inherit"}
   1613 	splitVals := splitValues(value)
   1614 	return in(splitVals, values)
   1615 }
   1616 
   1617 func PageBreakBeforeAfterHandler(value string) bool {
   1618 	values := []string{"auto", "always", "avoid", "left", "right", "initial", "inherit"}
   1619 	splitVals := splitValues(value)
   1620 	return in(splitVals, values)
   1621 }
   1622 
   1623 func PageBreakInsideHandler(value string) bool {
   1624 	values := []string{"auto", "avoid", "initial", "inherit"}
   1625 	splitVals := splitValues(value)
   1626 	return in(splitVals, values)
   1627 }
   1628 
   1629 func PerspectiveHandler(value string) bool {
   1630 	if LengthHandler(value) {
   1631 		return true
   1632 	}
   1633 	values := []string{"none", "initial", "inherit"}
   1634 	splitVals := splitValues(value)
   1635 	return in(splitVals, values)
   1636 }
   1637 
   1638 func PerspectiveOriginHandler(value string) bool {
   1639 	values := []string{"initial", "inherit"}
   1640 	if in([]string{value}, values) {
   1641 		return true
   1642 	}
   1643 	splitVals := strings.Split(value, " ")
   1644 	xValues := []string{"left", "center", "right"}
   1645 	yValues := []string{"top", "center", "bottom"}
   1646 	if len(splitVals) > 1 {
   1647 		if !in([]string{splitVals[0]}, xValues) && !LengthHandler(splitVals[0]) {
   1648 			return false
   1649 		}
   1650 		return in([]string{splitVals[1]}, yValues) || LengthHandler(splitVals[1])
   1651 	} else if len(splitVals) == 1 {
   1652 		return in(splitVals, xValues) || in(splitVals, yValues) || LengthHandler(splitVals[0])
   1653 	}
   1654 	return false
   1655 }
   1656 
   1657 func PointerEventsHandler(value string) bool {
   1658 	values := []string{"auto", "none", "initial", "inherit"}
   1659 	splitVals := splitValues(value)
   1660 	return in(splitVals, values)
   1661 }
   1662 
   1663 func PositionHandler(value string) bool {
   1664 	values := []string{"static", "absolute", "fixed", "relative", "sticky", "initial", "inherit"}
   1665 	splitVals := splitValues(value)
   1666 	return in(splitVals, values)
   1667 }
   1668 
   1669 func QuotesHandler(value string) bool {
   1670 	values := []string{"none", "initial", "inherit"}
   1671 	splitVals := splitValues(value)
   1672 	if in(splitVals, values) {
   1673 		return true
   1674 	}
   1675 	return Quotes.MatchString(value)
   1676 }
   1677 
   1678 func ResizeHandler(value string) bool {
   1679 	values := []string{"none", "both", "horizontal", "vertical", "initial", "inherit"}
   1680 	splitVals := splitValues(value)
   1681 	return in(splitVals, values)
   1682 }
   1683 
   1684 func ScrollBehaviorHandler(value string) bool {
   1685 	values := []string{"auto", "smooth", "initial", "inherit"}
   1686 	splitVals := splitValues(value)
   1687 	return in(splitVals, values)
   1688 }
   1689 
   1690 func TabSizeHandler(value string) bool {
   1691 	if LengthHandler(value) {
   1692 		return true
   1693 	}
   1694 	values := []string{"initial", "inherit"}
   1695 	splitVals := splitValues(value)
   1696 	return in(splitVals, values)
   1697 }
   1698 
   1699 func TableLayoutHandler(value string) bool {
   1700 	values := []string{"auto", "fixed", "initial", "inherit"}
   1701 	splitVals := splitValues(value)
   1702 	return in(splitVals, values)
   1703 }
   1704 
   1705 func TextAlignHandler(value string) bool {
   1706 	values := []string{"left", "right", "center", "justify", "initial", "inherit"}
   1707 	splitVals := splitValues(value)
   1708 	return in(splitVals, values)
   1709 }
   1710 
   1711 func TextAlignLastHandler(value string) bool {
   1712 	values := []string{"auto", "left", "right", "center", "justify", "start", "end", "initial", "inherit"}
   1713 	splitVals := splitValues(value)
   1714 	return in(splitVals, values)
   1715 }
   1716 
   1717 func TextCombineUprightHandler(value string) bool {
   1718 	values := []string{"none", "all"}
   1719 	splitVals := splitValues(value)
   1720 	if in(splitVals, values) {
   1721 		return true
   1722 	}
   1723 	return Digits.MatchString(value)
   1724 }
   1725 
   1726 func TextDecorationHandler(value string) bool {
   1727 	values := []string{"initial", "inherit"}
   1728 	if in([]string{value}, values) {
   1729 		return true
   1730 	}
   1731 	splitVals := strings.Split(value, " ")
   1732 	usedFunctions := []func(string) bool{
   1733 		TextDecorationStyleHandler,
   1734 		ColorHandler,
   1735 		TextDecorationLineHandler,
   1736 	}
   1737 	return recursiveCheck(splitVals, usedFunctions)
   1738 }
   1739 
   1740 func TextDecorationLineHandler(value string) bool {
   1741 	values := []string{"none", "underline", "overline", "line-through", "initial", "inherit"}
   1742 	splitVals := strings.Split(value, " ")
   1743 	return in(splitVals, values)
   1744 }
   1745 
   1746 func TextDecorationStyleHandler(value string) bool {
   1747 	values := []string{"solid", "double", "dotted", "dashed", "wavy", "initial", "inherit"}
   1748 	splitVals := splitValues(value)
   1749 	return in(splitVals, values)
   1750 }
   1751 
   1752 func TextIndentHandler(value string) bool {
   1753 	if LengthHandler(value) {
   1754 		return true
   1755 	}
   1756 	values := []string{"initial", "inherit"}
   1757 	splitVals := splitValues(value)
   1758 	return in(splitVals, values)
   1759 }
   1760 
   1761 func TextJustifyHandler(value string) bool {
   1762 	values := []string{"auto", "inter-word", "inter-character", "none", "initial", "inherit"}
   1763 	splitVals := splitValues(value)
   1764 	return in(splitVals, values)
   1765 }
   1766 
   1767 func TextOverflowHandler(value string) bool {
   1768 	if QuotedAlpha.MatchString(value) {
   1769 		return true
   1770 	}
   1771 	values := []string{"clip", "ellipsis", "initial", "inherit"}
   1772 	splitVals := splitValues(value)
   1773 	return in(splitVals, values)
   1774 }
   1775 
   1776 func TextOrientationHandler(value string) bool {
   1777 	values := []string{"mixed", "upright", "sideways", "sideways-right"}
   1778 	splitVals := splitValues(value)
   1779 	return in(splitVals, values)
   1780 }
   1781 
   1782 func TextShadowHandler(value string) bool {
   1783 	values := []string{"none", "initial", "inherit"}
   1784 	if in([]string{value}, values) {
   1785 		return true
   1786 	}
   1787 	commaSplitVals := strings.Split(value, ",")
   1788 	for _, val := range commaSplitVals {
   1789 		splitVals := strings.Split(val, " ")
   1790 		if len(splitVals) > 6 || len(splitVals) < 2 {
   1791 			return false
   1792 		}
   1793 		if !LengthHandler(splitVals[0]) {
   1794 			return false
   1795 		}
   1796 		if !LengthHandler(splitVals[1]) {
   1797 			return false
   1798 		}
   1799 		usedFunctions := []func(string) bool{
   1800 			LengthHandler,
   1801 			ColorHandler,
   1802 		}
   1803 		if len(splitVals) > 2 && !recursiveCheck(splitVals[2:], usedFunctions) {
   1804 			return false
   1805 		}
   1806 	}
   1807 	return true
   1808 }
   1809 
   1810 func TextTransformHandler(value string) bool {
   1811 	values := []string{"none", "capitalize", "uppercase", "lowercase", "initial", "inherit"}
   1812 	splitVals := splitValues(value)
   1813 	return in(splitVals, values)
   1814 }
   1815 
   1816 func TransformHandler(value string) bool {
   1817 	values := []string{"none", "initial", "inherit"}
   1818 	if in([]string{value}, values) {
   1819 		return true
   1820 	}
   1821 	if Matrix.MatchString(value) {
   1822 		return true
   1823 	}
   1824 	if Matrix3D.MatchString(value) {
   1825 		return true
   1826 	}
   1827 	subValue := string(TranslateScale.ReplaceAll([]byte(value), []byte{}))
   1828 	trimValue := strings.Split(strings.TrimSuffix(subValue, ")"), ",")
   1829 	valid := true
   1830 	for _, i := range trimValue {
   1831 		if !LengthHandler(strings.TrimSpace(i)) {
   1832 			valid = false
   1833 			break
   1834 		}
   1835 	}
   1836 	if valid && trimValue != nil {
   1837 		return true
   1838 	}
   1839 	if Rotate.MatchString(value) {
   1840 		return true
   1841 	}
   1842 	if Rotate3D.MatchString(value) {
   1843 		return true
   1844 	}
   1845 	subValue = string(Skew.ReplaceAll([]byte(value), []byte{}))
   1846 	subValue = strings.TrimSuffix(subValue, ")")
   1847 	trimValue = strings.Split(subValue, ",")
   1848 	valid = true
   1849 	for _, i := range trimValue {
   1850 		if !LengthHandler(strings.TrimSpace(i)) {
   1851 			valid = false
   1852 			break
   1853 		}
   1854 	}
   1855 	if valid {
   1856 		return true
   1857 	}
   1858 	subValue = string(Perspective.ReplaceAll([]byte(value), []byte{}))
   1859 	subValue = strings.TrimSuffix(subValue, ")")
   1860 	return LengthHandler(subValue)
   1861 }
   1862 
   1863 func TransformOriginHandler(value string) bool {
   1864 	values := []string{"initial", "inherit"}
   1865 	if in([]string{value}, values) {
   1866 		return true
   1867 	}
   1868 	splitVals := strings.Split(value, " ")
   1869 	xValues := []string{"left", "center", "right"}
   1870 	yValues := []string{"top", "center", "bottom"}
   1871 	if len(splitVals) > 2 {
   1872 		if !in([]string{splitVals[0]}, xValues) && !LengthHandler(splitVals[0]) {
   1873 			return false
   1874 		}
   1875 		if !in([]string{splitVals[1]}, yValues) && !LengthHandler(splitVals[1]) {
   1876 			return false
   1877 		}
   1878 		return LengthHandler(splitVals[2])
   1879 	} else if len(splitVals) > 1 {
   1880 		if !in([]string{splitVals[0]}, xValues) && !LengthHandler(splitVals[0]) {
   1881 			return false
   1882 		}
   1883 		return in([]string{splitVals[1]}, yValues) || LengthHandler(splitVals[1])
   1884 	} else if len(splitVals) == 1 {
   1885 		return in(splitVals, xValues) || in(splitVals, yValues) || LengthHandler(splitVals[0])
   1886 	}
   1887 	return false
   1888 }
   1889 
   1890 func TransformStyleHandler(value string) bool {
   1891 	values := []string{"flat", "preserve-3d", "initial", "inherit"}
   1892 	splitVals := splitValues(value)
   1893 	return in(splitVals, values)
   1894 }
   1895 
   1896 func TransitionHandler(value string) bool {
   1897 	values := []string{"initial", "inherit"}
   1898 	if in([]string{value}, values) {
   1899 		return true
   1900 	}
   1901 	splitVals := strings.Split(value, " ")
   1902 	usedFunctions := []func(string) bool{
   1903 		TransitionPropertyHandler,
   1904 		TransitionDurationHandler,
   1905 		TimingFunctionHandler,
   1906 		TransitionDelayHandler,
   1907 		ColorHandler,
   1908 	}
   1909 	return recursiveCheck(splitVals, usedFunctions)
   1910 }
   1911 
   1912 func TransitionDelayHandler(value string) bool {
   1913 	if Time.MatchString(value) {
   1914 		return true
   1915 	}
   1916 	values := []string{"initial", "inherit"}
   1917 	splitVals := splitValues(value)
   1918 	return in(splitVals, values)
   1919 }
   1920 
   1921 func TransitionDurationHandler(value string) bool {
   1922 	if Time.MatchString(value) {
   1923 		return true
   1924 	}
   1925 	values := []string{"initial", "inherit"}
   1926 	splitVals := splitValues(value)
   1927 	return in(splitVals, values)
   1928 }
   1929 
   1930 func TransitionPropertyHandler(value string) bool {
   1931 	if TransitionProp.MatchString(value) {
   1932 		return true
   1933 	}
   1934 	values := []string{"none", "all", "initial", "inherit"}
   1935 	splitVals := splitValues(value)
   1936 	return in(splitVals, values)
   1937 }
   1938 
   1939 func UnicodeBidiHandler(value string) bool {
   1940 	values := []string{"normal", "embed", "bidi-override", "isolate", "isolate-override", "plaintext", "initial", "inherit"}
   1941 	splitVals := splitValues(value)
   1942 	return in(splitVals, values)
   1943 }
   1944 
   1945 func UserSelectHandler(value string) bool {
   1946 	values := []string{"auto", "none", "text", "all"}
   1947 	splitVals := splitValues(value)
   1948 	return in(splitVals, values)
   1949 }
   1950 
   1951 func VerticalAlignHandler(value string) bool {
   1952 	if LengthHandler(value) {
   1953 		return true
   1954 	}
   1955 	values := []string{"baseline", "sub", "super", "top", "text-top", "middle", "bottom", "text-bottom", "initial", "inherit"}
   1956 	splitVals := splitValues(value)
   1957 	return in(splitVals, values)
   1958 }
   1959 
   1960 func VisiblityHandler(value string) bool {
   1961 	values := []string{"visible", "hidden", "collapse", "initial", "inherit"}
   1962 	splitVals := splitValues(value)
   1963 	return in(splitVals, values)
   1964 }
   1965 
   1966 func WhiteSpaceHandler(value string) bool {
   1967 	values := []string{"normal", "nowrap", "pre", "pre-line", "pre-wrap", "initial", "inherit"}
   1968 	splitVals := splitValues(value)
   1969 	return in(splitVals, values)
   1970 }
   1971 
   1972 func WidthHandler(value string) bool {
   1973 	if LengthHandler(value) {
   1974 		return true
   1975 	}
   1976 	values := []string{"auto", "initial", "inherit"}
   1977 	splitVals := splitValues(value)
   1978 	return in(splitVals, values)
   1979 }
   1980 
   1981 func WordSpacingHandler(value string) bool {
   1982 	if LengthHandler(value) {
   1983 		return true
   1984 	}
   1985 	values := []string{"normal", "initial", "inherit"}
   1986 	splitVals := splitValues(value)
   1987 	return in(splitVals, values)
   1988 }
   1989 
   1990 func WordBreakHandler(value string) bool {
   1991 	values := []string{"normal", "break-all", "keep-all", "break-word", "initial", "inherit"}
   1992 	splitVals := splitValues(value)
   1993 	return in(splitVals, values)
   1994 }
   1995 
   1996 func WordWrapHandler(value string) bool {
   1997 	values := []string{"normal", "break-word", "initial", "inherit"}
   1998 	splitVals := splitValues(value)
   1999 	return in(splitVals, values)
   2000 }
   2001 
   2002 func WritingModeHandler(value string) bool {
   2003 	values := []string{"horizontal-tb", "vertical-rl", "vertical-lr"}
   2004 	splitVals := splitValues(value)
   2005 	return in(splitVals, values)
   2006 }
   2007 
   2008 func ZIndexHandler(value string) bool {
   2009 	if ZIndex.MatchString(value) {
   2010 		return true
   2011 	}
   2012 	values := []string{"auto", "initial", "inherit"}
   2013 	splitVals := splitValues(value)
   2014 	return in(splitVals, values)
   2015 }