///|
/// Whether a candidate may carry a leading `-`.
///
/// Upstream registers the negative form of a utility explicitly — `functionalUtility`
/// only binds `-${classRoot}` when the description sets `supportsNegative`, and
/// `spacingUtility` forwards that flag — so `-gap-4` or `-p-4` are not candidates
/// at all, however well their value would resolve. Derived from every
/// `supportsNegative: true` registration and every `utilities.functional('-…')`
/// in upstream `src/utilities.ts`.
let negative_utilities : @set.Set[String] = Set([
// inset
"inset", "inset-x", "inset-y", "inset-s", "inset-e", "inset-bs", "inset-be", "top",
"right", "bottom", "left",
// grid placement
"z", "order", "col", "col-start", "col-end", "row", "row-start", "row-end",
// margin
"m", "mx", "my", "ms", "me", "mbs", "mbe", "mt", "mr", "mb", "ml",
// scroll margin
"scroll-m", "scroll-mx", "scroll-my", "scroll-ms", "scroll-me", "scroll-mbs",
"scroll-mbe", "scroll-mt", "scroll-mr", "scroll-mb", "scroll-ml",
// transforms
"translate", "translate-x", "translate-y", "translate-z", "scale", "scale-x",
"scale-y", "scale-z", "rotate", "rotate-x", "rotate-y", "rotate-z", "skew", "skew-x",
"skew-y",
// spacing between children
"space-x", "space-y",
// typography
"indent", "tracking", "underline-offset",
// gradients and masks
"bg-linear", "bg-conic", "mask-linear", "mask-conic",
// filters
"hue-rotate", "backdrop-hue-rotate",
// misc
"outline-offset",
])
///|
/// Utilities that sit under a negative-supporting name without inheriting it.
/// `inset-shadow` is not `inset` and `col-span` is not `col`, so a prefix match
/// alone would let `-inset-shadow-sm` and `-col-span-4` through. Upstream
/// registers `-translate-full` itself, which is why it is absent here.
let non_negative_utilities : @set.Set[String] = Set([
"col-span", "row-span", "inset-ring", "inset-shadow", "inset-shadow-initial", "rotate-none",
"scale-3d", "scale-none", "space-x-reverse", "space-y-reverse", "translate-3d",
"translate-none",
// Only the bare angle forms of the gradient masks negate; their stops do not.
"mask-linear-from", "mask-linear-to", "mask-conic-from", "mask-conic-to",
])
///|
/// `-inset-x-4` is the `inset-x` utility negated, so the utility name is a
/// `-`-bounded prefix of the base rather than the whole of it. The longest
/// prefix wins, so a utility that shadows a shorter negative one answers first.
fn supports_negative(base : String) -> Bool {
let boundaries = []
for index in 0../` as a ratio, and
// the parser hands it over the same way.
"aspect", "flex",
])
///|
/// Utilities that sit under a fraction-taking name without taking fractions.
let non_fraction_utilities : @set.Set[String] = Set(["translate-z"])
///|
/// The longest utility name answers, so `translate-z-1/2` is not a fraction
/// even though `translate` takes them.
fn supports_fractions(base : String) -> Bool {
let boundaries = []
for index in 0.. Bool {
// `scrollbar-color` names two colors at once; its alpha goes on the two
// custom properties it composes, which are listed below.
if property == "scrollbar-color" {
return false
}
property == "color" ||
property.has_suffix("-color") ||
property == "fill" ||
property == "stroke" ||
property == "--tw-gradient-from" ||
property == "--tw-gradient-via" ||
property == "--tw-gradient-to" ||
property == "--tw-scrollbar-thumb" ||
property == "--tw-scrollbar-track"
}
///|
/// Whether a value survives negation.
///
/// Upstream never offers a utility's static values to its negative form —
/// `staticValues` is consulted only when the candidate is not negative — so
/// `-z-auto` and `-top-auto` are not candidates. Every value the negative form
/// does reach is a number, dimension, percentage or expression, so a value made
/// only of letters and hyphens is a keyword that arrived from a static branch.
fn is_negatable_value(value : String) -> Bool {
for index in 0..= 'a' && character <= 'z') || character == '-') {
return true
}
}
false
}