@sugarcube-sh/core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE.md ADDED
@@ -0,0 +1,9 @@
1
+ MIT License
2
+
3
+ Copyright (c) Mark Tomlinson
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,13 @@
1
+ # @sugarcube-sh/core
2
+
3
+ <p>
4
+ <a href="https://www.npmjs.com/package/@sugarcube-sh/core"><img src="https://img.shields.io/npm/v/@sugarcube-sh/core.svg" alt="Latest Release"></a>
5
+ <a href="https://www.npmjs.com/package/@sugarcube-sh/core"><img src="https://img.shields.io/npm/dt/@sugarcube-sh/core.svg" alt="Total Downloads"></a>
6
+ <a href="https://github.com/sugarcube-sh/sugarcube/blob/main/LICENSE.md"><img src="https://img.shields.io/badge/license-see%20LICENSE-blue" alt="License"></a>
7
+ </p>
8
+
9
+ Core token processing and CSS generation for [sugarcube](https://sugarcube.sh).
10
+
11
+ ## License
12
+
13
+ See [LICENSE.md](./LICENSE.md) for terms.
@@ -0,0 +1,867 @@
1
+ import { z } from 'zod';
2
+
3
+ type DirectionalVariant = "top" | "right" | "bottom" | "left" | "x" | "y" | "full" | "all";
4
+ type PropertyUtilityConfig = {
5
+ /** Token path pattern (e.g., "space.*", "color.primary.*"). */
6
+ source: string;
7
+ /** Directional variants for spacing properties. */
8
+ directions?: DirectionalVariant | DirectionalVariant[];
9
+ /** Custom prefix for generated classes. */
10
+ prefix?: string;
11
+ /** Strip duplicate prefix (e.g., "text-text-quiet" → "text-quiet"). */
12
+ stripDuplicates?: boolean;
13
+ };
14
+
15
+ type ColorFallbackStrategy = "native" | "polyfill";
16
+ type FluidConfig = {
17
+ min: number;
18
+ max: number;
19
+ };
20
+ type TransformsConfig = {
21
+ fluid: FluidConfig;
22
+ colorFallbackStrategy: ColorFallbackStrategy;
23
+ };
24
+ type OutputConfig = {
25
+ cssRoot: string;
26
+ variables?: string;
27
+ variablesFilename: string;
28
+ utilities?: string;
29
+ utilitiesFilename: string;
30
+ cube?: string;
31
+ components?: string;
32
+ themeAttribute: string;
33
+ defaultContext?: string;
34
+ };
35
+ type UtilitiesConfig = Record<string, PropertyUtilityConfig | PropertyUtilityConfig[]>;
36
+ /**
37
+ * Configuration for sugarcube.
38
+ * This is the shape of your config file (sugarcube.config.ts).
39
+ *
40
+ * @example
41
+ * // sugarcube.config.ts
42
+ * import { defineConfig } from "@sugarcube-sh/vite";
43
+ *
44
+ * export default defineConfig({
45
+ * resolver: "./tokens.resolver.json",
46
+ * output: { cssRoot: "src/styles" }
47
+ * });
48
+ */
49
+ interface SugarcubeConfig {
50
+ /**
51
+ * Path to the DTCG resolver document (.resolver.json).
52
+ *
53
+ * **Optional** - If omitted, sugarcube will automatically discover
54
+ * `*.resolver.json` files in your project.
55
+ *
56
+ * Only specify this if you have multiple resolver files and need to
57
+ * choose a specific one.
58
+ */
59
+ resolver?: string;
60
+ /**
61
+ * Token transformation options.
62
+ */
63
+ transforms?: {
64
+ /**
65
+ * Viewport range for fluid typography calculations.
66
+ * Tokens with $type: "fluidDimension" will scale between min and max viewport widths.
67
+ */
68
+ fluid?: FluidConfig;
69
+ /**
70
+ * How to handle colors that can't be represented in sRGB.
71
+ * - "native": Use CSS color functions directly (modern browsers only)
72
+ * - "polyfill": Generate fallback values for older browsers
73
+ */
74
+ colorFallbackStrategy?: ColorFallbackStrategy;
75
+ };
76
+ /**
77
+ * Output configuration.
78
+ */
79
+ output?: {
80
+ /**
81
+ * Base directory path where CSS files will be written.
82
+ * This is the primary output location for generated styles.
83
+ */
84
+ cssRoot?: string;
85
+ /**
86
+ * Directory path where token variable CSS files will be written.
87
+ * @default "{cssRoot}/global"
88
+ */
89
+ variables?: string;
90
+ /**
91
+ * Filename for the generated token variables CSS file.
92
+ * @default "tokens.variables.gen.css"
93
+ */
94
+ variablesFilename?: string;
95
+ /**
96
+ * Directory path where utility class CSS files will be written.
97
+ * @default "{cssRoot}/utilities"
98
+ */
99
+ utilities?: string;
100
+ /**
101
+ * Filename for the generated utilities CSS file.
102
+ * @default "utilities.gen.css"
103
+ */
104
+ utilitiesFilename?: string;
105
+ /**
106
+ * Directory path where CUBE CSS files will be written.
107
+ * @default "{cssRoot}"
108
+ */
109
+ cube?: string;
110
+ /** Directory path where component files will be written. */
111
+ components?: string;
112
+ /**
113
+ * HTML attribute used for theme selectors.
114
+ * @default "data-theme"
115
+ */
116
+ themeAttribute?: string;
117
+ /**
118
+ * Which context should use the :root selector.
119
+ * Other contexts will use [themeAttribute="contextName"] selectors.
120
+ * @default The resolver's default context
121
+ */
122
+ defaultContext?: string;
123
+ };
124
+ /**
125
+ * CSS utility class generation configuration.
126
+ * Maps CSS property names to token sources and options.
127
+ *
128
+ * @example
129
+ * utilities: {
130
+ * "background-color": { source: "color.background.*" },
131
+ * "padding": { source: "space.*", directions: ["x", "y", "all"] }
132
+ * }
133
+ */
134
+ utilities?: UtilitiesConfig;
135
+ }
136
+ /**
137
+ * Normalized configuration with all defaults applied.
138
+ * Used internally after processing SugarcubeConfig.
139
+ */
140
+ interface InternalConfig {
141
+ resolver?: string;
142
+ transforms: TransformsConfig;
143
+ output: OutputConfig;
144
+ utilities?: UtilitiesConfig;
145
+ }
146
+
147
+ /**
148
+ * Define a sugarcube configuration with full type inference.
149
+ *
150
+ * @example
151
+ * ```ts
152
+ * // sugarcube.config.ts
153
+ * import { defineConfig } from "@sugarcube-sh/cli";
154
+ *
155
+ * export default defineConfig({
156
+ * resolver: "./tokens/resolver.json",
157
+ * output: { cssRoot: "src/styles" }
158
+ * });
159
+ * ```
160
+ */
161
+ declare function defineConfig(config: SugarcubeConfig): SugarcubeConfig;
162
+
163
+ declare const DEFAULT_CONFIG: {
164
+ readonly output: {
165
+ readonly cssRoot: "src/styles";
166
+ readonly variablesFilename: "tokens.variables.gen.css";
167
+ readonly utilitiesFilename: "utilities.gen.css";
168
+ readonly components: "src/components/ui";
169
+ readonly themeAttribute: "data-theme";
170
+ };
171
+ readonly transforms: {
172
+ readonly fluid: {
173
+ readonly min: 320;
174
+ readonly max: 1200;
175
+ };
176
+ readonly colorFallbackStrategy: "native";
177
+ };
178
+ };
179
+
180
+ declare function isNoConfigError(error: unknown): boolean;
181
+ /**
182
+ * Result of loading a sugarcube configuration file.
183
+ * Contains the validated, normalized configuration and its source path.
184
+ */
185
+ type LoadedConfig = {
186
+ /** The validated and normalized configuration with defaults applied. */
187
+ config: InternalConfig;
188
+ /** The absolute path to the config file that was loaded, or the resolver path if auto-discovered. */
189
+ configPath: string;
190
+ };
191
+ /**
192
+ * Checks if a sugarcube configuration file exists.
193
+ *
194
+ * @param basePath - Base path without extension (default: "sugarcube.config")
195
+ * @returns True if a .ts or .js config file exists
196
+ */
197
+ declare function configFileExists(basePath?: string): boolean;
198
+ /**
199
+ * Loads and validates a sugarcube configuration file.
200
+ * Returns the user-facing config without internal defaults applied.
201
+ *
202
+ * @param configPath - Optional path to config file. If omitted, searches for sugarcube.config.ts/js
203
+ * @returns The validated config and its resolved path
204
+ * @throws Error if config file not found or invalid
205
+ */
206
+ declare function loadSugarcubeConfig(configPath?: string): Promise<{
207
+ config: SugarcubeConfig;
208
+ configPath: string;
209
+ }>;
210
+ /**
211
+ * Loads, validates, and normalizes a sugarcube configuration file.
212
+ * Returns a complete internal config with all defaults applied.
213
+ *
214
+ * If no config file is found, attempts to auto-discover a resolver file and use defaults.
215
+ *
216
+ * @param configPath - Optional path to config file. If omitted, searches for sugarcube.config.ts/js
217
+ * @returns The normalized config with defaults, its resolved path, and source type
218
+ * @throws Error if config file not found, invalid, or if multiple resolvers are discovered
219
+ */
220
+ declare function loadInternalConfig(configPath?: string): Promise<LoadedConfig>;
221
+
222
+ /**
223
+ * Validates a user configuration object against the schema and fills in defaults.
224
+ *
225
+ * @param config - The user configuration object to validate
226
+ * @returns The validated configuration with defaults filled in
227
+ * @throws Error if the configuration is invalid
228
+ *
229
+ * @example
230
+ * const config = { resolver: "./tokens.resolver.json" };
231
+ * const validatedConfig = validateConfig(config);
232
+ */
233
+ declare function validateConfig(config: Partial<SugarcubeConfig>): InternalConfig;
234
+
235
+ /**
236
+ * Fills in default values for any omitted fields in a user configuration.
237
+ *
238
+ * This function takes a user config (with optional fields) and
239
+ * returns a complete internal config (with all required fields filled in).
240
+ *
241
+ * @param userConfig - The user configuration with optional fields
242
+ * @returns A complete configuration with all defaults filled in
243
+ *
244
+ * @example
245
+ * const userConfig = {
246
+ * resolver: "./tokens.resolver.json"
247
+ * };
248
+ * const completeConfig = fillDefaults(userConfig);
249
+ * // completeConfig.output.cssRoot === "src/styles"
250
+ */
251
+ declare function fillDefaults(userConfig: SugarcubeConfig): InternalConfig;
252
+
253
+ type ResolverDiscoveryResult = {
254
+ found: "one";
255
+ path: string;
256
+ } | {
257
+ found: "multiple";
258
+ paths: string[];
259
+ } | {
260
+ found: "none";
261
+ };
262
+ /**
263
+ * Auto-discover *.resolver.json files anywhere in the project.
264
+ * Searches recursively from the given directory, excluding build/dependency folders.
265
+ *
266
+ * @param directory - The directory to search from (typically process.cwd())
267
+ * @returns Discovery result indicating if one, multiple, or no resolvers were found
268
+ */
269
+ declare function findResolverDocument(directory: string): Promise<ResolverDiscoveryResult>;
270
+
271
+ type BaseError = {
272
+ message: string;
273
+ };
274
+
275
+ type TokenValue<T extends TokenType> = RawTokenValue<T> | Reference<T>;
276
+ type RawTokenValue<T extends TokenType> = T extends SimpleTokenType ? SimpleTokenValue<T> : T extends CompositeTokenType ? CompositeTokenValue<T> : never;
277
+ /** Reference to another token. String format: "{path.to.token}". */
278
+ type Reference<T extends TokenType = TokenType> = string & {
279
+ __tokenType?: T;
280
+ };
281
+ type NodeMetadata = {
282
+ $description?: string;
283
+ $extensions?: {
284
+ [key: string]: unknown;
285
+ };
286
+ };
287
+ type Token = NodeMetadata & {
288
+ $value: TokenValue<TokenType>;
289
+ $type?: TokenType;
290
+ };
291
+ type TokenGroup = NodeMetadata & {
292
+ $type?: TokenType;
293
+ [key: string]: Token | TokenGroup | TokenType | undefined;
294
+ };
295
+ type TokenType = SimpleTokenType | CompositeTokenType;
296
+ type SimpleTokenType = "color" | "dimension" | "fluidDimension" | "duration" | "cubicBezier" | "fontFamily" | "fontWeight" | "number";
297
+ type SimpleTokenValue<T extends SimpleTokenType = SimpleTokenType> = T extends "color" ? Color : T extends "dimension" ? Dimension : T extends "fluidDimension" ? FluidDimension : T extends "duration" ? Duration : T extends "cubicBezier" ? CubicBezier : T extends "fontFamily" ? FontFamily : T extends "fontWeight" ? FontWeight : T extends "number" ? number : never;
298
+ type CompositeTokenType = AlwaysDecomposedType | "border" | "shadow" | "gradient" | "transition" | StructuralCompositeType;
299
+ /** Types that decompose into multiple CSS properties (e.g., typography → font-family, font-size, etc.). */
300
+ type AlwaysDecomposedType = "typography";
301
+ type StructuralCompositeType = "strokeStyle";
302
+ type CompositeTokenValue<T extends CompositeTokenType = CompositeTokenType> = T extends "typography" ? Typography : T extends "border" ? Border : T extends "shadow" ? Shadow : T extends "gradient" ? Gradient : T extends "transition" ? Transition : T extends "strokeStyle" ? StrokeStyle : never;
303
+ /** CSS color string or W3C color object with colorSpace. */
304
+ type Color = string | {
305
+ colorSpace: "oklch" | "display-p3";
306
+ components: [number, number, number];
307
+ alpha?: number;
308
+ hex?: string;
309
+ };
310
+ type Dimension = {
311
+ value: number;
312
+ unit: "px" | "rem";
313
+ };
314
+ /** Responsive dimension that scales between viewport sizes. */
315
+ type FluidDimension = {
316
+ min: Dimension;
317
+ max: Dimension;
318
+ };
319
+ type Duration = {
320
+ value: number;
321
+ unit: "ms" | "s";
322
+ };
323
+ /** Bezier curve control points: [x1, y1, x2, y2]. */
324
+ type CubicBezier = [number, number, number, number];
325
+ type FontFamily = string | string[];
326
+ type FontWeight = number | FontWeightString;
327
+ type FontWeightString = "thin" | "hairline" | "extra-light" | "ultra-light" | "light" | "normal" | "regular" | "book" | "medium" | "semi-bold" | "demi-bold" | "bold" | "extra-bold" | "ultra-bold" | "black" | "heavy" | "extra-black" | "ultra-black";
328
+ type LineCap = "round" | "butt" | "square";
329
+ type Typography = {
330
+ fontFamily: TokenValue<"fontFamily">;
331
+ fontSize: TokenValue<"dimension">;
332
+ fontWeight?: TokenValue<"fontWeight">;
333
+ letterSpacing?: TokenValue<"dimension">;
334
+ lineHeight?: TokenValue<"number">;
335
+ };
336
+ type Transition = {
337
+ duration: TokenValue<"duration">;
338
+ delay?: TokenValue<"duration">;
339
+ timingFunction: TokenValue<"cubicBezier">;
340
+ };
341
+ type StrokeStyleKeyword = "solid" | "dashed" | "dotted" | "double" | "groove" | "ridge" | "outset" | "inset";
342
+ type StrokeStyleCustom = {
343
+ dashArray: Array<TokenValue<"dimension">>;
344
+ lineCap: LineCap;
345
+ };
346
+ type StrokeStyle = StrokeStyleKeyword | StrokeStyleCustom;
347
+ type Border = {
348
+ color: TokenValue<"color">;
349
+ width: TokenValue<"dimension">;
350
+ style: StrokeStyle | Reference<"strokeStyle">;
351
+ };
352
+ type ShadowObject = {
353
+ color: TokenValue<"color">;
354
+ offsetX: TokenValue<"dimension">;
355
+ offsetY: TokenValue<"dimension">;
356
+ blur: TokenValue<"dimension">;
357
+ spread: TokenValue<"dimension">;
358
+ inset?: boolean;
359
+ };
360
+ type Shadow = ShadowObject | ShadowObject[];
361
+ type GradientStop = {
362
+ color: TokenValue<"color">;
363
+ position: number | Reference<"number">;
364
+ };
365
+ type Gradient = GradientStop[];
366
+
367
+ /**
368
+ * Source information for a token, tracking where it came from.
369
+ * Used for error reporting and context-aware processing.
370
+ */
371
+ type TokenSource = {
372
+ /**
373
+ * The context name for modifier variations (e.g., "dark", "light").
374
+ * Aligns with DTCG Resolver Module 2025.10 terminology.
375
+ */
376
+ context?: string;
377
+ /** The file path where this token was defined. */
378
+ sourcePath: string;
379
+ };
380
+ /**
381
+ * A loaded token file with its contents and source metadata.
382
+ * Represents a single token file after loading but before processing.
383
+ */
384
+ type TokenTree = {
385
+ /**
386
+ * The context name for modifier variations (e.g., "dark", "compact").
387
+ * Undefined for base/default tokens.
388
+ */
389
+ context?: string;
390
+ /** The token data following the W3C Design Tokens format. */
391
+ tokens: TokenGroup;
392
+ /** The file path where these tokens were loaded from. */
393
+ sourcePath: string;
394
+ };
395
+
396
+ type FlattenError = BaseError & {
397
+ path: string;
398
+ source: TokenSource;
399
+ };
400
+
401
+ /**
402
+ * A generated CSS file with its output path and content.
403
+ */
404
+ type CSSFile = {
405
+ /** The file path where the CSS will be written. */
406
+ path: string;
407
+ /** The generated CSS content. */
408
+ css: string;
409
+ };
410
+ /**
411
+ * Array of generated CSS files from the pipeline.
412
+ * Each file contains a path and the CSS content to write.
413
+ */
414
+ type CSSFileOutput = CSSFile[];
415
+
416
+ /** In-memory token data keyed by file path. */
417
+ type TokenMemoryData = Record<string, {
418
+ context?: string;
419
+ content: string;
420
+ }>;
421
+ type LoadError = BaseError & {
422
+ file: string;
423
+ };
424
+
425
+ /**
426
+ * A token with all references resolved to their final values.
427
+ * Contains both the original value (which may include references)
428
+ * and the fully resolved value.
429
+ */
430
+ type ResolvedToken<T extends TokenType = TokenType> = NodeMetadata & {
431
+ /** The token type (e.g., "color", "dimension"). */
432
+ $type: T;
433
+ /** The original value, which may contain references like "{color.primary}". */
434
+ $value: RawTokenValue<T>;
435
+ /** The dot-separated path to this token (e.g., "color.primary"). */
436
+ $path: string;
437
+ /** Source information about where this token was defined. */
438
+ $source: TokenSource;
439
+ /** The original path before any processing. */
440
+ $originalPath: string;
441
+ /** The final value after all references have been resolved. */
442
+ $resolvedValue: RawTokenValue<T>;
443
+ };
444
+ /**
445
+ * A collection of resolved tokens keyed by their lookup path.
446
+ * Includes both tokens and group metadata nodes.
447
+ */
448
+ type ResolvedTokens = {
449
+ [lookupKey: string]: ResolvedToken | NodeMetadata;
450
+ };
451
+ type ResolutionErrorType = "circular" | "missing" | "type-mismatch";
452
+ type ResolutionError = BaseError & {
453
+ type: ResolutionErrorType;
454
+ path: string;
455
+ source: TokenSource;
456
+ };
457
+
458
+ type ValidationError = BaseError & {
459
+ path: string;
460
+ source: TokenSource;
461
+ };
462
+
463
+ /**
464
+ * Metadata about a modifier (e.g., theme, density) for CSS generation.
465
+ * Used to build attribute selectors like [data-theme="dark"].
466
+ */
467
+ type ModifierMeta = {
468
+ /** The modifier name (e.g., "theme", "density"). */
469
+ name: string;
470
+ /** The HTML attribute name (e.g., "data-theme", "data-density"). */
471
+ attribute: string;
472
+ /** The default context that uses :root selector. */
473
+ defaultContext: string;
474
+ /** Available non-default context names. */
475
+ contexts: string[];
476
+ };
477
+ /**
478
+ * Result of running the token processing pipeline.
479
+ * Contains generated CSS output, processed tokens, and any errors encountered.
480
+ */
481
+ type PipelineResult = {
482
+ /** The generated CSS files ready to be written to disk. */
483
+ output: CSSFileOutput;
484
+ /** The loaded and processed token trees. */
485
+ trees: TokenTree[];
486
+ /** Modifier metadata for CSS selector generation. */
487
+ modifiers?: ModifierMeta[];
488
+ /** Any errors that occurred during pipeline execution. */
489
+ errors: PipelineErrors;
490
+ };
491
+ /**
492
+ * Errors organized by the pipeline stage where they occurred.
493
+ */
494
+ type PipelineErrors = {
495
+ /** Errors from loading token files. */
496
+ load: LoadError[];
497
+ /** Errors from flattening token trees. */
498
+ flatten: FlattenError[];
499
+ /** Errors from validating token values. */
500
+ validation: ValidationError[];
501
+ /** Errors from resolving token references. */
502
+ resolution: ResolutionError[];
503
+ };
504
+ /**
505
+ * Defines the source of tokens for the pipeline.
506
+ *
507
+ * @example
508
+ * // Load from a DTCG resolver document
509
+ * const source: TokenPipelineSource = {
510
+ * type: "resolver",
511
+ * resolverPath: "./tokens.resolver.json",
512
+ * config: internalConfig
513
+ * };
514
+ *
515
+ * @example
516
+ * // Load from in-memory data (for testing)
517
+ * const source: TokenPipelineSource = {
518
+ * type: "memory",
519
+ * data: { "tokens.json": { content: '{"color": {...}}' } },
520
+ * config: internalConfig
521
+ * };
522
+ */
523
+ type TokenPipelineSource = {
524
+ type: "resolver";
525
+ /** Path to the DTCG resolver document (.resolver.json). */
526
+ resolverPath: string;
527
+ /** Pipeline configuration. */
528
+ config: InternalConfig;
529
+ } | {
530
+ type: "memory";
531
+ /** In-memory token data keyed by file path. */
532
+ data: TokenMemoryData;
533
+ /** Pipeline configuration. */
534
+ config: InternalConfig;
535
+ };
536
+
537
+ /**
538
+ * Result of loading and resolving tokens.
539
+ */
540
+ type LoadAndResolveResult = {
541
+ /** The loaded token trees */
542
+ trees: TokenTree[];
543
+ /** Resolved tokens after reference resolution */
544
+ resolved: ResolvedTokens;
545
+ /** Modifier metadata for CSS selector generation */
546
+ modifiers: ModifierMeta[];
547
+ /** Any errors that occurred */
548
+ errors: PipelineResult["errors"];
549
+ };
550
+ /**
551
+ * Core token processing pipeline that handles loading, validation, and resolution.
552
+ *
553
+ * This pipeline:
554
+ * 1. Loads token trees from resolver document or memory
555
+ * 2. Flattens trees into a single structure
556
+ * 3. Validates tokens for correctness
557
+ * 4. Resolves all token references
558
+ *
559
+ * For resolver sources, loads ALL contexts (not just default) and returns
560
+ * modifier metadata needed for CSS selector generation.
561
+ *
562
+ * @param source - The source of tokens to process (resolver or memory)
563
+ * @returns Processed tokens with modifier metadata and any errors
564
+ *
565
+ * @example
566
+ * const result = await loadAndResolveTokens({
567
+ * type: "resolver",
568
+ * resolverPath: "tokens.resolver.json",
569
+ * config
570
+ * });
571
+ * // result.trees - all token trees (base + modifier contexts)
572
+ * // result.modifiers - metadata for CSS selectors
573
+ */
574
+ declare function loadAndResolveTokens(source: TokenPipelineSource): Promise<LoadAndResolveResult>;
575
+
576
+ type ConvertedToken<T extends TokenType = TokenType> = ResolvedToken<T> & {
577
+ $cssProperties: CSSProperties<T>;
578
+ };
579
+ type ConvertedTokens = {
580
+ [lookupKey: string]: ConvertedToken | NodeMetadata;
581
+ };
582
+ /**
583
+ * Tokens that have been converted to CSS properties, organized by context.
584
+ * Each context (e.g., "default", "dark") maps to its converted tokens.
585
+ */
586
+ type NormalizedConvertedTokens = {
587
+ [context: string]: ConvertedTokens;
588
+ };
589
+ type CSSProperties<T extends TokenType> = T extends SimpleTokenType ? SimpleCSSProperties : T extends AlwaysDecomposedType ? AlwaysDecomposedProperties : T extends "border" ? CSSBorderProperties : T extends "shadow" ? CSSShadowProperties : T extends "gradient" ? CSSGradientProperties : T extends "transition" ? CSSTransitionProperties : T extends StructuralCompositeType ? SimpleCSSProperties : never;
590
+ type SimpleCSSProperties = {
591
+ value: string | number;
592
+ /** Feature queries for progressive enhancement (e.g., P3 colors). */
593
+ featureValues?: Array<{
594
+ query: string;
595
+ value: string;
596
+ }>;
597
+ };
598
+ type AlwaysDecomposedProperties = CSSTypographyProperties;
599
+ type CSSTypographyProperties = {
600
+ "font-family": string;
601
+ "font-size": string;
602
+ "font-weight"?: number | string;
603
+ "letter-spacing"?: string;
604
+ "line-height"?: number | string;
605
+ };
606
+ type CSSBorderProperties = {
607
+ value: string;
608
+ };
609
+ type CSSShadowProperties = {
610
+ value: string;
611
+ };
612
+ type CSSGradientProperties = {
613
+ value: string;
614
+ };
615
+ type CSSTransitionProperties = {
616
+ value: string;
617
+ };
618
+
619
+ /**
620
+ * Processes and converts token trees into CSS-ready format.
621
+ * This pipeline:
622
+ * 1. Processes trees with resolved tokens to create a unified structure
623
+ * 2. Normalizes tokens into a context-based organization
624
+ * 3. Converts tokens to their CSS representations with properties
625
+ *
626
+ *
627
+ * @param trees - The token trees to process
628
+ * @param resolved - The resolved tokens for processing
629
+ * @param config - The sugarcube configuration
630
+ * @param validationErrors - Optional array of validation errors. Tokens with validation errors will be filtered out before conversion.
631
+ * @returns The processed and converted tokens ready for CSS generation
632
+ *
633
+ * @example
634
+ * const convertedTokens = await processAndConvertTokens(trees, resolved, config);
635
+ * // convertedTokens = { "default": { "token.path": { $cssProperties: {...} } }, "dark": {...} }
636
+ */
637
+ declare function processAndConvertTokens(trees: TokenTree[], resolved: ResolvedTokens, config: InternalConfig, validationErrors?: ValidationError[]): Promise<NormalizedConvertedTokens>;
638
+
639
+ /**
640
+ * Generate CSS variable files from converted tokens.
641
+ *
642
+ * @param convertedTokens - The normalized and converted tokens
643
+ * @param config - The configuration object
644
+ * @param modifiers - Optional modifier metadata for generating per-modifier attribute selectors
645
+ * @returns Array of CSS file outputs
646
+ */
647
+ declare function generateCSSVariables(convertedTokens: NormalizedConvertedTokens, config: InternalConfig, modifiers?: ModifierMeta[]): Promise<CSSFileOutput>;
648
+
649
+ type CSSObject = Record<string, string | number | undefined>;
650
+ /**
651
+ * Clears the token matching cache.
652
+ * Call this when tokens change (e.g., on hot reload in dev mode).
653
+ */
654
+ declare function clearMatchCache(): void;
655
+ /**
656
+ * Converts a utilities configuration into UnoCSS dynamic rules.
657
+ *
658
+ * @param utilitiesConfig - The utilities configuration from sugarcube.config
659
+ * @param tokens - The converted tokens to generate rules for
660
+ * @returns Array of UnoCSS dynamic rules [pattern, handler]
661
+ */
662
+ declare function convertConfigToUnoRules(utilitiesConfig: UtilitiesConfig, tokens: NormalizedConvertedTokens): Array<[RegExp, (m: RegExpMatchArray) => CSSObject]>;
663
+
664
+ /**
665
+ * Performance monitor for tracking memory usage and watcher events.
666
+ * Only active when SUGARCUBE_PERF=true environment variable is set.
667
+ */
668
+ declare class PerfMonitor implements Disposable {
669
+ #private;
670
+ private defaultFlush;
671
+ constructor(defaultFlush?: (message: string) => undefined);
672
+ log(message: string, data?: Record<string, unknown>): void;
673
+ trackWatcherEvent(file: string, moduleGraphSize: number): void;
674
+ logWatcherSetup(pattern: string, dir: string): void;
675
+ logModuleGraphStats(modules: number, urls: number, context: string): void;
676
+ startMemoryMonitor(): void;
677
+ stopMemoryMonitor(): void;
678
+ [Symbol.dispose](): void;
679
+ }
680
+
681
+ /**
682
+ * Instrumentation for tracking function call counts and execution times.
683
+ * Only active when DEBUG=true environment variable is set.
684
+ * Inspired by Tailwind CSS instrumentation.
685
+ */
686
+ declare class Instrumentation implements Disposable {
687
+ #private;
688
+ private defaultFlush;
689
+ constructor(defaultFlush?: (message: string) => undefined);
690
+ hit(label: string): void;
691
+ start(label: string): void;
692
+ end(label: string): void;
693
+ report(flush?: (message: string) => undefined): void;
694
+ [Symbol.dispose](): void;
695
+ }
696
+
697
+ /**
698
+ * Writes CSS files to disk, creating directories as needed.
699
+ *
700
+ * @param output - Array of CSS file outputs to write
701
+ * @returns The original output array
702
+ * @throws Error if file writing fails
703
+ */
704
+ declare function writeCSSVariablesToDisk(output: CSSFileOutput): Promise<CSSFileOutput>;
705
+ /**
706
+ * Writes utility CSS files to disk, creating directories as needed.
707
+ *
708
+ * @param output - The CSS file output to write
709
+ * @returns The CSS file output that was written
710
+ * @throws Error if file writing fails
711
+ */
712
+ declare function writeCSSUtilitiesToDisk(output: CSSFileOutput): Promise<CSSFileOutput>;
713
+
714
+ declare const userConfigSchema: z.ZodObject<{
715
+ resolver: z.ZodOptional<z.ZodString>;
716
+ transforms: z.ZodOptional<z.ZodObject<{
717
+ fluid: z.ZodOptional<z.ZodObject<{
718
+ min: z.ZodNumber;
719
+ max: z.ZodNumber;
720
+ }, "strip", z.ZodTypeAny, {
721
+ min: number;
722
+ max: number;
723
+ }, {
724
+ min: number;
725
+ max: number;
726
+ }>>;
727
+ colorFallbackStrategy: z.ZodOptional<z.ZodEnum<["native", "polyfill"]>>;
728
+ }, "strip", z.ZodTypeAny, {
729
+ fluid?: {
730
+ min: number;
731
+ max: number;
732
+ } | undefined;
733
+ colorFallbackStrategy?: "native" | "polyfill" | undefined;
734
+ }, {
735
+ fluid?: {
736
+ min: number;
737
+ max: number;
738
+ } | undefined;
739
+ colorFallbackStrategy?: "native" | "polyfill" | undefined;
740
+ }>>;
741
+ output: z.ZodOptional<z.ZodObject<{
742
+ cssRoot: z.ZodOptional<z.ZodString>;
743
+ variables: z.ZodOptional<z.ZodString>;
744
+ variablesFilename: z.ZodOptional<z.ZodString>;
745
+ utilities: z.ZodOptional<z.ZodString>;
746
+ utilitiesFilename: z.ZodOptional<z.ZodString>;
747
+ cube: z.ZodOptional<z.ZodString>;
748
+ components: z.ZodOptional<z.ZodString>;
749
+ themeAttribute: z.ZodOptional<z.ZodString>;
750
+ defaultContext: z.ZodOptional<z.ZodString>;
751
+ }, "strip", z.ZodTypeAny, {
752
+ defaultContext?: string | undefined;
753
+ components?: string | undefined;
754
+ cssRoot?: string | undefined;
755
+ variables?: string | undefined;
756
+ variablesFilename?: string | undefined;
757
+ utilities?: string | undefined;
758
+ utilitiesFilename?: string | undefined;
759
+ cube?: string | undefined;
760
+ themeAttribute?: string | undefined;
761
+ }, {
762
+ defaultContext?: string | undefined;
763
+ components?: string | undefined;
764
+ cssRoot?: string | undefined;
765
+ variables?: string | undefined;
766
+ variablesFilename?: string | undefined;
767
+ utilities?: string | undefined;
768
+ utilitiesFilename?: string | undefined;
769
+ cube?: string | undefined;
770
+ themeAttribute?: string | undefined;
771
+ }>>;
772
+ utilities: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodObject<{
773
+ source: z.ZodString;
774
+ directions: z.ZodOptional<z.ZodUnion<[z.ZodEnum<["top", "right", "bottom", "left", "x", "y", "full", "all"]>, z.ZodArray<z.ZodEnum<["top", "right", "bottom", "left", "x", "y", "full", "all"]>, "many">]>>;
775
+ prefix: z.ZodOptional<z.ZodString>;
776
+ stripDuplicates: z.ZodOptional<z.ZodBoolean>;
777
+ }, "strip", z.ZodTypeAny, {
778
+ source: string;
779
+ directions?: "top" | "right" | "bottom" | "left" | "x" | "y" | "full" | "all" | ("top" | "right" | "bottom" | "left" | "x" | "y" | "full" | "all")[] | undefined;
780
+ prefix?: string | undefined;
781
+ stripDuplicates?: boolean | undefined;
782
+ }, {
783
+ source: string;
784
+ directions?: "top" | "right" | "bottom" | "left" | "x" | "y" | "full" | "all" | ("top" | "right" | "bottom" | "left" | "x" | "y" | "full" | "all")[] | undefined;
785
+ prefix?: string | undefined;
786
+ stripDuplicates?: boolean | undefined;
787
+ }>, z.ZodArray<z.ZodObject<{
788
+ source: z.ZodString;
789
+ directions: z.ZodOptional<z.ZodUnion<[z.ZodEnum<["top", "right", "bottom", "left", "x", "y", "full", "all"]>, z.ZodArray<z.ZodEnum<["top", "right", "bottom", "left", "x", "y", "full", "all"]>, "many">]>>;
790
+ prefix: z.ZodOptional<z.ZodString>;
791
+ stripDuplicates: z.ZodOptional<z.ZodBoolean>;
792
+ }, "strip", z.ZodTypeAny, {
793
+ source: string;
794
+ directions?: "top" | "right" | "bottom" | "left" | "x" | "y" | "full" | "all" | ("top" | "right" | "bottom" | "left" | "x" | "y" | "full" | "all")[] | undefined;
795
+ prefix?: string | undefined;
796
+ stripDuplicates?: boolean | undefined;
797
+ }, {
798
+ source: string;
799
+ directions?: "top" | "right" | "bottom" | "left" | "x" | "y" | "full" | "all" | ("top" | "right" | "bottom" | "left" | "x" | "y" | "full" | "all")[] | undefined;
800
+ prefix?: string | undefined;
801
+ stripDuplicates?: boolean | undefined;
802
+ }>, "many">]>>>;
803
+ }, "strip", z.ZodTypeAny, {
804
+ resolver?: string | undefined;
805
+ transforms?: {
806
+ fluid?: {
807
+ min: number;
808
+ max: number;
809
+ } | undefined;
810
+ colorFallbackStrategy?: "native" | "polyfill" | undefined;
811
+ } | undefined;
812
+ utilities?: Record<string, {
813
+ source: string;
814
+ directions?: "top" | "right" | "bottom" | "left" | "x" | "y" | "full" | "all" | ("top" | "right" | "bottom" | "left" | "x" | "y" | "full" | "all")[] | undefined;
815
+ prefix?: string | undefined;
816
+ stripDuplicates?: boolean | undefined;
817
+ } | {
818
+ source: string;
819
+ directions?: "top" | "right" | "bottom" | "left" | "x" | "y" | "full" | "all" | ("top" | "right" | "bottom" | "left" | "x" | "y" | "full" | "all")[] | undefined;
820
+ prefix?: string | undefined;
821
+ stripDuplicates?: boolean | undefined;
822
+ }[]> | undefined;
823
+ output?: {
824
+ defaultContext?: string | undefined;
825
+ components?: string | undefined;
826
+ cssRoot?: string | undefined;
827
+ variables?: string | undefined;
828
+ variablesFilename?: string | undefined;
829
+ utilities?: string | undefined;
830
+ utilitiesFilename?: string | undefined;
831
+ cube?: string | undefined;
832
+ themeAttribute?: string | undefined;
833
+ } | undefined;
834
+ }, {
835
+ resolver?: string | undefined;
836
+ transforms?: {
837
+ fluid?: {
838
+ min: number;
839
+ max: number;
840
+ } | undefined;
841
+ colorFallbackStrategy?: "native" | "polyfill" | undefined;
842
+ } | undefined;
843
+ utilities?: Record<string, {
844
+ source: string;
845
+ directions?: "top" | "right" | "bottom" | "left" | "x" | "y" | "full" | "all" | ("top" | "right" | "bottom" | "left" | "x" | "y" | "full" | "all")[] | undefined;
846
+ prefix?: string | undefined;
847
+ stripDuplicates?: boolean | undefined;
848
+ } | {
849
+ source: string;
850
+ directions?: "top" | "right" | "bottom" | "left" | "x" | "y" | "full" | "all" | ("top" | "right" | "bottom" | "left" | "x" | "y" | "full" | "all")[] | undefined;
851
+ prefix?: string | undefined;
852
+ stripDuplicates?: boolean | undefined;
853
+ }[]> | undefined;
854
+ output?: {
855
+ defaultContext?: string | undefined;
856
+ components?: string | undefined;
857
+ cssRoot?: string | undefined;
858
+ variables?: string | undefined;
859
+ variablesFilename?: string | undefined;
860
+ utilities?: string | undefined;
861
+ utilitiesFilename?: string | undefined;
862
+ cube?: string | undefined;
863
+ themeAttribute?: string | undefined;
864
+ } | undefined;
865
+ }>;
866
+
867
+ export { type CSSFileOutput, type ColorFallbackStrategy, DEFAULT_CONFIG, type FluidConfig, Instrumentation, type InternalConfig, type ModifierMeta, type NormalizedConvertedTokens, PerfMonitor, type ResolvedTokens, type ResolverDiscoveryResult, type SugarcubeConfig, type TokenPipelineSource, type TokenTree, clearMatchCache, configFileExists, convertConfigToUnoRules, defineConfig, fillDefaults, findResolverDocument, generateCSSVariables, isNoConfigError, loadAndResolveTokens, loadInternalConfig, loadSugarcubeConfig, processAndConvertTokens, userConfigSchema, validateConfig, writeCSSUtilitiesToDisk, writeCSSVariablesToDisk };
package/dist/index.js ADDED
@@ -0,0 +1,32 @@
1
+ var Je=Object.defineProperty;var s=(e,t)=>Je(e,"name",{value:t,configurable:!0});import{existsSync as Xe}from"node:fs";import Ze,{readFile as le,mkdir as fe,writeFile as pe}from"node:fs/promises";import{pathToFileURL as Qe}from"node:url";import{relative as x,resolve as O,isAbsolute as F,dirname as z}from"pathe";import{glob as et}from"tinyglobby";import{z as f}from"zod";function tt(e){return e}s(tt,"defineConfig");const b={output:{cssRoot:"src/styles",variablesFilename:"tokens.variables.gen.css",utilitiesFilename:"utilities.gen.css",components:"src/components/ui",themeAttribute:"data-theme"},transforms:{fluid:{min:320,max:1200},colorFallbackStrategy:"native"}},u={LOAD:{NO_FILES_FOUND:s(e=>`No files found matching pattern: ${e}.`,"NO_FILES_FOUND"),INVALID_JSON:s((e,t)=>`Invalid JSON in file ${e}: ${t}`,"INVALID_JSON"),GLOB_ERROR:s((e,t)=>`Error resolving glob pattern ${e}: ${t}`,"GLOB_ERROR")},FLATTEN:{INVALID_TOKEN_NAME:s(e=>`Invalid token name "${e}": Token names cannot contain dots (.), curly braces ({,}), or other special characters`,"INVALID_TOKEN_NAME"),MISSING_DOLLAR_PREFIX:s(e=>`Token at ${e} is using 'value' or 'type' without the required '$' prefix. Use '$value' and '$type' instead.`,"MISSING_DOLLAR_PREFIX"),INVALID_TOKEN_NESTING:s(e=>`Token at "${e}" cannot contain child tokens or groups. Only metadata properties (starting with $) are allowed.`,"INVALID_TOKEN_NESTING"),COMPOSITE_TOKEN_MISSING_TYPE:s(e=>`Composite token at '${e}' is missing the required "$type" property. Composite tokens (tokens with object values) must specify their type to define their structure.`,"COMPOSITE_TOKEN_MISSING_TYPE"),CONFLICT_TOKEN_VS_GROUP:s(e=>`Conflict at "${e}": token vs group. A token cannot be replaced by a group (or vice versa).`,"CONFLICT_TOKEN_VS_GROUP"),CONFLICT_INCOMPATIBLE_TYPES:s((e,t,n)=>`Type conflict at "${n}": expected ${e}, got ${t}`,"CONFLICT_INCOMPATIBLE_TYPES")},METADATA:{COLLECTION_ERROR:s(e=>`Error collecting metadata: ${e}`,"COLLECTION_ERROR"),INVALID_EXTENSIONS:s(e=>`Invalid extensions at ${e}: expected object, got ${typeof e}`,"INVALID_EXTENSIONS"),INVALID_DESCRIPTION:s(e=>`Invalid description at ${e}: expected string, got ${typeof e}`,"INVALID_DESCRIPTION")},VALIDATE:{MISSING_TYPE:s(e=>`Token at '${e}' is missing the "$type" property`,"MISSING_TYPE"),UNKNOWN_TOKEN_TYPE:s((e,t)=>`Unknown token type '${e}' at ${t}. Valid types are: color, dimension, fontFamily, fontWeight, duration, cubicBezier, strokeStyle, border, transition, shadow, gradient, typography`,"UNKNOWN_TOKEN_TYPE"),INVALID_COLOR:s((e,t)=>`Invalid color at ${t}: '${e}'. Color should be a valid hex value or W3C color object`,"INVALID_COLOR"),INVALID_DIMENSION:s((e,t)=>`Invalid dimension at '${t}': ${e}. Dimensions should have a numeric value and unit, like { "value": 16, "unit": "px" }`,"INVALID_DIMENSION"),INVALID_DIMENSION_UNIT:s((e,t)=>`Invalid unit at ${t}': '${e}'. Unit must be either "px" or "rem"`,"INVALID_DIMENSION_UNIT"),INVALID_FONT_FAMILY:s((e,t)=>`Invalid font family at '${t}': ${e}. Should be a string or array of strings, like "Arial" or ["Arial", "sans-serif"]`,"INVALID_FONT_FAMILY"),INVALID_FONT_WEIGHT:s((e,t)=>`Invalid font weight at '${t}': ${e}. Should be a number between 1-1000 or a keyword like "thin", "light", "normal", "bold"`,"INVALID_FONT_WEIGHT"),INVALID_DURATION:s((e,t)=>`Invalid duration at '${t}': ${e}. Should be like { "value": 300, "unit": "ms" }`,"INVALID_DURATION"),INVALID_DURATION_UNIT:s((e,t)=>`Invalid unit at ${t}: "${e}". Unit must be "ms" or "s"`,"INVALID_DURATION_UNIT"),INVALID_CUBIC_BEZIER:s((e,t)=>`Invalid cubic bezier at ${t}: "${e}". Should be an array of 4 numbers between 0 and 1`,"INVALID_CUBIC_BEZIER"),INVALID_STROKE_STYLE:s((e,t)=>`Invalid stroke style at ${t}: "${e}". Should be "solid", "dashed", "dotted", etc.`,"INVALID_STROKE_STYLE"),INVALID_STROKE_LINE_CAP:s((e,t)=>`Invalid line cap at ${t}: "${e}". Should be one of: round, butt, square`,"INVALID_STROKE_LINE_CAP"),INVALID_BORDER:s((e,t)=>`Invalid border at ${t}: "${e}". Should have color, width, and style properties`,"INVALID_BORDER"),INVALID_SHADOW:s((e,t)=>`Invalid shadow at ${t}: "${e}". Should have color, offsetX, offsetY properties (blur and spread are optional)`,"INVALID_SHADOW"),INVALID_SHADOW_INSET:s((e,t)=>`Invalid inset value at ${t}: "${e}". Should be true or false`,"INVALID_SHADOW_INSET"),INVALID_TRANSITION:s((e,t)=>`Invalid transition at ${t}: "${e}". Should have duration, delay, and timingFunction properties`,"INVALID_TRANSITION"),INVALID_GRADIENT:s((e,t)=>`Invalid gradient at ${t}: "${e}". Should be an array of color stops with position values between 0 and 1`,"INVALID_GRADIENT"),INVALID_GRADIENT_STOP_POSITION:s((e,t)=>`Invalid gradient stop position at ${t}: "${e}". Position must be between 0 and 1`,"INVALID_GRADIENT_STOP_POSITION"),INVALID_TYPOGRAPHY:s((e,t)=>`Invalid typography at ${t}: "${e}". Should have fontFamily and fontSize (fontWeight, letterSpacing, and lineHeight are optional)`,"INVALID_TYPOGRAPHY"),MISSING_REQUIRED_PROPERTY:s((e,t)=>`Missing required property '${e}' at ${t}`,"MISSING_REQUIRED_PROPERTY"),INVALID_NUMBER:s((e,t)=>`Invalid number at ${t}: "${e}". Expected a number value`,"INVALID_NUMBER"),INVALID_ARRAY:s((e,t)=>`Invalid array at ${t}: "${e}". Expected an array value`,"INVALID_ARRAY"),MISSING_FLUID_CONFIG:s(e=>`Missing fluid configuration. Token at ${e} requires fluid viewport settings.`,"MISSING_FLUID_CONFIG"),INVALID_FLUID_DIMENSION:s((e,t)=>`Invalid fluid dimension at ${t}: "${e}". Fluid dimensions should have min and max values, like { "min": { "value": 16, "unit": "px" }, "max": { "value": 24, "unit": "px" } }`,"INVALID_FLUID_DIMENSION"),INVALID_VIEWPORT_CONFIG:s((e,t)=>`Invalid viewport configuration at ${t}: "${e}". Viewport config should have min and max dimension values`,"INVALID_VIEWPORT_CONFIG"),MISMATCHED_UNITS:s((e,t,n)=>`Mismatched units at ${n}: min uses '${e}', max uses '${t}'. Both values must use the same unit`,"MISMATCHED_UNITS"),INVALID_FLUID_VALUE_RANGE:s(e=>`Invalid fluid value range at ${e}: min value must be less than max value`,"INVALID_FLUID_VALUE_RANGE"),INVALID_TOKEN_TYPE:s((e,t,n)=>`Invalid token type at ${n}: expected ${e}, got ${t}`,"INVALID_TOKEN_TYPE"),INVALID_TYPE:s((e,t,n)=>`Expected ${e}, received ${typeof t} at ${n}`,"INVALID_TYPE"),INVALID_ENUM_VALUE:s((e,t,n)=>`Expected value to be one of [${e.join(", ")}], but got ${String(t)} at ${n}`,"INVALID_ENUM_VALUE")},RESOLVE:{CIRCULAR_REFERENCE:s((e,t)=>`Circular reference detected: ${e} -> ${t}`,"CIRCULAR_REFERENCE"),REFERENCE_NOT_FOUND:s((e,t)=>`Reference not found: ${e} in ${t}. Does ${e} exist?`,"REFERENCE_NOT_FOUND"),TYPE_MISMATCH:s(e=>`Type mismatch in ${e}`,"TYPE_MISMATCH")},GENERATE:{INVALID_CSS_VALUE:s((e,t)=>`Invalid CSS value for property '${e}': ${t}`,"INVALID_CSS_VALUE"),INVALID_VARIABLE_NAME:s((e,t)=>`Invalid CSS variable name at '${e}': ${t}`,"INVALID_VARIABLE_NAME")},CONFIG:{INVALID_JSON:s(e=>`Invalid JSON in config file: ${e}`,"INVALID_JSON"),INVALID_CONFIG:s((e,t)=>`Invalid configuration at ${e}: ${t}`,"INVALID_CONFIG"),DUPLICATE_FILENAMES:s((e,t)=>`Duplicate filename "${e}":
2
+ ${t.map(n=>` - ${n}`).join(`
3
+ `)}`,"DUPLICATE_FILENAMES"),FILE_NOT_FOUND:s(e=>e==="sugarcube.config.ts"?"Cannot find sugarcube config file. Please ensure you have a valid sugarcube.config.ts file in your project root.":`Cannot find sugarcube config file at "${e}". Please check the path and file permissions.`,"FILE_NOT_FOUND"),MULTIPLE_RESOLVERS_FOUND:s(e=>`Multiple resolver files found:
4
+ ${e.map(t=>` - ${t}`).join(`
5
+ `)}
6
+
7
+ Please specify which one to use:
8
+ 1. Create sugarcube.config.ts with resolver field
9
+ 2. Use --resolver flag (generate command only)`,"MULTIPLE_RESOLVERS_FOUND"),NO_CONFIG_OR_RESOLVER:s(()=>`No configuration found. Either:
10
+ 1. Run: npx @sugarcube-sh/cli init
11
+ 2. Create a .resolver.json file
12
+ 3. Create a sugarcube.config.ts file`,"NO_CONFIG_OR_RESOLVER")},UTILITIES:{RESERVED_PREFIX:s((e,t)=>`Cannot use reserved prefix "${e}" for ${t} token type. This prefix is reserved for default utility classes. Please use a custom prefix instead.`,"RESERVED_PREFIX"),DUPLICATE_CLASS_NAME:s((e,t)=>`Ambiguous utility class "${e}" would be generated from multiple token paths: ${t.join(", ")}. This would make it impossible to know which token value should be used when this class is applied in HTML. To fix this, configure one or more paths with custom prefixes to make the intent clear.`,"DUPLICATE_CLASS_NAME"),INVALID_PROPERTY_MAPPING:s(e=>`Invalid property mapping for ${e} token type. When mapping multiple properties, each mapping must include a unique prefix to avoid class name collisions.`,"INVALID_PROPERTY_MAPPING"),DUPLICATE_PREFIX:s((e,t)=>`Duplicate prefix "${e}" found in property mappings for ${t} token type. Each property mapping must have a unique prefix to avoid class name collisions.`,"DUPLICATE_PREFIX"),MISSING_SOURCE:s(e=>`Utility config for '${e}' must have a valid 'source' property`,"MISSING_SOURCE"),INVALID_SOURCE_PATTERN:s((e,t)=>`Utility config for '${e}' has invalid source pattern '${t}'. Only patterns ending with '.*' are supported (e.g., 'color.*', 'font.weight.*').`,"INVALID_SOURCE_PATTERN"),INVALID_DIRECTIONS:s(e=>`Utility config for '${e}' must have 'directions' as an array`,"INVALID_DIRECTIONS"),INVALID_CONFIG_OBJECT:"utilitiesConfig must be an object",INVALID_TOKENS_OBJECT:"tokens must be an object"},RESOLVER:{FILE_NOT_FOUND:s(e=>`Cannot read resolver file at "${e}". Please check the path and file permissions.`,"FILE_NOT_FOUND"),INVALID_JSON:s(e=>`Invalid JSON in resolver file: ${e}`,"INVALID_JSON"),INVALID_REFERENCE:s(e=>`Invalid reference "${e}". References must use format #/sets/<name> or #/modifiers/<name>.`,"INVALID_REFERENCE"),INVALID_SOURCE_REFERENCE:s(e=>`Invalid source reference "${e}". Sources can only reference sets (#/sets/<name>), not modifiers.`,"INVALID_SOURCE_REFERENCE"),UNDEFINED_SET:s(e=>`Reference to undefined set "${e}". Define it in the "sets" section first.`,"UNDEFINED_SET"),UNDEFINED_MODIFIER:s(e=>`Reference to undefined modifier "${e}". Define it in the "modifiers" section first.`,"UNDEFINED_MODIFIER"),CIRCULAR_REFERENCE:s(e=>`Circular reference detected at "${e}".`,"CIRCULAR_REFERENCE"),EXTERNAL_FILE_NOT_FOUND:s(e=>`Referenced file not found: ${e}`,"EXTERNAL_FILE_NOT_FOUND"),EXTERNAL_FILE_ERROR:s((e,t)=>`Failed to load "${e}": ${t}`,"EXTERNAL_FILE_ERROR"),INVALID_JSON_POINTER:s((e,t)=>`Invalid JSON pointer "${e}": ${t}`,"INVALID_JSON_POINTER"),DUPLICATE_NAME:s(e=>`Duplicate name "${e}" in resolutionOrder.`,"DUPLICATE_NAME"),MODIFIER_NEEDS_CONTEXTS:"Modifier must have at least one context defined.",MODIFIER_SINGLE_CONTEXT:"Modifier has only one context. Consider using a set instead, or add more contexts.",INVALID_DEFAULT:s((e,t)=>`Default context "${e}" is not defined. Valid contexts: ${t.join(", ")}`,"INVALID_DEFAULT"),UNKNOWN_MODIFIER:s(e=>`Unknown modifier "${e}".`,"UNKNOWN_MODIFIER"),INVALID_CONTEXT:s((e,t,n)=>`Invalid context "${e}" for modifier "${t}". Valid contexts: ${n.join(", ")}`,"INVALID_CONTEXT"),MISSING_REQUIRED_INPUT:s(e=>`Missing required input for modifier "${e}". No default value is defined.`,"MISSING_REQUIRED_INPUT"),INVALID_INPUT_TYPE:s(e=>`Input for modifier "${e}" must be a string.`,"INVALID_INPUT_TYPE"),MALFORMED_REFERENCE:s((e,t)=>`Malformed source reference: { "${e}": "${t}" }. Did you mean { "$ref": "${t}" }?`,"MALFORMED_REFERENCE"),RESOLVER_AS_TOKEN_SOURCE:s(e=>`File "${e}" is a resolver document, not a token file. Resolver documents (version: "2025.10") cannot be used as token sources. Did you mean to reference a specific token file instead?`,"RESOLVER_AS_TOKEN_SOURCE")}};async function J(e){const n=await et(["**/*.resolver.json"],{cwd:e,onlyFiles:!0,absolute:!0,ignore:["**/node_modules/**","**/dist/**","**/build/**","**/out/**","**/.git/**","**/.next/**","**/.nuxt/**","**/.astro/**","**/.cache/**","**/.turbo/**","**/.vercel/**","**/.svelte-kit/**"]});if(n.length===0)return{found:"none"};const[r]=n;return n.length===1&&r?{found:"one",path:x(process.cwd(),r)}:{found:"multiple",paths:n.map(o=>x(process.cwd(),o))}}s(J,"findResolverDocument");function C(e){const t=e.output?.cssRoot??b.output.cssRoot,n={resolver:e.resolver,transforms:{fluid:e.transforms?.fluid??b.transforms.fluid,colorFallbackStrategy:e.transforms?.colorFallbackStrategy??b.transforms.colorFallbackStrategy},output:{cssRoot:t,variables:e.output?.variables??`${t}/global`,variablesFilename:e.output?.variablesFilename??b.output.variablesFilename,utilities:e.output?.utilities??`${t}/utilities`,utilitiesFilename:e.output?.utilitiesFilename??b.output.utilitiesFilename,cube:e.output?.cube??t,themeAttribute:e.output?.themeAttribute??b.output.themeAttribute,defaultContext:e.output?.defaultContext}};return(e.output?.components!==void 0||b.output.components!==void 0)&&(n.output.components=e.output?.components??b.output.components),e.utilities&&(n.utilities=e.utilities),n}s(C,"fillDefaults");const de=f.object({min:f.number(),max:f.number()}),me=f.object({source:f.string(),directions:f.union([f.enum(["top","right","bottom","left","x","y","full","all"]),f.array(f.enum(["top","right","bottom","left","x","y","full","all"]))]).optional(),prefix:f.string().optional(),stripDuplicates:f.boolean().optional()}),he=f.union([me,f.array(me)]),nt=f.object({resolver:f.string().optional(),transforms:f.object({fluid:de.optional(),colorFallbackStrategy:f.enum(["native","polyfill"]).optional()}).optional(),output:f.object({cssRoot:f.string().optional(),variables:f.string().optional(),variablesFilename:f.string().optional(),utilities:f.string().optional(),utilitiesFilename:f.string().optional(),cube:f.string().optional(),components:f.string().optional(),themeAttribute:f.string().optional(),defaultContext:f.string().optional()}).optional(),utilities:f.record(f.string(),he).optional()}),rt=f.object({resolver:f.string().optional(),transforms:f.object({fluid:de,colorFallbackStrategy:f.enum(["native","polyfill"])}),output:f.object({cssRoot:f.string(),variables:f.string().optional(),variablesFilename:f.string(),utilities:f.string().optional(),utilitiesFilename:f.string(),cube:f.string().optional(),components:f.string().optional(),themeAttribute:f.string(),defaultContext:f.string().optional()}),utilities:f.record(f.string(),he).optional()});function X(e){const t=nt.safeParse(e);if(!t.success){const n=t.error.errors.map(r=>{const o=r.path.join(".");return u.CONFIG.INVALID_CONFIG(o||"root",r.message)});throw new Error(n.join(`
13
+ `))}return t.data}s(X,"validateSugarcubeConfig");function Z(e){const t=rt.safeParse(e);if(!t.success){const n=t.error.errors.map(r=>{const o=r.path.join(".");return u.CONFIG.INVALID_CONFIG(o||"root",r.message)});throw new Error(n.join(`
14
+ `))}return t.data}s(Z,"validateInternalConfig");function ot(e){const t=X(e),n=C(t);return Z(n)}s(ot,"validateConfig");function st(e){return e instanceof Error&&e.message===u.CONFIG.NO_CONFIG_OR_RESOLVER()}s(st,"isNoConfigError");function Q(e="sugarcube.config"){const t=[".ts",".js"],n=process.cwd();for(const r of t){const o=O(n,`${e}${r}`);if(Xe(o))return o}return null}s(Q,"findConfigFile");function it(e="sugarcube.config"){return Q(e)!==null}s(it,"configFileExists");async function at(e){try{if(typeof globalThis.Bun<"u"){const i=Qe(e).href,c=await new Function("url","return import(url)")(i);if(c&&typeof c=="object"&&"default"in c)return c.default;throw new Error(u.CONFIG.INVALID_CONFIG("root","Config file must export a default object"))}const{createJiti:n}=await import("jiti"),o=await n(import.meta.url,{interopDefault:!0}).import(e);return o&&typeof o=="object"&&"default"in o?o.default:o}catch(t){throw t instanceof Error?new Error(u.CONFIG.INVALID_CONFIG("root",t.message)):t}}s(at,"loadTSConfig");async function Ie(e){if(e.endsWith(".ts")||e.endsWith(".js"))return await at(e);const n=await Ze.readFile(e,"utf-8");return JSON.parse(n)}s(Ie,"loadConfigFile");function ct(e){if(e)return O(process.cwd(),e);const t=Q();if(!t)throw new Error(u.CONFIG.FILE_NOT_FOUND("sugarcube.config.ts"));return t}s(ct,"resolveConfigPath");async function ut(e){const t=ct(e);try{const n=await Ie(t);return{config:X(n),configPath:t}}catch(n){throw n instanceof Error&&"code"in n&&n.code==="ENOENT"?new Error(u.CONFIG.FILE_NOT_FOUND(t)):n instanceof SyntaxError?new Error(u.CONFIG.INVALID_JSON(n.message)):n}}s(ut,"loadSugarcubeConfig");async function lt(e){const t=e?O(process.cwd(),e):Q();if(t)try{const r=await Ie(t),o=X(r);if(!o.resolver){const c=await J(process.cwd());if(c.found==="one")o.resolver=c.path;else{if(c.found==="multiple")throw new Error(u.CONFIG.MULTIPLE_RESOLVERS_FOUND(c.paths));if(c.found==="none")throw new Error(u.CONFIG.NO_CONFIG_OR_RESOLVER())}}const i=C(o);return{config:Z(i),configPath:t}}catch(r){throw r instanceof Error&&"code"in r&&r.code==="ENOENT"?new Error(u.CONFIG.FILE_NOT_FOUND(t)):r instanceof SyntaxError?new Error(u.CONFIG.INVALID_JSON(r.message)):r}const n=await J(process.cwd());if(n.found==="one"){const r={resolver:n.path},o=C(r);return{config:Z(o),configPath:n.path}}throw n.found==="multiple"?new Error(u.CONFIG.MULTIPLE_RESOLVERS_FOUND(n.paths)):new Error(u.CONFIG.NO_CONFIG_OR_RESOLVER())}s(lt,"loadInternalConfig");function h(e){return typeof e=="string"&&e.startsWith("{")&&e.endsWith("}")}s(h,"isReference$1");function ft(e){if(typeof e!="object"||e===null||!("$value"in e))return!1;const t=e.$value;return typeof t=="object"&&t!==null&&!Array.isArray(t)&&Object.keys(t).length>0}s(ft,"isCompositeToken");function pt(e){return e.$type==="typography"}s(pt,"isTypographyToken");function ee(e){return typeof e=="object"&&e!==null&&"$value"in e}s(ee,"isTokenNode");function dt(e,t,n){for(const[r,o]of Object.entries(t.tokens)){const i=e.tokens[r];if(!ee(o)){if(i&&ee(i)){const d=i;n.push({path:d.$path,source:d.$source,message:u.FLATTEN.CONFLICT_TOKEN_VS_GROUP(d.$path)});continue}e.tokens[r]=o;continue}if(!i){e.tokens[r]=o;continue}if(!ee(i)){n.push({path:o.$path,source:o.$source,message:u.FLATTEN.CONFLICT_TOKEN_VS_GROUP(o.$path)});continue}const c=o,l=i,p=!!c.$type,m=!!l.$type;if(p&&m&&c.$type!==l.$type){n.push({path:c.$path,source:c.$source,message:u.FLATTEN.CONFLICT_INCOMPATIBLE_TYPES(String(l.$type??"unknown"),String(c.$type??"unknown"),c.$path)});continue}e.tokens[r]=o}for(const[r,o]of t.pathIndex)e.pathIndex.set(r,o)}s(dt,"mergeFlattenedInto");function mt(e){if(typeof e!="object"||e===null||"$value"in e)return!1;const t="value"in e,n="type"in e;if(t&&n)return!0;if(t){const r=e.value;return typeof r=="string"||typeof r=="number"||Array.isArray(r)}return!1}s(mt,"looksLikeUnprefixedToken");function ht(e,t){const n={tokens:{},pathIndex:new Map},r=[];function o(a=[]){const c=[];return t.context&&c.push(t.context),a.length>0&&c.push(a.join(".")),c.length>0?c.join("."):""}s(o,"createLookupKey"),(e.$description||e.$extensions)&&(n.tokens[o()]={$description:e.$description,$extensions:e.$extensions});function i(a,c=[],l){if(c.join("."),c.length>0){const d=o(c);n.tokens[d]={$description:a.$description,$extensions:a.$extensions,$path:c.join("."),$source:{context:t.context,sourcePath:t.sourcePath}}}const p=Object.keys(a).filter(d=>!d.startsWith("$")),m=a.$type||l;for(const d of p){const I=a[d],E=[...c,d],$=E.join(".");if(mt(I)){r.push({path:$,source:t,message:u.FLATTEN.MISSING_DOLLAR_PREFIX($)});continue}if(d.includes(".")||d.includes("{")||d.includes("}")){r.push({path:$,source:t,message:u.FLATTEN.INVALID_TOKEN_NAME(d)});continue}if("$value"in I){if(Object.keys(I).filter(ze=>!ze.startsWith("$")).length>0){r.push({path:$,source:t,message:u.FLATTEN.INVALID_TOKEN_NESTING($)});continue}if(ft(I)&&!I.$type&&!m){r.push({path:$,source:t,message:u.FLATTEN.COMPOSITE_TOKEN_MISSING_TYPE($)});continue}const ue=o(E),q=E.join(".");n.tokens[ue]={...I,...I.$type||m?{$type:I.$type||m}:{},$path:q,$source:{context:t.context,sourcePath:t.sourcePath},$originalPath:q},n.pathIndex.set(q,ue)}else i(I,E,m)}}return s(i,"processNode"),i(e),{tokens:n,errors:r}}s(ht,"flattenTree");function It(e){const t={tokens:{},pathIndex:new Map},n=[];for(const r of e){const{tokens:o,errors:i}=ht(r.tokens,{context:r.context,sourcePath:r.sourcePath});n.push(...i),dt(t,o,n)}return{tokens:t,errors:n}}s(It,"flatten");const V=f.string().min(1,"Name cannot be empty").refine(e=>!e.startsWith("$"),"Names must not start with '$' (reserved prefix)").refine(e=>!e.includes("{"),"Names must not contain '{'").refine(e=>!e.includes("}"),"Names must not contain '}'").refine(e=>!e.includes("."),"Names must not contain '.'"),Ee=f.object({$ref:f.string().min(1,"$ref cannot be empty")}).passthrough(),te=f.union([Ee,f.record(f.string(),f.unknown())]),Et=f.object({description:f.string().optional(),sources:f.array(te),$extensions:f.record(f.string(),f.unknown()).optional()}),ye=f.record(f.string(),f.array(te)),yt=f.object({description:f.string().optional(),contexts:ye,default:f.string().optional(),$extensions:f.record(f.string(),f.unknown()).optional()}).refine(e=>Object.keys(e.contexts).length>=1,"Modifier must have at least 1 context"),$t=f.object({type:f.literal("set"),name:V,sources:f.array(te),description:f.string().optional(),$extensions:f.record(f.string(),f.unknown()).optional()}),gt=f.object({type:f.literal("modifier"),name:V,contexts:ye,description:f.string().optional(),default:f.string().optional(),$extensions:f.record(f.string(),f.unknown()).optional()}).refine(e=>Object.keys(e.contexts).length>=1,"Modifier must have at least 1 context"),Nt=f.union([Ee,$t,gt]),Tt=f.record(V,Et),St=f.record(V,yt),bt=f.object({version:f.literal("2025.10"),name:f.string().optional(),description:f.string().optional(),sets:Tt.optional(),modifiers:St.optional(),resolutionOrder:f.array(Nt),$schema:f.string().optional(),$extensions:f.record(f.string(),f.unknown()).optional(),$defs:f.record(f.string(),f.unknown()).optional()});function R(e){return typeof e=="object"&&e!==null&&"$ref"in e&&typeof e.$ref=="string"}s(R,"isReference");function $e(e){return typeof e=="object"&&e!==null&&"type"in e&&e.type==="set"}s($e,"isInlineSet");function _(e){return typeof e=="object"&&e!==null&&"type"in e&&e.type==="modifier"}s(_,"isInlineModifier");async function Ot(e){const t=F(e)?e:O(process.cwd(),e),n=await At(t);if(n.error)return{document:k(),errors:[n.error]};const r=Rt(n.content);if(r.error)return{document:k(),errors:[r.error]};const o=Dt(r.data);if(o.errors.length>0)return{document:k(),errors:o.errors};const i=[];return _t(o.document,i),{document:o.document,errors:i}}s(Ot,"parseResolverDocument");async function At(e){try{return{content:await le(e,"utf-8")}}catch{return{error:{path:e,message:u.RESOLVER.FILE_NOT_FOUND(e)}}}}s(At,"loadFile");function Rt(e){try{return{data:JSON.parse(e)}}catch(t){const n=t instanceof Error?t.message:"Unknown error";return{error:{path:"resolver",message:u.RESOLVER.INVALID_JSON(n)}}}}s(Rt,"parseJson");function Dt(e){const t=bt.safeParse(e);if(!t.success){const n=t.error.errors.map(r=>{const o=r.path.join(".")||"resolver";return{path:o,message:`Resolver error at ${o}: ${r.message}. See https://sugarcube.sh/docs/resolver`}});return{document:k(),errors:n}}return{document:t.data,errors:[]}}s(Dt,"validateSchema$1");function _t(e,t){Lt(e,t),vt(e,t),xt(e,t)}s(_t,"validateDocument");function Lt(e,t){if(e.modifiers)for(const[n,r]of Object.entries(e.modifiers))ge(r,`modifiers.${n}`,t);for(let n=0;n<e.resolutionOrder.length;n++){const r=e.resolutionOrder[n];_(r)&&ge(r,`resolutionOrder[${n}]`,t)}}s(Lt,"validateModifierContexts");function ge(e,t,n){const r=Object.keys(e.contexts).length;if(r===0){n.push({path:`${t}.contexts`,message:u.RESOLVER.MODIFIER_NEEDS_CONTEXTS});return}r===1&&n.push({path:`${t}.contexts`,message:u.RESOLVER.MODIFIER_SINGLE_CONTEXT}),e.default&&!e.contexts[e.default]&&n.push({path:`${t}.default`,message:u.RESOLVER.INVALID_DEFAULT(e.default,Object.keys(e.contexts))})}s(ge,"checkModifierContexts");function vt(e,t){const n=new Set;for(let r=0;r<e.resolutionOrder.length;r++){const o=e.resolutionOrder[r];if(R(o))continue;const i=o.name;n.has(i)&&t.push({path:`resolutionOrder[${r}].name`,message:u.RESOLVER.DUPLICATE_NAME(i)}),n.add(i)}}s(vt,"validateNameUniqueness");function xt(e,t){for(let n=0;n<e.resolutionOrder.length;n++){const r=e.resolutionOrder[n];if(R(r))Ft(r.$ref,`resolutionOrder[${n}].$ref`,e,t);else if($e(r))w(r.sources,`resolutionOrder[${n}].sources`,t);else if(_(r))for(const[o,i]of Object.entries(r.contexts))w(i,`resolutionOrder[${n}].contexts.${o}`,t)}if(e.sets)for(const[n,r]of Object.entries(e.sets))w(r.sources,`sets.${n}.sources`,t);if(e.modifiers)for(const[n,r]of Object.entries(e.modifiers))for(const[o,i]of Object.entries(r.contexts))w(i,`modifiers.${n}.contexts.${o}`,t)}s(xt,"validateReferences");function w(e,t,n){for(let r=0;r<e.length;r++){const o=e[r];if(!o)continue;if(!R(o)){const a=Object.keys(o);if(a.length===1){const c=a[0],l=o[c];typeof l=="string"&&(l.includes("/")||l.endsWith(".json"))&&n.push({path:`${t}[${r}]`,message:u.RESOLVER.MALFORMED_REFERENCE(c,l)})}continue}const i=o.$ref;i.startsWith("#/")&&(i.match(/^#\/sets\/[^/]+$/)||n.push({path:`${t}[${r}].$ref`,message:u.RESOLVER.INVALID_SOURCE_REFERENCE(i)}))}}s(w,"validateSourcesReferences");function Ft(e,t,n,r){if(!e.startsWith("#/"))return;const o=e.slice(2).split("/"),[i,a]=o;if(o.length!==2||!i||!a){r.push({path:t,message:u.RESOLVER.INVALID_REFERENCE(e)});return}if(i==="sets"){n.sets?.[a]||r.push({path:t,message:u.RESOLVER.UNDEFINED_SET(a)});return}if(i==="modifiers"){n.modifiers?.[a]||r.push({path:t,message:u.RESOLVER.UNDEFINED_MODIFIER(a)});return}r.push({path:t,message:u.RESOLVER.INVALID_REFERENCE(e)})}s(Ft,"validateReference");function k(){return{version:"2025.10",resolutionOrder:[]}}s(k,"createEmptyDocument");function Ne(e){if(typeof e!="object"||e===null)return!1;const t=e;return t.version==="2025.10"&&Array.isArray(t.resolutionOrder)}s(Ne,"isResolverFormat");function Te(e,t){return{document:e,basePath:t,visitedRefs:new Set,fileCache:new Map}}s(Te,"createResolveContext");async function Se(e,t){if(t.visitedRefs.has(e))return T({},u.RESOLVER.CIRCULAR_REFERENCE(e),e);t.visitedRefs.add(e);try{return e.startsWith("#/")?Ct(e,t):e.includes("#/")?await wt(e,t):await Vt(e,t)}finally{t.visitedRefs.delete(e)}}s(Se,"resolveReference");function Ct(e,t){const n=e.slice(2),[r,o]=n.split("/");if(!r||!o||n.split("/").length!==2)return T({sources:[]},u.RESOLVER.INVALID_REFERENCE(e));if(r==="sets"){const i=t.document.sets?.[o];return i?{content:i,sourcePath:"#",errors:[]}:T({sources:[]},u.RESOLVER.UNDEFINED_SET(o))}if(r==="modifiers"){const i=t.document.modifiers?.[o];return i?{content:i,sourcePath:"#",errors:[]}:T({contexts:{}},u.RESOLVER.UNDEFINED_MODIFIER(o))}return T({sources:[]},u.RESOLVER.INVALID_REFERENCE(e))}s(Ct,"resolveSameDocumentRef");async function Vt(e,t){const n=F(e)?e:O(t.basePath,e),r=t.fileCache.get(n);if(r)return Ne(r)?T({},u.RESOLVER.RESOLVER_AS_TOKEN_SOURCE(n),n):{content:r,sourcePath:n,errors:[]};const o=await be(n);return o.error?T({},o.error,n):Ne(o.content)?T({},u.RESOLVER.RESOLVER_AS_TOKEN_SOURCE(n),n):(t.fileCache.set(n,o.content),{content:o.content,sourcePath:n,errors:[]})}s(Vt,"resolveFileRef");async function wt(e,t){const[n="",r=""]=e.split("#"),o=F(n)?n:O(t.basePath,n);let i=t.fileCache.get(o);if(!i){const l=await be(o);if(l.error)return T({},l.error,o);i=l.content,t.fileCache.set(o,i)}const a=r.startsWith("/")?r:`/${r}`,c=kt(i,a);return c.error?T({},u.RESOLVER.INVALID_JSON_POINTER(a,c.error),o):{content:c.value,sourcePath:o,errors:[]}}s(wt,"resolveFileFragmentRef");async function be(e){try{const t=await le(e,"utf-8");return{content:JSON.parse(t)}}catch(t){if(t.code==="ENOENT")return{error:u.RESOLVER.EXTERNAL_FILE_NOT_FOUND(e)};const n=t instanceof Error?t.message:"Unknown error";return{error:u.RESOLVER.EXTERNAL_FILE_ERROR(e,n)}}}s(be,"loadJsonFile");function kt(e,t){if(t===""||t==="/")return{value:e};const n=t.slice(1).split("/").map(o=>o.replace(/~1/g,"/").replace(/~0/g,"~"));let r=e;for(const o of n){if(r===null||typeof r!="object")return{error:"cannot navigate into non-object"};if(Array.isArray(r)){const a=Number.parseInt(o,10);if(Number.isNaN(a)||a<0||a>=r.length)return{error:`invalid array index "${o}"`};r=r[a];continue}const i=r;if(!(o in i))return{error:`property "${o}" not found`};r=i[o]}return{value:r}}s(kt,"resolveJsonPointer");async function Oe(e,t){const n=[],r=[];for(const o of e){if(!R(o)){n.push(o);continue}const i=await Se(o.$ref,t);r.push(...i.errors),i.errors.length===0&&n.push(Mt(i.content,o))}return{resolved:n,errors:r}}s(Oe,"resolveSources");function Mt(e,t){const{$ref:n,...r}=t;return Object.keys(r).length===0?e:{...e,...r}}s(Mt,"applyExtending");function T(e,t,n="#"){return{content:e,sourcePath:n,errors:[{path:n,message:t}]}}s(T,"errorResult");function Ae(e){return typeof e=="object"&&e!==null&&"$value"in e}s(Ae,"isToken");function M(e,t){const n={...e};for(const[r,o]of Object.entries(t)){if(o===void 0)continue;if(r.startsWith("$")){n[r]=o;continue}if(Ae(o)){n[r]=o;continue}const i=n[r],a=i!==void 0&&typeof i=="object"&&i!==null&&typeof o=="object"&&o!==null&&!Ae(i);n[r]=a?M(i,o):o}return n}s(M,"deepMerge");function Re(e){const t=[],n=new Set;for(const r of e.resolutionOrder){const o=jt(r,e,n);o&&(t.push(o),n.add(o.name))}return t}s(Re,"extractModifiers");function jt(e,t,n){return R(e)&&e.$ref.startsWith("#/modifiers/")?Pt(e.$ref,t,n):_(e)?Ut(e,n):null}s(jt,"extractModifierFromItem");function Pt(e,t,n){const r=e.split("/")[2];if(!r||n.has(r))return null;const o=t.modifiers?.[r];return o?{name:r,contexts:Object.keys(o.contexts),default:o.default}:null}s(Pt,"extractReferencedModifier");function Ut(e,t){return t.has(e.name)?null:{name:e.name,contexts:Object.keys(e.contexts),default:e.default}}s(Ut,"extractInlineModifier");function Gt(e,t={}){const n=[],r={},o=Re(e);if(o.length===0)return Wt(t,n),{valid:n.length===0,errors:n,resolvedInputs:r};const i=new Map(o.map(a=>[a.name,a]));return Bt(t,i,n,r),Yt(o,r,n),{valid:n.length===0,errors:n,resolvedInputs:r}}s(Gt,"validateInputs$1");function Wt(e,t){for(const n of Object.keys(e))t.push({modifier:n,message:u.RESOLVER.UNKNOWN_MODIFIER(n)})}s(Wt,"validateNoModifiersCase");function Bt(e,t,n,r){for(const[o,i]of Object.entries(e)){const a=t.get(o);if(!a){n.push({modifier:o,message:u.RESOLVER.UNKNOWN_MODIFIER(o)});continue}if(typeof i!="string"){n.push({modifier:o,message:u.RESOLVER.INVALID_INPUT_TYPE(o)});continue}if(!a.contexts.includes(i)){n.push({modifier:o,message:u.RESOLVER.INVALID_CONTEXT(i,o,a.contexts)});continue}r[o]=i}}s(Bt,"validateProvidedInputs");function Yt(e,t,n){for(const r of e)t[r.name]===void 0&&(r.default!==void 0?t[r.name]=r.default:n.push({modifier:r.name,message:u.RESOLVER.MISSING_REQUIRED_INPUT(r.name)}))}s(Yt,"applyDefaults");async function De(e,t,n={}){const r=Gt(e,n);if(!r.valid)return{tokens:{},sources:[],errors:r.errors.map(a=>({path:a.modifier||"inputs",message:a.message}))};const o=Te(e,t),i=Ht();for(const a of e.resolutionOrder)await Kt(a,e,o,r.resolvedInputs,i);return{tokens:i.tokens,sources:i.sources,errors:i.errors}}s(De,"processResolutionOrder");function Ht(){return{tokens:{},sources:[],errors:[]}}s(Ht,"createProcessingState");async function Kt(e,t,n,r,o){if(R(e)){await qt(e,t,n,r,o);return}if($e(e)){await zt(e,n,o);return}_(e)&&await Jt(e,n,r,o)}s(Kt,"processItem");async function qt(e,t,n,r,o){const i=await Se(e.$ref,n);if(i.errors.length>0){o.errors.push(...i.errors);return}const a=e.$ref.split("/")[2];if(a){if(e.$ref.startsWith("#/sets/")){const c=await j(i.content.sources,n,{type:"set",name:a});P(c,o);return}if(e.$ref.startsWith("#/modifiers/")){const c=r[a];if(!c)return;const p=i.content.contexts[c];if(!p)return;const m=await j(p,n,{type:"modifier",name:a,context:c});P(m,o)}}}s(qt,"processReference");async function zt(e,t,n){const r=await j(e.sources,t,{type:"set",name:e.name});P(r,n)}s(zt,"processInlineSet");async function Jt(e,t,n,r){const o=n[e.name];if(!o)return;const i=e.contexts[o];if(!i)return;const a=await j(i,t,{type:"modifier",name:e.name,context:o});P(a,r)}s(Jt,"processInlineModifier");async function j(e,t,n){const r=await Oe(e,t);let o={};for(const i of r.resolved)o=M(o,i);return{tokens:o,source:{path:"#",...n},errors:r.errors}}s(j,"mergeSources");function P(e,t){t.errors.push(...e.errors),t.tokens=M(t.tokens,e.tokens),t.sources.push(e.source)}s(P,"applyResult");async function Xt(e,t){const n=[],r=Te(e,t),o=Re(e),i={};for(const p of o)p.default&&(i[p.name]=p.default);const a=await De(e,t,i);n.push(...a.errors);const c=a.tokens,l=[];for(const p of o){const m=new Map,d=p.default??p.contexts[0]??"default";for(const I of p.contexts){if(I===d)continue;const E=await Zt(e,t,r,p.name,I,n);Object.keys(E).length>0&&m.set(I,E)}l.push({name:p.name,defaultContext:d,contexts:m})}return{base:c,modifiers:l,errors:n}}s(Xt,"processForLayeredCSS");async function Zt(e,t,n,r,o,i){const a=Qt(e,r);if(!a)return{};const c=a.contexts[o];if(!c||c.length===0)return{};const l=await Oe(c,n);i.push(...l.errors.map(E=>({path:E.path,message:E.message})));let p={};for(const E of l.resolved)p=M(p,E);const m=new Set;_e(p,"",m);const d=await De(e,t,{[r]:o});i.push(...d.errors);const I={};for(const E of m){const $=en(d.tokens,E);$!==void 0&&tn(I,E,$)}return I}s(Zt,"processModifierContext");function Qt(e,t){if(e.modifiers?.[t])return e.modifiers[t];for(const n of e.resolutionOrder)if(_(n)&&n.name===t)return n}s(Qt,"findModifierDefinition");function _e(e,t,n){for(const[r,o]of Object.entries(e)){if(r.startsWith("$"))continue;const i=t?`${t}.${r}`:r;o&&typeof o=="object"&&"$value"in o?n.add(i):o&&typeof o=="object"&&_e(o,i,n)}}s(_e,"collectTokenPaths");function en(e,t){const n=t.split(".");let r=e;for(const o of n){if(r===null||typeof r!="object")return;r=r[o]}return r}s(en,"getTokenAtPath");function tn(e,t,n){const r=t.split(".");let o=e;for(let a=0;a<r.length-1;a++){const c=r[a];c&&(c in o||(o[c]={}),o=o[c])}const i=r[r.length-1];i&&(o[i]=n)}s(tn,"setTokenAtPath");async function nn(e){const t=F(e)?e:O(process.cwd(),e),n=z(t),r=[],o=[],i=x(process.cwd(),t),a=await Ot(t);if(a.errors.length>0)return{trees:[],modifiers:[],errors:a.errors.map(p=>({file:p.path,message:p.message}))};const c=await Xt(a.document,n);for(const p of c.errors)r.push({file:p.path,message:p.message});Object.keys(c.base).length>0&&o.push({context:void 0,tokens:c.base,sourcePath:i});const l=[];for(const p of c.modifiers){const m=[];for(const[d,I]of p.contexts)Object.keys(I).length>0&&(o.push({context:`${p.name}:${d}`,tokens:I,sourcePath:i}),m.push(d));l.push({name:p.name,attribute:`data-${p.name}`,defaultContext:p.defaultContext,contexts:m})}return{trees:o,modifiers:l,errors:r}}s(nn,"loadFromResolver");async function rn(e){const t=[],n=[],r=Object.entries(e);r.sort(([,o],[,i])=>{const a=!o.context,c=!i.context;return a&&!c?-1:!a&&c?1:0});for(const[o,{context:i,content:a}]of r)try{const c=JSON.parse(a);t.push({context:i,tokens:c,sourcePath:x(process.cwd(),o)})}catch(c){c instanceof Error?c instanceof SyntaxError?n.push({file:o,message:u.LOAD.INVALID_JSON(o,c.message)}):n.push({file:o,message:c.message}):n.push({file:o,message:"Unknown error"})}return{trees:t,errors:n}}s(rn,"loadTreesFromMemory");function U(e,t,n,r){return typeof t=="string"&&h(t)?sn(e,t,n,r):Array.isArray(t)?t.map(o=>U(e,o,n,r)):typeof t=="object"&&t!==null?Object.entries(t).reduce((i,[a,c])=>Object.assign(i,{[a]:U(`${e}.${a}`,c,n,r)}),{}):t}s(U,"resolveValue");function Le(e,t){const n=e.slice(1,-1),r=t.pathIndex.get(n);if(!r)return;const o=t.tokens[r];if(!(!o||!("$value"in o))){if(o.$type)return o.$type;if(typeof o.$value=="string"&&h(o.$value))return Le(o.$value,t)}}s(Le,"inferTypeFromReference");function on(e){const t={},n=new Set,r=[];for(const[o,i]of Object.entries(e.tokens))try{if(!("$value"in i)){t[o]=i;continue}const a=i;let c=a.$type;!c&&typeof a.$value=="string"&&h(a.$value)&&(c=Le(a.$value,e)),t[o]={...a,...c?{$type:c}:{},$resolvedValue:U(a.$path,a.$value,e,n)}}catch(a){const c=a instanceof Error?a.message:String(a),l=i,p=l.$path,m=l.$source;let d,I;c.includes("Circular reference detected")?(d="circular",I=c):c.includes("Reference not found")?(d="missing",I=c):(d="type-mismatch",I=u.RESOLVE.TYPE_MISMATCH(p)),r.push({type:d,path:p,source:m,message:I})}return{resolved:t,errors:r}}s(on,"resolve");function sn(e,t,n,r){const o=t.slice(1,-1),i=n.pathIndex.get(o);if(!i)throw new Error(u.RESOLVE.REFERENCE_NOT_FOUND(o,e));if(r.has(i)){const l=n.tokens[i];throw!l||!("$path"in l)?new Error(u.RESOLVE.REFERENCE_NOT_FOUND(o,e)):new Error(u.RESOLVE.CIRCULAR_REFERENCE(e,l.$path))}const a=n.tokens[i];if(!a||!("$value"in a))throw new Error(u.RESOLVE.REFERENCE_NOT_FOUND(o,e));r.add(i);const c=U(i,a.$value,n,r);return r.delete(i),c}s(sn,"resolveReferenceChain");function S(e){return{success:!0,value:e}}s(S,"success");function g(e){return{success:!1,error:e}}s(g,"error");function ne(e){if(typeof e!="object"||e===null)return!1;const t=e;return!(typeof t.colorSpace!="string"||!["oklch","display-p3","srgb","hsl"].includes(t.colorSpace)||!Array.isArray(t.components)||t.components.length!==3||!t.components.every(r=>typeof r=="number"||r==="none")||t.alpha!==void 0&&typeof t.alpha!="number"||t.hex!==void 0&&typeof t.hex!="string")}s(ne,"isDTCGColorValue");function G(e){const t=[],n=["oklch","display-p3","srgb","hsl"];if(n.includes(e.colorSpace)||t.push(`Unsupported colorSpace: "${e.colorSpace}". Supported color spaces: ${n.join(", ")}.`),!Array.isArray(e.components)||e.components.length!==3)t.push("Components must be an array of exactly 3 numbers.");else if(e.components.forEach((r,o)=>{r!=="none"&&(typeof r!="number"||!Number.isFinite(r))&&t.push(`Component ${o} must be a finite number or "none".`)}),e.colorSpace==="oklch"){const[r,o,i]=e.components;r!=="none"&&(r<0||r>1)&&t.push("OKLCH Lightness (L) must be between 0 and 1 or 'none'."),o!=="none"&&o<0&&t.push("OKLCH Chroma (C) must be >= 0 or 'none'."),i!=="none"&&(i<0||i>=360)&&t.push("OKLCH Hue (H) must be between 0 and 360 (exclusive) or 'none'.")}else if(e.colorSpace==="display-p3"){const[r,o,i]=e.components;r!=="none"&&(r<0||r>1)&&t.push("Display P3 Red component must be between 0 and 1 or 'none'."),o!=="none"&&(o<0||o>1)&&t.push("Display P3 Green component must be between 0 and 1 or 'none'."),i!=="none"&&(i<0||i>1)&&t.push("Display P3 Blue component must be between 0 and 1 or 'none'.")}else if(e.colorSpace==="srgb"){const[r,o,i]=e.components;r!=="none"&&(r<0||r>1)&&t.push("sRGB Red component must be between 0 and 1 or 'none'."),o!=="none"&&(o<0||o>1)&&t.push("sRGB Green component must be between 0 and 1 or 'none'."),i!=="none"&&(i<0||i>1)&&t.push("sRGB Blue component must be between 0 and 1 or 'none'.")}else if(e.colorSpace==="hsl"){const[r,o,i]=e.components;r!=="none"&&(r<0||r>=360)&&t.push("HSL Hue must be between 0 and 360 (exclusive) or 'none'."),o!=="none"&&(o<0||o>100)&&t.push("HSL Saturation must be between 0 and 100 or 'none'."),i!=="none"&&(i<0||i>100)&&t.push("HSL Lightness must be between 0 and 100 or 'none'.")}return e.alpha!==void 0&&(typeof e.alpha!="number"||!Number.isFinite(e.alpha)?t.push("Alpha must be a finite number."):(e.alpha<0||e.alpha>1)&&t.push("Alpha must be between 0 and 1.")),t}s(G,"validateDTCGColorValue");function an(e){const t=G(e);return t.length>0?g(t.join(", ")):S(e)}s(an,"validateDTCGColorValueResult");function cn(e){const t=an(e);if(!t.success)return t;const[n,r,o]=e.components,i=e.alpha,a=n==="none"?"none":Number(n.toFixed(4)),c=r==="none"?"none":Number(r.toFixed(4)),l=o==="none"?"none":Number(o.toFixed(4));if(i!==void 0&&i!==1){const p=Number(i.toFixed(4));return S(`oklch(${a} ${c} ${l} / ${p})`)}return S(`oklch(${a} ${c} ${l})`)}s(cn,"formatDTCGColorToOKLCH");const un={isObject:s(e=>typeof e=="object"&&e!==null&&!Array.isArray(e),"isObject")};function y(e,t,n,r){if(h(t))return[];switch(e.type){case"object":return fn(e,t,n,r);case"union":return pn(e,t,n,r);case"array":return dn(e,t,n,r);default:return ln(e,t,n,r)}}s(y,"validateSchema");function ln(e,t,n,r){return e.type!==typeof t?[{path:n,message:e.errorMessage?.(t,n)||u.VALIDATE.INVALID_TYPE(e.type,t,n),source:r}]:e.validate?.(t,n,r)??[]}s(ln,"validateSimpleValue");function fn(e,t,n,r){if(!un.isObject(t))return[{path:n,message:e.errorMessage?.(t,n)||u.VALIDATE.INVALID_TYPE("object",t,n),source:r}];const o=[],i=t;if(e.required)for(const a of e.required)a in i||o.push({path:`${n}.${a}`,message:u.VALIDATE.MISSING_REQUIRED_PROPERTY(a,n),source:r});for(const[a,c]of Object.entries(e.properties))a in i&&o.push(...y(c,i[a],`${n}.${a}`,r));return o}s(fn,"validateObject");function pn(e,t,n,r){let o=[],i=Number.POSITIVE_INFINITY;for(const a of e.oneOf){if(a.type==="string"&&typeof t!="string"||a.type==="object"&&typeof t!="object")continue;const c=y(a,t,n,r);if(c.length===0)return a.validate?.(t,n,r)??[];c.length<i&&(o=c,i=c.length)}return i===Number.POSITIVE_INFINITY?[{path:n,message:u.VALIDATE.INVALID_TYPE(e.oneOf.map(a=>a.type).join(" or "),t,n),source:r}]:o}s(pn,"validateUnion");function dn(e,t,n,r){return Array.isArray(t)?e.validate?.(t,n,r)??[]:[{path:n,message:e.errorMessage?.(t,n)||u.VALIDATE.INVALID_TYPE("array",t,n),source:r}]}s(dn,"validateArray");const W={schema:{type:"union",oneOf:[{type:"string",validate:s((e,t,n)=>/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$/.test(e)?[]:[{path:t,message:u.VALIDATE.INVALID_COLOR(e,t),source:n}],"validate")},{type:"object",required:["colorSpace","components"],properties:{colorSpace:{type:"string"},components:{type:"array"},alpha:{type:"number"},hex:{type:"string"}},validate:s((e,t,n)=>ne(e)?G(e).map(o=>({path:t,message:`Invalid color at ${t}: ${o}`,source:n})):[{path:t,message:u.VALIDATE.INVALID_COLOR(e,t),source:n}],"validate")}]}};function mn(e,t,n){return y(W.schema,e,t,n)}s(mn,"validateColor");const B={schema:{type:"number",errorMessage:s((e,t)=>u.VALIDATE.INVALID_NUMBER(e,t),"errorMessage"),validate:s((e,t,n)=>typeof e!="number"||Number.isNaN(e)?[{path:t,message:u.VALIDATE.INVALID_NUMBER(e,t),source:n}]:[],"validate")}};function hn(e,t,n){return y(B.schema,e,t,n)}s(hn,"validateNumber");const N={schema:{type:"object",errorMessage:s((e,t)=>u.VALIDATE.INVALID_DIMENSION(e,t),"errorMessage"),properties:{value:B.schema,unit:{type:"string",validate:s((e,t,n)=>typeof e!="string"||!["px","rem"].includes(e)?[{path:t,message:u.VALIDATE.INVALID_DIMENSION_UNIT(e,t),source:n}]:[],"validate")}},required:["value","unit"]}};function In(e,t,n){return y(N.schema,e,t,n)}s(In,"validateDimension");const En=["solid","dashed","dotted","double","groove","ridge","outset","inset"],yn=["round","butt","square"],$n={type:"object",errorMessage:s((e,t)=>u.VALIDATE.INVALID_STROKE_STYLE(e,t),"errorMessage"),properties:{dashArray:{type:"array",validate:s((e,t,n)=>{const r=e,o=[];return r.forEach((i,a)=>{typeof i!="string"&&o.push(...y(N.schema,i,`${t}.${a}`,n))}),o},"validate")},lineCap:{type:"string",validate:s((e,t,n)=>yn.includes(e)?[]:[{path:t,message:u.VALIDATE.INVALID_STROKE_LINE_CAP(e,t),source:n}],"validate")}},required:["dashArray","lineCap"]},ve={schema:{type:"union",oneOf:[{type:"string",validate:s((e,t,n)=>!En.includes(e)&&typeof e=="string"?[{path:t,message:u.VALIDATE.INVALID_STROKE_STYLE(e,t),source:n}]:[],"validate")},$n]}};function gn(e,t,n){return y(ve.schema,e,t,n)}s(gn,"validateStrokeStyle");const Nn={schema:{type:"object",properties:{color:W.schema,width:N.schema,style:ve.schema},required:["color","width","style"],errorMessage:s((e,t)=>u.VALIDATE.INVALID_BORDER(e,t),"errorMessage")}};function Tn(e,t,n){return y(Nn.schema,e,t,n)}s(Tn,"validateBorder");const xe={schema:{type:"array",errorMessage:s((e,t)=>u.VALIDATE.INVALID_CUBIC_BEZIER(e,t),"errorMessage"),validate:s((e,t,n)=>{const r=e;if(r.length!==4||!r.every(a=>typeof a=="number"))return[{path:t,message:u.VALIDATE.INVALID_CUBIC_BEZIER(e,t),source:n}];const[o,,i]=r;return o<0||o>1||i<0||i>1?[{path:t,message:u.VALIDATE.INVALID_CUBIC_BEZIER(e,t),source:n}]:[]},"validate")}};function Sn(e,t,n){return y(xe.schema,e,t,n)}s(Sn,"validateCubicBezier");const bn=["ms","s"],re={schema:{type:"object",errorMessage:s((e,t)=>u.VALIDATE.INVALID_DURATION(e,t),"errorMessage"),properties:{value:B.schema,unit:{type:"string",validate:s((e,t,n)=>bn.includes(e)?[]:[{path:t,message:u.VALIDATE.INVALID_DURATION_UNIT(e,t),source:n}],"validate")}},required:["value","unit"]}};function On(e,t,n){return y(re.schema,e,t,n)}s(On,"validateDuration");const An={schema:{type:"object",errorMessage:s((e,t)=>u.VALIDATE.INVALID_FLUID_DIMENSION(e,t),"errorMessage"),properties:{min:N.schema,max:N.schema},required:["min","max"]}};function Rn(e,t,n){return y(An.schema,e,t,n)}s(Rn,"validateFluidDimension");const Fe={schema:{type:"union",oneOf:[{type:"string",errorMessage:s((e,t)=>u.VALIDATE.INVALID_FONT_FAMILY(e,t),"errorMessage")},{type:"array",errorMessage:s((e,t)=>u.VALIDATE.INVALID_FONT_FAMILY(e,t),"errorMessage"),validate:s((e,t,n)=>e.every(o=>typeof o=="string")?[]:[{path:t,message:u.VALIDATE.INVALID_FONT_FAMILY(e,t),source:n}],"validate")}],errorMessage:s((e,t)=>u.VALIDATE.INVALID_FONT_FAMILY(e,t),"errorMessage")}};function Dn(e,t,n){return y(Fe.schema,e,t,n)}s(Dn,"validateFontFamily");const _n=["thin","hairline","extra-light","ultra-light","light","normal","regular","book","medium","semi-bold","demi-bold","bold","extra-bold","ultra-bold","black","heavy","extra-black","ultra-black"],Ce={schema:{type:"union",errorMessage:s((e,t)=>u.VALIDATE.INVALID_FONT_WEIGHT(e,t),"errorMessage"),oneOf:[{type:"number",errorMessage:s((e,t)=>u.VALIDATE.INVALID_FONT_WEIGHT(e,t),"errorMessage"),validate:s((e,t,n)=>e<1||e>1e3?[{path:t,message:u.VALIDATE.INVALID_FONT_WEIGHT(e,t),source:n}]:[],"validate")},{type:"string",errorMessage:s((e,t)=>u.VALIDATE.INVALID_FONT_WEIGHT(e,t),"errorMessage"),validate:s((e,t,n)=>_n.includes(e.toLowerCase())?[]:[{path:t,message:u.VALIDATE.INVALID_FONT_WEIGHT(e,t),source:n}],"validate")}]}};function Ln(e,t,n){return y(Ce.schema,e,t,n)}s(Ln,"validateFontWeight");const vn={type:"object",errorMessage:s((e,t)=>u.VALIDATE.INVALID_GRADIENT(e,t),"errorMessage"),properties:{color:W.schema,position:{type:"number",validate:s((e,t,n)=>e<0||e>1?[{path:t,message:u.VALIDATE.INVALID_GRADIENT_STOP_POSITION(e,t),source:n}]:[],"validate")}},required:["color","position"]},xn={schema:{type:"array",errorMessage:s((e,t)=>u.VALIDATE.INVALID_ARRAY(e,t),"errorMessage"),validate:s((e,t,n)=>{const r=e,o=[];return r.forEach((i,a)=>{o.push(...y(vn,i,`${t}[${a}]`,n))}),o},"validate")}};function Fn(e,t,n){return y(xn.schema,e,t,n)}s(Fn,"validateGradient");const Ve={schema:{type:"object",properties:{color:{type:"union",oneOf:[W.schema]},offsetX:N.schema,offsetY:N.schema,blur:N.schema,spread:N.schema,inset:{type:"boolean",errorMessage:s((e,t)=>u.VALIDATE.INVALID_SHADOW_INSET(e,t),"errorMessage")}},required:["color","offsetX","offsetY","blur","spread"],errorMessage:s((e,t)=>u.VALIDATE.INVALID_SHADOW(e,t),"errorMessage")}};function Cn(e,t,n){const r=[];return Array.isArray(e)?(e.forEach((o,i)=>{r.push(...y(Ve.schema,o,`${t}[${i}]`,n))}),r):y(Ve.schema,e,t,n)}s(Cn,"validateShadow");const Vn={schema:{type:"object",properties:{duration:re.schema,delay:re.schema,timingFunction:xe.schema},required:["duration","delay","timingFunction"],errorMessage:s((e,t)=>u.VALIDATE.INVALID_TRANSITION(e,t),"errorMessage")}};function wn(e,t,n){return y(Vn.schema,e,t,n)}s(wn,"validateTransition");const kn={schema:{type:"object",properties:{fontFamily:Fe.schema,fontSize:N.schema,letterSpacing:N.schema,lineHeight:B.schema,fontWeight:Ce.schema},required:["fontFamily","fontSize"],errorMessage:s((e,t)=>u.VALIDATE.INVALID_TYPOGRAPHY(e,t),"errorMessage")}};function Mn(e,t,n){return y(kn.schema,e,t,n)}s(Mn,"validateTypography");const jn={color:mn,dimension:In,fluidDimension:Rn,duration:On,cubicBezier:Sn,fontFamily:Dn,fontWeight:Ln,number:hn,strokeStyle:gn,typography:Mn,border:Tn,shadow:Cn,gradient:Fn,transition:wn};function Pn(e){const t=[];for(const[n,r]of Object.entries(e.tokens)){if(typeof r!="object"||r===null||!("$type"in r)||!("$path"in r)||r.$path.startsWith("$"))continue;if(!("$value"in r)){t.push({path:r.$path,message:u.VALIDATE.MISSING_REQUIRED_PROPERTY("$value",r.$path),source:r.$source});continue}const o=jn[r.$type];if(!o){t.push({path:r.$path,message:u.VALIDATE.UNKNOWN_TOKEN_TYPE(r.$type,r.$path),source:r.$source});continue}const i=r;t.push(...o(i.$value,i.$path,i.$source))}return t}s(Pn,"validate");async function Un(e){const{trees:t,modifiers:n,errors:r}=await Gn(e),{tokens:o,errors:i}=It(t),a=Pn(o),{resolved:c,errors:l}=on(o);return{trees:t,resolved:c,modifiers:n,errors:{load:r,flatten:i,validation:a,resolution:l}}}s(Un,"loadAndResolveTokens");async function Gn(e){switch(e.type){case"memory":{const t=await rn(e.data);return{trees:t.trees,modifiers:[],errors:t.errors}}case"resolver":{const t=await nn(e.resolverPath);return{trees:t.trees,modifiers:t.modifiers,errors:t.errors}}}}s(Gn,"loadTokens");function we(e){return h(e)?{value:e}:typeof e=="string"?{value:e}:{value:`${e.dashArray.map(n=>h(n)?n:`${n.value}${n.unit}`).join(" ")} ${e.lineCap}`}}s(we,"convertStrokeStyleToken");function Wn(e){if(h(e))return{value:e};const t=h(e.width)?e.width:`${e.width.value}${e.width.unit}`,n=(h(e.color),e.color),r=typeof e.style=="string"?e.style:we(e.style).value;return{value:`${t} ${r} ${n}`}}s(Wn,"convertBorderToken");function ke(e,t="native"){return ne(e)?Bn(e):S(e)}s(ke,"convertColorToString");function Bn(e){switch(e.colorSpace){case"oklch":return cn(e);case"display-p3":return Yn(e);case"srgb":return Hn(e);case"hsl":return Kn(e);default:return g(`Unsupported color space: ${e.colorSpace}. Supported color spaces: oklch, display-p3, srgb, hsl.`)}}s(Bn,"formatDTCGColorNative");function Yn(e){if(e.colorSpace!=="display-p3")return g(`Expected display-p3 color space, got: ${e.colorSpace}`);if(!Array.isArray(e.components)||e.components.length!==3)return g("Display P3 components must be an array of exactly 3 numbers [R, G, B]");const[t,n,r]=e.components,o=e.alpha;if(t!=="none"&&(t<0||t>1))return g("Display P3 Red component must be between 0 and 1 or 'none'");if(n!=="none"&&(n<0||n>1))return g("Display P3 Green component must be between 0 and 1 or 'none'");if(r!=="none"&&(r<0||r>1))return g("Display P3 Blue component must be between 0 and 1 or 'none'");if(o!==void 0&&(o<0||o>1))return g("Alpha must be between 0 and 1");const i=t==="none"?"none":Number(t.toFixed(4)),a=n==="none"?"none":Number(n.toFixed(4)),c=r==="none"?"none":Number(r.toFixed(4));if(o!==void 0&&o!==1){const l=Number(o.toFixed(4));return S(`color(display-p3 ${i} ${a} ${c} / ${l})`)}return S(`color(display-p3 ${i} ${a} ${c})`)}s(Yn,"formatDTCGColorToP3");function Hn(e){if(e.colorSpace!=="srgb")return g(`Expected srgb color space, got: ${e.colorSpace}`);const t=G(e);if(t.length>0)return g(`Invalid DTCG color value: ${t.join(", ")}`);const[n,r,o]=e.components,i=e.alpha,a=n==="none"?"none":Math.round(n*255),c=r==="none"?"none":Math.round(r*255),l=o==="none"?"none":Math.round(o*255);if(i!==void 0&&i!==1){const p=Number(i.toFixed(4));return S(`rgb(${a} ${c} ${l} / ${p})`)}return S(`rgb(${a} ${c} ${l})`)}s(Hn,"formatDTCGColorToRGB");function Kn(e){if(e.colorSpace!=="hsl")return g(`Expected hsl color space, got: ${e.colorSpace}`);const t=G(e);if(t.length>0)return g(`Invalid DTCG color value: ${t.join(", ")}`);const[n,r,o]=e.components,i=e.alpha,a=n==="none"?"none":Number(n.toFixed(1)),c=r==="none"?"none":Math.round(r),l=o==="none"?"none":Math.round(o);if(i!==void 0&&i!==1){const d=Number(i.toFixed(4)),I=c==="none"?"none":`${c}%`,E=l==="none"?"none":`${l}%`;return S(`hsl(${a} ${I} ${E} / ${d})`)}const p=c==="none"?"none":`${c}%`,m=l==="none"?"none":`${l}%`;return S(`hsl(${a} ${p} ${m})`)}s(Kn,"formatDTCGColorToHSL");function qn(e,t){if(typeof e=="string"&&h(e))return{value:e};const n=t.colorFallbackStrategy;if(ne(e))return zn(e,n);const r=ke(e,n);return r.success?{value:r.value}:(console.warn(`[sugarcube] Failed to convert color ${typeof e=="string"?e:"DTCG color object"}: ${r.error}`),{value:typeof e=="string"?e:"#000000"})}s(qn,"convertColorToken");function zn(e,t){const n=ke(e,t);if(!n.success)return console.warn(`[sugarcube] Failed to convert DTCG color: ${n.error}`),{value:"#000000"};const r=n.value;if(t==="native")return{value:r};if(e.colorSpace==="srgb"||e.colorSpace==="hsl")return{value:r};if(!e.hex)throw new Error(`${e.colorSpace} colors require a 'hex' fallback when using 'polyfill' strategy. Tip: Switch to 'native' strategy if targeting modern browsers only.`);return{value:e.hex,featureValues:[{query:Jn(e.colorSpace),value:r}]}}s(zn,"convertDTCGColorToken");function Jn(e){switch(e){case"oklch":return"@supports (color: oklch(0 0 0))";case"display-p3":return"@supports (color: color(display-p3 1 1 1))";default:throw new Error(`No feature query defined for color space: ${e}`)}}s(Jn,"getFeatureQuery");function Xn(e){return h(e)?{value:e}:{value:`cubic-bezier(${e.join(", ")})`}}s(Xn,"convertCubicBezierToken");function Zn(e){return h(e)?{value:e}:{value:`${e.value}${e.unit}`}}s(Zn,"convertDimensionToken");function Qn(e){return h(e)?{value:e}:{value:`${e.value}${e.unit}`}}s(Qn,"convertDurationToken");function Me(e,t=16){return e.unit==="px"?e.value:e.value*t}s(Me,"normalizeToPixels");function er(e,t){const{min:n,max:r}=e,o=t.fluidConfig,i=16,a=Me(n,i),c=Me(r,i),l=o.min,p=o.max;if(a===c)return{value:`${a/i}rem`};const m=a/i,d=c/i,I=l/i,E=p/i,$=(d-m)/(E-I),ce=-1*I*$+m;return{value:`clamp(${m}rem, ${ce.toFixed(2)}rem + ${($*100).toFixed(2)}vw, ${d}rem)`}}s(er,"convertFluidDimension");function tr(e,t){return h(e)?{value:e}:er(e,t)}s(tr,"convertFluidDimensionToken");function Y(e){return["serif","sans-serif","monospace","cursive","fantasy","system-ui","ui-serif","ui-sans-serif","ui-monospace","ui-rounded","emoji","math","fangsong"].includes(e.toLowerCase())?e:/[\s'"!@#$%^&*()=+[\]{};:|\\/,.<>?~]/.test(e)?`"${e}"`:e}s(Y,"quoteFont");function nr(e){return h(e)?{value:e}:{value:Array.isArray(e)?e.map(n=>Y(n)).join(", "):Y(e)}}s(nr,"convertFontFamilyToken");const rr={thin:100,hairline:100,"extra-light":200,"ultra-light":200,light:300,normal:400,regular:400,book:400,medium:500,"semi-bold":600,"demi-bold":600,bold:700,"extra-bold":800,"ultra-bold":800,black:900,heavy:900,"extra-black":950,"ultra-black":950};function je(e){return h(e)?{value:e}:typeof e=="number"?{value:e}:{value:rr[e.toLowerCase()]??e}}s(je,"convertFontWeightToken");function or(e){return h(e)?{value:e}:{value:`linear-gradient(${e.map(n=>{const r=(h(n.color),n.color),o=h(n.position)?n.position:`${n.position*100}`;return`${r} ${o}%`}).join(", ")})`}}s(or,"convertGradientToken");function sr(e){return h(e)?{value:e}:{value:e}}s(sr,"convertNumberToken");function Pe(e){const t=h(e.offsetX)?e.offsetX:`${e.offsetX.value}${e.offsetX.unit}`,n=h(e.offsetY)?e.offsetY:`${e.offsetY.value}${e.offsetY.unit}`,r=h(e.blur)?e.blur:`${e.blur.value}${e.blur.unit}`,o=h(e.spread)?e.spread:`${e.spread.value}${e.spread.unit}`,i=(h(e.color),e.color);return`${e.inset?"inset ":""}${t} ${n} ${r} ${o} ${i}`}s(Pe,"convertSingleShadow");function ir(e){return h(e)?{value:e}:Array.isArray(e)?{value:e.map(Pe).join(", ")}:{value:Pe(e)}}s(ir,"convertShadowToken");function Ue(e){return e?`${e.value}${e.unit}`:"0ms"}s(Ue,"formatDuration");function ar(e){if(h(e))return{value:e};const t=h(e.duration)?e.duration:Ue(e.duration),n=h(e.timingFunction)?e.timingFunction:`cubic-bezier(${e.timingFunction.join(", ")})`,r=e.delay&&(h(e.delay)?e.delay:Ue(e.delay));return{value:[t,n,r].filter(Boolean).join(" ")}}s(ar,"convertTransitionToken");function cr(e){if(h(e))return{"font-family":e,"font-size":e};const t={"font-family":h(e.fontFamily)?e.fontFamily:Array.isArray(e.fontFamily)?e.fontFamily.map(n=>Y(n)).join(", "):Y(e.fontFamily),"font-size":h(e.fontSize)?e.fontSize:`${e.fontSize.value}${e.fontSize.unit}`};return e.fontWeight&&(t["font-weight"]=h(e.fontWeight)?e.fontWeight:je(e.fontWeight).value),e.letterSpacing&&(t["letter-spacing"]=h(e.letterSpacing)?e.letterSpacing:`${e.letterSpacing.value}${e.letterSpacing.unit}`),e.lineHeight&&(t["line-height"]=(h(e.lineHeight),e.lineHeight)),t}s(cr,"convertTypographyToken");const Ge={duration:Qn,number:sr,cubicBezier:Xn,color:qn,dimension:Zn,fluidDimension:tr,typography:cr,border:Wn,shadow:ir,gradient:or,transition:ar,strokeStyle:we,fontFamily:nr,fontWeight:je};function ur(e,t){const n=Ge[e.$type];return{...e.$description?{$description:e.$description}:{},...e.$extensions?{$extensions:e.$extensions}:{},$type:e.$type,$value:e.$value,$path:e.$path,$source:e.$source,$originalPath:e.$originalPath,$resolvedValue:e.$resolvedValue,$cssProperties:n(e.$value,t)}}s(ur,"convertSingleToken");function lr(e,t,n){const r={};for(const[o,i]of Object.entries(e)){if(!i||typeof i!="object")continue;if(!("$type"in i)){r[o]={...i.$description?{$description:i.$description}:{},...i.$extensions?{$extensions:i.$extensions}:{}};continue}if(n?.(i.$path)||!Ge[i.$type])continue;const a={fluidConfig:t.transforms.fluid,colorFallbackStrategy:t.transforms.colorFallbackStrategy,path:i.$path,resolvedTokens:e};r[o]=ur(i,a)}return r}s(lr,"convertTokens");function fr(e,t,n){const r={};for(const[o,i]of Object.entries(e))r[o]=lr(i,t,n);return r}s(fr,"convert");function pr(e,t){const n={},r=new Set;for(const o of e){const i=o.context??"default";r.add(i)}for(const o of r)n[o]={};for(const o of e){const{context:i,tokens:a}=o,c=i??"default";n[c]||(n[c]={});for(const[l,p]of Object.entries(a))n[c][l]=p}return{tokens:n,defaultContext:t}}s(pr,"normalizeTokens");function dr(e,t){const n=new Map;for(const[r,o]of Object.entries(t)){if(!("$source"in o)){for(const c of e){const l=c.context??"";n.has(l)||n.set(l,{});const p=n.get(l);p&&(p[r]=o)}continue}const i=o.$source.context??"";n.has(i)||n.set(i,{});const a=n.get(i);a&&(a[r]=o)}return e.map(r=>{const o=r.context??"",i=n.get(o)||{};return{context:r.context,tokens:i}})}s(dr,"processTrees");async function mr(e,t,n,r){const o=dr(e,t),{tokens:i}=pr(o);return fr(i,n,r?l=>r.some(p=>p.path===l||p.path.startsWith(`${l}.`)):void 0)}s(mr,"processAndConvertTokens");function hr(e){return Object.entries(e).sort(([t],[n])=>t.localeCompare(n))}s(hr,"deterministicEntries");const We=new Map;function Ir(e){const t=We.get(e);if(t)return t;const n=e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").replace(/([A-Z])([A-Z])(?=[a-z])/g,"$1-$2").toLowerCase();return We.set(e,n),n}s(Ir,"toKebabCase");function oe(e){return e.split(".").join("-")}s(oe,"formatCSSVarPath");function se(e){return typeof e=="number"?e:typeof e!="string"?(console.warn("[sugarcube] Unexpected value type in convertReferenceToCSSVar:",e),String(e)):e.replace(/\{([^}]+)\}/g,(t,n)=>`var(--${n.split(".").map(Ir).join("-")})`)}s(se,"convertReferenceToCSSVar");function Er(e){const t=e.$cssProperties;if("value"in t)return{name:`--${oe(e.$path)}`,value:se(t.value)}}s(Er,"generateSingleVariable");function yr(e){return Object.entries(e.$cssProperties).filter(([t,n])=>n!==void 0).map(([t,n])=>({name:`--${oe(e.$path)}-${t}`,value:se(n)}))}s(yr,"generateTypographyVariables");function Be(e){if(e.$type!=="color")return[];const t=e.$cssProperties;if(!("featureValues"in t))return[];const n=new Map;for(const r of t.featureValues||[]){n.has(r.query)||n.set(r.query,[]);const o=n.get(r.query);o&&o.push({name:`--${oe(e.$path)}`,value:se(r.value)})}return Array.from(n.entries()).map(([r,o])=>({query:r,vars:o}))}s(Be,"generateFeatureVariables");function Ye(e){const t=[`${e.selector} {`];if(e.comment&&t.push(` /* ${e.comment} */`),e.vars.length>0){const n=e.vars.map(r=>` ${r.name}: ${r.value};`).join(`
15
+ `);t.push(n)}return t.push("}"),t.join(`
16
+ `)}s(Ye,"generateCSSBlock");function $r(e){const t=[];e.root.vars.length>0&&t.push(Ye({selector:e.root.selector,vars:e.root.vars}));for(const n of e.features){const o=Ye({selector:e.root.selector,vars:n.vars}).split(`
17
+ `).map(i=>` ${i}`).join(`
18
+ `);t.push(`${n.query} {
19
+ ${o}
20
+ }`)}return t.filter(Boolean).join(`
21
+
22
+ `)}s($r,"convertCSSVarsToString");function gr(e){if(pt(e))return{vars:yr(e),features:Be(e)};const t=Er(e);return{vars:t?[t]:[],features:Be(e)}}s(gr,"generateVariablesForToken");function Nr(e,t,n){if(!e||e==="default")return":root";const r=e.indexOf(":");if(r!==-1){const o=e.slice(0,r),i=e.slice(r+1);return`[${t?.find(l=>l.name===o)?.attribute??`data-${o}`}="${i}"]`}return`[${n.output.themeAttribute}="${e}"]`}s(Nr,"buildSelector");async function Tr(e,t,n){const r=hr(e).filter(([m,d])=>m!=="$extensions"&&"$type"in d).map(([m,d])=>gr(d)),o=Nr(n.context,n.modifiers,t),i=r.flatMap(m=>m.vars),a=r.flatMap(m=>m.features||[]),c=new Map;for(const m of a){c.has(m.query)||c.set(m.query,[]);const d=c.get(m.query);d&&d.push(...m.vars)}const l=Array.from(c.entries()).map(([m,d])=>({query:m,vars:d})),p=$r({root:{selector:o,vars:i},features:l});return p.trim()?{output:[{path:t.output.variablesFilename,css:Sr(p)}]}:{output:[{path:t.output.variablesFilename,css:""}]}}s(Tr,"generateCSS");function Sr(e){return e.endsWith(`
23
+ `)?e:`${e}
24
+ `}s(Sr,"formatCSSVars");async function br(e,t,n){const r=t.output.variables,o=[],i=Object.entries(e).sort(([a],[c])=>!a||a==="default"?-1:!c||c==="default"?1:a.localeCompare(c));for(const[a,c]of i){const l=await Tr(c,t,{context:a,modifiers:n});l.output[0].css.trim()&&o.push(l.output[0].css)}return o.length===0?[]:[{path:`${r}/${t.output.variablesFilename}`,css:`${o.filter(Boolean).join(`
25
+ `).trim()}
26
+ `}]}s(br,"generateSingleFile");async function Or(e,t,n){const r={};for(const[o,i]of Object.entries(e))Object.keys(i).length>0&&(r[o]=i);return{output:await br(r,t,n)}}s(Or,"generate");async function Ar(e,t,n){const{output:r}=await Or(e,t,n);return r}s(Ar,"generateCSSVariables");const L="--",A="-",Rr=["all","full"],Dr={top:"t",right:"r",bottom:"b",left:"l",x:"x",y:"y",full:"",all:""},_r={top:"block-start",right:"inline-end",bottom:"block-end",left:"inline-start",x:"inline",y:"block"};function Lr(e){return Dr[e]}s(Lr,"getDirectionAbbreviation");function He(e,t){if(t==="full"||t==="all")return e;const n=_r[t];return n?`${e}${A}${n}`:e}s(He,"getLogicalProperty");const vr=["top","right","bottom","left","x","y","full"];function xr(e){return(Array.isArray(e)?e:[e]).flatMap(n=>n==="all"?vr:[n])}s(xr,"expandDirections");function Fr(e,t){const r={color:["color"],"background-color":["color"],"border-color":["color"],"font-size":["dimension","fluidDimension"],"font-weight":["fontWeight"],"line-height":["number"],"border-radius":["dimension","fluidDimension"],"border-width":["dimension","fluidDimension"],padding:["dimension","fluidDimension"],margin:["dimension","fluidDimension"],width:["dimension","fluidDimension"],height:["dimension","fluidDimension"],gap:["dimension","fluidDimension"],"font-family":["fontFamily"],"transition-duration":["duration"],"transition-timing-function":["cubicBezier"],"border-style":["strokeStyle"],"box-shadow":["shadow"],"text-shadow":["shadow"],"background-image":["gradient"],opacity:["number"]}[t];return r?r.includes(e):!0}s(Fr,"isTokenTypeValidForProperty");const Ke=new WeakMap,D=new Map;function Cr(){D.clear()}s(Cr,"clearMatchCache");function Vr(e){const t=Ke.get(e);if(t)return t;const n=new Map;for(const r of Object.values(e)){if(!("$path"in r))continue;const o=r;n.set(o.$path,o)}return Ke.set(e,n),n}s(Vr,"buildPathIndex");function wr(e){if(e.default)return e.default;const t=Object.keys(e);return t.length>0&&t[0]?e[t[0]]:null}s(wr,"getDefaultContextTokens");function H(e,t,n){const r=`${t.source}:${t.prefix??""}:${t.property??""}:${e}`;if(D.has(r))return D.get(r)??null;const o=[t.source.replace("*",e),t.source.replace("*",e.split("-").join("."))];if(t.stripDuplicates&&t.prefix){const c=t.source.lastIndexOf(".*");if(c!==-1){const l=t.source.slice(0,c);l&&o.push(`${l}.${t.prefix}.${e}`,`${l}.${t.prefix}.${e.split("-").join(".")}`)}}const i=wr(n);if(!i)return D.set(r,null),null;const a=Vr(i);for(const c of o){const l=a.get(c);if(l){if(t.property&&l.$type&&!Fr(l.$type,t.property))continue;const p=l.$path.split(".");return D.set(r,p),p}}return D.set(r,null),null}s(H,"findMatchingToken");function ie(e,t){return t.stripDuplicates&&t.prefix&&e.startsWith(`${t.prefix}-`)?e.slice(t.prefix.length+1):e}s(ie,"stripDuplicatePrefix");function K(e,t=""){const n=e??"",r=n||t?A:"";return new RegExp(`^${n}${t}${r}(.+)$`)}s(K,"createUtilityPattern");function ae(e,t,n){return[K(t.prefix),o=>{const i=o[1];if(!i)return{};const a=ie(i,t),c={...t,property:e},l=H(a,c,n);return l?{[e]:`var(${L}${l.join(A)})`}:{}}]}s(ae,"createSimpleRule");function kr(e,t,n,r){if(n==="all")return ae(e,t,r);const o=Lr(n);return[K(t.prefix,o),a=>{const c=a[1];if(!c)return{};const l=ie(c,t),p={...t,property:e},m=H(l,p,r);return m?{[He(e,n)]:`var(${L}${m.join(A)})`}:{}}]}s(kr,"createDirectionalRule");function Mr(e,t){return[K(e),r=>{const o=r[1];if(!o)return{};for(const{property:i,config:a,direction:c,tokens:l}of t){const p=ie(o,a),m={...a,property:i},d=H(p,m,l);if(d)return c?{[He(i,c)]:`var(${L}${d.join(A)})`}:{[i]:`var(${L}${d.join(A)})`}}return{}}]}s(Mr,"createSmartRule");function jr(e,t,n){const r=t.source.indexOf("."),o=r!==-1?t.source.slice(0,r):t.source;return[K(o),a=>{const c=a[1];if(!c)return{};const l={...t,property:e},p=H(c,l,n);return p?{[e]:`var(${L}${p.join(A)})`}:{}}]}s(jr,"createDirectTokenPathRule");function Pr(e,t){if(!e?.source||typeof e.source!="string")throw new Error(u.UTILITIES.MISSING_SOURCE(t));if(e.source.includes("*")&&!e.source.endsWith(".*"))throw new Error(u.UTILITIES.INVALID_SOURCE_PATTERN(t,e.source));if(e.directions&&!Array.isArray(e.directions))throw new Error(u.UTILITIES.INVALID_DIRECTIONS(t))}s(Pr,"validateUtilityConfig");function Ur(e,t){if(!e||typeof e!="object")throw new Error(u.UTILITIES.INVALID_CONFIG_OBJECT);if(!t||typeof t!="object")throw new Error(u.UTILITIES.INVALID_TOKENS_OBJECT)}s(Ur,"validateInputs");function Gr(e,t){Ur(e,t);const n=[],r={};for(const[o,i]of Object.entries(e)){const a=Array.isArray(i)?i:[i];for(const c of a)if(Pr(c,o),c.prefix){const l=c.prefix;r[l]||(r[l]=[]),r[l].push({property:o,config:c,direction:null,tokens:t})}else{const l=jr(o,c,t);n.push(l)}}for(const[o,i]of Object.entries(r))if(i.length===1){const a=i[0];if(!a)continue;const{property:c,config:l,tokens:p}=a;if(l.directions){const m=xr(l.directions);(Array.isArray(l.directions)?l.directions:[l.directions]).includes("all")&&n.push(ae(c,l,p));for(const E of m)Rr.includes(E)||n.push(kr(c,l,E,p))}else n.push(ae(c,l,p))}else n.push(Mr(o,i));return n}s(Gr,"convertConfigToUnoRules");const v=process.env.SUGARCUBE_PERF==="true";class Wr{static{s(this,"PerfMonitor")}constructor(t=n=>void process.stderr.write(`${n}
27
+ `)){this.defaultFlush=t}#n=0;#t=0;#e=Date.now();#r=null;#o=0;#s(){return Math.round(process.memoryUsage().heapUsed/1024/1024)}#i(){return new Date().toISOString().split("T")[1]?.slice(0,-1)??""}log(t,n){if(!v)return;const r=this.#i(),o=this.#s(),i=o-this.#n;this.#n=o,this.defaultFlush(`[perf ${r}] ${t} ${n?JSON.stringify(n):""} | heap: ${o}MB (${i>=0?"+":""}${i}MB)`)}trackWatcherEvent(t,n){if(!v)return;this.#t++;const r=Date.now(),o=t.split("/").slice(-3).join("/");this.log(`WATCHER EVENT #${this.#t}: ${o}`),r-this.#e>1e4&&(this.log("WATCHER STATS (last 10s)",{events:this.#t,moduleGraphSize:n}),this.#t=0,this.#e=r)}logWatcherSetup(t,n){v&&this.log("WATCHER SETUP: Adding watch pattern",{pattern:t,dir:n})}logModuleGraphStats(t,n,r){v&&this.log(`MODULE GRAPH (${r})`,{modules:t,urls:n})}startMemoryMonitor(){!v||this.#r||(this.log("PERF MONITORING ENABLED - Starting memory monitor"),this.#o=this.#s(),this.#r=setInterval(()=>{const t=this.#s(),n=t-this.#o;Math.abs(n)>5&&(this.log("MEMORY CHANGE",{from:this.#o,to:t,delta:n}),this.#o=t)},5e3))}stopMemoryMonitor(){this.#r&&(clearInterval(this.#r),this.#r=null)}[Symbol.dispose](){this.stopMemoryMonitor()}}class qe extends Map{static{s(this,"DefaultMap")}constructor(t){super(),this.factory=t}get(t){let n=super.get(t);return n===void 0&&(n=this.factory(t,this),this.set(t,n)),n}}const Br=process.env.DEBUG==="true";class Yr{static{s(this,"Instrumentation")}constructor(t=n=>void process.stderr.write(`${n}
28
+ `)){this.defaultFlush=t}#n=new qe(()=>({value:0}));#t=new qe(()=>({value:0n}));#e=[];hit(t){this.#n.get(t).value++}start(t){const n=this.#e.map(o=>o.label).join("//"),r=`${n}${n.length===0?"":"//"}${t}`;this.#n.get(r).value++,this.#t.get(r),this.#e.push({id:r,label:t,namespace:n,value:process.hrtime.bigint()})}end(t){const n=process.hrtime.bigint();if(this.#e.length===0)throw new Error("Timer stack is empty");const r=this.#e.length-1,o=this.#e[r];if(!o)throw new Error("Timer stack is corrupted");if(o.label!==t)throw new Error(`Mismatched timer label: ${t}`);const i=this.#e.pop();if(!i)throw new Error("Timer stack is empty");const a=n-i.value;this.#t.get(i.id).value+=a}report(t=this.defaultFlush){const n=[];let r=!1;for(let o=this.#e.length-1;o>=0;o--){const i=this.#e[o];i&&this.end(i.label)}for(const[o,{value:i}]of this.#n.entries()){if(this.#t.has(o))continue;n.length===0&&(r=!0,n.push("Hits:"));const a=o.split("//").length;n.push(`${" ".repeat(a)}${o} \xD7 ${i}`)}if(this.#t.size>0){r&&n.push(`
29
+ Timers:`);for(const[o,{value:i}]of this.#t){const a=o.split("//").length,c=`${(Number(i)/1e6).toFixed(2)}ms`;n.push(`${" ".repeat(a-1)}${o.split("//").pop()} [${c}] ${this.#n.get(o).value===1?"":`\xD7 ${this.#n.get(o).value}`}`.trimEnd())}}t(`
30
+ ${n.join(`
31
+ `)}
32
+ `)}[Symbol.dispose](){Br&&this.report()}}async function Hr(e){for(const t of e)try{await fe(z(t.path),{recursive:!0}),await pe(t.path,t.css,"utf-8")}catch(n){throw new Error(`Failed to write CSS file ${t.path}: ${n instanceof Error?n.message:"Unknown error"}`)}return e}s(Hr,"writeCSSVariablesToDisk");async function Kr(e){for(const t of e)try{await fe(z(t.path),{recursive:!0}),await pe(t.path,t.css,"utf-8")}catch(n){throw new Error(`Failed to write utility CSS file ${t.path}: ${n instanceof Error?n.message:"Unknown error"}`)}return e}s(Kr,"writeCSSUtilitiesToDisk");export{b as DEFAULT_CONFIG,Yr as Instrumentation,Wr as PerfMonitor,Cr as clearMatchCache,it as configFileExists,Gr as convertConfigToUnoRules,tt as defineConfig,C as fillDefaults,J as findResolverDocument,Ar as generateCSSVariables,st as isNoConfigError,Un as loadAndResolveTokens,lt as loadInternalConfig,ut as loadSugarcubeConfig,mr as processAndConvertTokens,ot as validateConfig,Kr as writeCSSUtilitiesToDisk,Hr as writeCSSVariablesToDisk};
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "@sugarcube-sh/core",
3
+ "version": "0.1.0",
4
+ "publishConfig": {
5
+ "access": "public",
6
+ "provenance": false
7
+ },
8
+ "description": "Core functionality for sugarcube",
9
+ "license": "MIT",
10
+ "author": {
11
+ "name": "Mark Tomlinson",
12
+ "email": "mark@marktomlinson.dev",
13
+ "url": "https://marktomlinson.dev"
14
+ },
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://github.com/sugarcube-sh/sugarcube"
18
+ },
19
+ "bugs": {
20
+ "url": "https://github.com/sugarcube-sh/sugarcube/issues"
21
+ },
22
+ "keywords": [
23
+ "design-tokens",
24
+ "design-system",
25
+ "cube-css",
26
+ "css",
27
+ "sugarcube"
28
+ ],
29
+ "main": "./dist/index.js",
30
+ "types": "./dist/index.d.ts",
31
+ "type": "module",
32
+ "exports": {
33
+ ".": "./dist/index.js"
34
+ },
35
+ "engines": {
36
+ "node": ">=18.0.0"
37
+ },
38
+ "files": [
39
+ "dist",
40
+ "README.md",
41
+ "LICENSE.md"
42
+ ],
43
+ "scripts": {
44
+ "build": "pkgroll --minify",
45
+ "build:clean": "rm -rf dist && pkgroll --minify",
46
+ "dev": "pkgroll --watch",
47
+ "test": "vitest run",
48
+ "test:watch": "vitest",
49
+ "test:coverage": "vitest run --coverage",
50
+ "test:bench": "vitest bench --no-watch",
51
+ "test:bench:save": "vitest bench --no-watch --outputJson benchmarks/$(date +%Y-%m-%d)-results.json",
52
+ "test:bench:compare": "./scripts/bench-compare.sh",
53
+ "type-check": "tsc --noEmit"
54
+ },
55
+ "devDependencies": {
56
+ "pkgroll": "2.5.1",
57
+ "vitest": "2.1.1"
58
+ },
59
+ "dependencies": {
60
+ "jiti": "2.4.2",
61
+ "pathe": "2.0.3",
62
+ "tinyglobby": "^0.2.9",
63
+ "zod": "^3.23.8"
64
+ }
65
+ }