@master/css-binding 0.0.0-site.1793659883.g69c9aebcf628

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.
Files changed (66) hide show
  1. package/artifacts/mastercss.node +0 -0
  2. package/artifacts/mcss +0 -0
  3. package/dist/binding-options.d.ts +14 -0
  4. package/dist/binding-options.js +15 -0
  5. package/dist/binding.d.ts +12 -0
  6. package/dist/binding.js +23 -0
  7. package/dist/browser.d.ts +3 -0
  8. package/dist/browser.js +3 -0
  9. package/dist/compiler-binding-adapter.js +55 -0
  10. package/dist/compiler-binding-browser.d.ts +6 -0
  11. package/dist/compiler-binding-browser.js +24 -0
  12. package/dist/compiler-binding-contract.d.ts +45 -0
  13. package/dist/compiler-binding-node.d.ts +5 -0
  14. package/dist/compiler-binding-node.js +20 -0
  15. package/dist/compiler-binding-wasm.js +58 -0
  16. package/dist/compiler-binding.d.ts +6 -0
  17. package/dist/compiler-binding.js +42 -0
  18. package/dist/compiler.js +52 -0
  19. package/dist/engine-binding-adapter.js +61 -0
  20. package/dist/engine-binding-browser.d.ts +8 -0
  21. package/dist/engine-binding-browser.js +35 -0
  22. package/dist/engine-binding-js.js +81 -0
  23. package/dist/engine-binding-node.d.ts +9 -0
  24. package/dist/engine-binding-node.js +38 -0
  25. package/dist/engine-binding-wasm.js +64 -0
  26. package/dist/engine-binding.d.ts +40 -0
  27. package/dist/engine-binding.js +57 -0
  28. package/dist/engine-contract.d.ts +14 -0
  29. package/dist/engine-js/src/animation.js +154 -0
  30. package/dist/engine-js/src/apply.js +207 -0
  31. package/dist/engine-js/src/class-syntax.js +333 -0
  32. package/dist/engine-js/src/condition.js +440 -0
  33. package/dist/engine-js/src/css-syntax.js +247 -0
  34. package/dist/engine-js/src/generate.js +288 -0
  35. package/dist/engine-js/src/mixin.js +328 -0
  36. package/dist/engine-js/src/native-properties.js +5 -0
  37. package/dist/engine-js/src/order.js +97 -0
  38. package/dist/engine-js/src/program-model.js +19 -0
  39. package/dist/engine-js/src/program.js +434 -0
  40. package/dist/engine-js/src/selector.js +195 -0
  41. package/dist/engine-js/src/session.js +540 -0
  42. package/dist/engine-js/src/state.js +62 -0
  43. package/dist/engine-js/src/text.js +51 -0
  44. package/dist/engine-js/src/utility.js +236 -0
  45. package/dist/engine-js/src/value.js +254 -0
  46. package/dist/engine.js +86 -0
  47. package/dist/errors.js +10 -0
  48. package/dist/index.d.ts +4 -0
  49. package/dist/index.js +3 -0
  50. package/dist/native-loader.js +134 -0
  51. package/dist/normalize-error.js +63 -0
  52. package/dist/protocol.d.ts +1119 -0
  53. package/dist/protocol.js +14 -0
  54. package/dist/tooling-binding-adapter.js +23 -0
  55. package/dist/tooling-binding-browser.d.ts +5 -0
  56. package/dist/tooling-binding-browser.js +15 -0
  57. package/dist/tooling-binding-contract.d.ts +92 -0
  58. package/dist/tooling-binding-native.js +46 -0
  59. package/dist/tooling-binding-node.d.ts +4 -0
  60. package/dist/tooling-binding-node.js +11 -0
  61. package/dist/tooling-binding-wasm.js +127 -0
  62. package/dist/tooling-binding.d.ts +5 -0
  63. package/dist/tooling-binding.js +21 -0
  64. package/dist/tooling.js +144 -0
  65. package/dist/version.js +3 -0
  66. package/package.json +78 -0
