specweave 0.23.8 → 0.23.10
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/CLAUDE.md +118 -0
- package/dist/src/cli/commands/migrate-config.d.ts +22 -0
- package/dist/src/cli/commands/migrate-config.d.ts.map +1 -0
- package/dist/src/cli/commands/migrate-config.js +149 -0
- package/dist/src/cli/commands/migrate-config.js.map +1 -0
- package/dist/src/cli/helpers/issue-tracker/index.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/index.js +112 -60
- package/dist/src/cli/helpers/issue-tracker/index.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/jira.d.ts +24 -1
- package/dist/src/cli/helpers/issue-tracker/jira.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/jira.js +111 -131
- package/dist/src/cli/helpers/issue-tracker/jira.js.map +1 -1
- package/dist/src/core/config/config-manager.d.ts +135 -0
- package/dist/src/core/config/config-manager.d.ts.map +1 -0
- package/dist/src/core/config/config-manager.js +341 -0
- package/dist/src/core/config/config-manager.js.map +1 -0
- package/dist/src/core/config/config-migrator.d.ts +102 -0
- package/dist/src/core/config/config-migrator.d.ts.map +1 -0
- package/dist/src/core/config/config-migrator.js +367 -0
- package/dist/src/core/config/config-migrator.js.map +1 -0
- package/dist/src/core/config/index.d.ts +10 -0
- package/dist/src/core/config/index.d.ts.map +1 -0
- package/dist/src/core/config/index.js +10 -0
- package/dist/src/core/config/index.js.map +1 -0
- package/dist/src/core/config/types.d.ts +216 -0
- package/dist/src/core/config/types.d.ts.map +1 -0
- package/dist/src/core/config/types.js +32 -0
- package/dist/src/core/config/types.js.map +1 -0
- package/dist/src/integrations/jira/jira-hierarchy-mapper.d.ts +104 -0
- package/dist/src/integrations/jira/jira-hierarchy-mapper.d.ts.map +1 -0
- package/dist/src/integrations/jira/jira-hierarchy-mapper.js +178 -0
- package/dist/src/integrations/jira/jira-hierarchy-mapper.js.map +1 -0
- package/package.json +1 -1
- package/plugins/specweave/commands/migrate-config.md +104 -0
- package/plugins/specweave/hooks/post-task-completion.sh +1 -1
- package/plugins/specweave/hooks/pre-task-completion.sh +1 -1
- package/plugins/specweave-ado/hooks/post-task-completion.sh +1 -1
- package/plugins/specweave-github/hooks/post-task-completion.sh +1 -1
- package/plugins/specweave-jira/hooks/post-task-completion.sh +1 -1
- package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +132 -0
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SpecWeave Configuration Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages .specweave/config.json for non-sensitive configuration
|
|
5
|
+
* (Secrets like API tokens go in .env, NOT in config.json)
|
|
6
|
+
*
|
|
7
|
+
* @module core/config/config-manager
|
|
8
|
+
*/
|
|
9
|
+
import { promises as fs } from 'fs';
|
|
10
|
+
import path from 'path';
|
|
11
|
+
import { DEFAULT_CONFIG } from './types.js';
|
|
12
|
+
/**
|
|
13
|
+
* Configuration file path
|
|
14
|
+
*/
|
|
15
|
+
const CONFIG_FILE_NAME = 'config.json';
|
|
16
|
+
/**
|
|
17
|
+
* Manages SpecWeave configuration
|
|
18
|
+
*/
|
|
19
|
+
export class ConfigManager {
|
|
20
|
+
/**
|
|
21
|
+
* Create a new ConfigManager
|
|
22
|
+
*
|
|
23
|
+
* @param projectRoot - Path to project root (default: process.cwd())
|
|
24
|
+
*/
|
|
25
|
+
constructor(projectRoot = process.cwd()) {
|
|
26
|
+
this.config = null;
|
|
27
|
+
this.configPath = path.join(projectRoot, '.specweave', CONFIG_FILE_NAME);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Read configuration from disk
|
|
31
|
+
*
|
|
32
|
+
* @returns Configuration object
|
|
33
|
+
*/
|
|
34
|
+
async read() {
|
|
35
|
+
if (this.config) {
|
|
36
|
+
return this.config;
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
const content = await fs.readFile(this.configPath, 'utf-8');
|
|
40
|
+
const parsed = JSON.parse(content);
|
|
41
|
+
// Merge with defaults (for backward compatibility)
|
|
42
|
+
this.config = this.mergeWithDefaults(parsed);
|
|
43
|
+
return this.config;
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
if (error.code === 'ENOENT') {
|
|
47
|
+
// Config file doesn't exist, return defaults
|
|
48
|
+
this.config = { ...DEFAULT_CONFIG };
|
|
49
|
+
return this.config;
|
|
50
|
+
}
|
|
51
|
+
throw new Error(`Failed to read config: ${error.message}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Read configuration synchronously
|
|
56
|
+
*
|
|
57
|
+
* @returns Configuration object
|
|
58
|
+
*/
|
|
59
|
+
readSync() {
|
|
60
|
+
if (this.config) {
|
|
61
|
+
return this.config;
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
const { readFileSync } = require('fs');
|
|
65
|
+
const content = readFileSync(this.configPath, 'utf-8');
|
|
66
|
+
const parsed = JSON.parse(content);
|
|
67
|
+
// Merge with defaults
|
|
68
|
+
this.config = this.mergeWithDefaults(parsed);
|
|
69
|
+
return this.config;
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
if (error.code === 'ENOENT') {
|
|
73
|
+
// Config file doesn't exist, return defaults
|
|
74
|
+
this.config = { ...DEFAULT_CONFIG };
|
|
75
|
+
return this.config;
|
|
76
|
+
}
|
|
77
|
+
throw new Error(`Failed to read config: ${error.message}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Write configuration to disk
|
|
82
|
+
*
|
|
83
|
+
* @param config - Configuration to write
|
|
84
|
+
*/
|
|
85
|
+
async write(config) {
|
|
86
|
+
// Validate before writing
|
|
87
|
+
const validation = this.validate(config);
|
|
88
|
+
if (!validation.valid) {
|
|
89
|
+
const errorMessages = validation.errors.map(e => `${e.path}: ${e.message}`).join('\n');
|
|
90
|
+
throw new Error(`Invalid configuration:\n${errorMessages}`);
|
|
91
|
+
}
|
|
92
|
+
try {
|
|
93
|
+
// Ensure .specweave directory exists
|
|
94
|
+
const dir = path.dirname(this.configPath);
|
|
95
|
+
await fs.mkdir(dir, { recursive: true });
|
|
96
|
+
// Write with pretty formatting
|
|
97
|
+
const content = JSON.stringify(config, null, 2);
|
|
98
|
+
await fs.writeFile(this.configPath, content, 'utf-8');
|
|
99
|
+
// Update cached config
|
|
100
|
+
this.config = config;
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
throw new Error(`Failed to write config: ${error.message}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Update configuration with partial values
|
|
108
|
+
*
|
|
109
|
+
* @param partial - Partial configuration to merge
|
|
110
|
+
*/
|
|
111
|
+
async update(partial) {
|
|
112
|
+
const current = await this.read();
|
|
113
|
+
const updated = this.deepMerge(current, partial);
|
|
114
|
+
await this.write(updated);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Get a specific configuration value by path
|
|
118
|
+
*
|
|
119
|
+
* @param path - Dot-separated path (e.g., "issueTracker.domain")
|
|
120
|
+
* @returns Configuration value
|
|
121
|
+
*/
|
|
122
|
+
async get(path) {
|
|
123
|
+
const config = await this.read();
|
|
124
|
+
return this.getByPath(config, path);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Set a specific configuration value by path
|
|
128
|
+
*
|
|
129
|
+
* @param path - Dot-separated path (e.g., "issueTracker.domain")
|
|
130
|
+
* @param value - Value to set
|
|
131
|
+
*/
|
|
132
|
+
async set(path, value) {
|
|
133
|
+
const config = await this.read();
|
|
134
|
+
const updated = this.setByPath(config, path, value);
|
|
135
|
+
await this.write(updated);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Check if configuration file exists
|
|
139
|
+
*
|
|
140
|
+
* @returns True if config exists
|
|
141
|
+
*/
|
|
142
|
+
async exists() {
|
|
143
|
+
try {
|
|
144
|
+
await fs.access(this.configPath);
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Validate configuration
|
|
153
|
+
*
|
|
154
|
+
* @param config - Configuration to validate (default: current config)
|
|
155
|
+
* @returns Validation result
|
|
156
|
+
*/
|
|
157
|
+
validate(config) {
|
|
158
|
+
const errors = [];
|
|
159
|
+
const cfg = config || this.config || DEFAULT_CONFIG;
|
|
160
|
+
// Validate version
|
|
161
|
+
if (!cfg.version) {
|
|
162
|
+
errors.push({
|
|
163
|
+
path: 'version',
|
|
164
|
+
message: 'Version is required',
|
|
165
|
+
value: cfg.version
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
// Validate repository provider
|
|
169
|
+
if (cfg.repository?.provider) {
|
|
170
|
+
const validProviders = ['local', 'github', 'bitbucket', 'ado', 'gitlab', 'generic'];
|
|
171
|
+
if (!validProviders.includes(cfg.repository.provider)) {
|
|
172
|
+
errors.push({
|
|
173
|
+
path: 'repository.provider',
|
|
174
|
+
message: `Invalid provider. Must be one of: ${validProviders.join(', ')}`,
|
|
175
|
+
value: cfg.repository.provider
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
// Validate issue tracker provider
|
|
180
|
+
if (cfg.issueTracker?.provider) {
|
|
181
|
+
const validTrackers = ['none', 'jira', 'github', 'ado'];
|
|
182
|
+
if (!validTrackers.includes(cfg.issueTracker.provider)) {
|
|
183
|
+
errors.push({
|
|
184
|
+
path: 'issueTracker.provider',
|
|
185
|
+
message: `Invalid tracker. Must be one of: ${validTrackers.join(', ')}`,
|
|
186
|
+
value: cfg.issueTracker.provider
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
// Validate Jira configuration
|
|
191
|
+
if (cfg.issueTracker?.provider === 'jira') {
|
|
192
|
+
if (!cfg.issueTracker.domain) {
|
|
193
|
+
errors.push({
|
|
194
|
+
path: 'issueTracker.domain',
|
|
195
|
+
message: 'Domain is required for Jira',
|
|
196
|
+
value: cfg.issueTracker.domain
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
if (cfg.issueTracker.strategy) {
|
|
200
|
+
const validStrategies = ['single-project', 'project-per-team', 'component-based', 'board-based'];
|
|
201
|
+
if (!validStrategies.includes(cfg.issueTracker.strategy)) {
|
|
202
|
+
errors.push({
|
|
203
|
+
path: 'issueTracker.strategy',
|
|
204
|
+
message: `Invalid strategy. Must be one of: ${validStrategies.join(', ')}`,
|
|
205
|
+
value: cfg.issueTracker.strategy
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
// Validate sync direction
|
|
211
|
+
if (cfg.sync?.direction) {
|
|
212
|
+
const validDirections = ['import', 'export', 'bidirectional'];
|
|
213
|
+
if (!validDirections.includes(cfg.sync.direction)) {
|
|
214
|
+
errors.push({
|
|
215
|
+
path: 'sync.direction',
|
|
216
|
+
message: `Invalid direction. Must be one of: ${validDirections.join(', ')}`,
|
|
217
|
+
value: cfg.sync.direction
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return {
|
|
222
|
+
valid: errors.length === 0,
|
|
223
|
+
errors
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Merge configuration with defaults
|
|
228
|
+
*
|
|
229
|
+
* @param config - User configuration
|
|
230
|
+
* @returns Merged configuration
|
|
231
|
+
*/
|
|
232
|
+
mergeWithDefaults(config) {
|
|
233
|
+
return this.deepMerge(DEFAULT_CONFIG, config);
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Deep merge two objects
|
|
237
|
+
*
|
|
238
|
+
* @param target - Target object
|
|
239
|
+
* @param source - Source object
|
|
240
|
+
* @returns Merged object
|
|
241
|
+
*/
|
|
242
|
+
deepMerge(target, source) {
|
|
243
|
+
const result = { ...target };
|
|
244
|
+
for (const key in source) {
|
|
245
|
+
if (source[key] !== undefined && source[key] !== null) {
|
|
246
|
+
if (typeof source[key] === 'object' && !Array.isArray(source[key])) {
|
|
247
|
+
result[key] = this.deepMerge(result[key] || {}, source[key]);
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
result[key] = source[key];
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return result;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Get value by dot-separated path
|
|
258
|
+
*
|
|
259
|
+
* @param obj - Object to get value from
|
|
260
|
+
* @param path - Dot-separated path
|
|
261
|
+
* @returns Value at path
|
|
262
|
+
*/
|
|
263
|
+
getByPath(obj, path) {
|
|
264
|
+
const parts = path.split('.');
|
|
265
|
+
let current = obj;
|
|
266
|
+
for (const part of parts) {
|
|
267
|
+
if (current === null || current === undefined) {
|
|
268
|
+
return undefined;
|
|
269
|
+
}
|
|
270
|
+
current = current[part];
|
|
271
|
+
}
|
|
272
|
+
return current;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Set value by dot-separated path
|
|
276
|
+
*
|
|
277
|
+
* @param obj - Object to set value in
|
|
278
|
+
* @param path - Dot-separated path
|
|
279
|
+
* @param value - Value to set
|
|
280
|
+
* @returns Updated object
|
|
281
|
+
*/
|
|
282
|
+
setByPath(obj, path, value) {
|
|
283
|
+
const parts = path.split('.');
|
|
284
|
+
const result = { ...obj };
|
|
285
|
+
let current = result;
|
|
286
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
287
|
+
const part = parts[i];
|
|
288
|
+
current[part] = { ...(current[part] || {}) };
|
|
289
|
+
current = current[part];
|
|
290
|
+
}
|
|
291
|
+
current[parts[parts.length - 1]] = value;
|
|
292
|
+
return result;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Clear cached configuration
|
|
296
|
+
*/
|
|
297
|
+
clearCache() {
|
|
298
|
+
this.config = null;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Global config manager instance
|
|
303
|
+
*/
|
|
304
|
+
let globalConfigManager = null;
|
|
305
|
+
/**
|
|
306
|
+
* Get global config manager instance
|
|
307
|
+
*
|
|
308
|
+
* @param projectRoot - Path to project root (default: process.cwd())
|
|
309
|
+
* @returns ConfigManager instance
|
|
310
|
+
*/
|
|
311
|
+
export function getConfigManager(projectRoot) {
|
|
312
|
+
if (!globalConfigManager || projectRoot) {
|
|
313
|
+
globalConfigManager = new ConfigManager(projectRoot);
|
|
314
|
+
}
|
|
315
|
+
return globalConfigManager;
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Read configuration
|
|
319
|
+
*
|
|
320
|
+
* Convenience function for reading config
|
|
321
|
+
*
|
|
322
|
+
* @param projectRoot - Path to project root (default: process.cwd())
|
|
323
|
+
* @returns Configuration object
|
|
324
|
+
*/
|
|
325
|
+
export async function readConfig(projectRoot) {
|
|
326
|
+
const manager = getConfigManager(projectRoot);
|
|
327
|
+
return manager.read();
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Write configuration
|
|
331
|
+
*
|
|
332
|
+
* Convenience function for writing config
|
|
333
|
+
*
|
|
334
|
+
* @param config - Configuration to write
|
|
335
|
+
* @param projectRoot - Path to project root (default: process.cwd())
|
|
336
|
+
*/
|
|
337
|
+
export async function writeConfig(config, projectRoot) {
|
|
338
|
+
const manager = getConfigManager(projectRoot);
|
|
339
|
+
await manager.write(config);
|
|
340
|
+
}
|
|
341
|
+
//# sourceMappingURL=config-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-manager.js","sourceRoot":"","sources":["../../../../src/core/config/config-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration Migration Tool
|
|
3
|
+
*
|
|
4
|
+
* Migrates old .env-only format to split secrets/config format
|
|
5
|
+
*
|
|
6
|
+
* @module core/config/config-migrator
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Classification result for an environment variable
|
|
10
|
+
*/
|
|
11
|
+
export interface EnvVarClassification {
|
|
12
|
+
key: string;
|
|
13
|
+
value: string;
|
|
14
|
+
type: 'secret' | 'config';
|
|
15
|
+
reason: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Migration result
|
|
19
|
+
*/
|
|
20
|
+
export interface MigrationResult {
|
|
21
|
+
success: boolean;
|
|
22
|
+
secretsCount: number;
|
|
23
|
+
configCount: number;
|
|
24
|
+
backupPath?: string;
|
|
25
|
+
errors: string[];
|
|
26
|
+
warnings: string[];
|
|
27
|
+
classified: EnvVarClassification[];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Migration options
|
|
31
|
+
*/
|
|
32
|
+
export interface MigrationOptions {
|
|
33
|
+
dryRun?: boolean;
|
|
34
|
+
backup?: boolean;
|
|
35
|
+
force?: boolean;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Migrates .env-only configuration to split format
|
|
39
|
+
*/
|
|
40
|
+
export declare class ConfigMigrator {
|
|
41
|
+
private projectRoot;
|
|
42
|
+
private envPath;
|
|
43
|
+
private configManager;
|
|
44
|
+
/**
|
|
45
|
+
* Secret keywords (case-insensitive)
|
|
46
|
+
*/
|
|
47
|
+
private static SECRET_KEYWORDS;
|
|
48
|
+
/**
|
|
49
|
+
* Email patterns (for auth purposes, considered secrets)
|
|
50
|
+
*/
|
|
51
|
+
private static EMAIL_PATTERN;
|
|
52
|
+
constructor(projectRoot?: string);
|
|
53
|
+
/**
|
|
54
|
+
* Check if migration is needed
|
|
55
|
+
*
|
|
56
|
+
* @returns True if project needs migration
|
|
57
|
+
*/
|
|
58
|
+
needsMigration(): Promise<boolean>;
|
|
59
|
+
/**
|
|
60
|
+
* Classify environment variables as secrets or config
|
|
61
|
+
*
|
|
62
|
+
* @param envVars - Parsed environment variables
|
|
63
|
+
* @returns Classification results
|
|
64
|
+
*/
|
|
65
|
+
classifyVariables(envVars: Record<string, string>): EnvVarClassification[];
|
|
66
|
+
/**
|
|
67
|
+
* Classify a single variable
|
|
68
|
+
*
|
|
69
|
+
* @param key - Environment variable key
|
|
70
|
+
* @param value - Environment variable value
|
|
71
|
+
* @returns Classification result
|
|
72
|
+
*/
|
|
73
|
+
private classifyVariable;
|
|
74
|
+
/**
|
|
75
|
+
* Build config object from classified variables
|
|
76
|
+
*
|
|
77
|
+
* @param classified - Classified variables
|
|
78
|
+
* @returns Configuration object
|
|
79
|
+
*/
|
|
80
|
+
private buildConfigFromVars;
|
|
81
|
+
/**
|
|
82
|
+
* Migrate configuration
|
|
83
|
+
*
|
|
84
|
+
* @param options - Migration options
|
|
85
|
+
* @returns Migration result
|
|
86
|
+
*/
|
|
87
|
+
migrate(options?: MigrationOptions): Promise<MigrationResult>;
|
|
88
|
+
/**
|
|
89
|
+
* Generate placeholder value for .env.example
|
|
90
|
+
*
|
|
91
|
+
* @param key - Environment variable key
|
|
92
|
+
* @returns Placeholder value
|
|
93
|
+
*/
|
|
94
|
+
private generatePlaceholder;
|
|
95
|
+
/**
|
|
96
|
+
* Preview migration (dry run)
|
|
97
|
+
*
|
|
98
|
+
* @returns Migration preview
|
|
99
|
+
*/
|
|
100
|
+
preview(): Promise<MigrationResult>;
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=config-migrator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-migrator.d.ts","sourceRoot":"","sources":["../../../../src/core/config/config-migrator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,EAAE,oBAAoB,EAAE,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,aAAa,CAAgB;IAErC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,eAAe,CAS5B;IAEF;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,aAAa,CAAsD;gBAEtE,WAAW,GAAE,MAAsB;IAM/C;;;;OAIG;IACG,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;IA2BxC;;;;;OAKG;IACH,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,oBAAoB,EAAE;IAW1E;;;;;;OAMG;IACH,OAAO,CAAC,gBAAgB;IAkCxB;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;IAmG3B;;;;;OAKG;IACG,OAAO,CAAC,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,eAAe,CAAC;IAmHvE;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;IAuB3B;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,eAAe,CAAC;CAG1C"}
|