'use strict'; function escapeRegExp(string) { return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } function escapeSelector(str) { const length = str.length; let index = -1; let codeUnit; let result = ""; const firstCodeUnit = str.charCodeAt(0); while (++index < length) { codeUnit = str.charCodeAt(index); if (codeUnit === 0) { result += "\uFFFD"; continue; } if (codeUnit === 37) { result += "\\%"; continue; } if (codeUnit === 44) { result += "\\,"; continue; } if ( // If the character is in the range [\1-\1F] (U+0001 to U+001F) or is // U+007F, […] codeUnit >= 1 && codeUnit <= 31 || codeUnit === 127 || index === 0 && codeUnit >= 48 && codeUnit <= 57 || index === 1 && codeUnit >= 48 && codeUnit <= 57 && firstCodeUnit === 45 ) { result += `\\${codeUnit.toString(16)} `; continue; } if ( // If the character is the first character and is a `-` (U+002D), and // there is no second character, […] index === 0 && length === 1 && codeUnit === 45 ) { result += `\\${str.charAt(index)}`; continue; } if (codeUnit >= 128 || codeUnit === 45 || codeUnit === 95 || codeUnit >= 48 && codeUnit <= 57 || codeUnit >= 65 && codeUnit <= 90 || codeUnit >= 97 && codeUnit <= 122) { result += str.charAt(index); continue; } result += `\\${str.charAt(index)}`; } return result; } const e = escapeSelector; function toArray(value = []) { return Array.isArray(value) ? value : [value]; } function uniq(value) { return Array.from(new Set(value)); } function uniqueBy(array, equalFn) { return array.reduce((acc, cur) => { const index = acc.findIndex((item) => equalFn(cur, item)); if (index === -1) acc.push(cur); return acc; }, []); } function isString(s) { return typeof s === "string"; } function normalizeCSSEntries(obj) { if (isString(obj)) return obj; return (!Array.isArray(obj) ? Object.entries(obj) : obj).filter((i) => i[1] != null); } function normalizeCSSValues(obj) { if (Array.isArray(obj)) { if (obj.find((i) => !Array.isArray(i) || Array.isArray(i[0]))) return obj.map((i) => normalizeCSSEntries(i)); else return [obj]; } else { return [normalizeCSSEntries(obj)]; } } function clearIdenticalEntries(entry) { return entry.filter(([k, v], idx) => { if (k.startsWith("$$")) return false; for (let i = idx - 1; i >= 0; i--) { if (entry[i][0] === k && entry[i][1] === v) return false; } return true; }); } function entriesToCss(arr) { if (arr == null) return ""; return clearIdenticalEntries(arr).map(([key, value]) => value != null ? `${key}:${value};` : void 0).filter(Boolean).join(""); } function isObject(item) { return item && typeof item === "object" && !Array.isArray(item); } function mergeDeep(original, patch, mergeArray = false) { const o = original; const p = patch; if (Array.isArray(p)) { if (mergeArray && Array.isArray(p)) return [...o, ...p]; else return [...p]; } const output = { ...o }; if (isObject(o) && isObject(p)) { Object.keys(p).forEach((key) => { if (isObject(o[key]) && isObject(p[key]) || Array.isArray(o[key]) && Array.isArray(p[key])) output[key] = mergeDeep(o[key], p[key], mergeArray); else Object.assign(output, { [key]: p[key] }); }); } return output; } function clone(val) { let k, out, tmp; if (Array.isArray(val)) { out = Array(k = val.length); while (k--) out[k] = (tmp = val[k]) && typeof tmp === "object" ? clone(tmp) : tmp; return out; } if (Object.prototype.toString.call(val) === "[object Object]") { out = {}; for (k in val) { if (k === "__proto__") { Object.defineProperty(out, k, { value: clone(val[k]), configurable: true, enumerable: true, writable: true }); } else { out[k] = (tmp = val[k]) && typeof tmp === "object" ? clone(tmp) : tmp; } } return out; } return val; } function isStaticRule(rule) { return isString(rule[0]); } function isStaticShortcut(sc) { return isString(sc[0]); } const attributifyRE = /^\[(.+?)~?="(.*)"\]$/; const cssIdRE = /\.(css|postcss|sass|scss|less|stylus|styl)($|\?)/; const validateFilterRE = /[\w\u00A0-\uFFFF-_:%-?]/; const CONTROL_SHORTCUT_NO_MERGE = "$$shortcut-no-merge"; function isAttributifySelector(selector) { return selector.match(attributifyRE); } function isValidSelector(selector = "") { return validateFilterRE.test(selector); } function normalizeVariant(variant) { return typeof variant === "function" ? { match: variant } : variant; } function isRawUtil(util) { return util.length === 3; } function notNull(value) { return value != null; } function noop() { } var __defProp$2 = Object.defineProperty; var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField$2 = (obj, key, value) => { __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; class TwoKeyMap { constructor() { __publicField$2(this, "_map", /* @__PURE__ */ new Map()); } get(key1, key2) { const m2 = this._map.get(key1); if (m2) return m2.get(key2); } getFallback(key1, key2, fallback) { let m2 = this._map.get(key1); if (!m2) { m2 = /* @__PURE__ */ new Map(); this._map.set(key1, m2); } if (!m2.has(key2)) m2.set(key2, fallback); return m2.get(key2); } set(key1, key2, value) { let m2 = this._map.get(key1); if (!m2) { m2 = /* @__PURE__ */ new Map(); this._map.set(key1, m2); } m2.set(key2, value); return this; } has(key1, key2) { return this._map.get(key1)?.has(key2); } delete(key1, key2) { return this._map.get(key1)?.delete(key2) || false; } deleteTop(key1) { return this._map.delete(key1); } map(fn) { return Array.from(this._map.entries()).flatMap(([k1, m2]) => Array.from(m2.entries()).map(([k2, v]) => { return fn(v, k1, k2); })); } } class BetterMap extends Map { map(mapFn) { const result = []; this.forEach((v, k) => { result.push(mapFn(v, k)); }); return result; } } var __defProp$1 = Object.defineProperty; var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField$1 = (obj, key, value) => { __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; class CountableSet extends Set { constructor(values) { super(values); __publicField$1(this, "_map"); this._map ?? (this._map = /* @__PURE__ */ new Map()); } add(key) { this._map ?? (this._map = /* @__PURE__ */ new Map()); this._map.set(key, (this._map.get(key) ?? 0) + 1); return super.add(key); } delete(key) { this._map.delete(key); return super.delete(key); } clear() { this._map.clear(); super.clear(); } getCount(key) { return this._map.get(key) ?? 0; } setCount(key, count) { this._map.set(key, count); return super.add(key); } } function isCountableSet(value) { return value instanceof CountableSet; } function withLayer(layer, rules) { rules.forEach((r) => { if (!r[2]) r[2] = { layer }; else r[2].layer = layer; }); return rules; } const regexCache = {}; function makeRegexClassGroup(separators = ["-", ":"]) { const key = separators.join("|"); if (!regexCache[key]) regexCache[key] = new RegExp(`((?:[!@<~\\w+:_/-]|\\[&?>?:?\\S*\\])+?)(${key})\\(((?:[~!<>\\w\\s:/\\\\,%#.$?-]|\\[.*?\\])+?)\\)(?!\\s*?=>)`, "gm"); regexCache[key].lastIndex = 0; return regexCache[key]; } function parseVariantGroup(str, separators = ["-", ":"], depth = 5) { const regexClassGroup = makeRegexClassGroup(separators); let hasChanged; let content = str.toString(); const prefixes = /* @__PURE__ */ new Set(); const groupsByOffset = /* @__PURE__ */ new Map(); do { hasChanged = false; content = content.replace( regexClassGroup, (from, pre, sep, body, groupOffset) => { if (!separators.includes(sep)) return from; hasChanged = true; prefixes.add(pre + sep); const bodyOffset = groupOffset + pre.length + sep.length + 1; const group = { length: from.length, items: [] }; groupsByOffset.set(groupOffset, group); for (const itemMatch of [...body.matchAll(/\S+/g)]) { const itemOffset = bodyOffset + itemMatch.index; let innerItems = groupsByOffset.get(itemOffset)?.items; if (innerItems) { groupsByOffset.delete(itemOffset); } else { innerItems = [{ offset: itemOffset, length: itemMatch[0].length, className: itemMatch[0] }]; } for (const item of innerItems) { item.className = item.className === "~" ? pre : item.className.replace(/^(!?)(.*)/, `$1${pre}${sep}$2`); group.items.push(item); } } return "$".repeat(from.length); } ); depth -= 1; } while (hasChanged && depth); let expanded; if (typeof str === "string") { expanded = ""; let prevOffset = 0; for (const [offset, group] of groupsByOffset) { expanded += str.slice(prevOffset, offset); expanded += group.items.map((item) => item.className).join(" "); prevOffset = offset + group.length; } expanded += str.slice(prevOffset); } else { expanded = str; for (const [offset, group] of groupsByOffset) { expanded.overwrite( offset, offset + group.length, group.items.map((item) => item.className).join(" ") ); } } return { prefixes: Array.from(prefixes), hasChanged, groupsByOffset, // Computed lazily because MagicString's toString does a lot of work get expanded() { return expanded.toString(); } }; } function collapseVariantGroup(str, prefixes) { const collection = /* @__PURE__ */ new Map(); const sortedPrefix = prefixes.sort((a, b) => b.length - a.length); return str.split(/\s+/g).map((part) => { const prefix = sortedPrefix.find((prefix2) => part.startsWith(prefix2)); if (!prefix) return part; const body = part.slice(prefix.length); if (collection.has(prefix)) { collection.get(prefix).push(body); return null; } else { const items = [body]; collection.set(prefix, items); return { prefix, items }; } }).filter(notNull).map((i) => { if (typeof i === "string") return i; return `${i.prefix}(${i.items.join(" ")})`; }).join(" "); } function expandVariantGroup(str, separators = ["-", ":"], depth = 5) { const res = parseVariantGroup(str, separators, depth); return typeof str === "string" ? res.expanded : str; } const warned = /* @__PURE__ */ new Set(); function warnOnce(msg) { if (warned.has(msg)) return; console.warn("[unocss]", msg); warned.add(msg); } const defaultSplitRE = /[\\:]?[\s'"`;{}]+/g; const splitWithVariantGroupRE = /([\\:]?[\s"'`;<>]|:\(|\)"|\)\s)/g; function splitCode(code) { return code.split(defaultSplitRE); } const extractorSplit = { name: "@unocss/core/extractor-split", order: 0, extract({ code }) { return splitCode(code); } }; function createNanoEvents() { return { events: {}, emit(event, ...args) { (this.events[event] || []).forEach((i) => i(...args)); }, on(event, cb) { (this.events[event] = this.events[event] || []).push(cb); return () => this.events[event] = (this.events[event] || []).filter((i) => i !== cb); } }; } const LAYER_DEFAULT = "default"; const LAYER_PREFLIGHTS = "preflights"; const LAYER_SHORTCUTS = "shortcuts"; const LAYER_IMPORTS = "imports"; const DEFAULT_LAYERS = { [LAYER_IMPORTS]: -200, [LAYER_PREFLIGHTS]: -100, [LAYER_SHORTCUTS]: -10, [LAYER_DEFAULT]: 0 }; function resolveShortcuts(shortcuts) { return toArray(shortcuts).flatMap((s) => { if (Array.isArray(s)) return [s]; return Object.entries(s); }); } const __RESOLVED = "_uno_resolved"; function resolvePreset(presetInput) { let preset = typeof presetInput === "function" ? presetInput() : presetInput; if (__RESOLVED in preset) return preset; preset = { ...preset }; Object.defineProperty(preset, __RESOLVED, { value: true, enumerable: false }); const shortcuts = preset.shortcuts ? resolveShortcuts(preset.shortcuts) : void 0; preset.shortcuts = shortcuts; if (preset.prefix || preset.layer) { const apply = (i) => { if (!i[2]) i[2] = {}; const meta = i[2]; if (meta.prefix == null && preset.prefix) meta.prefix = toArray(preset.prefix); if (meta.layer == null && preset.layer) meta.layer = preset.layer; }; shortcuts?.forEach(apply); preset.rules?.forEach(apply); } return preset; } function resolvePresets(preset) { const root = resolvePreset(preset); if (!root.presets) return [root]; const nested = (root.presets || []).flatMap(toArray).flatMap(resolvePresets); return [root, ...nested]; } function resolveConfig(userConfig = {}, defaults = {}) { const config = Object.assign({}, defaults, userConfig); const rawPresets = uniqueBy((config.presets || []).flatMap(toArray).flatMap(resolvePresets), (a, b) => a.name === b.name); const sortedPresets = [ ...rawPresets.filter((p) => p.enforce === "pre"), ...rawPresets.filter((p) => !p.enforce), ...rawPresets.filter((p) => p.enforce === "post") ]; const sources = [ ...sortedPresets, config ]; const sourcesReversed = [...sources].reverse(); const layers = Object.assign({}, DEFAULT_LAYERS, ...sources.map((i) => i.layers)); function getMerged(key) { return uniq(sources.flatMap((p) => toArray(p[key] || []))); } const extractors = getMerged("extractors"); let extractorDefault = sourcesReversed.find((i) => i.extractorDefault !== void 0)?.extractorDefault; if (extractorDefault === void 0) extractorDefault = extractorSplit; if (extractorDefault && !extractors.includes(extractorDefault)) extractors.unshift(extractorDefault); extractors.sort((a, b) => (a.order || 0) - (b.order || 0)); const rules = getMerged("rules"); const rulesStaticMap = {}; const rulesSize = rules.length; const rulesDynamic = rules.map((rule, i) => { if (isStaticRule(rule)) { const prefixes = toArray(rule[2]?.prefix || ""); prefixes.forEach((prefix) => { rulesStaticMap[prefix + rule[0]] = [i, rule[1], rule[2], rule]; }); return void 0; } return [i, ...rule]; }).filter(Boolean).reverse(); let theme = mergeThemes(sources.map((p) => p.theme)); const extendThemes = getMerged("extendTheme"); for (const extendTheme of extendThemes) theme = extendTheme(theme) || theme; const autocomplete = { templates: uniq(sources.flatMap((p) => toArray(p.autocomplete?.templates))), extractors: sources.flatMap((p) => toArray(p.autocomplete?.extractors)).sort((a, b) => (a.order || 0) - (b.order || 0)), shorthands: mergeAutocompleteShorthands(sources.map((p) => p.autocomplete?.shorthands || {})) }; let separators = getMerged("separators"); if (!separators.length) separators = [":", "-"]; const resolved = { mergeSelectors: true, warn: true, sortLayers: (layers2) => layers2, ...config, blocklist: getMerged("blocklist"), presets: sortedPresets, envMode: config.envMode || "build", shortcutsLayer: config.shortcutsLayer || "shortcuts", layers, theme, rulesSize, rulesDynamic, rulesStaticMap, preprocess: getMerged("preprocess"), postprocess: getMerged("postprocess"), preflights: getMerged("preflights"), autocomplete, variants: getMerged("variants").map(normalizeVariant).sort((a, b) => (a.order || 0) - (b.order || 0)), shortcuts: resolveShortcuts(getMerged("shortcuts")).reverse(), extractors, safelist: getMerged("safelist"), separators, details: config.details ?? config.envMode === "dev" }; for (const p of sources) p?.configResolved?.(resolved); return resolved; } function mergeConfigs(configs) { const maybeArrays = ["shortcuts", "preprocess", "postprocess"]; const config = configs.map((config2) => Object.entries(config2).reduce((acc, [key, value]) => ({ ...acc, [key]: maybeArrays.includes(key) ? toArray(value) : value }), {})).reduce(({ theme: themeA, ...a }, { theme: themeB, ...b }) => { const c = mergeDeep(a, b, true); if (themeA || themeB) c.theme = mergeThemes([themeA, themeB]); return c; }, {}); return config; } function mergeThemes(themes) { return themes.map((theme) => theme ? clone(theme) : {}).reduce((a, b) => mergeDeep(a, b), {}); } function mergeAutocompleteShorthands(shorthands) { return shorthands.reduce((a, b) => { const rs = {}; for (const key in b) { const value = b[key]; if (Array.isArray(value)) rs[key] = `(${value.join("|")})`; else rs[key] = value; } return { ...a, ...rs }; }, {}); } function definePreset(preset) { return preset; } const version = "0.57.7"; var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => { __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; class UnoGenerator { constructor(userConfig = {}, defaults = {}) { this.userConfig = userConfig; this.defaults = defaults; __publicField(this, "version", version); __publicField(this, "_cache", /* @__PURE__ */ new Map()); __publicField(this, "config"); __publicField(this, "blocked", /* @__PURE__ */ new Set()); __publicField(this, "parentOrders", /* @__PURE__ */ new Map()); __publicField(this, "events", createNanoEvents()); this.config = resolveConfig(userConfig, defaults); this.events.emit("config", this.config); } setConfig(userConfig, defaults) { if (!userConfig) return; if (defaults) this.defaults = defaults; this.userConfig = userConfig; this.blocked.clear(); this.parentOrders.clear(); this._cache.clear(); this.config = resolveConfig(userConfig, this.defaults); this.events.emit("config", this.config); } async applyExtractors(code, id, extracted = /* @__PURE__ */ new Set()) { const context = { original: code, code, id, extracted, envMode: this.config.envMode }; for (const extractor of this.config.extractors) { const result = await extractor.extract?.(context); if (!result) continue; if (isCountableSet(result) && isCountableSet(extracted)) { for (const token of result) extracted.setCount(token, extracted.getCount(token) + result.getCount(token)); } else { for (const token of result) extracted.add(token); } } return extracted; } makeContext(raw, applied) { const context = { rawSelector: raw, currentSelector: applied[1], theme: this.config.theme, generator: this, variantHandlers: applied[2], constructCSS: (...args) => this.constructCustomCSS(context, ...args), variantMatch: applied }; return context; } async parseToken(raw, alias) { if (this.blocked.has(raw)) return; const cacheKey = `${raw}${alias ? ` ${alias}` : ""}`; if (this._cache.has(cacheKey)) return this._cache.get(cacheKey); let current = raw; for (const p of this.config.preprocess) current = p(raw); if (this.isBlocked(current)) { this.blocked.add(raw); this._cache.set(cacheKey, null); return; } const applied = await this.matchVariants(raw, current); if (!applied || this.isBlocked(applied[1])) { this.blocked.add(raw); this._cache.set(cacheKey, null); return; } const context = this.makeContext(raw, [alias || applied[0], applied[1], applied[2], applied[3]]); if (this.config.details) context.variants = [...applied[3]]; const expanded = await this.expandShortcut(context.currentSelector, context); const utils = expanded ? await this.stringifyShortcuts(context.variantMatch, context, expanded[0], expanded[1]) : (await this.parseUtil(context.variantMatch, context))?.map((i) => this.stringifyUtil(i, context)).filter(notNull); if (utils?.length) { this._cache.set(cacheKey, utils); return utils; } this._cache.set(cacheKey, null); } async generate(input, options = {}) { const { id, scope, preflights = true, safelist = true, minify = false, extendedInfo = false } = options; const tokens = isString(input) ? await this.applyExtractors( input, id, extendedInfo ? new CountableSet() : /* @__PURE__ */ new Set() ) : Array.isArray(input) ? new Set(input) : input; if (safelist) { this.config.safelist.forEach((s) => { if (!tokens.has(s)) tokens.add(s); }); } const nl = minify ? "" : "\n"; const layerSet = /* @__PURE__ */ new Set([LAYER_DEFAULT]); const matched = extendedInfo ? /* @__PURE__ */ new Map() : /* @__PURE__ */ new Set(); const sheet = /* @__PURE__ */ new Map(); let preflightsMap = {}; const tokenPromises = Array.from(tokens).map(async (raw) => { if (matched.has(raw)) return; const payload = await this.parseToken(raw); if (payload == null) return; if (matched instanceof Map) { matched.set(raw, { data: payload, count: isCountableSet(tokens) ? tokens.getCount(raw) : -1 }); } else { matched.add(raw); } for (const item of payload) { const parent = item[3] || ""; const layer = item[4]?.layer; if (!sheet.has(parent)) sheet.set(parent, []); sheet.get(parent).push(item); if (layer) layerSet.add(layer); } }); await Promise.all(tokenPromises); await (async () => { if (!preflights) return; const preflightContext = { generator: this, theme: this.config.theme }; const preflightLayerSet = /* @__PURE__ */ new Set([]); this.config.preflights.forEach(({ layer = LAYER_PREFLIGHTS }) => { layerSet.add(layer); preflightLayerSet.add(layer); }); preflightsMap = Object.fromEntries( await Promise.all(Array.from(preflightLayerSet).map( async (layer) => { const preflights2 = await Promise.all( this.config.preflights.filter((i) => (i.layer || LAYER_PREFLIGHTS) === layer).map(async (i) => await i.getCSS(preflightContext)) ); const css = preflights2.filter(Boolean).join(nl); return [layer, css]; } )) ); })(); const layers = this.config.sortLayers(Array.from(layerSet).sort((a, b) => (this.config.layers[a] ?? 0) - (this.config.layers[b] ?? 0) || a.localeCompare(b))); const layerCache = {}; const getLayer = (layer) => { if (layerCache[layer]) return layerCache[layer]; let css = Array.from(sheet).sort((a, b) => (this.parentOrders.get(a[0]) ?? 0) - (this.parentOrders.get(b[0]) ?? 0) || a[0]?.localeCompare(b[0] || "") || 0).map(([parent, items]) => { const size = items.length; const sorted = items.filter((i) => (i[4]?.layer || LAYER_DEFAULT) === layer).sort((a, b) => { return a[0] - b[0] || (a[4]?.sort || 0) - (b[4]?.sort || 0) || a[5]?.currentSelector?.localeCompare(b[5]?.currentSelector ?? "") || a[1]?.localeCompare(b[1] || "") || a[2]?.localeCompare(b[2] || "") || 0; }).map(([, selector, body, , meta, , variantNoMerge]) => { const scopedSelector = selector ? applyScope(selector, scope) : selector; return [ [[scopedSelector ?? "", meta?.sort ?? 0]], body, !!(variantNoMerge ?? meta?.noMerge) ]; }); if (!sorted.length) return void 0; const rules = sorted.reverse().map(([selectorSortPair, body, noMerge], idx) => { if (!noMerge && this.config.mergeSelectors) { for (let i = idx + 1; i < size; i++) { const current = sorted[i]; if (current && !current[2] && (selectorSortPair && current[0] || selectorSortPair == null && current[0] == null) && current[1] === body) { if (selectorSortPair && current[0]) current[0].push(...selectorSortPair); return null; } } } const selectors = selectorSortPair ? uniq(selectorSortPair.sort((a, b) => a[1] - b[1] || a[0]?.localeCompare(b[0] || "") || 0).map((pair) => pair[0]).filter(Boolean)) : []; return selectors.length ? `${selectors.join(`,${nl}`)}{${body}}` : body; }).filter(Boolean).reverse().join(nl); if (!parent) return rules; const parents = parent.split(" $$ "); return `${parents.join("{")}{${nl}${rules}${nl}${"}".repeat(parents.length)}`; }).filter(Boolean).join(nl); if (preflights) { css = [preflightsMap[layer], css].filter(Boolean).join(nl); } const layerMark = minify ? "" : `/* layer: ${layer} */${nl}`; return layerCache[layer] = css ? layerMark + css : ""; }; const getLayers = (includes = layers, excludes) => { return includes.filter((i) => !excludes?.includes(i)).map((i) => getLayer(i) || "").filter(Boolean).join(nl); }; return { get css() { return getLayers(); }, layers, matched, getLayers, getLayer }; } async matchVariants(raw, current) { const variants = /* @__PURE__ */ new Set(); const handlers = []; let processed = current || raw; let applied = true; const context = { rawSelector: raw, theme: this.config.theme, generator: this }; while (applied) { applied = false; for (const v of this.config.variants) { if (!v.multiPass && variants.has(v)) continue; let handler = await v.match(processed, context); if (!handler) continue; if (isString(handler)) { if (handler === processed) continue; handler = { matcher: handler }; } processed = handler.matcher; handlers.unshift(handler); variants.add(v); applied = true; break; } if (!applied) break; if (handlers.length > 500) throw new Error(`Too many variants applied to "${raw}"`); } return [raw, processed, handlers, variants]; } applyVariants(parsed, variantHandlers = parsed[4], raw = parsed[1]) { const handler = variantHandlers.slice().sort((a, b) => (a.order || 0) - (b.order || 0)).reduceRight( (previous, v) => (input) => { const entries = v.body?.(input.entries) || input.entries; const parents = Array.isArray(v.parent) ? v.parent : [v.parent, void 0]; return (v.handle ?? defaultVariantHandler)({ ...input, entries, selector: v.selector?.(input.selector, entries) || input.selector, parent: parents[0] || input.parent, parentOrder: parents[1] || input.parentOrder, layer: v.layer || input.layer, sort: v.sort || input.sort }, previous); }, (input) => input ); const variantContextResult = handler({ prefix: "", selector: toEscapedSelector(raw), pseudo: "", entries: parsed[2] }); const { parent, parentOrder } = variantContextResult; if (parent != null && parentOrder != null) this.parentOrders.set(parent, parentOrder); const obj = { selector: [ variantContextResult.prefix, variantContextResult.selector, variantContextResult.pseudo ].join(""), entries: variantContextResult.entries, parent, layer: variantContextResult.layer, sort: variantContextResult.sort, noMerge: variantContextResult.noMerge }; for (const p of this.config.postprocess) p(obj); return obj; } constructCustomCSS(context, body, overrideSelector) { const normalizedBody = normalizeCSSEntries(body); if (isString(normalizedBody)) return normalizedBody; const { selector, entries, parent } = this.applyVariants([0, overrideSelector || context.rawSelector, normalizedBody, void 0, context.variantHandlers]); const cssBody = `${selector}{${entriesToCss(entries)}}`; if (parent) return `${parent}{${cssBody}}`; return cssBody; } async parseUtil(input, context, internal = false, shortcutPrefix) { const [raw, processed, variantHandlers] = isString(input) ? await this.matchVariants(input) : input; if (this.config.details) context.rules = context.rules ?? []; const staticMatch = this.config.rulesStaticMap[processed]; if (staticMatch) { if (staticMatch[1] && (internal || !staticMatch[2]?.internal)) { if (this.config.details) context.rules.push(staticMatch[3]); const index = staticMatch[0]; const entry = normalizeCSSEntries(staticMatch[1]); const meta = staticMatch[2]; if (isString(entry)) return [[index, entry, meta]]; else return [[index, raw, entry, meta, variantHandlers]]; } } context.variantHandlers = variantHandlers; const { rulesDynamic } = this.config; for (const [i, matcher, handler, meta] of rulesDynamic) { if (meta?.internal && !internal) continue; let unprefixed = processed; if (meta?.prefix) { const prefixes = toArray(meta.prefix); if (shortcutPrefix) { const shortcutPrefixes = toArray(shortcutPrefix); if (!prefixes.some((i2) => shortcutPrefixes.includes(i2))) continue; } else { const prefix = prefixes.find((i2) => processed.startsWith(i2)); if (prefix == null) continue; unprefixed = processed.slice(prefix.length); } } const match = unprefixed.match(matcher); if (!match) continue; const result = await handler(match, context); if (!result) continue; if (this.config.details) context.rules.push([matcher, handler, meta]); const entries = normalizeCSSValues(result).filter((i2) => i2.length); if (entries.length) { return entries.map((e2) => { if (isString(e2)) return [i, e2, meta]; else return [i, raw, e2, meta, variantHandlers]; }); } } } stringifyUtil(parsed, context) { if (!parsed) return; if (isRawUtil(parsed)) return [parsed[0], void 0, parsed[1], void 0, parsed[2], this.config.details ? context : void 0, void 0]; const { selector, entries, parent, layer: variantLayer, sort: variantSort, noMerge } = this.applyVariants(parsed); const body = entriesToCss(entries); if (!body) return; const { layer: metaLayer, sort: metaSort, ...meta } = parsed[3] ?? {}; const ruleMeta = { ...meta, layer: variantLayer ?? metaLayer, sort: variantSort ?? metaSort }; return [parsed[0], selector, body, parent, ruleMeta, this.config.details ? context : void 0, noMerge]; } async expandShortcut(input, context, depth = 5) { if (depth === 0) return; const recordShortcut = this.config.details ? (s) => { context.shortcuts = context.shortcuts ?? []; context.shortcuts.push(s); } : noop; let meta; let result; for (const s of this.config.shortcuts) { let unprefixed = input; if (s[2]?.prefix) { const prefixes = toArray(s[2].prefix); const prefix = prefixes.find((i) => input.startsWith(i)); if (prefix == null) continue; unprefixed = input.slice(prefix.length); } if (isStaticShortcut(s)) { if (s[0] === unprefixed) { meta = meta || s[2]; result = s[1]; recordShortcut(s); break; } } else { const match = unprefixed.match(s[0]); if (match) result = s[1](match, context); if (result) { meta = meta || s[2]; recordShortcut(s); break; } } } if (isString(result)) result = expandVariantGroup(result.trim()).split(/\s+/g); if (!result) { const [raw, inputWithoutVariant] = isString(input) ? await this.matchVariants(input) : input; if (raw !== inputWithoutVariant) { const expanded = await this.expandShortcut(inputWithoutVariant, context, depth - 1); if (expanded) result = expanded[0].map((item) => isString(item) ? raw.replace(inputWithoutVariant, item) : item); } } if (!result) return; return [ (await Promise.all(result.map(async (r) => (isString(r) ? (await this.expandShortcut(r, context, depth - 1))?.[0] : void 0) || [r]))).flat(1).filter(Boolean), meta ]; } async stringifyShortcuts(parent, context, expanded, meta = { layer: this.config.shortcutsLayer }) { const selectorMap = new TwoKeyMap(); const parsed = (await Promise.all(uniq(expanded).map(async (i) => { const result = isString(i) ? await this.parseUtil(i, context, true, meta.prefix) : [[Number.POSITIVE_INFINITY, "{inline}", normalizeCSSEntries(i), void 0, []]]; if (!result && this.config.warn) warnOnce(`unmatched utility "${i}" in shortcut "${parent[1]}"`); return result || []; }))).flat(1).filter(Boolean).sort((a, b) => a[0] - b[0]); const [raw, , parentVariants] = parent; const rawStringifiedUtil = []; for (const item of parsed) { if (isRawUtil(item)) { rawStringifiedUtil.push([item[0], void 0, item[1], void 0, item[2], context, void 0]); continue; } const { selector, entries, parent: parent2, sort, noMerge } = this.applyVariants(item, [...item[4], ...parentVariants], raw); const mapItem = selectorMap.getFallback(selector, parent2, [[], item[0]]); mapItem[0].push([entries, !!(noMerge ?? item[3]?.noMerge), sort ?? 0]); } return rawStringifiedUtil.concat(selectorMap.map(([e2, index], selector, joinedParents) => { const stringify = (flatten, noMerge, entrySortPair) => { const maxSort = Math.max(...entrySortPair.map((e3) => e3[1])); const entriesList = entrySortPair.map((e3) => e3[0]); return (flatten ? [entriesList.flat(1)] : entriesList).map((entries) => { const body = entriesToCss(entries); if (body) return [index, selector, body, joinedParents, { ...meta, noMerge, sort: maxSort }, context, void 0]; return void 0; }); }; const merges = [ [e2.filter(([, noMerge]) => noMerge).map(([entries, , sort]) => [entries, sort]), true], [e2.filter(([, noMerge]) => !noMerge).map(([entries, , sort]) => [entries, sort]), false] ]; return merges.map(([e3, noMerge]) => [ ...stringify(false, noMerge, e3.filter(([entries]) => entries.some((entry) => entry[0] === CONTROL_SHORTCUT_NO_MERGE))), ...stringify(true, noMerge, e3.filter(([entries]) => entries.every((entry) => entry[0] !== CONTROL_SHORTCUT_NO_MERGE))) ]); }).flat(2).filter(Boolean)); } isBlocked(raw) { return !raw || this.config.blocklist.some((e2) => typeof e2 === "function" ? e2(raw) : isString(e2) ? e2 === raw : e2.test(raw)); } } function createGenerator(config, defaults) { return new UnoGenerator(config, defaults); } const regexScopePlaceholder = /\s\$\$\s+/g; function hasScopePlaceholder(css) { return css.match(/\s\$\$\s/); } function applyScope(css, scope) { if (hasScopePlaceholder(css)) return css.replace(regexScopePlaceholder, scope ? ` ${scope} ` : " "); else return scope ? `${scope} ${css}` : css; } const attributifyRe = /^\[(.+?)(~?=)"(.*)"\]$/; function toEscapedSelector(raw) { if (attributifyRe.test(raw)) return raw.replace(attributifyRe, (_, n, s, i) => `[${e(n)}${s}"${e(i)}"]`); return `.${e(raw)}`; } function defaultVariantHandler(input, next) { return next(input); } exports.BetterMap = BetterMap; exports.CONTROL_SHORTCUT_NO_MERGE = CONTROL_SHORTCUT_NO_MERGE; exports.CountableSet = CountableSet; exports.TwoKeyMap = TwoKeyMap; exports.UnoGenerator = UnoGenerator; exports.attributifyRE = attributifyRE; exports.clearIdenticalEntries = clearIdenticalEntries; exports.clone = clone; exports.collapseVariantGroup = collapseVariantGroup; exports.createGenerator = createGenerator; exports.cssIdRE = cssIdRE; exports.defaultSplitRE = defaultSplitRE; exports.definePreset = definePreset; exports.e = e; exports.entriesToCss = entriesToCss; exports.escapeRegExp = escapeRegExp; exports.escapeSelector = escapeSelector; exports.expandVariantGroup = expandVariantGroup; exports.extractorDefault = extractorSplit; exports.extractorSplit = extractorSplit; exports.hasScopePlaceholder = hasScopePlaceholder; exports.isAttributifySelector = isAttributifySelector; exports.isCountableSet = isCountableSet; exports.isObject = isObject; exports.isRawUtil = isRawUtil; exports.isStaticRule = isStaticRule; exports.isStaticShortcut = isStaticShortcut; exports.isString = isString; exports.isValidSelector = isValidSelector; exports.makeRegexClassGroup = makeRegexClassGroup; exports.mergeConfigs = mergeConfigs; exports.mergeDeep = mergeDeep; exports.noop = noop; exports.normalizeCSSEntries = normalizeCSSEntries; exports.normalizeCSSValues = normalizeCSSValues; exports.normalizeVariant = normalizeVariant; exports.notNull = notNull; exports.parseVariantGroup = parseVariantGroup; exports.regexScopePlaceholder = regexScopePlaceholder; exports.resolveConfig = resolveConfig; exports.resolvePreset = resolvePreset; exports.resolvePresets = resolvePresets; exports.resolveShortcuts = resolveShortcuts; exports.splitWithVariantGroupRE = splitWithVariantGroupRE; exports.toArray = toArray; exports.toEscapedSelector = toEscapedSelector; exports.uniq = uniq; exports.uniqueBy = uniqueBy; exports.validateFilterRE = validateFilterRE; exports.warnOnce = warnOnce; exports.withLayer = withLayer;