@spwig/theme-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/README.md +367 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/schemas/component_manifest_schema.json +221 -0
- package/dist/schemas/theme_manifest_schema.json +267 -0
- package/dist/types/manifest.d.ts +183 -0
- package/dist/types/manifest.d.ts.map +1 -0
- package/dist/types/manifest.js +5 -0
- package/dist/types/manifest.js.map +1 -0
- package/dist/types/validation-result.d.ts +48 -0
- package/dist/types/validation-result.d.ts.map +1 -0
- package/dist/types/validation-result.js +26 -0
- package/dist/types/validation-result.js.map +1 -0
- package/dist/validators/component-validator.d.ts +50 -0
- package/dist/validators/component-validator.d.ts.map +1 -0
- package/dist/validators/component-validator.js +235 -0
- package/dist/validators/component-validator.js.map +1 -0
- package/dist/validators/design-tokens-validator.d.ts +46 -0
- package/dist/validators/design-tokens-validator.d.ts.map +1 -0
- package/dist/validators/design-tokens-validator.js +202 -0
- package/dist/validators/design-tokens-validator.js.map +1 -0
- package/dist/validators/manifest-validator.d.ts +69 -0
- package/dist/validators/manifest-validator.d.ts.map +1 -0
- package/dist/validators/manifest-validator.js +206 -0
- package/dist/validators/manifest-validator.js.map +1 -0
- package/dist/validators/template-validator.d.ts +34 -0
- package/dist/validators/template-validator.d.ts.map +1 -0
- package/dist/validators/template-validator.js +170 -0
- package/dist/validators/template-validator.js.map +1 -0
- package/dist/validators/theme-validator.d.ts +44 -0
- package/dist/validators/theme-validator.d.ts.map +1 -0
- package/dist/validators/theme-validator.js +237 -0
- package/dist/validators/theme-validator.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component Validator
|
|
3
|
+
* Validates component packages against manifest schema and file structure
|
|
4
|
+
*/
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import fs from 'fs-extra';
|
|
7
|
+
import { ManifestValidator } from './manifest-validator.js';
|
|
8
|
+
import { createError, createWarning, } from '../types/validation-result.js';
|
|
9
|
+
export class ComponentValidator extends ManifestValidator {
|
|
10
|
+
componentDir;
|
|
11
|
+
manifest = null;
|
|
12
|
+
static REQUIRED_FILES = [
|
|
13
|
+
'manifest.json',
|
|
14
|
+
'template.html',
|
|
15
|
+
'schema.json',
|
|
16
|
+
];
|
|
17
|
+
static OPTIONAL_FILES = [
|
|
18
|
+
'preview.png',
|
|
19
|
+
'preview.jpg',
|
|
20
|
+
'preview.jpeg',
|
|
21
|
+
'preview.webp',
|
|
22
|
+
];
|
|
23
|
+
constructor(componentDir) {
|
|
24
|
+
super();
|
|
25
|
+
this.componentDir = path.resolve(componentDir);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Validate complete component package
|
|
29
|
+
*/
|
|
30
|
+
async validate() {
|
|
31
|
+
this.reset();
|
|
32
|
+
// 1. Check directory exists
|
|
33
|
+
if (!(await this.directoryExists(this.componentDir))) {
|
|
34
|
+
this.addError(createError('directory_not_found', `Component directory does not exist: ${this.componentDir}`));
|
|
35
|
+
return this.buildResult();
|
|
36
|
+
}
|
|
37
|
+
// 2. Check required files
|
|
38
|
+
if (!(await this.validateRequiredFiles())) {
|
|
39
|
+
return this.buildResult();
|
|
40
|
+
}
|
|
41
|
+
// 3. Load and validate manifest
|
|
42
|
+
const manifestPath = path.join(this.componentDir, 'manifest.json');
|
|
43
|
+
try {
|
|
44
|
+
this.manifest = await this.loadJSON(manifestPath);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return this.buildResult();
|
|
48
|
+
}
|
|
49
|
+
// Load component manifest schema
|
|
50
|
+
const schemaPath = path.join(__dirname, '../../schemas/component_manifest_schema.json');
|
|
51
|
+
const schema = await this.loadSchema(schemaPath);
|
|
52
|
+
if (!this.validateAgainstSchema(this.manifest, schema, 'component manifest')) {
|
|
53
|
+
return this.buildResult();
|
|
54
|
+
}
|
|
55
|
+
// 4. Validate template file
|
|
56
|
+
await this.validateTemplate();
|
|
57
|
+
// 5. Validate props schema file
|
|
58
|
+
await this.validatePropsSchema();
|
|
59
|
+
// 6. Validate assets if declared
|
|
60
|
+
if (this.manifest.assets) {
|
|
61
|
+
await this.validateAssets();
|
|
62
|
+
}
|
|
63
|
+
// 7. Validate locales if declared
|
|
64
|
+
if (this.manifest.locales) {
|
|
65
|
+
await this.validateLocales();
|
|
66
|
+
}
|
|
67
|
+
// 8. Validate preview image if declared
|
|
68
|
+
if (this.manifest.preview) {
|
|
69
|
+
await this.validatePreview();
|
|
70
|
+
}
|
|
71
|
+
// 9. Validate dependencies format
|
|
72
|
+
if (this.manifest.dependencies) {
|
|
73
|
+
await this.validateDependencies();
|
|
74
|
+
}
|
|
75
|
+
return this.buildResult();
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Validate required files exist
|
|
79
|
+
*/
|
|
80
|
+
async validateRequiredFiles() {
|
|
81
|
+
let allExist = true;
|
|
82
|
+
for (const filename of ComponentValidator.REQUIRED_FILES) {
|
|
83
|
+
const filePath = path.join(this.componentDir, filename);
|
|
84
|
+
if (!(await this.fileExists(filePath))) {
|
|
85
|
+
this.addError(createError('missing_file', `Required file missing: ${filename}`));
|
|
86
|
+
allExist = false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return allExist;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Validate template.html file
|
|
93
|
+
*/
|
|
94
|
+
async validateTemplate() {
|
|
95
|
+
const templatePath = path.join(this.componentDir, 'template.html');
|
|
96
|
+
if (!(await this.fileExists(templatePath))) {
|
|
97
|
+
this.addError(createError('missing_file', 'Template file (template.html) does not exist'));
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
// Check file is not empty
|
|
101
|
+
if (!(await this.validateFileNotEmpty(templatePath, 'Template'))) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
// Check it's valid UTF-8
|
|
105
|
+
await this.validateUTF8(templatePath, 'Template');
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Validate props schema file
|
|
109
|
+
*/
|
|
110
|
+
async validatePropsSchema() {
|
|
111
|
+
const schemaPath = path.join(this.componentDir, 'schema.json');
|
|
112
|
+
if (!(await this.fileExists(schemaPath))) {
|
|
113
|
+
this.addError(createError('missing_file', 'Props schema file (schema.json) does not exist'));
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
// Load and validate it's valid JSON
|
|
117
|
+
let propsSchema;
|
|
118
|
+
try {
|
|
119
|
+
propsSchema = await this.loadJSON(schemaPath);
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
// Error already added by loadJSON
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
// Check it matches the props_schema in manifest (if present)
|
|
126
|
+
if (this.manifest?.props_schema) {
|
|
127
|
+
const manifestSchema = JSON.stringify(this.manifest.props_schema, null, 2);
|
|
128
|
+
const fileSchema = JSON.stringify(propsSchema, null, 2);
|
|
129
|
+
if (manifestSchema !== fileSchema) {
|
|
130
|
+
this.addError(createError('schema_mismatch', 'Props schema in schema.json does not match manifest.props_schema'));
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// Validate it's a valid JSON Schema (basic check)
|
|
135
|
+
if (!propsSchema.$schema && !propsSchema.type) {
|
|
136
|
+
this.addWarning(createWarning('invalid_schema', 'Props schema may not be a valid JSON Schema (missing $schema or type)', {
|
|
137
|
+
suggestion: 'Add "$schema": "http://json-schema.org/draft-07/schema#" to schema.json',
|
|
138
|
+
}));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Validate declared asset files exist
|
|
143
|
+
*/
|
|
144
|
+
async validateAssets() {
|
|
145
|
+
if (!this.manifest?.assets)
|
|
146
|
+
return;
|
|
147
|
+
const validAssetTypes = ['css', 'js', 'images'];
|
|
148
|
+
for (const [assetType, assetPaths] of Object.entries(this.manifest.assets)) {
|
|
149
|
+
if (!validAssetTypes.includes(assetType)) {
|
|
150
|
+
this.addError(createError('invalid_asset_type', `Unknown asset type: ${assetType}`));
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
for (const assetPath of assetPaths) {
|
|
154
|
+
const fullPath = path.join(this.componentDir, assetPath);
|
|
155
|
+
if (!(await this.fileExists(fullPath))) {
|
|
156
|
+
this.addError(createError('missing_asset', `Asset file does not exist: ${assetPath}`));
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Validate locale files exist for declared locales
|
|
164
|
+
*/
|
|
165
|
+
async validateLocales() {
|
|
166
|
+
if (!this.manifest?.locales)
|
|
167
|
+
return;
|
|
168
|
+
const localesDir = path.join(this.componentDir, 'locales');
|
|
169
|
+
if (!(await this.directoryExists(localesDir))) {
|
|
170
|
+
this.addError(createError('missing_directory', 'Locales declared but locales/ directory does not exist'));
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
for (const locale of this.manifest.locales) {
|
|
174
|
+
const localeFile = path.join(localesDir, `${locale}.json`);
|
|
175
|
+
if (!(await this.fileExists(localeFile))) {
|
|
176
|
+
this.addError(createError('missing_locale', `Locale file does not exist: locales/${locale}.json`));
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
// Validate it's valid JSON
|
|
180
|
+
try {
|
|
181
|
+
await this.loadJSON(localeFile);
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
// Error already added by loadJSON
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Validate preview image file exists
|
|
190
|
+
*/
|
|
191
|
+
async validatePreview() {
|
|
192
|
+
if (!this.manifest?.preview)
|
|
193
|
+
return;
|
|
194
|
+
const previewPath = path.join(this.componentDir, this.manifest.preview);
|
|
195
|
+
if (!(await this.fileExists(previewPath))) {
|
|
196
|
+
this.addError(createError('missing_preview', `Preview image does not exist: ${this.manifest.preview}`));
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
// Check file size is reasonable (not too large)
|
|
200
|
+
const maxSize = 5 * 1024 * 1024; // 5 MB
|
|
201
|
+
const stats = await fs.stat(previewPath);
|
|
202
|
+
if (stats.size > maxSize) {
|
|
203
|
+
this.addError(createError('file_too_large', `Preview image is too large (max 5MB): ${this.manifest.preview}`));
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Validate dependency format
|
|
208
|
+
*/
|
|
209
|
+
async validateDependencies() {
|
|
210
|
+
if (!this.manifest?.dependencies)
|
|
211
|
+
return;
|
|
212
|
+
for (const dep of this.manifest.dependencies) {
|
|
213
|
+
const minVer = dep.min_version;
|
|
214
|
+
const maxVer = dep.max_version;
|
|
215
|
+
if (minVer && maxVer) {
|
|
216
|
+
// Compare versions
|
|
217
|
+
if (this.compareVersions(minVer, maxVer) > 0) {
|
|
218
|
+
this.addError(createError('invalid_dependency', `Dependency ${dep.name}: min_version (${minVer}) is greater than max_version (${maxVer})`));
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Build validation result
|
|
225
|
+
*/
|
|
226
|
+
buildResult() {
|
|
227
|
+
return {
|
|
228
|
+
isValid: this.getErrors().length === 0,
|
|
229
|
+
errors: this.getErrors(),
|
|
230
|
+
warnings: this.getWarnings(),
|
|
231
|
+
componentInfo: this.manifest,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
//# sourceMappingURL=component-validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component-validator.js","sourceRoot":"","sources":["../../src/validators/component-validator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Design Tokens Validator
|
|
3
|
+
* Validates design token files (colors, typography, spacing, etc.)
|
|
4
|
+
*/
|
|
5
|
+
import { ValidationResult } from '../types/validation-result.js';
|
|
6
|
+
export declare class DesignTokensValidator {
|
|
7
|
+
private errors;
|
|
8
|
+
private warnings;
|
|
9
|
+
/**
|
|
10
|
+
* Validate a design tokens file
|
|
11
|
+
*/
|
|
12
|
+
validate(tokensPath: string): Promise<ValidationResult>;
|
|
13
|
+
/**
|
|
14
|
+
* Check file exists
|
|
15
|
+
*/
|
|
16
|
+
private fileExists;
|
|
17
|
+
/**
|
|
18
|
+
* Load and parse tokens file
|
|
19
|
+
*/
|
|
20
|
+
private loadTokens;
|
|
21
|
+
/**
|
|
22
|
+
* Validate overall token structure
|
|
23
|
+
*/
|
|
24
|
+
private validateTokenStructure;
|
|
25
|
+
/**
|
|
26
|
+
* Validate color tokens
|
|
27
|
+
*/
|
|
28
|
+
private validateColors;
|
|
29
|
+
/**
|
|
30
|
+
* Validate typography tokens
|
|
31
|
+
*/
|
|
32
|
+
private validateTypography;
|
|
33
|
+
/**
|
|
34
|
+
* Validate spacing tokens
|
|
35
|
+
*/
|
|
36
|
+
private validateSpacing;
|
|
37
|
+
/**
|
|
38
|
+
* Check for recommended properties
|
|
39
|
+
*/
|
|
40
|
+
private checkRecommendedProperties;
|
|
41
|
+
/**
|
|
42
|
+
* Build validation result
|
|
43
|
+
*/
|
|
44
|
+
private buildResult;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=design-tokens-validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"design-tokens-validator.d.ts","sourceRoot":"","sources":["../../src/validators/design-tokens-validator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACL,gBAAgB,EAKjB,MAAM,+BAA+B,CAAC;AAGvC,qBAAa,qBAAqB;IAChC,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,QAAQ,CAA2B;IAE3C;;OAEG;IACG,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA0C7D;;OAEG;YACW,UAAU;IASxB;;OAEG;YACW,UAAU;IAsBxB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAoB9B;;OAEG;IACH,OAAO,CAAC,cAAc;IAgDtB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA8B1B;;OAEG;IACH,OAAO,CAAC,eAAe;IA2BvB;;OAEG;IACH,OAAO,CAAC,0BAA0B;IA4BlC;;OAEG;IACH,OAAO,CAAC,WAAW;CAOpB"}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Design Tokens Validator
|
|
3
|
+
* Validates design token files (colors, typography, spacing, etc.)
|
|
4
|
+
*/
|
|
5
|
+
import fs from 'fs-extra';
|
|
6
|
+
import { createError, createWarning, } from '../types/validation-result.js';
|
|
7
|
+
export class DesignTokensValidator {
|
|
8
|
+
errors = [];
|
|
9
|
+
warnings = [];
|
|
10
|
+
/**
|
|
11
|
+
* Validate a design tokens file
|
|
12
|
+
*/
|
|
13
|
+
async validate(tokensPath) {
|
|
14
|
+
this.errors = [];
|
|
15
|
+
this.warnings = [];
|
|
16
|
+
// Check file exists
|
|
17
|
+
if (!(await this.fileExists(tokensPath))) {
|
|
18
|
+
this.errors.push(createError('file_not_found', `Design tokens file does not exist: ${tokensPath}`));
|
|
19
|
+
return this.buildResult();
|
|
20
|
+
}
|
|
21
|
+
// Load and parse JSON
|
|
22
|
+
const tokens = await this.loadTokens(tokensPath);
|
|
23
|
+
if (!tokens) {
|
|
24
|
+
return this.buildResult();
|
|
25
|
+
}
|
|
26
|
+
// Validate token structure
|
|
27
|
+
this.validateTokenStructure(tokens, tokensPath);
|
|
28
|
+
// Validate colors
|
|
29
|
+
if (tokens.colors) {
|
|
30
|
+
this.validateColors(tokens.colors, tokensPath);
|
|
31
|
+
}
|
|
32
|
+
// Validate typography
|
|
33
|
+
if (tokens.typography) {
|
|
34
|
+
this.validateTypography(tokens.typography, tokensPath);
|
|
35
|
+
}
|
|
36
|
+
// Validate spacing
|
|
37
|
+
if (tokens.spacing) {
|
|
38
|
+
this.validateSpacing(tokens.spacing, tokensPath);
|
|
39
|
+
}
|
|
40
|
+
// Check for recommended properties
|
|
41
|
+
this.checkRecommendedProperties(tokens, tokensPath);
|
|
42
|
+
return this.buildResult();
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Check file exists
|
|
46
|
+
*/
|
|
47
|
+
async fileExists(filePath) {
|
|
48
|
+
try {
|
|
49
|
+
const stats = await fs.stat(filePath);
|
|
50
|
+
return stats.isFile();
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Load and parse tokens file
|
|
58
|
+
*/
|
|
59
|
+
async loadTokens(tokensPath) {
|
|
60
|
+
try {
|
|
61
|
+
const content = await fs.readFile(tokensPath, 'utf-8');
|
|
62
|
+
return JSON.parse(content);
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
if (error instanceof SyntaxError) {
|
|
66
|
+
this.errors.push(createError('json_parse_error', `Invalid JSON in design tokens: ${error.message}`, {
|
|
67
|
+
path: tokensPath,
|
|
68
|
+
}));
|
|
69
|
+
}
|
|
70
|
+
else if (error instanceof Error) {
|
|
71
|
+
this.errors.push(createError('read_error', `Failed to read design tokens: ${error.message}`, {
|
|
72
|
+
path: tokensPath,
|
|
73
|
+
}));
|
|
74
|
+
}
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Validate overall token structure
|
|
80
|
+
*/
|
|
81
|
+
validateTokenStructure(tokens, tokensPath) {
|
|
82
|
+
if (typeof tokens !== 'object' || tokens === null) {
|
|
83
|
+
this.errors.push(createError('invalid_structure', 'Design tokens must be an object', {
|
|
84
|
+
path: tokensPath,
|
|
85
|
+
}));
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
// Check that it's not empty
|
|
89
|
+
if (Object.keys(tokens).length === 0) {
|
|
90
|
+
this.errors.push(createError('empty_tokens', 'Design tokens file is empty', {
|
|
91
|
+
path: tokensPath,
|
|
92
|
+
}));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Validate color tokens
|
|
97
|
+
*/
|
|
98
|
+
validateColors(colors, tokensPath) {
|
|
99
|
+
const hexPattern = /^#[0-9A-Fa-f]{6}$/;
|
|
100
|
+
const rgbaPattern = /^rgba?\(/;
|
|
101
|
+
const hslPattern = /^hsla?\(/;
|
|
102
|
+
for (const [name, value] of Object.entries(colors)) {
|
|
103
|
+
if (typeof value !== 'string') {
|
|
104
|
+
this.errors.push(createError('invalid_color', `Color "${name}" must be a string`, {
|
|
105
|
+
path: tokensPath,
|
|
106
|
+
}));
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
// Check if it's a valid color format
|
|
110
|
+
if (!hexPattern.test(value) && !rgbaPattern.test(value) && !hslPattern.test(value)) {
|
|
111
|
+
this.warnings.push(createWarning('color_format', `Color "${name}" may not be in a valid format: ${value}`, {
|
|
112
|
+
path: tokensPath,
|
|
113
|
+
suggestion: 'Use hex (#RRGGBB), rgb(), rgba(), hsl(), or hsla() format',
|
|
114
|
+
}));
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// Check for recommended color tokens
|
|
118
|
+
const recommendedColors = ['primary', 'secondary', 'background', 'text', 'border'];
|
|
119
|
+
const missingColors = recommendedColors.filter((color) => !(color in colors));
|
|
120
|
+
if (missingColors.length > 0) {
|
|
121
|
+
this.warnings.push(createWarning('missing_recommended', `Missing recommended color tokens: ${missingColors.join(', ')}`, {
|
|
122
|
+
path: tokensPath,
|
|
123
|
+
suggestion: 'Add these colors for better theme consistency',
|
|
124
|
+
}));
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Validate typography tokens
|
|
129
|
+
*/
|
|
130
|
+
validateTypography(typography, tokensPath) {
|
|
131
|
+
for (const [name, value] of Object.entries(typography)) {
|
|
132
|
+
if (typeof value !== 'object' || value === null) {
|
|
133
|
+
this.warnings.push(createWarning('invalid_typography', `Typography "${name}" should be an object`, {
|
|
134
|
+
path: tokensPath,
|
|
135
|
+
}));
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
// Check for recommended properties
|
|
139
|
+
const recommendedProps = ['fontSize', 'lineHeight', 'fontWeight'];
|
|
140
|
+
const hasProps = recommendedProps.some((prop) => prop in value);
|
|
141
|
+
if (!hasProps) {
|
|
142
|
+
this.warnings.push(createWarning('incomplete_typography', `Typography "${name}" is missing recommended properties`, {
|
|
143
|
+
path: tokensPath,
|
|
144
|
+
suggestion: 'Add fontSize, lineHeight, and/or fontWeight',
|
|
145
|
+
}));
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Validate spacing tokens
|
|
151
|
+
*/
|
|
152
|
+
validateSpacing(spacing, tokensPath) {
|
|
153
|
+
const validUnits = ['px', 'rem', 'em', '%', 'vh', 'vw'];
|
|
154
|
+
for (const [name, value] of Object.entries(spacing)) {
|
|
155
|
+
if (typeof value !== 'string') {
|
|
156
|
+
this.errors.push(createError('invalid_spacing', `Spacing "${name}" must be a string`, {
|
|
157
|
+
path: tokensPath,
|
|
158
|
+
}));
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
// Check if value has a valid unit
|
|
162
|
+
const hasValidUnit = validUnits.some((unit) => value.endsWith(unit));
|
|
163
|
+
if (!hasValidUnit && value !== '0') {
|
|
164
|
+
this.warnings.push(createWarning('spacing_unit', `Spacing "${name}" may be missing a unit: ${value}`, {
|
|
165
|
+
path: tokensPath,
|
|
166
|
+
suggestion: `Add a unit like px, rem, or em`,
|
|
167
|
+
}));
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Check for recommended properties
|
|
173
|
+
*/
|
|
174
|
+
checkRecommendedProperties(tokens, tokensPath) {
|
|
175
|
+
const recommended = ['colors', 'typography', 'spacing'];
|
|
176
|
+
const missing = recommended.filter((prop) => !(prop in tokens));
|
|
177
|
+
if (missing.length > 0) {
|
|
178
|
+
this.warnings.push(createWarning('missing_sections', `Missing recommended design token sections: ${missing.join(', ')}`, {
|
|
179
|
+
path: tokensPath,
|
|
180
|
+
suggestion: 'Add these sections for a complete design system',
|
|
181
|
+
}));
|
|
182
|
+
}
|
|
183
|
+
// Suggest adding breakpoints for responsive design
|
|
184
|
+
if (!tokens.breakpoints) {
|
|
185
|
+
this.warnings.push(createWarning('missing_breakpoints', 'No breakpoints defined', {
|
|
186
|
+
path: tokensPath,
|
|
187
|
+
suggestion: 'Add breakpoints for responsive design (mobile, tablet, desktop)',
|
|
188
|
+
}));
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Build validation result
|
|
193
|
+
*/
|
|
194
|
+
buildResult() {
|
|
195
|
+
return {
|
|
196
|
+
isValid: this.errors.length === 0,
|
|
197
|
+
errors: this.errors,
|
|
198
|
+
warnings: this.warnings,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=design-tokens-validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"design-tokens-validator.js","sourceRoot":"","sources":["../../src/validators/design-tokens-validator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,EAIL,WAAW,EACX,aAAa,GACd,MAAM,+BAA+B,CAAC;AAGvC,MAAM,OAAO,qBAAqB;IACxB,MAAM,GAAsB,EAAE,CAAC;IAC/B,QAAQ,GAAwB,EAAE,CAAC;IAE3C;;OAEG;IACH,KAAK,CAAC,QAAQ,CAAC,UAAkB;QAC/B,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;QAEnB,oBAAoB;QACpB,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;YACzC,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,WAAW,CAAC,gBAAgB,EAAE,sCAAsC,UAAU,EAAE,CAAC,CAClF,CAAC;YACF,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC;QAC5B,CAAC;QAED,sBAAsB;QACtB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QACjD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC;QAC5B,CAAC;QAED,2BAA2B;QAC3B,IAAI,CAAC,sBAAsB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QAEhD,kBAAkB;QAClB,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClB,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QACjD,CAAC;QAED,sBAAsB;QACtB,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACtB,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;QACzD,CAAC;QAED,mBAAmB;QACnB,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QACnD,CAAC;QAED,mCAAmC;QACnC,IAAI,CAAC,0BAA0B,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QAEpD,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC;IAC5B,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,UAAU,CAAC,QAAgB;QACvC,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACtC,OAAO,KAAK,CAAC,MAAM,EAAE,CAAC;QACxB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,UAAU,CAAC,UAAkB;QACzC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YACvD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,WAAW,EAAE,CAAC;gBACjC,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,WAAW,CAAC,kBAAkB,EAAE,kCAAkC,KAAK,CAAC,OAAO,EAAE,EAAE;oBACjF,IAAI,EAAE,UAAU;iBACjB,CAAC,CACH,CAAC;YACJ,CAAC;iBAAM,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;gBAClC,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,WAAW,CAAC,YAAY,EAAE,iCAAiC,KAAK,CAAC,OAAO,EAAE,EAAE;oBAC1E,IAAI,EAAE,UAAU;iBACjB,CAAC,CACH,CAAC;YACJ,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED;;OAEG;IACK,sBAAsB,CAAC,MAAoB,EAAE,UAAkB;QACrE,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YAClD,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,WAAW,CAAC,mBAAmB,EAAE,iCAAiC,EAAE;gBAClE,IAAI,EAAE,UAAU;aACjB,CAAC,CACH,CAAC;YACF,OAAO;QACT,CAAC;QAED,4BAA4B;QAC5B,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,WAAW,CAAC,cAAc,EAAE,6BAA6B,EAAE;gBACzD,IAAI,EAAE,UAAU;aACjB,CAAC,CACH,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;OAEG;IACK,cAAc,CAAC,MAA8B,EAAE,UAAkB;QACvE,MAAM,UAAU,GAAG,mBAAmB,CAAC;QACvC,MAAM,WAAW,GAAG,UAAU,CAAC;QAC/B,MAAM,UAAU,GAAG,UAAU,CAAC;QAE9B,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACnD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC9B,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,WAAW,CAAC,eAAe,EAAE,UAAU,IAAI,oBAAoB,EAAE;oBAC/D,IAAI,EAAE,UAAU;iBACjB,CAAC,CACH,CAAC;gBACF,SAAS;YACX,CAAC;YAED,qCAAqC;YACrC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBACnF,IAAI,CAAC,QAAQ,CAAC,IAAI,CAChB,aAAa,CACX,cAAc,EACd,UAAU,IAAI,mCAAmC,KAAK,EAAE,EACxD;oBACE,IAAI,EAAE,UAAU;oBAChB,UAAU,EAAE,2DAA2D;iBACxE,CACF,CACF,CAAC;YACJ,CAAC;QACH,CAAC;QAED,qCAAqC;QACrC,MAAM,iBAAiB,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QACnF,MAAM,aAAa,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,MAAM,CAAC,CAAC,CAAC;QAE9E,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAChB,aAAa,CACX,qBAAqB,EACrB,qCAAqC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAC/D;gBACE,IAAI,EAAE,UAAU;gBAChB,UAAU,EAAE,+CAA+C;aAC5D,CACF,CACF,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;OAEG;IACK,kBAAkB,CAAC,UAA+B,EAAE,UAAkB;QAC5E,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;YACvD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBAChD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAChB,aAAa,CAAC,oBAAoB,EAAE,eAAe,IAAI,uBAAuB,EAAE;oBAC9E,IAAI,EAAE,UAAU;iBACjB,CAAC,CACH,CAAC;gBACF,SAAS;YACX,CAAC;YAED,mCAAmC;YACnC,MAAM,gBAAgB,GAAG,CAAC,UAAU,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC;YAClE,MAAM,QAAQ,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,KAAK,CAAC,CAAC;YAEhE,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,IAAI,CAAC,QAAQ,CAAC,IAAI,CAChB,aAAa,CACX,uBAAuB,EACvB,eAAe,IAAI,qCAAqC,EACxD;oBACE,IAAI,EAAE,UAAU;oBAChB,UAAU,EAAE,6CAA6C;iBAC1D,CACF,CACF,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACK,eAAe,CAAC,OAA+B,EAAE,UAAkB;QACzE,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAExD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACpD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC9B,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,WAAW,CAAC,iBAAiB,EAAE,YAAY,IAAI,oBAAoB,EAAE;oBACnE,IAAI,EAAE,UAAU;iBACjB,CAAC,CACH,CAAC;gBACF,SAAS;YACX,CAAC;YAED,kCAAkC;YAClC,MAAM,YAAY,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;YAErE,IAAI,CAAC,YAAY,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;gBACnC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAChB,aAAa,CAAC,cAAc,EAAE,YAAY,IAAI,4BAA4B,KAAK,EAAE,EAAE;oBACjF,IAAI,EAAE,UAAU;oBAChB,UAAU,EAAE,gCAAgC;iBAC7C,CAAC,CACH,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACK,0BAA0B,CAAC,MAAoB,EAAE,UAAkB;QACzE,MAAM,WAAW,GAAG,CAAC,QAAQ,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;QACxD,MAAM,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC;QAEhE,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAChB,aAAa,CACX,kBAAkB,EAClB,8CAA8C,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAClE;gBACE,IAAI,EAAE,UAAU;gBAChB,UAAU,EAAE,iDAAiD;aAC9D,CACF,CACF,CAAC;QACJ,CAAC;QAED,mDAAmD;QACnD,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YACxB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAChB,aAAa,CAAC,qBAAqB,EAAE,wBAAwB,EAAE;gBAC7D,IAAI,EAAE,UAAU;gBAChB,UAAU,EAAE,iEAAiE;aAC9E,CAAC,CACH,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;OAEG;IACK,WAAW;QACjB,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;YACjC,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ;SACxB,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manifest Validator
|
|
3
|
+
* Validates JSON manifests against schemas using Ajv
|
|
4
|
+
*/
|
|
5
|
+
import { ValidationError, ValidationWarning } from '../types/validation-result.js';
|
|
6
|
+
export declare class ManifestValidator {
|
|
7
|
+
private ajv;
|
|
8
|
+
private errors;
|
|
9
|
+
private warnings;
|
|
10
|
+
constructor();
|
|
11
|
+
/**
|
|
12
|
+
* Load a JSON schema from file
|
|
13
|
+
*/
|
|
14
|
+
protected loadSchema(schemaPath: string): Promise<any>;
|
|
15
|
+
/**
|
|
16
|
+
* Load a JSON file
|
|
17
|
+
*/
|
|
18
|
+
protected loadJSON<T = any>(filePath: string): Promise<T>;
|
|
19
|
+
/**
|
|
20
|
+
* Validate manifest against schema
|
|
21
|
+
*/
|
|
22
|
+
protected validateAgainstSchema(manifest: any, schema: any, manifestType?: string): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Convert Ajv error to ValidationError
|
|
25
|
+
*/
|
|
26
|
+
private convertAjvError;
|
|
27
|
+
/**
|
|
28
|
+
* Reset errors and warnings
|
|
29
|
+
*/
|
|
30
|
+
protected reset(): void;
|
|
31
|
+
/**
|
|
32
|
+
* Get current errors
|
|
33
|
+
*/
|
|
34
|
+
protected getErrors(): ValidationError[];
|
|
35
|
+
/**
|
|
36
|
+
* Get current warnings
|
|
37
|
+
*/
|
|
38
|
+
protected getWarnings(): ValidationWarning[];
|
|
39
|
+
/**
|
|
40
|
+
* Add an error
|
|
41
|
+
*/
|
|
42
|
+
protected addError(error: ValidationError): void;
|
|
43
|
+
/**
|
|
44
|
+
* Add a warning
|
|
45
|
+
*/
|
|
46
|
+
protected addWarning(warning: ValidationWarning): void;
|
|
47
|
+
/**
|
|
48
|
+
* Check if file exists
|
|
49
|
+
*/
|
|
50
|
+
protected fileExists(filePath: string): Promise<boolean>;
|
|
51
|
+
/**
|
|
52
|
+
* Check if directory exists
|
|
53
|
+
*/
|
|
54
|
+
protected directoryExists(dirPath: string): Promise<boolean>;
|
|
55
|
+
/**
|
|
56
|
+
* Compare semantic versions
|
|
57
|
+
* @returns -1 if v1 < v2, 0 if equal, 1 if v1 > v2
|
|
58
|
+
*/
|
|
59
|
+
protected compareVersions(v1: string, v2: string): number;
|
|
60
|
+
/**
|
|
61
|
+
* Validate file is not empty
|
|
62
|
+
*/
|
|
63
|
+
protected validateFileNotEmpty(filePath: string, fileType: string): Promise<boolean>;
|
|
64
|
+
/**
|
|
65
|
+
* Validate file is valid UTF-8
|
|
66
|
+
*/
|
|
67
|
+
protected validateUTF8(filePath: string, fileType: string): Promise<boolean>;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=manifest-validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest-validator.d.ts","sourceRoot":"","sources":["../../src/validators/manifest-validator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAEL,eAAe,EACf,iBAAiB,EAElB,MAAM,+BAA+B,CAAC;AAEvC,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,QAAQ,CAA2B;;IAW3C;;OAEG;cACa,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAY5D;;OAEG;cACa,QAAQ,CAAC,CAAC,GAAG,GAAG,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAsB/D;;OAEG;IACH,SAAS,CAAC,qBAAqB,CAC7B,QAAQ,EAAE,GAAG,EACb,MAAM,EAAE,GAAG,EACX,YAAY,GAAE,MAAmB,GAChC,OAAO;IAaV;;OAEG;IACH,OAAO,CAAC,eAAe;IAsBvB;;OAEG;IACH,SAAS,CAAC,KAAK,IAAI,IAAI;IAKvB;;OAEG;IACH,SAAS,CAAC,SAAS,IAAI,eAAe,EAAE;IAIxC;;OAEG;IACH,SAAS,CAAC,WAAW,IAAI,iBAAiB,EAAE;IAI5C;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAIhD;;OAEG;IACH,SAAS,CAAC,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI;IAItD;;OAEG;cACa,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAS9D;;OAEG;cACa,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IASlE;;;OAGG;IACH,SAAS,CAAC,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM;IAezD;;OAEG;cACa,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAsB1F;;OAEG;cACa,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAanF"}
|