@@ -0,0 +1,97 @@
1
+ import { asciiLowercase, compareText, isAsciiDigit } from "./text.js";
2
+ // ../engine-js/src/order.ts
3
+ const sign = (value) => value < 0 ? -1 : value > 0 ? 1 : 0;
4
+ /** Rust `f64::total_cmp`; condition bounds are never NaN. */
5
+ const compareNumber = (left, right) => left < right ? -1 : left > right ? 1 : Object.is(left, right) ? 0 : Object.is(left, -0) ? -1 : Object.is(right, -0) ? 1 : 0;
6
+ /** Text order that compares runs of ASCII digits by value, then by spelling. */
7
+ function naturalCompare(left, right) {
8
+ let i = 0;
9
+ const length = Math.min(left.length, right.length);
10
+ while (i < length && left.charCodeAt(i) === right.charCodeAt(i)) i++;
11
+ if (i === left.length && i === right.length) return 0;
12
+ while (i > 0 && isAsciiDigit(left.charCodeAt(i - 1))) i--;
13
+ let j = i;
14
+ for (;;) {
15
+ if (i >= left.length) return j >= right.length ? 0 : -1;
16
+ if (j >= right.length) return 1;
17
+ if (isAsciiDigit(left.charCodeAt(i)) && isAsciiDigit(right.charCodeAt(j))) {
18
+ const leftStart = i;
19
+ const rightStart = j;
20
+ while (isAsciiDigit(left.charCodeAt(i))) i++;
21
+ while (isAsciiDigit(right.charCodeAt(j))) j++;
22
+ const leftDigits = left.slice(leftStart, i);
23
+ const rightDigits = right.slice(rightStart, j);
24
+ const order = sign(leftDigits.replace(/^0+/, "").length - rightDigits.replace(/^0+/, "").length) || compareText(leftDigits, rightDigits);
25
+ if (order) return order;
26
+ continue;
27
+ }
28
+ const leftPoint = left.codePointAt(i);
29
+ const rightPoint = right.codePointAt(j);
30
+ if (leftPoint !== rightPoint) return leftPoint < rightPoint ? -1 : 1;
31
+ i += leftPoint > 65535 ? 2 : 1;
32
+ j += rightPoint > 65535 ? 2 : 1;
33
+ }
34
+ }
35
+ const lower = (range) => range.lower ? range.lower.value : -Infinity;
36
+ const upper = (range) => range.upper ? range.upper.value : Infinity;
37
+ /** Rust `Option<bool>` order: `None` before `false` before `true`. */
38
+ const inclusiveRank = (bound) => bound ? bound.inclusive ? 2 : 1 : 0;
39
+ function compareConditionFeatures(left, right) {
40
+ for (let index = 0; index < Math.max(left.length, right.length); index++) {
41
+ if (index >= left.length) return -1;
42
+ if (index >= right.length) return 1;
43
+ const a = left[index];
44
+ const b = right[index];
45
+ const identity = naturalCompare(a.domain, b.domain) || naturalCompare(a.feature, b.feature) || naturalCompare(a.unit, b.unit);
46
+ if (identity) return identity;
47
+ const order = (!a.upper && !b.upper ? compareNumber(lower(a), lower(b)) : !a.lower && !b.lower ? compareNumber(upper(b), upper(a)) : 0) || compareNumber(upper(b) - lower(b), upper(a) - lower(a)) || compareNumber(lower(b), lower(a)) || compareNumber(upper(b), upper(a)) || sign(inclusiveRank(b.lower) - inclusiveRank(a.lower)) || sign(inclusiveRank(b.upper) - inclusiveRank(a.upper));
48
+ if (order) return order;
49
+ }
50
+ return 0;
51
+ }
52
+ function compareConditions(left = [], right = []) {
53
+ for (let index = 0; index < Math.min(left.length, right.length); index++) {
54
+ const order = compareText(left[index], right[index]);
55
+ if (order) return order;
56
+ }
57
+ return sign(left.length - right.length);
58
+ }
59
+ function compareStoredRules(left, right) {
60
+ const a = left.ir;
61
+ const b = right.ir;
62
+ const p = a.priority;
63
+ const q = b.priority;
64
+ return sign(a.sortTier - b.sortTier) || compareConditionFeatures(left.features, right.features) || compareConditions(p.conditions, q.conditions) || sign(p.selector - q.selector) || sign(p.category - q.category) || compareText(p.family ?? "", q.family ?? "") || sign((p.coverage ?? 0) - (q.coverage ?? 0)) || p.category !== 1 && sign(a.type - b.type) || sign((p.valuePriority ?? 0) - (q.valuePriority ?? 0)) || compareText(p.property ?? "", q.property ?? "") || naturalCompare(p.sortKey ?? "", q.sortKey ?? "") || naturalCompare(a.key, b.key);
65
+ }
66
+ const atomicShape = (property, value) => {
67
+ const [family, coverage] = propertyFamily(property);
68
+ return {
69
+ category: 1,
70
+ family,
71
+ coverage,
72
+ property,
73
+ content: `${property}:${value}`
74
+ };
75
+ };
76
+ const BOX = /^(margin|padding|scroll-margin|scroll-padding|inset)(-(inline|block)(-start|-end)?|-(top|right|bottom|left))?$/;
77
+ const BORDER = /^border(-(inline|block)(-start|-end)?|-(top|right|bottom|left))?-(width|style|color)$/;
78
+ const AXIS = /^(?:(row|column)-gap|overflow-(?:x|y|inline|block))$/;
79
+ const CORNER = /^border-(?:(?:top|bottom)-(?:left|right)|(?:start|end)-(?:start|end))-radius$/;
80
+ const coverage = (side, axis, end) => side || end ? 2 : axis ? 1 : 0;
81
+ /**
82
+ * The family a property belongs to and its coverage in it, as `property_family` in the
83
+ * engine's ordering.rs: 0 sets the whole family, 1 an axis and 2 one side or corner.
84
+ * Custom properties are case-sensitive families of their own; other unlisted
85
+ * properties, shorthands included, are their own family.
86
+ */
87
+ function propertyFamily(property) {
88
+ if (property.startsWith("--")) return [property, 0];
89
+ property = asciiLowercase(property);
90
+ let match = BOX.exec(property);
91
+ if (match) return [match[1], coverage(match[5], match[3], match[4])];
92
+ if (/^(top|right|bottom|left)$/.test(property)) return ["inset", 2];
93
+ if (match = BORDER.exec(property)) return [`border-${match[5]}`, coverage(match[4], match[2], match[3])];
94
+ if (match = AXIS.exec(property)) return [match[1] ? "gap" : "overflow", 1];
95
+ return CORNER.test(property) ? ["border-radius", 2] : [property, 0];
96
+ }
97
+ export { atomicShape, compareConditionFeatures, compareStoredRules, naturalCompare, propertyFamily };
@@ -0,0 +1,19 @@
1
+ // ../engine-js/src/program-model.ts
2
+ const MIXIN_PARAMETER_SYNTAXES = [
3
+ "integer",
4
+ "number",
5
+ "string",
6
+ "custom-ident"
7
+ ];
8
+ const UTILITY_KINDS = [
9
+ "static",
10
+ "token",
11
+ "function"
12
+ ];
13
+ const UTILITY_LAYERS = [
14
+ "base",
15
+ "defaults",
16
+ "components",
17
+ "utilities"
18
+ ];
19
+ export { MIXIN_PARAMETER_SYNTAXES, UTILITY_KINDS, UTILITY_LAYERS };
@@ -0,0 +1,434 @@
1
+ import { MIXIN_PARAMETER_SYNTAXES, UTILITY_KINDS } from "./program-model.js";
2
+ import { selectedInlineValue } from "./value.js";
3
+ const MAGIC = [
4
+ 77,
5
+ 67,
6
+ 83,
7
+ 80
8
+ ];
9
+ const MAX_DEPTH = 512;
10
+ const MAX_U32 = 4294967295;
11
+ var Malformed = class {
12
+ code;
13
+ message;
14
+ constructor(code, message) {
15
+ this.code = code;
16
+ this.message = message;
17
+ }
18
+ };
19
+ const invalid = (message) => {
20
+ throw new Malformed("INVALID_PROGRAM", message);
21
+ };
22
+ let bytes;
23
+ let view;
24
+ let position;
25
+ let strings;
26
+ let used;
27
+ let depth;
28
+ function byte() {
29
+ if (position >= bytes.length) invalid("truncated");
30
+ return bytes[position++];
31
+ }
32
+ /** An unsigned LEB128 varint. Values past 2^53 lose precision, but every use rejects them anyway. */
33
+ function uint() {
34
+ let value = 0;
35
+ for (let shift = 0; shift < 64; shift += 7) {
36
+ const current = byte();
37
+ const bits = current & 127;
38
+ if (shift === 63 && bits > 1) invalid("integer overflow");
39
+ value += bits * 2 ** shift;
40
+ if (!(current & 128)) return value;
41
+ }
42
+ return invalid("integer overflow");
43
+ }
44
+ function u32() {
45
+ const value = uint();
46
+ return value > MAX_U32 ? invalid("integer overflow") : value;
47
+ }
48
+ function i32() {
49
+ const value = uint();
50
+ const decoded = value % 2 ? -(value + 1) / 2 : value / 2;
51
+ return decoded > 2147483647 || decoded < -2147483648 ? invalid("integer overflow") : decoded;
52
+ }
53
+ function length() {
54
+ const value = uint();
55
+ return value > bytes.length - position ? invalid("length exceeds input") : value;
56
+ }
57
+ function tag(variants) {
58
+ const value = byte();
59
+ return value >= variants ? invalid("unknown variant") : value;
60
+ }
61
+ function string() {
62
+ const reference = uint();
63
+ let index;
64
+ if (reference === 0) index = used++;
65
+ else if (reference - 1 < used) index = reference - 1;
66
+ else return invalid("unknown string");
67
+ return index < strings.length ? strings[index] : invalid("unknown string");
68
+ }
69
+ const bool = () => tag(2) === 1;
70
+ const f64 = () => {
71
+ if (position + 8 > bytes.length) invalid("truncated");
72
+ const value = view.getFloat64(position, true);
73
+ position += 8;
74
+ return value;
75
+ };
76
+ const option = (decode) => tag(2) === 1 ? decode() : void 0;
77
+ function vec(decode) {
78
+ const count = length();
79
+ const items = [];
80
+ for (let index = 0; index < count; index++) items.push(decode());
81
+ return items;
82
+ }
83
+ function nested(decode) {
84
+ if (++depth > MAX_DEPTH) invalid("nesting too deep");
85
+ const value = decode();
86
+ depth--;
87
+ return value;
88
+ }
89
+ const stringList = () => vec(string);
90
+ const position32 = () => ({
91
+ line: u32(),
92
+ column: u32()
93
+ });
94
+ const sourceReference = () => {
95
+ return {
96
+ file: option(string),
97
+ range: {
98
+ start: u32(),
99
+ end: u32()
100
+ },
101
+ loc: option(() => ({
102
+ start: position32(),
103
+ end: position32()
104
+ }))
105
+ };
106
+ };
107
+ const source = () => option(sourceReference);
108
+ function themeNode() {
109
+ return nested(() => tag(2) === 0 ? {
110
+ type: "rule",
111
+ prelude: string(),
112
+ children: vec(themeNode)
113
+ } : {
114
+ type: "declaration",
115
+ name: string(),
116
+ value: string(),
117
+ inline: bool(),
118
+ isStatic: bool()
119
+ });
120
+ }
121
+ function keyframe() {
122
+ return {
123
+ id: string(),
124
+ name: string(),
125
+ text: string(),
126
+ containers: vec(() => ({
127
+ id: string(),
128
+ prelude: string()
129
+ })),
130
+ native: bool(),
131
+ safelisted: bool(),
132
+ dependencies: stringList(),
133
+ source: source()
134
+ };
135
+ }
136
+ function mediaQuery() {
137
+ return nested(() => {
138
+ switch (tag(7)) {
139
+ case 0: return { type: "true" };
140
+ case 1: return { type: "false" };
141
+ case 2: return {
142
+ type: "feature",
143
+ value: string()
144
+ };
145
+ case 3: return {
146
+ type: "media-type",
147
+ name: string()
148
+ };
149
+ case 4: return {
150
+ type: "not",
151
+ query: mediaQuery()
152
+ };
153
+ case 5: return {
154
+ type: "and",
155
+ queries: vec(mediaQuery)
156
+ };
157
+ default: return {
158
+ type: "or",
159
+ queries: vec(mediaQuery)
160
+ };
161
+ }
162
+ });
163
+ }
164
+ function valuePart() {
165
+ return nested(() => tag(2) === 0 ? {
166
+ type: "text",
167
+ value: string()
168
+ } : {
169
+ type: "function",
170
+ name: string(),
171
+ value: vec(valuePart)
172
+ });
173
+ }
174
+ const mixinValue = () => vec(valuePart);
175
+ function mixinNode() {
176
+ return nested(() => {
177
+ switch (tag(5)) {
178
+ case 0: return {
179
+ type: "declaration",
180
+ property: string(),
181
+ value: mixinValue(),
182
+ source: source()
183
+ };
184
+ case 1: return {
185
+ type: "rule",
186
+ selector: string(),
187
+ body: vec(mixinNode)
188
+ };
189
+ case 2: return {
190
+ type: "condition",
191
+ condition: string(),
192
+ body: vec(mixinNode)
193
+ };
194
+ case 3: return {
195
+ type: "apply",
196
+ name: string(),
197
+ arguments: vec(mixinValue),
198
+ contents: option(() => vec(mixinNode)),
199
+ source: source()
200
+ };
201
+ default: return {
202
+ type: "contents",
203
+ fallback: vec(mixinNode)
204
+ };
205
+ }
206
+ });
207
+ }
208
+ const mixinDefinition = () => ({
209
+ name: string(),
210
+ parameters: vec(() => ({
211
+ name: string(),
212
+ syntax: option(() => MIXIN_PARAMETER_SYNTAXES[tag(4)]),
213
+ default: option(string),
214
+ source: source()
215
+ })),
216
+ body: vec(mixinNode),
217
+ source: source()
218
+ });
219
+ const tokenFamily = () => ({
220
+ utility: string(),
221
+ prefix: string(),
222
+ namespace: string(),
223
+ argument: tag(2) === 0 ? "value" : "key",
224
+ properties: stringList()
225
+ });
226
+ function variable() {
227
+ const key = string();
228
+ const namespace = string();
229
+ const name = option(string) ?? (!namespace ? key : !key ? namespace : `${namespace}-${key}`);
230
+ const values = vec(() => ({
231
+ path: stringList(),
232
+ value: string(),
233
+ inline: bool(),
234
+ isStatic: bool()
235
+ }));
236
+ return {
237
+ name,
238
+ key,
239
+ namespace,
240
+ values,
241
+ numeric: option(() => ({
242
+ value: f64(),
243
+ unit: string()
244
+ })),
245
+ variableType: string(),
246
+ dependencies: stringList(),
247
+ inlineValue: selectedInlineValue(values),
248
+ isStatic: values.some((value) => value.isStatic)
249
+ };
250
+ }
251
+ function matcher() {
252
+ switch (tag(3)) {
253
+ case 0: return {
254
+ type: "static",
255
+ name: string()
256
+ };
257
+ case 1: return {
258
+ type: "token",
259
+ prefix: string()
260
+ };
261
+ default: return {
262
+ type: "function",
263
+ name: string()
264
+ };
265
+ }
266
+ }
267
+ const utility = () => ({
268
+ id: string(),
269
+ name: option(string),
270
+ utilityType: i32(),
271
+ variableAliasRefs: stringList(),
272
+ nativeFallback: false,
273
+ emit: tag(2) === 0 ? {
274
+ type: "recipe",
275
+ definition: u32(),
276
+ key: bool()
277
+ } : {
278
+ type: "property",
279
+ property: string()
280
+ },
281
+ matchers: vec(matcher)
282
+ });
283
+ /** `CSS.escape` as `mastercss_lexer::css_escape` implements it, code unit by code unit. */
284
+ function cssEscape(value) {
285
+ if (value === "-") return "\\-";
286
+ let result = "";
287
+ for (let index = 0; index < value.length; index++) {
288
+ const unit = value.charCodeAt(index);
289
+ const digit = unit >= 48 && unit <= 57;
290
+ if (unit === 0) result += "�";
291
+ else if (unit <= 31 || unit === 127 || index === 0 && digit || index === 1 && digit && value.charCodeAt(0) === 45) result += `\\${unit.toString(16)} `;
292
+ else if (unit >= 128) result += unit >= 55296 && unit <= 57343 ? "�" : value[index];
293
+ else if (unit === 45 || unit === 95 || digit || unit >= 65 && unit <= 90 || unit >= 97 && unit <= 122) result += value[index];
294
+ else result += `\\${value[index]}`;
295
+ }
296
+ return result;
297
+ }
298
+ /** Disjunction of conjunctions of native media queries, as `custom_media_branches` builds it. */
299
+ function customMediaBranches(query) {
300
+ let remaining = 32768;
301
+ const branches = (query, negate, level) => {
302
+ if (remaining === 0 || level > 128) return;
303
+ remaining--;
304
+ switch (query.type) {
305
+ case "true": return negate ? [] : [[]];
306
+ case "false": return negate ? [[]] : [];
307
+ case "feature": return [[negate ? `not ${query.value}` : query.value]];
308
+ case "media-type": {
309
+ const name = cssEscape(query.name);
310
+ return [[negate ? `not ${name}` : name]];
311
+ }
312
+ case "not": return branches(query.query, !negate, level + 1);
313
+ default: {
314
+ const and = query.type === "and" !== negate;
315
+ let result = and ? [[]] : [];
316
+ for (const item of query.queries) {
317
+ const next = branches(item, negate, level + 1);
318
+ if (!next) return;
319
+ if ((and ? result.length * next.length : result.length + next.length) > 4096) return;
320
+ result = and ? result.flatMap((prefix) => next.map((suffix) => [...prefix, ...suffix])) : [...result, ...next];
321
+ }
322
+ return result;
323
+ }
324
+ }
325
+ };
326
+ return branches(query, false, 0);
327
+ }
328
+ function push(map, key, value) {
329
+ const values = map.get(key);
330
+ if (values) values.push(value);
331
+ else map.set(key, [value]);
332
+ }
333
+ /** What `finish_program` derives: defaults, match order and indexes. */
334
+ function finish(program, encoded) {
335
+ const utilities = encoded.map((entry) => ({
336
+ ...entry,
337
+ name: entry.name ?? entry.id
338
+ }));
339
+ const isStatic = (entry) => entry.matchers.some((item) => item.type === "static");
340
+ program.utilities = [...utilities.filter(isStatic), ...utilities.filter((entry) => !isStatic(entry))];
341
+ for (const [index, entry] of program.utilities.entries()) for (const item of entry.matchers) if (item.type === "token") push(program.tokenUtilities, item.prefix, index);
342
+ else if (item.type === "function") program.functionUtilities.set(item.name, index);
343
+ else push(program.staticUtilities, item.name, index);
344
+ for (const prefix of program.tokenUtilities.keys()) push(program.tokenPrefixes, prefix[0] ?? "", prefix);
345
+ for (const prefixes of program.tokenPrefixes.values()) prefixes.sort((left, right) => right.length - left.length);
346
+ }
347
+ function decodeProgram(input) {
348
+ bytes = input;
349
+ view = new DataView(input.buffer, input.byteOffset, input.byteLength);
350
+ position = 0;
351
+ strings = [];
352
+ used = 0;
353
+ depth = 0;
354
+ try {
355
+ if (MAGIC.some((value, index) => input[index] !== value)) invalid("not a Master CSS program");
356
+ position = MAGIC.length;
357
+ if (uint() !== 3 || uint() !== 18) throw new Malformed("UNSUPPORTED_PROGRAM_VERSION", "unsupported program version");
358
+ const decoder = new TextDecoder("utf-8", {
359
+ fatal: true,
360
+ ignoreBOM: true
361
+ });
362
+ const count = length();
363
+ for (let index = 0; index < count; index++) {
364
+ const size = length();
365
+ try {
366
+ strings.push(decoder.decode(input.subarray(position, position + size)));
367
+ } catch {
368
+ invalid("invalid UTF-8");
369
+ }
370
+ position += size;
371
+ }
372
+ const program = {
373
+ theme: vec(themeNode),
374
+ keyframes: vec(keyframe),
375
+ animationVariables: new Map(vec(() => [string(), stringList()])),
376
+ customMedia: new Map(vec(() => [string(), mediaQuery()])),
377
+ customMediaPaths: /* @__PURE__ */ new Map(),
378
+ customContainers: new Map(vec(() => [string(), string()])),
379
+ mixins: vec(mixinDefinition),
380
+ utilityDefinitions: vec(() => ({
381
+ kind: UTILITY_KINDS[tag(3)],
382
+ recipe: mixinDefinition()
383
+ })),
384
+ tokenFamilies: vec(tokenFamily),
385
+ variables: /* @__PURE__ */ new Map(),
386
+ variableOrder: [],
387
+ hasInlineTokens: false,
388
+ utilities: [],
389
+ staticUtilities: /* @__PURE__ */ new Map(),
390
+ tokenUtilities: /* @__PURE__ */ new Map(),
391
+ functionUtilities: /* @__PURE__ */ new Map(),
392
+ tokenPrefixes: /* @__PURE__ */ new Map()
393
+ };
394
+ const variables = vec(variable);
395
+ const encoded = vec(utility);
396
+ if (position !== input.length || used !== strings.length) invalid("trailing bytes");
397
+ for (const entry of variables) {
398
+ program.variables.set(entry.name, entry);
399
+ program.variableOrder.push(entry.name);
400
+ if (entry.inlineValue !== void 0) program.hasInlineTokens = true;
401
+ }
402
+ if (program.variables.size !== variables.length) invalid("duplicate variable");
403
+ for (const entry of encoded) if (entry.emit.type === "recipe" && entry.emit.definition >= program.utilityDefinitions.length) invalid("unknown recipe");
404
+ for (const [name, query] of program.customMedia) {
405
+ const paths = customMediaBranches(query);
406
+ if (!paths) invalid("invalid custom media");
407
+ program.customMediaPaths.set(name, paths);
408
+ }
409
+ finish(program, encoded);
410
+ return {
411
+ ok: true,
412
+ program
413
+ };
414
+ } catch (error) {
415
+ if (error instanceof Malformed) return {
416
+ ok: false,
417
+ error: {
418
+ code: error.code,
419
+ message: error.message
420
+ }
421
+ };
422
+ if (error instanceof RangeError) return {
423
+ ok: false,
424
+ error: {
425
+ code: "INVALID_PROGRAM",
426
+ message: "nesting too deep"
427
+ }
428
+ };
429
+ throw error;
430
+ } finally {
431
+ bytes = view = strings = void 0;
432
+ }
433
+ }
434
+ export { cssEscape, customMediaBranches, decodeProgram };