import type { Declarations } from './types' ; import { isAtRuleVariant } from './css' ; import { join , tail } from './util' ; let precedence ; let match ; const responsivePrecedence = ( css ) : number => ( match = /\(\s*min-width:\s*(\d+(?:.\d+)?)(p)?/ . exec ( css ) ) ? + match [ 1 ] / ( match [ 2 ] ? 15 : 1 ) / 10 : 0 ; const seperatorPrecedence = ( string ) : number => { precedence = 0 ; for ( let index = string . length ; index -- ; ) { if ( ~ '-:,' . indexOf ( string [ index ] ) ) { ++ precedence ; } } return precedence ; } ; const PRECEDENCES_BY_PSEUDO_CLASS = [ 'rst' , 'st' , 'h-chi' , 'nk' , 'sited' , 'pty' , 'ecked' , 'oup-h' , 'oup-f' , 'cus-w' , 'ver' , 'cus' , 'cus-v' , 'tive' , 'sable' , ] ; const pseudoPrecedence = ( pseudoClass ) : number => ~ ( precedence = PRECEDENCES_BY_PSEUDO_CLASS . indexOf ( pseudoClass . slice ( 3 , 8 ) ) ) ? precedence : PRECEDENCES_BY_PSEUDO_CLASS . length ; const accumulatePseudoPrecedence = ( precedence , variant ) : number => { return precedence | ( isAtRuleVariant ( variant ) ? 0 : 1 << pseudoPrecedence ( variant ) ) ; } ; const PROPERTY_PRECEDENCE_CORRECTION_GROUPS = /^(?:(border-(?:[tlbr].{2,4}-)?(?:w|c|sty)|[tlbr].{2,4}m?$|c.{7}$)|([fl].{5}l|g.{8}$|pl))/ ; const propertyPrecedence = ( property ) : number => { const unprefixedProperty = property [ 0 ] === '-' ? tail ( property , property . indexOf ( '-' , 1 ) + 1 ) : property ; const match = PROPERTY_PRECEDENCE_CORRECTION_GROUPS . exec ( unprefixedProperty ) ; return ( seperatorPrecedence ( unprefixedProperty ) + ( match ? + ! ! match [ 1 ] || - ! ! match [ 2 ] : 0 ) + 1 ) ; } ; const declarationPropertyPrecedence = ( property ) : number => property [ 0 ] === '-' ? 0 : propertyPrecedence ( property ) ; const descending = ( value ) : number => Math . max ( 0 , 15 - value ) ; const declarationValuePrecedence = ( property , value ) : number => descending ( seperatorPrecedence ( value ) ) ; const declarationsCountPrecedence = ( declarations ) : number => descending ( Object . keys ( declarations ) . filter ( ( property ) => declarations [ property ] ) . length ) ; const max = ( declarations , iteratee ) : number => Object . keys ( declarations ) . reduce ( ( result , property ) => declarations [ property ] ? Math . max ( result , iteratee ( property , declarations [ property ] as string ) ) : result , 0 ) ; export const calculatePrecedence = ( darkMode , variantsCss , declarations ) : number => { const rp = responsivePrecedence ( variantsCss [ 0 ] || '' ) ; return ( ( ( ( rp & 31 ) << 21 ) | ( + darkMode << 20 ) | ( ( seperatorPrecedence ( join ( ( rp ? tail ( variantsCss ) : variantsCss ) . filter ( isAtRuleVariant ) , ';' ) ) & 15 ) << 16 ) | ( variantsCss . reduce ( accumulatePseudoPrecedence , 0 ) & 0xffff ) ) * ( 1 << 12 ) + ( ( ( declarationsCountPrecedence ( declarations ) & 15 ) << 8 ) | ( ( max ( declarations , declarationPropertyPrecedence ) & 15 ) << 4 ) | ( max ( declarations , declarationValuePrecedence ) & 15 ) ) ) ; } ;