@eddacraft/anvil-core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +14 -0
- package/dist/antipattern/index.d.ts +11 -0
- package/dist/antipattern/index.d.ts.map +1 -0
- package/dist/antipattern/index.js +31 -0
- package/dist/antipattern/patterns-css.d.ts +17 -0
- package/dist/antipattern/patterns-css.d.ts.map +1 -0
- package/dist/antipattern/patterns-css.js +72 -0
- package/dist/antipattern/patterns-html.d.ts +21 -0
- package/dist/antipattern/patterns-html.d.ts.map +1 -0
- package/dist/antipattern/patterns-html.js +139 -0
- package/dist/antipattern/patterns.d.ts +72 -0
- package/dist/antipattern/patterns.d.ts.map +1 -0
- package/dist/antipattern/patterns.js +301 -0
- package/dist/antipattern/scanner.d.ts +32 -0
- package/dist/antipattern/scanner.d.ts.map +1 -0
- package/dist/antipattern/scanner.js +89 -0
- package/dist/antipattern/types.d.ts +318 -0
- package/dist/antipattern/types.d.ts.map +1 -0
- package/dist/antipattern/types.js +278 -0
- package/dist/architecture/analyzer.d.ts +123 -0
- package/dist/architecture/analyzer.d.ts.map +1 -0
- package/dist/architecture/analyzer.js +321 -0
- package/dist/architecture/baseline.d.ts +112 -0
- package/dist/architecture/baseline.d.ts.map +1 -0
- package/dist/architecture/baseline.js +245 -0
- package/dist/architecture/compiler.d.ts +24 -0
- package/dist/architecture/compiler.d.ts.map +1 -0
- package/dist/architecture/compiler.js +57 -0
- package/dist/architecture/context.d.ts +129 -0
- package/dist/architecture/context.d.ts.map +1 -0
- package/dist/architecture/context.js +116 -0
- package/dist/architecture/dc-generator.d.ts +9 -0
- package/dist/architecture/dc-generator.d.ts.map +1 -0
- package/dist/architecture/dc-generator.js +220 -0
- package/dist/architecture/definition-schema.d.ts +128 -0
- package/dist/architecture/definition-schema.d.ts.map +1 -0
- package/dist/architecture/definition-schema.js +94 -0
- package/dist/architecture/edge-detector-html.d.ts +6 -0
- package/dist/architecture/edge-detector-html.d.ts.map +1 -0
- package/dist/architecture/edge-detector-html.js +5 -0
- package/dist/architecture/edge-detector-web.d.ts +32 -0
- package/dist/architecture/edge-detector-web.d.ts.map +1 -0
- package/dist/architecture/edge-detector-web.js +133 -0
- package/dist/architecture/edge-detector.d.ts +116 -0
- package/dist/architecture/edge-detector.d.ts.map +1 -0
- package/dist/architecture/edge-detector.js +229 -0
- package/dist/architecture/entry-detector.d.ts +44 -0
- package/dist/architecture/entry-detector.d.ts.map +1 -0
- package/dist/architecture/entry-detector.js +263 -0
- package/dist/architecture/index.d.ts +21 -0
- package/dist/architecture/index.d.ts.map +1 -0
- package/dist/architecture/index.js +48 -0
- package/dist/architecture/layer-detector.d.ts +60 -0
- package/dist/architecture/layer-detector.d.ts.map +1 -0
- package/dist/architecture/layer-detector.js +331 -0
- package/dist/architecture/rego-generator.d.ts +25 -0
- package/dist/architecture/rego-generator.d.ts.map +1 -0
- package/dist/architecture/rego-generator.js +229 -0
- package/dist/architecture/templates/index.d.ts +39 -0
- package/dist/architecture/templates/index.d.ts.map +1 -0
- package/dist/architecture/templates/index.js +124 -0
- package/dist/architecture/types.d.ts +280 -0
- package/dist/architecture/types.d.ts.map +1 -0
- package/dist/architecture/types.js +269 -0
- package/dist/architecture/yaml-parser.d.ts +13 -0
- package/dist/architecture/yaml-parser.d.ts.map +1 -0
- package/dist/architecture/yaml-parser.js +234 -0
- package/dist/config/constants.d.ts +9 -0
- package/dist/config/constants.d.ts.map +1 -0
- package/dist/config/constants.js +20 -0
- package/dist/config/index.d.ts +9 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +8 -0
- package/dist/config/loader.d.ts +41 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +76 -0
- package/dist/config/nudge-config.d.ts +35 -0
- package/dist/config/nudge-config.d.ts.map +1 -0
- package/dist/config/nudge-config.js +34 -0
- package/dist/config/types.d.ts +30 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +4 -0
- package/dist/contracts/index.d.ts +14 -0
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/index.js +13 -0
- package/dist/contracts/schemas/aps.schema.d.ts +269 -0
- package/dist/contracts/schemas/aps.schema.d.ts.map +1 -0
- package/dist/contracts/schemas/aps.schema.js +183 -0
- package/dist/contracts/schemas/index.d.ts +12 -0
- package/dist/contracts/schemas/index.d.ts.map +1 -0
- package/dist/contracts/schemas/index.js +14 -0
- package/dist/contracts/schemas/json-schema.d.ts +14 -0
- package/dist/contracts/schemas/json-schema.d.ts.map +1 -0
- package/dist/contracts/schemas/json-schema.js +31 -0
- package/dist/contracts/schemas/warning.schema.d.ts +171 -0
- package/dist/contracts/schemas/warning.schema.d.ts.map +1 -0
- package/dist/contracts/schemas/warning.schema.js +123 -0
- package/dist/contracts/types/gate.types.d.ts +194 -0
- package/dist/contracts/types/gate.types.d.ts.map +1 -0
- package/dist/contracts/types/gate.types.js +19 -0
- package/dist/contracts/types/index.d.ts +9 -0
- package/dist/contracts/types/index.d.ts.map +1 -0
- package/dist/contracts/types/index.js +8 -0
- package/dist/crypto/hash.d.ts +47 -0
- package/dist/crypto/hash.d.ts.map +1 -0
- package/dist/crypto/hash.js +110 -0
- package/dist/crypto/index.d.ts +7 -0
- package/dist/crypto/index.d.ts.map +1 -0
- package/dist/crypto/index.js +6 -0
- package/dist/drift/index.d.ts +6 -0
- package/dist/drift/index.d.ts.map +1 -0
- package/dist/drift/index.js +5 -0
- package/dist/drift/report-generator.d.ts +21 -0
- package/dist/drift/report-generator.d.ts.map +1 -0
- package/dist/drift/report-generator.js +240 -0
- package/dist/drift/snapshot-capture.d.ts +26 -0
- package/dist/drift/snapshot-capture.d.ts.map +1 -0
- package/dist/drift/snapshot-capture.js +195 -0
- package/dist/drift/snapshot-compare.d.ts +50 -0
- package/dist/drift/snapshot-compare.d.ts.map +1 -0
- package/dist/drift/snapshot-compare.js +142 -0
- package/dist/drift/snapshot-schema.d.ts +197 -0
- package/dist/drift/snapshot-schema.d.ts.map +1 -0
- package/dist/drift/snapshot-schema.js +193 -0
- package/dist/drift/snapshot-storage.d.ts +25 -0
- package/dist/drift/snapshot-storage.d.ts.map +1 -0
- package/dist/drift/snapshot-storage.js +179 -0
- package/dist/explain/antipattern-explainer.d.ts +4 -0
- package/dist/explain/antipattern-explainer.d.ts.map +1 -0
- package/dist/explain/antipattern-explainer.js +196 -0
- package/dist/explain/boundary-explainer.d.ts +5 -0
- package/dist/explain/boundary-explainer.d.ts.map +1 -0
- package/dist/explain/boundary-explainer.js +261 -0
- package/dist/explain/explain-service.d.ts +19 -0
- package/dist/explain/explain-service.d.ts.map +1 -0
- package/dist/explain/explain-service.js +106 -0
- package/dist/explain/index.d.ts +7 -0
- package/dist/explain/index.d.ts.map +1 -0
- package/dist/explain/index.js +5 -0
- package/dist/explain/template-loader.d.ts +9 -0
- package/dist/explain/template-loader.d.ts.map +1 -0
- package/dist/explain/template-loader.js +51 -0
- package/dist/explain/types.d.ts +46 -0
- package/dist/explain/types.d.ts.map +1 -0
- package/dist/explain/types.js +31 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +37 -0
- package/dist/provenance/collector.d.ts +86 -0
- package/dist/provenance/collector.d.ts.map +1 -0
- package/dist/provenance/collector.js +425 -0
- package/dist/provenance/git-ai-standard/git-notes.d.ts +85 -0
- package/dist/provenance/git-ai-standard/git-notes.d.ts.map +1 -0
- package/dist/provenance/git-ai-standard/git-notes.js +292 -0
- package/dist/provenance/git-ai-standard/index.d.ts +44 -0
- package/dist/provenance/git-ai-standard/index.d.ts.map +1 -0
- package/dist/provenance/git-ai-standard/index.js +47 -0
- package/dist/provenance/git-ai-standard/serializer.d.ts +54 -0
- package/dist/provenance/git-ai-standard/serializer.d.ts.map +1 -0
- package/dist/provenance/git-ai-standard/serializer.js +224 -0
- package/dist/provenance/git-ai-standard/session.d.ts +51 -0
- package/dist/provenance/git-ai-standard/session.d.ts.map +1 -0
- package/dist/provenance/git-ai-standard/session.js +118 -0
- package/dist/provenance/git-ai-standard/types.d.ts +173 -0
- package/dist/provenance/git-ai-standard/types.d.ts.map +1 -0
- package/dist/provenance/git-ai-standard/types.js +109 -0
- package/dist/provenance/index.d.ts +5 -0
- package/dist/provenance/index.d.ts.map +1 -0
- package/dist/provenance/index.js +6 -0
- package/dist/provenance/store.d.ts +83 -0
- package/dist/provenance/store.d.ts.map +1 -0
- package/dist/provenance/store.js +248 -0
- package/dist/provenance/types.d.ts +160 -0
- package/dist/provenance/types.d.ts.map +1 -0
- package/dist/provenance/types.js +112 -0
- package/dist/suppression/index.d.ts +4 -0
- package/dist/suppression/index.d.ts.map +1 -0
- package/dist/suppression/index.js +3 -0
- package/dist/suppression/parser.d.ts +31 -0
- package/dist/suppression/parser.d.ts.map +1 -0
- package/dist/suppression/parser.js +219 -0
- package/dist/suppression/service.d.ts +29 -0
- package/dist/suppression/service.d.ts.map +1 -0
- package/dist/suppression/service.js +132 -0
- package/dist/suppression/store.d.ts +61 -0
- package/dist/suppression/store.d.ts.map +1 -0
- package/dist/suppression/store.js +169 -0
- package/dist/utils/debug.d.ts +48 -0
- package/dist/utils/debug.d.ts.map +1 -0
- package/dist/utils/debug.js +100 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/path-safety.d.ts +21 -0
- package/dist/utils/path-safety.d.ts.map +1 -0
- package/dist/utils/path-safety.js +49 -0
- package/dist/utils/severity.d.ts +37 -0
- package/dist/utils/severity.d.ts.map +1 -0
- package/dist/utils/severity.js +22 -0
- package/dist/validation/aps-validator.d.ts +66 -0
- package/dist/validation/aps-validator.d.ts.map +1 -0
- package/dist/validation/aps-validator.js +173 -0
- package/dist/validation/errors.d.ts +52 -0
- package/dist/validation/errors.d.ts.map +1 -0
- package/dist/validation/errors.js +115 -0
- package/dist/validation/index.d.ts +8 -0
- package/dist/validation/index.d.ts.map +1 -0
- package/dist/validation/index.js +13 -0
- package/dist/warnings/index.d.ts +2 -0
- package/dist/warnings/index.d.ts.map +1 -0
- package/dist/warnings/index.js +1 -0
- package/dist/warnings/warning-id.d.ts +180 -0
- package/dist/warnings/warning-id.d.ts.map +1 -0
- package/dist/warnings/warning-id.js +257 -0
- package/package.json +79 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Architecture analyzer
|
|
3
|
+
*
|
|
4
|
+
* Main entry point for architecture analysis. Combines layer detection,
|
|
5
|
+
* entry point detection, and dependency analysis.
|
|
6
|
+
*/
|
|
7
|
+
import { BaselineManager } from './baseline.js';
|
|
8
|
+
import { type ArchitectureBaseline, type Layers, type EntryPoint, type LayerAssignment, type BoundaryViolation } from './types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Analysis result
|
|
11
|
+
*/
|
|
12
|
+
export interface AnalysisResult {
|
|
13
|
+
/** Detected entry points */
|
|
14
|
+
entryPoints: EntryPoint[];
|
|
15
|
+
/** Suggested layer structure */
|
|
16
|
+
layers: Layers;
|
|
17
|
+
/** Layer assignments for all files */
|
|
18
|
+
assignments: LayerAssignment[];
|
|
19
|
+
/** Files with ambiguous layer assignments */
|
|
20
|
+
ambiguous: LayerAssignment[];
|
|
21
|
+
/** Total modules analysed */
|
|
22
|
+
moduleCount: number;
|
|
23
|
+
/** Detected violations */
|
|
24
|
+
violations: BoundaryViolation[];
|
|
25
|
+
/** New violations (not in baseline) */
|
|
26
|
+
newViolations: BoundaryViolation[];
|
|
27
|
+
/** Existing violations (in baseline) */
|
|
28
|
+
existingViolations: BoundaryViolation[];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Analyzer options
|
|
32
|
+
*/
|
|
33
|
+
export interface AnalyzerOptions {
|
|
34
|
+
/** Custom layers (overrides detection) */
|
|
35
|
+
layers?: Layers;
|
|
36
|
+
/** Include test files in analysis */
|
|
37
|
+
includeTests?: boolean;
|
|
38
|
+
/** File patterns to include */
|
|
39
|
+
includePatterns?: string[];
|
|
40
|
+
/** File patterns to exclude */
|
|
41
|
+
excludePatterns?: string[];
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Architecture analyzer
|
|
45
|
+
*/
|
|
46
|
+
export declare class ArchitectureAnalyzer {
|
|
47
|
+
private workspaceRoot;
|
|
48
|
+
private layerDetector;
|
|
49
|
+
private entryPointDetector;
|
|
50
|
+
private baselineManager;
|
|
51
|
+
private options;
|
|
52
|
+
constructor(workspaceRoot: string, options?: AnalyzerOptions);
|
|
53
|
+
/**
|
|
54
|
+
* Analyse the codebase and return results
|
|
55
|
+
*/
|
|
56
|
+
analyse(filePaths: string[]): Promise<AnalysisResult>;
|
|
57
|
+
/**
|
|
58
|
+
* Filter files based on include/exclude patterns
|
|
59
|
+
*/
|
|
60
|
+
private filterFiles;
|
|
61
|
+
/**
|
|
62
|
+
* Classify violations as new or existing
|
|
63
|
+
*/
|
|
64
|
+
private classifyViolations;
|
|
65
|
+
/**
|
|
66
|
+
* Detect boundary violations by extracting imports and checking layer rules.
|
|
67
|
+
*
|
|
68
|
+
* For each import edge that crosses layer boundaries, checks whether the
|
|
69
|
+
* dependency is allowed by the layer's `depends_on` rules. Disallowed
|
|
70
|
+
* cross-layer imports are returned as BoundaryViolations.
|
|
71
|
+
*/
|
|
72
|
+
private detectViolations;
|
|
73
|
+
/**
|
|
74
|
+
* Create a baseline from analysis results
|
|
75
|
+
*/
|
|
76
|
+
createBaseline(result: AnalysisResult): ArchitectureBaseline;
|
|
77
|
+
/**
|
|
78
|
+
* Update baseline with new analysis
|
|
79
|
+
*/
|
|
80
|
+
updateBaseline(result: AnalysisResult): ArchitectureBaseline | null;
|
|
81
|
+
/**
|
|
82
|
+
* Get the baseline manager
|
|
83
|
+
*/
|
|
84
|
+
getBaselineManager(): BaselineManager;
|
|
85
|
+
/**
|
|
86
|
+
* Check if baseline exists
|
|
87
|
+
*/
|
|
88
|
+
hasBaseline(): boolean;
|
|
89
|
+
/**
|
|
90
|
+
* Load existing baseline
|
|
91
|
+
*/
|
|
92
|
+
loadBaseline(): ArchitectureBaseline | null;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Create an architecture analyzer
|
|
96
|
+
*/
|
|
97
|
+
export declare function createArchitectureAnalyzer(workspaceRoot: string, options?: AnalyzerOptions): ArchitectureAnalyzer;
|
|
98
|
+
/**
|
|
99
|
+
* Quick analysis helper - analyse and optionally create baseline
|
|
100
|
+
*/
|
|
101
|
+
export declare function analyseArchitecture(workspaceRoot: string, filePaths: string[], options?: AnalyzerOptions & {
|
|
102
|
+
createBaseline?: boolean;
|
|
103
|
+
}): Promise<AnalysisResult & {
|
|
104
|
+
baseline?: ArchitectureBaseline;
|
|
105
|
+
}>;
|
|
106
|
+
/**
|
|
107
|
+
* Options for baseline inference
|
|
108
|
+
*/
|
|
109
|
+
export interface InferBaselineOptions extends AnalyzerOptions {
|
|
110
|
+
/** Save baseline to .anvil/architecture.json (default: true) */
|
|
111
|
+
save?: boolean;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Infer architecture baseline from codebase
|
|
115
|
+
*
|
|
116
|
+
* Scans the workspace, detects layers and entry points, and creates a baseline.
|
|
117
|
+
* This is the primary entry point for `anvil init` architecture setup.
|
|
118
|
+
*/
|
|
119
|
+
export declare function inferBaseline(workspaceRoot: string, options?: InferBaselineOptions): Promise<{
|
|
120
|
+
result: AnalysisResult;
|
|
121
|
+
baseline: ArchitectureBaseline;
|
|
122
|
+
}>;
|
|
123
|
+
//# sourceMappingURL=analyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../../src/architecture/analyzer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,OAAO,EAAE,eAAe,EAAyB,MAAM,eAAe,CAAC;AAEvE,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,MAAM,EAEX,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,iBAAiB,EAKvB,MAAM,YAAY,CAAC;AAIpB;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,4BAA4B;IAC5B,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,gCAAgC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,WAAW,EAAE,eAAe,EAAE,CAAC;IAC/B,6CAA6C;IAC7C,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,6BAA6B;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,0BAA0B;IAC1B,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,uCAAuC;IACvC,aAAa,EAAE,iBAAiB,EAAE,CAAC;IACnC,wCAAwC;IACxC,kBAAkB,EAAE,iBAAiB,EAAE,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,0CAA0C;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,+BAA+B;IAC/B,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,+BAA+B;IAC/B,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AA0BD;;GAEG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,OAAO,CAA4B;gBAE/B,aAAa,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB;IAchE;;OAEG;IACG,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC;IAwC3D;;OAEG;IACH,OAAO,CAAC,WAAW;IAoBnB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAwC1B;;;;;;OAMG;IACH,OAAO,CAAC,gBAAgB;IA2CxB;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,cAAc,GAAG,oBAAoB;IAmB5D;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,cAAc,GAAG,oBAAoB,GAAG,IAAI;IAkBnE;;OAEG;IACH,kBAAkB,IAAI,eAAe;IAIrC;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;IACH,YAAY,IAAI,oBAAoB,GAAG,IAAI;CAG5C;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,eAAe,GACxB,oBAAoB,CAEtB;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,MAAM,EAAE,EACnB,OAAO,CAAC,EAAE,eAAe,GAAG;IAAE,cAAc,CAAC,EAAE,OAAO,CAAA;CAAE,GACvD,OAAO,CAAC,cAAc,GAAG;IAAE,QAAQ,CAAC,EAAE,oBAAoB,CAAA;CAAE,CAAC,CAU/D;AAED;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,eAAe;IAC3D,gEAAgE;IAChE,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC;IAAE,MAAM,EAAE,cAAc,CAAC;IAAC,QAAQ,EAAE,oBAAoB,CAAA;CAAE,CAAC,CAWrE"}
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Architecture analyzer
|
|
3
|
+
*
|
|
4
|
+
* Main entry point for architecture analysis. Combines layer detection,
|
|
5
|
+
* entry point detection, and dependency analysis.
|
|
6
|
+
*/
|
|
7
|
+
import { readdirSync, statSync } from 'node:fs';
|
|
8
|
+
import { join } from 'node:path';
|
|
9
|
+
import { minimatch } from 'minimatch';
|
|
10
|
+
import { createDebugger } from '../utils/debug.js';
|
|
11
|
+
import { createLayerDetector } from './layer-detector.js';
|
|
12
|
+
import { createEntryPointDetector } from './entry-detector.js';
|
|
13
|
+
import { createBaselineManager } from './baseline.js';
|
|
14
|
+
import { extractImportsFromFiles, toDependencyEdge } from './edge-detector.js';
|
|
15
|
+
import { createViolationId, createDefaultLayers, createDefaultBoundaries, } from './types.js';
|
|
16
|
+
const debug = createDebugger('architecture');
|
|
17
|
+
/**
|
|
18
|
+
* Default exclude patterns
|
|
19
|
+
*/
|
|
20
|
+
const DEFAULT_EXCLUDE_PATTERNS = [
|
|
21
|
+
'**/node_modules/**',
|
|
22
|
+
'**/.git/**',
|
|
23
|
+
'**/dist/**',
|
|
24
|
+
'**/build/**',
|
|
25
|
+
'**/coverage/**',
|
|
26
|
+
'**/*.d.ts',
|
|
27
|
+
];
|
|
28
|
+
/**
|
|
29
|
+
* Default include patterns
|
|
30
|
+
*/
|
|
31
|
+
const DEFAULT_INCLUDE_PATTERNS = [
|
|
32
|
+
'**/*.ts',
|
|
33
|
+
'**/*.tsx',
|
|
34
|
+
'**/*.js',
|
|
35
|
+
'**/*.jsx',
|
|
36
|
+
'**/*.mjs',
|
|
37
|
+
'**/*.cjs',
|
|
38
|
+
];
|
|
39
|
+
/**
|
|
40
|
+
* Architecture analyzer
|
|
41
|
+
*/
|
|
42
|
+
export class ArchitectureAnalyzer {
|
|
43
|
+
workspaceRoot;
|
|
44
|
+
layerDetector;
|
|
45
|
+
entryPointDetector;
|
|
46
|
+
baselineManager;
|
|
47
|
+
options;
|
|
48
|
+
constructor(workspaceRoot, options = {}) {
|
|
49
|
+
this.workspaceRoot = workspaceRoot;
|
|
50
|
+
this.options = {
|
|
51
|
+
layers: options.layers ?? createDefaultLayers(),
|
|
52
|
+
includeTests: options.includeTests ?? false,
|
|
53
|
+
includePatterns: options.includePatterns ?? DEFAULT_INCLUDE_PATTERNS,
|
|
54
|
+
excludePatterns: options.excludePatterns ?? DEFAULT_EXCLUDE_PATTERNS,
|
|
55
|
+
};
|
|
56
|
+
this.layerDetector = createLayerDetector(this.options.layers);
|
|
57
|
+
this.entryPointDetector = createEntryPointDetector(workspaceRoot);
|
|
58
|
+
this.baselineManager = createBaselineManager(workspaceRoot);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Analyse the codebase and return results
|
|
62
|
+
*/
|
|
63
|
+
async analyse(filePaths) {
|
|
64
|
+
// Filter files
|
|
65
|
+
const filteredPaths = this.filterFiles(filePaths);
|
|
66
|
+
// Detect entry points
|
|
67
|
+
let entryPoints = this.entryPointDetector.detectEntryPoints(filteredPaths);
|
|
68
|
+
if (!this.options.includeTests) {
|
|
69
|
+
entryPoints = this.entryPointDetector.filterNonTestEntryPoints(entryPoints);
|
|
70
|
+
}
|
|
71
|
+
// Detect layers
|
|
72
|
+
const assignments = this.layerDetector.detectLayers(filteredPaths);
|
|
73
|
+
const ambiguous = this.layerDetector.findAmbiguousAssignments(filteredPaths);
|
|
74
|
+
// Suggest layers based on detected patterns
|
|
75
|
+
const suggestedLayers = this.layerDetector.suggestLayers(filteredPaths);
|
|
76
|
+
// Use suggested layers if no custom layers provided
|
|
77
|
+
const layers = Object.keys(this.options.layers).length > 0 ? this.options.layers : suggestedLayers;
|
|
78
|
+
// Detect violations by extracting imports and checking against layer boundaries
|
|
79
|
+
const violations = this.detectViolations(filteredPaths, layers);
|
|
80
|
+
// Classify violations as new or existing
|
|
81
|
+
const baseline = this.baselineManager.load();
|
|
82
|
+
const { newViolations, existingViolations } = this.classifyViolations(violations, baseline);
|
|
83
|
+
return {
|
|
84
|
+
entryPoints,
|
|
85
|
+
layers,
|
|
86
|
+
assignments,
|
|
87
|
+
ambiguous,
|
|
88
|
+
moduleCount: filteredPaths.length,
|
|
89
|
+
violations,
|
|
90
|
+
newViolations,
|
|
91
|
+
existingViolations,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Filter files based on include/exclude patterns
|
|
96
|
+
*/
|
|
97
|
+
filterFiles(filePaths) {
|
|
98
|
+
return filePaths.filter((path) => {
|
|
99
|
+
// Check excludes
|
|
100
|
+
for (const pattern of this.options.excludePatterns) {
|
|
101
|
+
if (minimatch(path, pattern, { matchBase: true })) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// Check includes
|
|
106
|
+
for (const pattern of this.options.includePatterns) {
|
|
107
|
+
if (minimatch(path, pattern, { matchBase: true })) {
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return false;
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Classify violations as new or existing
|
|
116
|
+
*/
|
|
117
|
+
classifyViolations(violations, baseline) {
|
|
118
|
+
if (!baseline) {
|
|
119
|
+
// No baseline = all violations are new
|
|
120
|
+
return {
|
|
121
|
+
newViolations: violations.map((v) => ({ ...v, is_new: true })),
|
|
122
|
+
existingViolations: [],
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
const baselineIds = new Set(baseline.baseline_snapshot.violations.map((v) => v.id));
|
|
126
|
+
const newViolations = [];
|
|
127
|
+
const existingViolations = [];
|
|
128
|
+
for (const violation of violations) {
|
|
129
|
+
const id = createViolationId(violation.edge.from, violation.edge.to, violation.edge.line);
|
|
130
|
+
if (baselineIds.has(id)) {
|
|
131
|
+
existingViolations.push({
|
|
132
|
+
...violation,
|
|
133
|
+
is_new: false,
|
|
134
|
+
baseline_id: id,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
newViolations.push({
|
|
139
|
+
...violation,
|
|
140
|
+
is_new: true,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return { newViolations, existingViolations };
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Detect boundary violations by extracting imports and checking layer rules.
|
|
148
|
+
*
|
|
149
|
+
* For each import edge that crosses layer boundaries, checks whether the
|
|
150
|
+
* dependency is allowed by the layer's `depends_on` rules. Disallowed
|
|
151
|
+
* cross-layer imports are returned as BoundaryViolations.
|
|
152
|
+
*/
|
|
153
|
+
detectViolations(filePaths, layers) {
|
|
154
|
+
const violations = [];
|
|
155
|
+
// Extract all import edges from source files
|
|
156
|
+
const edges = extractImportsFromFiles(filePaths, this.workspaceRoot);
|
|
157
|
+
// Build boundary rules (disallowed layer pairs)
|
|
158
|
+
const boundaries = createDefaultBoundaries(layers);
|
|
159
|
+
const boundaryMap = new Map();
|
|
160
|
+
for (const boundary of boundaries) {
|
|
161
|
+
boundaryMap.set(`${boundary.from}->${boundary.to}`, boundary);
|
|
162
|
+
}
|
|
163
|
+
// Check each edge against layer rules
|
|
164
|
+
for (const edge of edges) {
|
|
165
|
+
const fromAssignment = this.layerDetector.detectLayer(edge.from);
|
|
166
|
+
const toAssignment = this.layerDetector.detectLayer(edge.to);
|
|
167
|
+
const fromLayer = fromAssignment.layer;
|
|
168
|
+
const toLayer = toAssignment.layer;
|
|
169
|
+
// Skip if either file has no layer assignment or they're in the same layer
|
|
170
|
+
if (!fromLayer || !toLayer || fromLayer === toLayer) {
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
// Check if this cross-layer dependency is allowed
|
|
174
|
+
if (!this.layerDetector.isAllowedDependency(fromLayer, toLayer, layers)) {
|
|
175
|
+
const boundaryKey = `${fromLayer}->${toLayer}`;
|
|
176
|
+
const boundary = boundaryMap.get(boundaryKey);
|
|
177
|
+
violations.push({
|
|
178
|
+
edge: toDependencyEdge(edge, fromLayer, toLayer),
|
|
179
|
+
boundary,
|
|
180
|
+
is_new: true, // Will be reclassified by classifyViolations
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
debug(`detected ${violations.length} boundary violations from ${edges.length} edges`);
|
|
185
|
+
return violations;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Create a baseline from analysis results
|
|
189
|
+
*/
|
|
190
|
+
createBaseline(result) {
|
|
191
|
+
const violations = result.violations.map((v) => ({
|
|
192
|
+
id: createViolationId(v.edge.from, v.edge.to, v.edge.line),
|
|
193
|
+
from_layer: v.edge.from_layer ?? 'unknown',
|
|
194
|
+
to_layer: v.edge.to_layer ?? 'unknown',
|
|
195
|
+
from_file: v.edge.from,
|
|
196
|
+
to_file: v.edge.to,
|
|
197
|
+
import_line: v.edge.line,
|
|
198
|
+
}));
|
|
199
|
+
return this.baselineManager.create({
|
|
200
|
+
entryPoints: result.entryPoints,
|
|
201
|
+
layers: result.layers,
|
|
202
|
+
boundaries: createDefaultBoundaries(result.layers),
|
|
203
|
+
violations,
|
|
204
|
+
moduleCount: result.moduleCount,
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Update baseline with new analysis
|
|
209
|
+
*/
|
|
210
|
+
updateBaseline(result) {
|
|
211
|
+
const violations = result.violations.map((v) => ({
|
|
212
|
+
id: createViolationId(v.edge.from, v.edge.to, v.edge.line),
|
|
213
|
+
from_layer: v.edge.from_layer ?? 'unknown',
|
|
214
|
+
to_layer: v.edge.to_layer ?? 'unknown',
|
|
215
|
+
from_file: v.edge.from,
|
|
216
|
+
to_file: v.edge.to,
|
|
217
|
+
import_line: v.edge.line,
|
|
218
|
+
}));
|
|
219
|
+
return this.baselineManager.update({
|
|
220
|
+
entryPoints: result.entryPoints,
|
|
221
|
+
layers: result.layers,
|
|
222
|
+
violations,
|
|
223
|
+
moduleCount: result.moduleCount,
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Get the baseline manager
|
|
228
|
+
*/
|
|
229
|
+
getBaselineManager() {
|
|
230
|
+
return this.baselineManager;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Check if baseline exists
|
|
234
|
+
*/
|
|
235
|
+
hasBaseline() {
|
|
236
|
+
return this.baselineManager.exists();
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Load existing baseline
|
|
240
|
+
*/
|
|
241
|
+
loadBaseline() {
|
|
242
|
+
return this.baselineManager.load();
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Create an architecture analyzer
|
|
247
|
+
*/
|
|
248
|
+
export function createArchitectureAnalyzer(workspaceRoot, options) {
|
|
249
|
+
return new ArchitectureAnalyzer(workspaceRoot, options);
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Quick analysis helper - analyse and optionally create baseline
|
|
253
|
+
*/
|
|
254
|
+
export async function analyseArchitecture(workspaceRoot, filePaths, options) {
|
|
255
|
+
const analyzer = createArchitectureAnalyzer(workspaceRoot, options);
|
|
256
|
+
const result = await analyzer.analyse(filePaths);
|
|
257
|
+
if (options?.createBaseline) {
|
|
258
|
+
const baseline = analyzer.createBaseline(result);
|
|
259
|
+
return { ...result, baseline };
|
|
260
|
+
}
|
|
261
|
+
return result;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Infer architecture baseline from codebase
|
|
265
|
+
*
|
|
266
|
+
* Scans the workspace, detects layers and entry points, and creates a baseline.
|
|
267
|
+
* This is the primary entry point for `anvil init` architecture setup.
|
|
268
|
+
*/
|
|
269
|
+
export async function inferBaseline(workspaceRoot, options) {
|
|
270
|
+
const analyzer = createArchitectureAnalyzer(workspaceRoot, options);
|
|
271
|
+
const filePaths = collectSourceFiles(workspaceRoot, options);
|
|
272
|
+
const result = await analyzer.analyse(filePaths);
|
|
273
|
+
const baseline = analyzer.createBaseline(result);
|
|
274
|
+
if (options?.save !== false) {
|
|
275
|
+
analyzer.getBaselineManager().save(baseline);
|
|
276
|
+
}
|
|
277
|
+
return { result, baseline };
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Collect source files from workspace
|
|
281
|
+
*/
|
|
282
|
+
function collectSourceFiles(workspaceRoot, options) {
|
|
283
|
+
const includePatterns = options?.includePatterns ?? DEFAULT_INCLUDE_PATTERNS;
|
|
284
|
+
const excludePatterns = options?.excludePatterns ?? DEFAULT_EXCLUDE_PATTERNS;
|
|
285
|
+
const files = [];
|
|
286
|
+
function walk(dir, relativePath = '') {
|
|
287
|
+
let entries;
|
|
288
|
+
try {
|
|
289
|
+
entries = readdirSync(dir);
|
|
290
|
+
}
|
|
291
|
+
catch (err) {
|
|
292
|
+
debug('skipping directory (read error):', err);
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
for (const entry of entries) {
|
|
296
|
+
const fullPath = join(dir, entry);
|
|
297
|
+
const relPath = relativePath ? `${relativePath}/${entry}` : entry;
|
|
298
|
+
if (excludePatterns.some((p) => minimatch(relPath, p, { matchBase: true }))) {
|
|
299
|
+
continue;
|
|
300
|
+
}
|
|
301
|
+
let stat;
|
|
302
|
+
try {
|
|
303
|
+
stat = statSync(fullPath);
|
|
304
|
+
}
|
|
305
|
+
catch (err) {
|
|
306
|
+
debug('skipping entry (stat error):', err);
|
|
307
|
+
continue;
|
|
308
|
+
}
|
|
309
|
+
if (stat.isDirectory()) {
|
|
310
|
+
walk(fullPath, relPath);
|
|
311
|
+
}
|
|
312
|
+
else if (stat.isFile()) {
|
|
313
|
+
if (includePatterns.some((p) => minimatch(relPath, p, { matchBase: true }))) {
|
|
314
|
+
files.push(relPath);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
walk(workspaceRoot);
|
|
320
|
+
return files;
|
|
321
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Architecture baseline storage
|
|
3
|
+
*
|
|
4
|
+
* Handles reading/writing .anvil/architecture.json
|
|
5
|
+
*/
|
|
6
|
+
import { type ArchitectureBaseline, type Layers, type EntryPoint, type Boundary, type BaselineViolation } from './types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Default baseline file path
|
|
9
|
+
*/
|
|
10
|
+
export declare const BASELINE_FILENAME = "architecture.json";
|
|
11
|
+
export declare const ANVIL_DIR = ".anvil";
|
|
12
|
+
/**
|
|
13
|
+
* Get the full path to the baseline file
|
|
14
|
+
*/
|
|
15
|
+
export declare function getBaselinePath(workspaceRoot: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Check if a baseline exists
|
|
18
|
+
*/
|
|
19
|
+
export declare function baselineExists(workspaceRoot: string): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Load the architecture baseline
|
|
22
|
+
*/
|
|
23
|
+
export declare function loadBaseline(workspaceRoot: string): ArchitectureBaseline | null;
|
|
24
|
+
/**
|
|
25
|
+
* Save the architecture baseline
|
|
26
|
+
*/
|
|
27
|
+
export declare function saveBaseline(workspaceRoot: string, baseline: ArchitectureBaseline): void;
|
|
28
|
+
/**
|
|
29
|
+
* Create a new baseline with defaults
|
|
30
|
+
*/
|
|
31
|
+
export declare function createBaseline(options: {
|
|
32
|
+
entryPoints?: EntryPoint[];
|
|
33
|
+
layers?: Layers;
|
|
34
|
+
boundaries?: Boundary[];
|
|
35
|
+
violations?: BaselineViolation[];
|
|
36
|
+
moduleCount?: number;
|
|
37
|
+
}): ArchitectureBaseline;
|
|
38
|
+
/**
|
|
39
|
+
* Update an existing baseline
|
|
40
|
+
*/
|
|
41
|
+
export declare function updateBaseline(existing: ArchitectureBaseline, updates: Partial<{
|
|
42
|
+
entryPoints: EntryPoint[];
|
|
43
|
+
layers: Layers;
|
|
44
|
+
boundaries: Boundary[];
|
|
45
|
+
violations: BaselineViolation[];
|
|
46
|
+
moduleCount: number;
|
|
47
|
+
}>): ArchitectureBaseline;
|
|
48
|
+
/**
|
|
49
|
+
* Merge new violations into baseline (for incremental updates)
|
|
50
|
+
*/
|
|
51
|
+
export declare function mergeViolations(existing: BaselineViolation[], newViolations: BaselineViolation[]): BaselineViolation[];
|
|
52
|
+
/**
|
|
53
|
+
* Find violations that are NEW (not in baseline)
|
|
54
|
+
*/
|
|
55
|
+
export declare function findNewViolations(current: BaselineViolation[], baseline: BaselineViolation[]): BaselineViolation[];
|
|
56
|
+
/**
|
|
57
|
+
* Find violations that were FIXED (in baseline but not current)
|
|
58
|
+
*/
|
|
59
|
+
export declare function findFixedViolations(current: BaselineViolation[], baseline: BaselineViolation[]): BaselineViolation[];
|
|
60
|
+
/**
|
|
61
|
+
* Baseline manager for convenient operations
|
|
62
|
+
*/
|
|
63
|
+
export declare class BaselineManager {
|
|
64
|
+
private workspaceRoot;
|
|
65
|
+
private baseline;
|
|
66
|
+
constructor(workspaceRoot: string);
|
|
67
|
+
/**
|
|
68
|
+
* Check if baseline exists
|
|
69
|
+
*/
|
|
70
|
+
exists(): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Load baseline (cached)
|
|
73
|
+
*/
|
|
74
|
+
load(): ArchitectureBaseline | null;
|
|
75
|
+
/**
|
|
76
|
+
* Force reload baseline
|
|
77
|
+
*/
|
|
78
|
+
reload(): ArchitectureBaseline | null;
|
|
79
|
+
/**
|
|
80
|
+
* Save baseline
|
|
81
|
+
*/
|
|
82
|
+
save(baseline: ArchitectureBaseline): void;
|
|
83
|
+
/**
|
|
84
|
+
* Create and save a new baseline
|
|
85
|
+
*/
|
|
86
|
+
create(options: Parameters<typeof createBaseline>[0]): ArchitectureBaseline;
|
|
87
|
+
/**
|
|
88
|
+
* Update and save existing baseline
|
|
89
|
+
*/
|
|
90
|
+
update(updates: Parameters<typeof updateBaseline>[1]): ArchitectureBaseline | null;
|
|
91
|
+
/**
|
|
92
|
+
* Get layers from baseline or defaults
|
|
93
|
+
*/
|
|
94
|
+
getLayers(): Layers;
|
|
95
|
+
/**
|
|
96
|
+
* Get boundaries from baseline or defaults
|
|
97
|
+
*/
|
|
98
|
+
getBoundaries(): Boundary[];
|
|
99
|
+
/**
|
|
100
|
+
* Check if a violation is new
|
|
101
|
+
*/
|
|
102
|
+
isNewViolation(violation: BaselineViolation): boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Get baseline path
|
|
105
|
+
*/
|
|
106
|
+
getPath(): string;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Create a baseline manager
|
|
110
|
+
*/
|
|
111
|
+
export declare function createBaselineManager(workspaceRoot: string): BaselineManager;
|
|
112
|
+
//# sourceMappingURL=baseline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseline.d.ts","sourceRoot":"","sources":["../../src/architecture/baseline.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,MAAM,EACX,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,iBAAiB,EAGvB,MAAM,YAAY,CAAC;AAKpB;;GAEG;AACH,eAAO,MAAM,iBAAiB,sBAAsB,CAAC;AACrD,eAAO,MAAM,SAAS,WAAW,CAAC;AAElC;;GAEG;AACH,wBAAgB,eAAe,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAE7D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,aAAa,EAAE,MAAM,GAAG,oBAAoB,GAAG,IAAI,CAgC/E;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,oBAAoB,GAAG,IAAI,CAkBxF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE;IACtC,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,QAAQ,EAAE,CAAC;IACxB,UAAU,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,oBAAoB,CAkBvB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,oBAAoB,EAC9B,OAAO,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,QAAQ,EAAE,CAAC;IACvB,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC,GACD,oBAAoB,CAgBtB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,iBAAiB,EAAE,EAC7B,aAAa,EAAE,iBAAiB,EAAE,GACjC,iBAAiB,EAAE,CAcrB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,iBAAiB,EAAE,EAC5B,QAAQ,EAAE,iBAAiB,EAAE,GAC5B,iBAAiB,EAAE,CAGrB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,iBAAiB,EAAE,EAC5B,QAAQ,EAAE,iBAAiB,EAAE,GAC5B,iBAAiB,EAAE,CAGrB;AAED;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAqC;gBAEzC,aAAa,EAAE,MAAM;IAIjC;;OAEG;IACH,MAAM,IAAI,OAAO;IAIjB;;OAEG;IACH,IAAI,IAAI,oBAAoB,GAAG,IAAI;IAOnC;;OAEG;IACH,MAAM,IAAI,oBAAoB,GAAG,IAAI;IAKrC;;OAEG;IACH,IAAI,CAAC,QAAQ,EAAE,oBAAoB,GAAG,IAAI;IAK1C;;OAEG;IACH,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,CAAC,CAAC,GAAG,oBAAoB;IAM3E;;OAEG;IACH,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,CAAC,CAAC,GAAG,oBAAoB,GAAG,IAAI;IAWlF;;OAEG;IACH,SAAS,IAAI,MAAM;IAKnB;;OAEG;IACH,aAAa,IAAI,QAAQ,EAAE;IAQ3B;;OAEG;IACH,cAAc,CAAC,SAAS,EAAE,iBAAiB,GAAG,OAAO;IASrD;;OAEG;IACH,OAAO,IAAI,MAAM;CAGlB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,MAAM,GAAG,eAAe,CAE5E"}
|