design-constraint-validator 1.0.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 +21 -0
- package/README.md +659 -0
- package/adapters/README.md +46 -0
- package/adapters/css.d.ts +44 -0
- package/adapters/css.d.ts.map +1 -0
- package/adapters/css.js +97 -0
- package/adapters/css.ts +116 -0
- package/adapters/js.d.ts +3 -0
- package/adapters/js.d.ts.map +1 -0
- package/adapters/js.js +15 -0
- package/adapters/js.ts +14 -0
- package/adapters/json.d.ts +18 -0
- package/adapters/json.d.ts.map +1 -0
- package/adapters/json.js +35 -0
- package/adapters/json.ts +45 -0
- package/cli/build-css.d.ts +2 -0
- package/cli/build-css.d.ts.map +1 -0
- package/cli/build-css.js +23 -0
- package/cli/build-css.ts +32 -0
- package/cli/commands/build.d.ts +5 -0
- package/cli/commands/build.d.ts.map +1 -0
- package/cli/commands/build.js +89 -0
- package/cli/commands/build.ts +65 -0
- package/cli/commands/graph.d.ts +3 -0
- package/cli/commands/graph.d.ts.map +1 -0
- package/cli/commands/graph.js +219 -0
- package/cli/commands/graph.ts +137 -0
- package/cli/commands/index.d.ts +8 -0
- package/cli/commands/index.d.ts.map +1 -0
- package/cli/commands/index.js +7 -0
- package/cli/commands/index.ts +7 -0
- package/cli/commands/patch-apply.d.ts +3 -0
- package/cli/commands/patch-apply.d.ts.map +1 -0
- package/cli/commands/patch-apply.js +75 -0
- package/cli/commands/patch-apply.ts +80 -0
- package/cli/commands/patch.d.ts +3 -0
- package/cli/commands/patch.d.ts.map +1 -0
- package/cli/commands/patch.js +21 -0
- package/cli/commands/patch.ts +22 -0
- package/cli/commands/set.d.ts +3 -0
- package/cli/commands/set.d.ts.map +1 -0
- package/cli/commands/set.js +286 -0
- package/cli/commands/set.ts +225 -0
- package/cli/commands/utils.d.ts +4 -0
- package/cli/commands/utils.d.ts.map +1 -0
- package/cli/commands/utils.js +51 -0
- package/cli/commands/utils.ts +50 -0
- package/cli/commands/validate.d.ts +3 -0
- package/cli/commands/validate.d.ts.map +1 -0
- package/cli/commands/validate.js +131 -0
- package/cli/commands/validate.ts +115 -0
- package/cli/commands/why.d.ts +3 -0
- package/cli/commands/why.d.ts.map +1 -0
- package/cli/commands/why.js +64 -0
- package/cli/commands/why.ts +46 -0
- package/cli/config-schema.d.ts +238 -0
- package/cli/config-schema.d.ts.map +1 -0
- package/cli/config-schema.js +21 -0
- package/cli/config-schema.ts +27 -0
- package/cli/config.d.ts +4 -0
- package/cli/config.d.ts.map +1 -0
- package/cli/config.js +37 -0
- package/cli/config.ts +35 -0
- package/cli/dcv.d.ts +3 -0
- package/cli/dcv.d.ts.map +1 -0
- package/cli/dcv.js +86 -0
- package/cli/dcv.ts +107 -0
- package/cli/engine-helpers.d.ts +8 -0
- package/cli/engine-helpers.d.ts.map +1 -0
- package/cli/engine-helpers.js +70 -0
- package/cli/engine-helpers.ts +61 -0
- package/cli/graph-poset.d.ts +9 -0
- package/cli/graph-poset.d.ts.map +1 -0
- package/cli/graph-poset.js +58 -0
- package/cli/graph-poset.ts +74 -0
- package/cli/index.d.ts +3 -0
- package/cli/index.d.ts.map +1 -0
- package/cli/index.js +2 -0
- package/cli/index.ts +2 -0
- package/cli/result.d.ts +17 -0
- package/cli/result.d.ts.map +1 -0
- package/cli/result.js +29 -0
- package/cli/result.ts +27 -0
- package/cli/run.d.ts +3 -0
- package/cli/run.d.ts.map +1 -0
- package/cli/run.js +47 -0
- package/cli/run.ts +54 -0
- package/cli/smoke-test.d.ts +2 -0
- package/cli/smoke-test.d.ts.map +1 -0
- package/cli/smoke-test.js +33 -0
- package/cli/smoke-test.ts +40 -0
- package/cli/types.d.ts +86 -0
- package/cli/types.d.ts.map +1 -0
- package/cli/types.js +1 -0
- package/cli/types.ts +78 -0
- package/core/breakpoints.d.ts +12 -0
- package/core/breakpoints.d.ts.map +1 -0
- package/core/breakpoints.js +48 -0
- package/core/breakpoints.ts +50 -0
- package/core/cli-format.d.ts +8 -0
- package/core/cli-format.d.ts.map +1 -0
- package/core/cli-format.js +29 -0
- package/core/cli-format.ts +31 -0
- package/core/color.d.ts +14 -0
- package/core/color.d.ts.map +1 -0
- package/core/color.js +136 -0
- package/core/color.ts +148 -0
- package/core/constraints/cross-axis.d.ts +33 -0
- package/core/constraints/cross-axis.d.ts.map +1 -0
- package/core/constraints/cross-axis.js +93 -0
- package/core/constraints/cross-axis.ts +114 -0
- package/core/constraints/monotonic-lightness.d.ts +5 -0
- package/core/constraints/monotonic-lightness.d.ts.map +1 -0
- package/core/constraints/monotonic-lightness.js +37 -0
- package/core/constraints/monotonic-lightness.ts +38 -0
- package/core/constraints/monotonic.d.ts +7 -0
- package/core/constraints/monotonic.d.ts.map +1 -0
- package/core/constraints/monotonic.js +65 -0
- package/core/constraints/monotonic.ts +74 -0
- package/core/constraints/threshold.d.ts +10 -0
- package/core/constraints/threshold.d.ts.map +1 -0
- package/core/constraints/threshold.js +36 -0
- package/core/constraints/threshold.ts +43 -0
- package/core/constraints/wcag.d.ts +11 -0
- package/core/constraints/wcag.d.ts.map +1 -0
- package/core/constraints/wcag.js +53 -0
- package/core/constraints/wcag.ts +70 -0
- package/core/cross-axis-config.d.ts +5 -0
- package/core/cross-axis-config.d.ts.map +1 -0
- package/core/cross-axis-config.js +144 -0
- package/core/cross-axis-config.ts +152 -0
- package/core/engine.d.ts +32 -0
- package/core/engine.d.ts.map +1 -0
- package/core/engine.js +46 -0
- package/core/engine.ts +65 -0
- package/core/flatten.d.ts +20 -0
- package/core/flatten.d.ts.map +1 -0
- package/core/flatten.js +80 -0
- package/core/flatten.ts +116 -0
- package/core/image-export.d.ts +10 -0
- package/core/image-export.d.ts.map +1 -0
- package/core/image-export.js +43 -0
- package/core/image-export.ts +48 -0
- package/core/index.d.ts +31 -0
- package/core/index.d.ts.map +1 -0
- package/core/index.js +54 -0
- package/core/index.ts +72 -0
- package/core/patch.d.ts +28 -0
- package/core/patch.d.ts.map +1 -0
- package/core/patch.js +110 -0
- package/core/patch.ts +134 -0
- package/core/poset.d.ts +41 -0
- package/core/poset.d.ts.map +1 -0
- package/core/poset.js +275 -0
- package/core/poset.ts +311 -0
- package/core/why.d.ts +17 -0
- package/core/why.d.ts.map +1 -0
- package/core/why.js +45 -0
- package/core/why.ts +63 -0
- package/dist/test-overrides-removal.json +4 -0
- package/dist/tmp.patch.json +35 -0
- package/package.json +90 -0
- package/themes/color.lg.order.json +15 -0
- package/themes/color.md.order.json +15 -0
- package/themes/color.order.json +15 -0
- package/themes/color.sm.order.json +15 -0
- package/themes/cross-axis.rules.json +36 -0
- package/themes/cross-axis.sm.rules.json +12 -0
- package/themes/layout.lg.order.json +18 -0
- package/themes/layout.md.order.json +18 -0
- package/themes/layout.order.json +18 -0
- package/themes/layout.sm.order.json +18 -0
- package/themes/spacing.order.json +14 -0
- package/themes/typography.lg.order.json +15 -0
- package/themes/typography.md.order.json +15 -0
- package/themes/typography.order.json +15 -0
- package/themes/typography.sm.order.json +15 -0
- package/tokens/overrides/base.json +22 -0
- package/tokens/overrides/lg.json +20 -0
- package/tokens/overrides/md.json +16 -0
- package/tokens/overrides/sm.json +16 -0
- package/tokens/overrides/viol.color.json +6 -0
- package/tokens/overrides/viol.typography.json +6 -0
- package/tokens/tokens.demo-violations.json +116 -0
- package/tokens/tokens.example.json +128 -0
- package/tokens/tokens.json +67 -0
- package/tokens/tokens.multi-violations.json +21 -0
- package/tokens/tokens.schema.d.ts +2298 -0
- package/tokens/tokens.schema.d.ts.map +1 -0
- package/tokens/tokens.schema.js +148 -0
- package/tokens/tokens.schema.ts +196 -0
- package/tokens/tokens.test.json +38 -0
- package/tokens/tokens.touch-violation.json +8 -0
- package/tokens/typography.classes.css +11 -0
- package/tokens/typography.css +20 -0
package/cli/result.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export function ok(value) { return { ok: true, value }; }
|
|
2
|
+
export function err(error) { return { ok: false, error }; }
|
|
3
|
+
export function wrap(fn) {
|
|
4
|
+
try {
|
|
5
|
+
return ok(fn());
|
|
6
|
+
}
|
|
7
|
+
catch (e) {
|
|
8
|
+
return err(e);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export async function wrapAsync(fn) {
|
|
12
|
+
try {
|
|
13
|
+
return ok(await fn());
|
|
14
|
+
}
|
|
15
|
+
catch (e) {
|
|
16
|
+
return err(e);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export function map(r, f) {
|
|
20
|
+
return r.ok ? ok(f(r.value)) : r;
|
|
21
|
+
}
|
|
22
|
+
export function chain(r, f) {
|
|
23
|
+
return r.ok ? f(r.value) : r;
|
|
24
|
+
}
|
|
25
|
+
export function getOrThrow(r) {
|
|
26
|
+
if (!r.ok)
|
|
27
|
+
throw r.error; // consumer decides how to handle
|
|
28
|
+
return r.value;
|
|
29
|
+
}
|
package/cli/result.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export type Ok<T> = { ok: true; value: T };
|
|
2
|
+
export type Err<E> = { ok: false; error: E };
|
|
3
|
+
export type Result<T, E = Error> = Ok<T> | Err<E>;
|
|
4
|
+
|
|
5
|
+
export function ok<T>(value: T): Ok<T> { return { ok: true, value }; }
|
|
6
|
+
export function err<E>(error: E): Err<E> { return { ok: false, error }; }
|
|
7
|
+
|
|
8
|
+
export function wrap<T>(fn: () => T): Result<T, unknown> {
|
|
9
|
+
try { return ok(fn()); } catch (e) { return err(e); }
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export async function wrapAsync<T>(fn: () => Promise<T>): Promise<Result<T, unknown>> {
|
|
13
|
+
try { return ok(await fn()); } catch (e) { return err(e); }
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function map<T, U, E>(r: Result<T, E>, f: (v: T) => U): Result<U, E> {
|
|
17
|
+
return r.ok ? ok(f(r.value)) : r;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function chain<T, U, E>(r: Result<T, E>, f: (v: T) => Result<U, E>): Result<U, E> {
|
|
21
|
+
return r.ok ? f(r.value) : r;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function getOrThrow<T, E>(r: Result<T, E>): T {
|
|
25
|
+
if (!r.ok) throw r.error as any; // consumer decides how to handle
|
|
26
|
+
return r.value;
|
|
27
|
+
}
|
package/cli/run.d.ts
ADDED
package/cli/run.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["run.ts"],"names":[],"mappings":""}
|
package/cli/run.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env ts-node
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { flattenTokens } from "../core/flatten.js";
|
|
4
|
+
import { Engine } from "../core/engine.js";
|
|
5
|
+
import { WcagContrastPlugin } from "../core/constraints/wcag.js";
|
|
6
|
+
const tokensRoot = JSON.parse(readFileSync("tokens/tokens.example.json", "utf8"));
|
|
7
|
+
const { flat, edges } = flattenTokens(tokensRoot);
|
|
8
|
+
// Build init values map
|
|
9
|
+
const init = {};
|
|
10
|
+
for (const [id, t] of Object.entries(flat))
|
|
11
|
+
init[id] = t.value;
|
|
12
|
+
// Engine + plugin (example pairs; adjust IDs to your roles)
|
|
13
|
+
const engine = new Engine(init, edges).use(WcagContrastPlugin([
|
|
14
|
+
{ fg: "color.role.text.default", bg: "color.role.surface.default", min: 4.5, where: "Body text" },
|
|
15
|
+
{ fg: "color.role.accent.default", bg: "color.role.surface.default", min: 3.0, where: "Accent on surface" }
|
|
16
|
+
]));
|
|
17
|
+
// Apply overrides if present
|
|
18
|
+
let overrides = {};
|
|
19
|
+
try {
|
|
20
|
+
const maybe = JSON.parse(readFileSync("tokens/overrides/local.json", "utf8"));
|
|
21
|
+
overrides = maybe.overrides ?? maybe;
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
// File doesn't exist or invalid JSON, use empty overrides
|
|
25
|
+
}
|
|
26
|
+
import { patchToJson } from "../adapters/json.js";
|
|
27
|
+
import yargs from "yargs/yargs";
|
|
28
|
+
import { hideBin } from "yargs/helpers";
|
|
29
|
+
const argvPromise = yargs(hideBin(process.argv)).option('json', {
|
|
30
|
+
alias: 'j',
|
|
31
|
+
type: 'boolean',
|
|
32
|
+
description: 'Output result as JSON'
|
|
33
|
+
}).argv;
|
|
34
|
+
// ... existing code ...
|
|
35
|
+
(async () => {
|
|
36
|
+
const argv = await argvPromise;
|
|
37
|
+
for (const [id, val] of Object.entries(overrides)) {
|
|
38
|
+
const res = engine.commit(id, val);
|
|
39
|
+
if (argv.json) {
|
|
40
|
+
const jsonOutput = patchToJson(res);
|
|
41
|
+
console.log(JSON.stringify(jsonOutput, null, 2));
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
console.log(JSON.stringify(res, null, 2));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
})();
|
package/cli/run.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#!/usr/bin/env ts-node
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { flattenTokens } from "../core/flatten.js";
|
|
4
|
+
import { Engine } from "../core/engine.js";
|
|
5
|
+
import { WcagContrastPlugin } from "../core/constraints/wcag.js";
|
|
6
|
+
|
|
7
|
+
const tokensRoot = JSON.parse(readFileSync("tokens/tokens.example.json","utf8"));
|
|
8
|
+
const { flat, edges } = flattenTokens(tokensRoot);
|
|
9
|
+
|
|
10
|
+
// Build init values map
|
|
11
|
+
const init: Record<string, string|number> = {};
|
|
12
|
+
for (const [id, t] of Object.entries(flat)) init[id] = t.value;
|
|
13
|
+
|
|
14
|
+
// Engine + plugin (example pairs; adjust IDs to your roles)
|
|
15
|
+
const engine = new Engine(init, edges).use(
|
|
16
|
+
WcagContrastPlugin([
|
|
17
|
+
{ fg: "color.role.text.default", bg: "color.role.surface.default", min: 4.5, where: "Body text" },
|
|
18
|
+
{ fg: "color.role.accent.default", bg: "color.role.surface.default", min: 3.0, where: "Accent on surface" }
|
|
19
|
+
])
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
// Apply overrides if present
|
|
23
|
+
let overrides: Record<string, string|number> = {};
|
|
24
|
+
try {
|
|
25
|
+
const maybe = JSON.parse(readFileSync("tokens/overrides/local.json","utf8"));
|
|
26
|
+
overrides = maybe.overrides ?? maybe;
|
|
27
|
+
} catch {
|
|
28
|
+
// File doesn't exist or invalid JSON, use empty overrides
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
import { patchToJson } from "../adapters/json.js";
|
|
32
|
+
import yargs from "yargs/yargs";
|
|
33
|
+
import { hideBin } from "yargs/helpers";
|
|
34
|
+
|
|
35
|
+
const argvPromise = yargs(hideBin(process.argv)).option('json', {
|
|
36
|
+
alias: 'j',
|
|
37
|
+
type: 'boolean',
|
|
38
|
+
description: 'Output result as JSON'
|
|
39
|
+
}).argv;
|
|
40
|
+
|
|
41
|
+
// ... existing code ...
|
|
42
|
+
|
|
43
|
+
(async () => {
|
|
44
|
+
const argv = await argvPromise;
|
|
45
|
+
for (const [id, val] of Object.entries(overrides)) {
|
|
46
|
+
const res = engine.commit(id, val);
|
|
47
|
+
if (argv.json) {
|
|
48
|
+
const jsonOutput = patchToJson(res);
|
|
49
|
+
console.log(JSON.stringify(jsonOutput, null, 2));
|
|
50
|
+
} else {
|
|
51
|
+
console.log(JSON.stringify(res, null, 2));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
})();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smoke-test.d.ts","sourceRoot":"","sources":["smoke-test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// cli/smoke-test.ts
|
|
2
|
+
import { writeFileSync, readFileSync, mkdirSync } from "node:fs";
|
|
3
|
+
import { dirname } from "node:path";
|
|
4
|
+
import { flattenTokens } from "../core/flatten.js";
|
|
5
|
+
import { Engine } from "../core/engine.js";
|
|
6
|
+
import { WcagContrastPlugin } from "../core/constraints/wcag.js";
|
|
7
|
+
import { patchToCss } from "../adapters/css.js";
|
|
8
|
+
// 1. Flatten tokens
|
|
9
|
+
const tokensRoot = JSON.parse(readFileSync("tokens/tokens.example.json", "utf8"));
|
|
10
|
+
const { flat, edges } = flattenTokens(tokensRoot);
|
|
11
|
+
// 2. Build engine
|
|
12
|
+
const init = {};
|
|
13
|
+
for (const [id, t] of Object.entries(flat))
|
|
14
|
+
init[id] = t.value;
|
|
15
|
+
const engine = new Engine(init, edges).use(WcagContrastPlugin([
|
|
16
|
+
{ fg: "color.role.text.default", bg: "color.role.bg.surface", min: 4.5, where: "Body text" },
|
|
17
|
+
]));
|
|
18
|
+
// 3. Commit one change
|
|
19
|
+
const overrideId = "color.palette.brand.600";
|
|
20
|
+
const overrideValue = "#FF00FF"; // A loud magenta to make it obvious
|
|
21
|
+
const result = engine.commit(overrideId, overrideValue);
|
|
22
|
+
console.log("--- Smoke Test ---");
|
|
23
|
+
console.log(`Committed: ${overrideId} = ${overrideValue}`);
|
|
24
|
+
console.log("Affected:", result.affected);
|
|
25
|
+
console.log("Issues:", result.issues);
|
|
26
|
+
console.log("Patch:", result.patch);
|
|
27
|
+
// 4. Write overrides.css using the adapter
|
|
28
|
+
const css = patchToCss(result.patch);
|
|
29
|
+
const outFile = "css/overrides.css";
|
|
30
|
+
mkdirSync(dirname(outFile), { recursive: true });
|
|
31
|
+
writeFileSync(outFile, css);
|
|
32
|
+
console.log(`\nWrote ${outFile}`);
|
|
33
|
+
console.log("--- End Smoke Test ---");
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// cli/smoke-test.ts
|
|
2
|
+
import { writeFileSync, readFileSync, mkdirSync } from "node:fs";
|
|
3
|
+
import { dirname } from "node:path";
|
|
4
|
+
import { flattenTokens } from "../core/flatten.js";
|
|
5
|
+
import { Engine } from "../core/engine.js";
|
|
6
|
+
import { WcagContrastPlugin } from "../core/constraints/wcag.js";
|
|
7
|
+
import { patchToCss } from "../adapters/css.js";
|
|
8
|
+
|
|
9
|
+
// 1. Flatten tokens
|
|
10
|
+
const tokensRoot = JSON.parse(readFileSync("tokens/tokens.example.json", "utf8"));
|
|
11
|
+
const { flat, edges } = flattenTokens(tokensRoot);
|
|
12
|
+
|
|
13
|
+
// 2. Build engine
|
|
14
|
+
const init: Record<string, string | number> = {};
|
|
15
|
+
for (const [id, t] of Object.entries(flat)) init[id] = t.value;
|
|
16
|
+
|
|
17
|
+
const engine = new Engine(init, edges).use(
|
|
18
|
+
WcagContrastPlugin([
|
|
19
|
+
{ fg: "color.role.text.default", bg: "color.role.bg.surface", min: 4.5, where: "Body text" },
|
|
20
|
+
])
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
// 3. Commit one change
|
|
24
|
+
const overrideId = "color.palette.brand.600";
|
|
25
|
+
const overrideValue = "#FF00FF"; // A loud magenta to make it obvious
|
|
26
|
+
const result = engine.commit(overrideId, overrideValue);
|
|
27
|
+
|
|
28
|
+
console.log("--- Smoke Test ---");
|
|
29
|
+
console.log(`Committed: ${overrideId} = ${overrideValue}`);
|
|
30
|
+
console.log("Affected:", result.affected);
|
|
31
|
+
console.log("Issues:", result.issues);
|
|
32
|
+
console.log("Patch:", result.patch);
|
|
33
|
+
|
|
34
|
+
// 4. Write overrides.css using the adapter
|
|
35
|
+
const css = patchToCss(result.patch);
|
|
36
|
+
const outFile = "css/overrides.css";
|
|
37
|
+
mkdirSync(dirname(outFile), { recursive: true });
|
|
38
|
+
writeFileSync(outFile, css);
|
|
39
|
+
console.log(`\nWrote ${outFile}`);
|
|
40
|
+
console.log("--- End Smoke Test ---");
|
package/cli/types.d.ts
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { TokenValue } from '../core/flatten.js';
|
|
2
|
+
import type { Breakpoint } from '../core/breakpoints.js';
|
|
3
|
+
import type { DcvConfigParsed } from './config-schema.js';
|
|
4
|
+
export interface WcagRuleConfig {
|
|
5
|
+
foreground: string;
|
|
6
|
+
background: string;
|
|
7
|
+
ratio?: number;
|
|
8
|
+
description?: string;
|
|
9
|
+
}
|
|
10
|
+
export type DcvConfig = DcvConfigParsed;
|
|
11
|
+
export type ValuesPatch = Record<string, TokenValue>;
|
|
12
|
+
export interface OverridesLeaf {
|
|
13
|
+
$value?: string | number | null;
|
|
14
|
+
}
|
|
15
|
+
export type OverridesTree = {
|
|
16
|
+
[k: string]: OverridesTree | OverridesLeaf;
|
|
17
|
+
} & OverridesLeaf;
|
|
18
|
+
export interface GlobalOptions {
|
|
19
|
+
tokens?: string;
|
|
20
|
+
config?: string;
|
|
21
|
+
verbose?: boolean;
|
|
22
|
+
quiet?: boolean;
|
|
23
|
+
breakpoint?: 'sm' | 'md' | 'lg';
|
|
24
|
+
allBreakpoints?: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface SetOptions extends GlobalOptions {
|
|
27
|
+
expressions: string[];
|
|
28
|
+
output?: string;
|
|
29
|
+
format?: 'json' | 'css' | 'js';
|
|
30
|
+
theme?: string;
|
|
31
|
+
write?: boolean;
|
|
32
|
+
json?: string;
|
|
33
|
+
unset?: string[];
|
|
34
|
+
}
|
|
35
|
+
export interface BuildOptions extends GlobalOptions {
|
|
36
|
+
output?: string;
|
|
37
|
+
format?: 'css' | 'json' | 'js';
|
|
38
|
+
watch?: boolean;
|
|
39
|
+
theme?: string;
|
|
40
|
+
mapper?: string;
|
|
41
|
+
dryRun?: boolean;
|
|
42
|
+
allFormats?: boolean;
|
|
43
|
+
}
|
|
44
|
+
export interface ValidateOptions extends GlobalOptions {
|
|
45
|
+
strict?: boolean;
|
|
46
|
+
constraints?: string[];
|
|
47
|
+
perf?: boolean;
|
|
48
|
+
budgetTotalMs?: number;
|
|
49
|
+
budgetPerBpMs?: number;
|
|
50
|
+
}
|
|
51
|
+
export interface GraphOptions extends GlobalOptions {
|
|
52
|
+
output?: string;
|
|
53
|
+
format?: 'dot' | 'mermaid' | 'json' | 'svg' | 'png';
|
|
54
|
+
imageFrom?: 'mermaid' | 'dot';
|
|
55
|
+
filter?: string;
|
|
56
|
+
hasse?: string;
|
|
57
|
+
filterPrefix?: string;
|
|
58
|
+
excludePrefix?: string;
|
|
59
|
+
onlyViolations?: boolean;
|
|
60
|
+
highlightViolations?: boolean;
|
|
61
|
+
violationColor?: string;
|
|
62
|
+
labelViolations?: boolean;
|
|
63
|
+
labelTruncate?: number;
|
|
64
|
+
minSeverity?: 'warn' | 'error';
|
|
65
|
+
focus?: string;
|
|
66
|
+
radius?: number;
|
|
67
|
+
tokens?: string;
|
|
68
|
+
}
|
|
69
|
+
export interface WhyOptions extends GlobalOptions {
|
|
70
|
+
tokenId: string;
|
|
71
|
+
format?: 'json' | 'table';
|
|
72
|
+
}
|
|
73
|
+
export interface PatchOptions extends GlobalOptions {
|
|
74
|
+
overrides?: string;
|
|
75
|
+
output?: string;
|
|
76
|
+
format?: 'json' | 'css' | 'js';
|
|
77
|
+
tokens?: string;
|
|
78
|
+
}
|
|
79
|
+
export interface PatchApplyOptions extends GlobalOptions {
|
|
80
|
+
patch: string;
|
|
81
|
+
output?: string;
|
|
82
|
+
tokens?: string;
|
|
83
|
+
dryRun?: boolean;
|
|
84
|
+
}
|
|
85
|
+
export type { Breakpoint };
|
|
86
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"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"}
|
package/cli/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/cli/types.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { TokenValue } from '../core/flatten.js';
|
|
2
|
+
import type { Breakpoint } from '../core/breakpoints.js';
|
|
3
|
+
import type { DcvConfigParsed } from './config-schema.js';
|
|
4
|
+
|
|
5
|
+
export interface WcagRuleConfig { foreground: string; background: string; ratio?: number; description?: string }
|
|
6
|
+
export type DcvConfig = DcvConfigParsed;
|
|
7
|
+
export type ValuesPatch = Record<string, TokenValue>;
|
|
8
|
+
export interface OverridesLeaf { $value?: string | number | null }
|
|
9
|
+
export type OverridesTree = { [k: string]: OverridesTree | OverridesLeaf } & OverridesLeaf;
|
|
10
|
+
|
|
11
|
+
export interface GlobalOptions {
|
|
12
|
+
tokens?: string;
|
|
13
|
+
config?: string;
|
|
14
|
+
verbose?: boolean;
|
|
15
|
+
quiet?: boolean;
|
|
16
|
+
breakpoint?: 'sm' | 'md' | 'lg';
|
|
17
|
+
allBreakpoints?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface SetOptions extends GlobalOptions {
|
|
20
|
+
expressions: string[];
|
|
21
|
+
output?: string;
|
|
22
|
+
format?: 'json' | 'css' | 'js';
|
|
23
|
+
theme?: string;
|
|
24
|
+
write?: boolean;
|
|
25
|
+
json?: string;
|
|
26
|
+
unset?: string[];
|
|
27
|
+
}
|
|
28
|
+
export interface BuildOptions extends GlobalOptions {
|
|
29
|
+
output?: string;
|
|
30
|
+
format?: 'css' | 'json' | 'js';
|
|
31
|
+
watch?: boolean;
|
|
32
|
+
theme?: string;
|
|
33
|
+
mapper?: string;
|
|
34
|
+
dryRun?: boolean;
|
|
35
|
+
allFormats?: boolean;
|
|
36
|
+
}
|
|
37
|
+
export interface ValidateOptions extends GlobalOptions {
|
|
38
|
+
strict?: boolean;
|
|
39
|
+
constraints?: string[];
|
|
40
|
+
perf?: boolean;
|
|
41
|
+
budgetTotalMs?: number;
|
|
42
|
+
budgetPerBpMs?: number;
|
|
43
|
+
}
|
|
44
|
+
export interface GraphOptions extends GlobalOptions {
|
|
45
|
+
output?: string;
|
|
46
|
+
format?: 'dot' | 'mermaid' | 'json' | 'svg' | 'png';
|
|
47
|
+
imageFrom?: 'mermaid' | 'dot';
|
|
48
|
+
filter?: string;
|
|
49
|
+
hasse?: string;
|
|
50
|
+
filterPrefix?: string;
|
|
51
|
+
excludePrefix?: string;
|
|
52
|
+
onlyViolations?: boolean;
|
|
53
|
+
highlightViolations?: boolean;
|
|
54
|
+
violationColor?: string;
|
|
55
|
+
labelViolations?: boolean;
|
|
56
|
+
labelTruncate?: number;
|
|
57
|
+
minSeverity?: 'warn' | 'error';
|
|
58
|
+
focus?: string;
|
|
59
|
+
radius?: number;
|
|
60
|
+
tokens?: string;
|
|
61
|
+
}
|
|
62
|
+
export interface WhyOptions extends GlobalOptions {
|
|
63
|
+
tokenId: string;
|
|
64
|
+
format?: 'json' | 'table';
|
|
65
|
+
}
|
|
66
|
+
export interface PatchOptions extends GlobalOptions {
|
|
67
|
+
overrides?: string; // path to flat overrides json or inline json
|
|
68
|
+
output?: string;
|
|
69
|
+
format?: 'json' | 'css' | 'js';
|
|
70
|
+
tokens?: string;
|
|
71
|
+
}
|
|
72
|
+
export interface PatchApplyOptions extends GlobalOptions {
|
|
73
|
+
patch: string; // path or inline patch JSON
|
|
74
|
+
output?: string; // where to write updated tokens (if omitted, prints result)
|
|
75
|
+
tokens?: string; // source tokens file (baseline)
|
|
76
|
+
dryRun?: boolean; // if true do not write
|
|
77
|
+
}
|
|
78
|
+
export type { Breakpoint };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { TokenNode } from "./flatten.js";
|
|
2
|
+
export type Breakpoint = "sm" | "md" | "lg";
|
|
3
|
+
export declare function parseBreakpoints(argv: string[]): Breakpoint[];
|
|
4
|
+
export declare function loadJsonSafe<T = unknown>(path: string): T | null;
|
|
5
|
+
export declare function loadOrders(axis: string, bp?: Breakpoint): [string, "<=" | ">=", string][];
|
|
6
|
+
export declare function mergeTokens(base: unknown, overlay: unknown): TokenNode;
|
|
7
|
+
/** Load tokens with optional breakpoint override: base + overrides/<bp>.json */
|
|
8
|
+
/**
|
|
9
|
+
* Load tokens with override precedence: base < local < breakpoint
|
|
10
|
+
*/
|
|
11
|
+
export declare function loadTokensWithBreakpoint(bp?: Breakpoint): TokenNode;
|
|
12
|
+
//# sourceMappingURL=breakpoints.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"breakpoints.d.ts","sourceRoot":"","sources":["breakpoints.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE5C,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,EAAE,CAM7D;AAED,wBAAgB,YAAY,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CAOhE;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,UAAU,GAAG,CAAC,MAAM,EAAE,IAAI,GAAG,IAAI,EAAE,MAAM,CAAC,EAAE,CAKzF;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,SAAS,CAQtE;AAED,gFAAgF;AAChF;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,EAAE,CAAC,EAAE,UAAU,GAAG,SAAS,CAKnE"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// core/breakpoints.ts
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
export function parseBreakpoints(argv) {
|
|
4
|
+
const allIdx = argv.indexOf("--all-breakpoints");
|
|
5
|
+
if (allIdx >= 0)
|
|
6
|
+
return ["sm", "md", "lg"];
|
|
7
|
+
const bpIdx = argv.indexOf("--breakpoint");
|
|
8
|
+
if (bpIdx >= 0)
|
|
9
|
+
return [argv[bpIdx + 1]];
|
|
10
|
+
return []; // no BP slicing requested
|
|
11
|
+
}
|
|
12
|
+
export function loadJsonSafe(path) {
|
|
13
|
+
try {
|
|
14
|
+
const data = JSON.parse(fs.readFileSync(path, "utf8"));
|
|
15
|
+
return data;
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export function loadOrders(axis, bp) {
|
|
22
|
+
const withBp = bp ? loadJsonSafe(`themes/${axis}.${bp}.order.json`) : null;
|
|
23
|
+
if (withBp?.order)
|
|
24
|
+
return withBp.order;
|
|
25
|
+
const global = loadJsonSafe(`themes/${axis}.order.json`);
|
|
26
|
+
return (global?.order ?? []);
|
|
27
|
+
}
|
|
28
|
+
export function mergeTokens(base, overlay) {
|
|
29
|
+
if (!overlay)
|
|
30
|
+
return base;
|
|
31
|
+
if (typeof base !== "object" || base === null)
|
|
32
|
+
return overlay;
|
|
33
|
+
const out = Array.isArray(base) ? [...base] : { ...base };
|
|
34
|
+
for (const k of Object.keys(overlay)) {
|
|
35
|
+
out[k] = mergeTokens(base?.[k], overlay[k]);
|
|
36
|
+
}
|
|
37
|
+
return out;
|
|
38
|
+
}
|
|
39
|
+
/** Load tokens with optional breakpoint override: base + overrides/<bp>.json */
|
|
40
|
+
/**
|
|
41
|
+
* Load tokens with override precedence: base < local < breakpoint
|
|
42
|
+
*/
|
|
43
|
+
export function loadTokensWithBreakpoint(bp) {
|
|
44
|
+
const base = loadJsonSafe("tokens/tokens.example.json") ?? {};
|
|
45
|
+
const local = loadJsonSafe("tokens/overrides/local.json");
|
|
46
|
+
const ov = bp ? loadJsonSafe(`tokens/overrides/${bp}.json`) : null;
|
|
47
|
+
return mergeTokens(mergeTokens(base, local), ov);
|
|
48
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// core/breakpoints.ts
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import type { TokenNode } from "./flatten.js";
|
|
4
|
+
|
|
5
|
+
export type Breakpoint = "sm" | "md" | "lg";
|
|
6
|
+
|
|
7
|
+
export function parseBreakpoints(argv: string[]): Breakpoint[] {
|
|
8
|
+
const allIdx = argv.indexOf("--all-breakpoints");
|
|
9
|
+
if (allIdx >= 0) return ["sm", "md", "lg"];
|
|
10
|
+
const bpIdx = argv.indexOf("--breakpoint");
|
|
11
|
+
if (bpIdx >= 0) return [argv[bpIdx + 1] as Breakpoint];
|
|
12
|
+
return []; // no BP slicing requested
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function loadJsonSafe<T = unknown>(path: string): T | null {
|
|
16
|
+
try {
|
|
17
|
+
const data = JSON.parse(fs.readFileSync(path, "utf8"));
|
|
18
|
+
return data;
|
|
19
|
+
} catch {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function loadOrders(axis: string, bp?: Breakpoint): [string, "<=" | ">=", string][] {
|
|
25
|
+
const withBp = bp ? loadJsonSafe<{ order: unknown[] }>(`themes/${axis}.${bp}.order.json`) : null;
|
|
26
|
+
if (withBp?.order) return withBp.order as [string, "<=" | ">=", string][];
|
|
27
|
+
const global = loadJsonSafe<{ order: unknown[] }>(`themes/${axis}.order.json`);
|
|
28
|
+
return (global?.order ?? []) as [string, "<=" | ">=", string][];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function mergeTokens(base: unknown, overlay: unknown): TokenNode {
|
|
32
|
+
if (!overlay) return base as TokenNode;
|
|
33
|
+
if (typeof base !== "object" || base === null) return overlay as TokenNode;
|
|
34
|
+
const out = Array.isArray(base) ? [...base] : { ...base };
|
|
35
|
+
for (const k of Object.keys(overlay as Record<string, unknown>)) {
|
|
36
|
+
(out as Record<string, unknown>)[k] = mergeTokens((base as Record<string, unknown>)?.[k], (overlay as Record<string, unknown>)[k]);
|
|
37
|
+
}
|
|
38
|
+
return out as TokenNode;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Load tokens with optional breakpoint override: base + overrides/<bp>.json */
|
|
42
|
+
/**
|
|
43
|
+
* Load tokens with override precedence: base < local < breakpoint
|
|
44
|
+
*/
|
|
45
|
+
export function loadTokensWithBreakpoint(bp?: Breakpoint): TokenNode {
|
|
46
|
+
const base = loadJsonSafe<TokenNode>("tokens/tokens.example.json") ?? {};
|
|
47
|
+
const local = loadJsonSafe<TokenNode>("tokens/overrides/local.json");
|
|
48
|
+
const ov = bp ? loadJsonSafe<TokenNode>(`tokens/overrides/${bp}.json`) : null;
|
|
49
|
+
return mergeTokens(mergeTokens(base, local), ov);
|
|
50
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function pad(s: string, w: number): string;
|
|
2
|
+
export declare function trunc(s: string, w: number): string;
|
|
3
|
+
export declare function levenshtein(a: string, b: string): number;
|
|
4
|
+
export declare function suggestIds(id: string, candidates: string[], k?: number): {
|
|
5
|
+
id: string;
|
|
6
|
+
d: number;
|
|
7
|
+
}[];
|
|
8
|
+
//# sourceMappingURL=cli-format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-format.d.ts","sourceRoot":"","sources":["cli-format.ts"],"names":[],"mappings":"AACA,wBAAgB,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,UAGvC;AAED,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,UAEzC;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAaxD;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,CAAC,SAAI,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,CAK/F"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// core/cli-format.ts
|
|
2
|
+
export function pad(s, w) {
|
|
3
|
+
if (s.length >= w)
|
|
4
|
+
return s;
|
|
5
|
+
return s + " ".repeat(w - s.length);
|
|
6
|
+
}
|
|
7
|
+
export function trunc(s, w) {
|
|
8
|
+
return s.length <= w ? s : s.slice(0, Math.max(0, w - 1)) + "…";
|
|
9
|
+
}
|
|
10
|
+
export function levenshtein(a, b) {
|
|
11
|
+
const dp = Array(b.length + 1).fill(0).map((_, j) => j);
|
|
12
|
+
for (let i = 1; i <= a.length; i++) {
|
|
13
|
+
let prev = i - 1, cur = i;
|
|
14
|
+
for (let j = 1; j <= b.length; j++) {
|
|
15
|
+
const tmp = cur;
|
|
16
|
+
cur = Math.min(dp[j] + 1, cur + 1, prev + (a[i - 1] === b[j - 1] ? 0 : 1));
|
|
17
|
+
dp[j] = tmp;
|
|
18
|
+
prev = tmp;
|
|
19
|
+
}
|
|
20
|
+
dp[b.length] = cur;
|
|
21
|
+
}
|
|
22
|
+
return dp[b.length];
|
|
23
|
+
}
|
|
24
|
+
export function suggestIds(id, candidates, k = 3) {
|
|
25
|
+
return candidates
|
|
26
|
+
.map(c => ({ id: c, d: levenshtein(id, c) }))
|
|
27
|
+
.sort((x, y) => x.d - y.d)
|
|
28
|
+
.slice(0, k);
|
|
29
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// core/cli-format.ts
|
|
2
|
+
export function pad(s: string, w: number) {
|
|
3
|
+
if (s.length >= w) return s;
|
|
4
|
+
return s + " ".repeat(w - s.length);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function trunc(s: string, w: number) {
|
|
8
|
+
return s.length <= w ? s : s.slice(0, Math.max(0, w - 1)) + "…";
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function levenshtein(a: string, b: string): number {
|
|
12
|
+
const dp = Array(b.length + 1).fill(0).map((_, j) => j);
|
|
13
|
+
for (let i = 1; i <= a.length; i++) {
|
|
14
|
+
let prev = i - 1, cur = i;
|
|
15
|
+
for (let j = 1; j <= b.length; j++) {
|
|
16
|
+
const tmp = cur;
|
|
17
|
+
cur = Math.min(dp[j] + 1, cur + 1, prev + (a[i - 1] === b[j - 1] ? 0 : 1));
|
|
18
|
+
dp[j] = tmp;
|
|
19
|
+
prev = tmp;
|
|
20
|
+
}
|
|
21
|
+
dp[b.length] = cur;
|
|
22
|
+
}
|
|
23
|
+
return dp[b.length];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function suggestIds(id: string, candidates: string[], k = 3): { id: string; d: number }[] {
|
|
27
|
+
return candidates
|
|
28
|
+
.map(c => ({ id: c, d: levenshtein(id, c) }))
|
|
29
|
+
.sort((x, y) => x.d - y.d)
|
|
30
|
+
.slice(0, k);
|
|
31
|
+
}
|
package/core/color.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type RGBA = {
|
|
2
|
+
r: number;
|
|
3
|
+
g: number;
|
|
4
|
+
b: number;
|
|
5
|
+
a: number;
|
|
6
|
+
};
|
|
7
|
+
export declare function srgbToLin(c: number): number;
|
|
8
|
+
export declare function linToSrgb(c: number): number;
|
|
9
|
+
export declare function relativeLuminance(rgb: RGBA): number;
|
|
10
|
+
export declare function contrastRatio(L1: number, L2: number): number;
|
|
11
|
+
export declare function parseCssColor(input: string | undefined | null): RGBA | null;
|
|
12
|
+
export declare function compositeOver(fg: RGBA, bg: RGBA): RGBA;
|
|
13
|
+
export declare function isOpaque(c: RGBA): boolean;
|
|
14
|
+
//# sourceMappingURL=color.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"color.d.ts","sourceRoot":"","sources":["color.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,IAAI,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAMlE,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAG3C;AACD,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAI3C;AAGD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,IAAI,GAAG,MAAM,CAMnD;AACD,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAG5D;AAMD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CA4D3E;AAsCD,wBAAgB,aAAa,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,GAAG,IAAI,CAStD;AAGD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,IAAI,GAAG,OAAO,CAAyB"}
|