svelte-docinfo 0.4.0 → 0.5.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 +21 -12
- package/dist/analyze-core.d.ts +45 -9
- package/dist/analyze-core.d.ts.map +1 -1
- package/dist/analyze-core.js +43 -17
- package/dist/declaration-build.d.ts +16 -19
- package/dist/declaration-build.d.ts.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/postprocess.d.ts +118 -28
- package/dist/postprocess.d.ts.map +1 -1
- package/dist/postprocess.js +279 -31
- package/dist/svelte.d.ts.map +1 -1
- package/dist/svelte.js +47 -3
- package/dist/types.d.ts +145 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +115 -1
- package/dist/typescript-exports.d.ts +3 -1
- package/dist/typescript-exports.d.ts.map +1 -1
- package/dist/typescript-exports.js +237 -158
- package/package.json +9 -9
- package/virtual-svelte-docinfo.d.ts +12 -12
package/dist/postprocess.d.ts
CHANGED
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
* @module
|
|
14
14
|
*/
|
|
15
15
|
import type { DeclarationJson, ModuleJson } from './types.js';
|
|
16
|
-
import type { ReExportInfo } from './declaration-build.js';
|
|
17
16
|
import type { SourceFileInfo } from './source.js';
|
|
18
17
|
/**
|
|
19
18
|
* A duplicate declaration with its full metadata and module path.
|
|
@@ -27,6 +26,14 @@ export interface DuplicateDeclaration {
|
|
|
27
26
|
/**
|
|
28
27
|
* Find duplicate declaration names across modules.
|
|
29
28
|
*
|
|
29
|
+
* A duplicate is two *different things* sharing a name in the flat namespace.
|
|
30
|
+
* Occurrences are compared by canonical identity — `aliasOf` chains are
|
|
31
|
+
* resolved first, so an alias and its canonical (or two aliases of the same
|
|
32
|
+
* canonical) are one thing, not a collision. Documenting a same-name re-export
|
|
33
|
+
* (which synthesizes an alias) or re-exporting a component under its own name
|
|
34
|
+
* (`export {default as Foo} from './Foo.svelte'`) therefore doesn't flag.
|
|
35
|
+
* When a name does flag, all occurrences are reported, aliases included.
|
|
36
|
+
*
|
|
30
37
|
* Callers can decide how to handle duplicates (throw, warn, ignore).
|
|
31
38
|
*
|
|
32
39
|
* @returns `Map` of declaration names to their `DuplicateDeclaration` occurrences (only includes duplicates)
|
|
@@ -46,59 +53,59 @@ export interface DuplicateDeclaration {
|
|
|
46
53
|
* ```
|
|
47
54
|
*/
|
|
48
55
|
export declare const findDuplicates: (modules: Array<ModuleJson>) => Map<string, Array<DuplicateDeclaration>>;
|
|
56
|
+
/**
|
|
57
|
+
* Code-unit string comparator for deterministic output ordering.
|
|
58
|
+
*
|
|
59
|
+
* Unlike `localeCompare` (host-locale/ICU-dependent, so byte-identical input
|
|
60
|
+
* can serialize in different orders on different machines), code-unit order is
|
|
61
|
+
* environment-independent — and it matches the default `Array.prototype.sort`
|
|
62
|
+
* used for `alsoExportedFrom`, `dependencies`, and `dependents`.
|
|
63
|
+
*/
|
|
64
|
+
export declare const compareStrings: (a: string, b: string) => number;
|
|
49
65
|
/**
|
|
50
66
|
* Sort modules alphabetically by path for deterministic output and cleaner diffs.
|
|
51
67
|
*
|
|
68
|
+
* Code-unit order (`compareStrings`) so the output is environment-independent.
|
|
69
|
+
*
|
|
52
70
|
* @param modules - the modules to sort
|
|
53
71
|
* @returns a new sorted array (does not mutate input)
|
|
54
72
|
*/
|
|
55
73
|
export declare const sortModules: (modules: Array<ModuleJson>) => Array<ModuleJson>;
|
|
56
74
|
/**
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* Used during the two-phase re-export resolution:
|
|
60
|
-
* 1. Phase 1: Collect re-exports from each module during analysis
|
|
61
|
-
* 2. Phase 2: Group by original module and merge into `alsoExportedFrom`
|
|
62
|
-
*/
|
|
63
|
-
export interface ReExportEntry {
|
|
64
|
-
/** The module that re-exports the declaration. */
|
|
65
|
-
reExportingModule: string;
|
|
66
|
-
/** The re-export info (name and original module). */
|
|
67
|
-
reExport: ReExportInfo;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Build `alsoExportedFrom` arrays from collected re-export data.
|
|
71
|
-
*
|
|
72
|
-
* This function resolves the two-phase re-export problem:
|
|
75
|
+
* Build `alsoExportedFrom` arrays from the modules' forward re-export edges.
|
|
73
76
|
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
77
|
+
* Each module carries its same-name re-export edges as `ModuleJson.reExports`
|
|
78
|
+
* (collected in phase 1); this phase-2 pass inverts them onto the canonical
|
|
79
|
+
* declarations so both directions of the same fact are queryable. Edges whose
|
|
80
|
+
* canonical module or declaration is absent from `modules` are skipped — the
|
|
81
|
+
* forward entry remains without a back-link (see `ReExportJson` for the
|
|
82
|
+
* presence caveats).
|
|
80
83
|
*
|
|
81
84
|
* Component-only fields on renamed component aliases (`props`,
|
|
82
85
|
* `acceptsChildren`, etc.) are populated separately by `resolveComponentAliases`
|
|
83
86
|
* — call it after this function. They split because they touch disjoint fields
|
|
84
87
|
* and have different inputs.
|
|
85
88
|
*
|
|
86
|
-
* @param modules - the modules array with all modules (will be mutated)
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
+
* @param modules - the modules array with all modules (will be mutated).
|
|
90
|
+
* Must be parsed `ModuleJson`s — wire JSON strips empty arrays, so run
|
|
91
|
+
* raw JSON through `AnalyzeResultJson.parse` first or `reExports` may be
|
|
92
|
+
* `undefined`
|
|
93
|
+
* @mutates modules - unions re-exporters into `declaration.alsoExportedFrom`
|
|
89
94
|
* (deduped + sorted), so a second call with the same inputs is a no-op
|
|
90
95
|
*
|
|
91
96
|
* @example
|
|
92
97
|
* ```ts
|
|
93
98
|
* // helpers.ts exports: foo, bar
|
|
94
|
-
* // index.ts does: export {foo, bar} from './
|
|
99
|
+
* // index.ts does: export {foo, bar} from './helpers.js'
|
|
100
|
+
* // (so index.ts's ModuleJson carries reExports:
|
|
101
|
+
* // [{name: 'foo', module: 'helpers.ts'}, {name: 'bar', module: 'helpers.ts'}])
|
|
95
102
|
* //
|
|
96
103
|
* // After processing:
|
|
97
104
|
* // - helpers.ts foo declaration gets: alsoExportedFrom: ['index.ts']
|
|
98
105
|
* // - helpers.ts bar declaration gets: alsoExportedFrom: ['index.ts']
|
|
99
106
|
* ```
|
|
100
107
|
*/
|
|
101
|
-
export declare const mergeReExports: (modules: Array<ModuleJson
|
|
108
|
+
export declare const mergeReExports: (modules: Array<ModuleJson>) => void;
|
|
102
109
|
/**
|
|
103
110
|
* Copy props/acceptsChildren/lang/etc. from canonical component declarations
|
|
104
111
|
* onto synthesized component-aliased declarations.
|
|
@@ -142,4 +149,87 @@ export declare const resolveComponentAliases: (modules: Array<ModuleJson>) => vo
|
|
|
142
149
|
export declare const computeDependents: (files: ReadonlyArray<SourceFileInfo>) => Array<SourceFileInfo & {
|
|
143
150
|
dependents?: ReadonlyArray<string>;
|
|
144
151
|
}>;
|
|
152
|
+
/**
|
|
153
|
+
* One name on a module's resolved export surface.
|
|
154
|
+
*/
|
|
155
|
+
export interface ExportSurfaceEntry {
|
|
156
|
+
/**
|
|
157
|
+
* Exported name, in the docinfo model's terms — Svelte components appear
|
|
158
|
+
* under their filename-derived name (the model's convention for default
|
|
159
|
+
* exports of `.svelte` files), not `'default'`.
|
|
160
|
+
*/
|
|
161
|
+
name: string;
|
|
162
|
+
/**
|
|
163
|
+
* How the name reaches this module's surface: an own declaration
|
|
164
|
+
* (including synthesized aliases), a same-name re-export edge, a direct
|
|
165
|
+
* external re-export, or projection through `export * from './x'`.
|
|
166
|
+
*/
|
|
167
|
+
via: 'declaration' | 'reExport' | 'external' | 'star';
|
|
168
|
+
/** Canonical module path, when known (`undefined` for external entries). */
|
|
169
|
+
module?: string;
|
|
170
|
+
/** The canonical declaration, when present in the analyzed set. */
|
|
171
|
+
declaration?: DeclarationJson;
|
|
172
|
+
/** Package specifier for external entries (as written in the statement). */
|
|
173
|
+
specifier?: string;
|
|
174
|
+
/** Name inside the external package when renamed. */
|
|
175
|
+
originalName?: string;
|
|
176
|
+
/** Type-only re-export — the name is erased at runtime. */
|
|
177
|
+
typeOnly?: boolean;
|
|
178
|
+
/** For star-projected entries: the `starExports` target the name arrived through. */
|
|
179
|
+
starFrom?: string;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* A module's resolved export surface — see `resolveExportSurface`.
|
|
183
|
+
*/
|
|
184
|
+
export interface ExportSurface {
|
|
185
|
+
/** Surface entries, sorted by `name` (code-unit order). */
|
|
186
|
+
entries: Array<ExportSurfaceEntry>;
|
|
187
|
+
/**
|
|
188
|
+
* Star targets (own or transitive) absent from the analyzed set — their
|
|
189
|
+
* projected names are unknown, so the surface is incomplete.
|
|
190
|
+
*/
|
|
191
|
+
unresolvedStarExports: Array<string>;
|
|
192
|
+
/**
|
|
193
|
+
* External star specifiers reachable from this module (own or transitive)
|
|
194
|
+
* — their projected names are unknowable without analyzing the package.
|
|
195
|
+
*/
|
|
196
|
+
externalStarExports: Array<string>;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Resolve a module's full export surface from the analyzed model, applying
|
|
200
|
+
* ES module semantics to star exports.
|
|
201
|
+
*
|
|
202
|
+
* Combines the module's own `declarations` (including synthesized aliases),
|
|
203
|
+
* `reExports` edges, `externalReExports`, and transitively-resolved
|
|
204
|
+
* `starExports` into one deduped, name-sorted list. The ES rules applied to
|
|
205
|
+
* star projection:
|
|
206
|
+
*
|
|
207
|
+
* - explicit exports (declarations, edges, externals) shadow star-projected
|
|
208
|
+
* names
|
|
209
|
+
* - a name projected by two stars that resolve to *different* canonicals is
|
|
210
|
+
* ambiguous and excluded (same canonical through a diamond is included
|
|
211
|
+
* once)
|
|
212
|
+
* - `default` is never star-projected — including canonical Svelte component
|
|
213
|
+
* declarations, which represent their file's default export. (Caveat: a
|
|
214
|
+
* star-projected re-export edge whose canonical is a component is treated
|
|
215
|
+
* as a default-slot re-export and skipped; a `<script module>` const
|
|
216
|
+
* sharing the component's exact name would be skipped with it.)
|
|
217
|
+
*
|
|
218
|
+
* A Position-3 alias and its `reExports` edge are the same fact — the
|
|
219
|
+
* declaration entry wins, inheriting the edge's `typeOnly`.
|
|
220
|
+
*
|
|
221
|
+
* Cyclic star graphs terminate by contributing nothing along the back-edge
|
|
222
|
+
* (an approximation of ES fixpoint resolution — fine in practice). Surfaces
|
|
223
|
+
* resolved inside a cycle are path-relative and not memoized, so sibling
|
|
224
|
+
* star paths resolve independently rather than inheriting them. Star
|
|
225
|
+
* targets missing from `modules` are reported in `unresolvedStarExports`
|
|
226
|
+
* rather than guessed at; `externalStarExports` aggregates external star
|
|
227
|
+
* specifiers reachable from the module, whose names are unknowable.
|
|
228
|
+
*
|
|
229
|
+
* @param modules - the analyzed modules (parsed `ModuleJson`s — run wire
|
|
230
|
+
* JSON through `AnalyzeResultJson.parse` first)
|
|
231
|
+
* @param path - the module to resolve, as a `ModuleJson.path` value
|
|
232
|
+
* @returns the resolved surface, or `null` when `path` isn't in `modules`
|
|
233
|
+
*/
|
|
234
|
+
export declare const resolveExportSurface: (modules: Array<ModuleJson>, path: string) => ExportSurface | null;
|
|
145
235
|
//# sourceMappingURL=postprocess.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postprocess.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/postprocess.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAA2B,eAAe,EAAE,UAAU,EAAC,MAAM,YAAY,CAAC;AACtF,OAAO,KAAK,EAAC,
|
|
1
|
+
{"version":3,"file":"postprocess.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/postprocess.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAA2B,eAAe,EAAE,UAAU,EAAC,MAAM,YAAY,CAAC;AACtF,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,aAAa,CAAC;AAuBhD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACpC,qCAAqC;IACrC,WAAW,EAAE,eAAe,CAAC;IAC7B,qDAAqD;IACrD,MAAM,EAAE,MAAM,CAAC;CACf;AA6CD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,cAAc,GAC1B,SAAS,KAAK,CAAC,UAAU,CAAC,KACxB,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,oBAAoB,CAAC,CAwCzC,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,GAAI,GAAG,MAAM,EAAE,GAAG,MAAM,KAAG,MAAsC,CAAC;AAE7F;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,GAAI,SAAS,KAAK,CAAC,UAAU,CAAC,KAAG,KAAK,CAAC,UAAU,CAExE,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,eAAO,MAAM,cAAc,GAAI,SAAS,KAAK,CAAC,UAAU,CAAC,KAAG,IAmC3D,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,uBAAuB,GAAI,SAAS,KAAK,CAAC,UAAU,CAAC,KAAG,IAoDpE,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,iBAAiB,GAC7B,OAAO,aAAa,CAAC,cAAc,CAAC,KAClC,KAAK,CAAC,cAAc,GAAG;IAAC,UAAU,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CAAC,CAwD7D,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC;;;;OAIG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,GAAG,EAAE,aAAa,GAAG,UAAU,GAAG,UAAU,GAAG,MAAM,CAAC;IACtD,4EAA4E;IAC5E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qFAAqF;IACrF,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC7B,2DAA2D;IAC3D,OAAO,EAAE,KAAK,CAAC,kBAAkB,CAAC,CAAC;IACnC;;;OAGG;IACH,qBAAqB,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACrC;;;OAGG;IACH,mBAAmB,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CACnC;AAcD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,eAAO,MAAM,oBAAoB,GAChC,SAAS,KAAK,CAAC,UAAU,CAAC,EAC1B,MAAM,MAAM,KACV,aAAa,GAAG,IA+IlB,CAAC"}
|
package/dist/postprocess.js
CHANGED
|
@@ -32,9 +32,56 @@ const posixifyArray = (arr) => {
|
|
|
32
32
|
}
|
|
33
33
|
return changed ?? arr;
|
|
34
34
|
};
|
|
35
|
+
/**
|
|
36
|
+
* Build the `(module, name)` → declaration lookup used for `aliasOf`-chain
|
|
37
|
+
* walking. Key format: `` `${modulePath}\n${name}` `` — `\n` can't appear in
|
|
38
|
+
* either part.
|
|
39
|
+
*/
|
|
40
|
+
const buildDeclarationIndex = (modules) => {
|
|
41
|
+
const byIdentity = new Map();
|
|
42
|
+
for (const mod of modules) {
|
|
43
|
+
for (const declaration of mod.declarations) {
|
|
44
|
+
byIdentity.set(`${mod.path}\n${declaration.name}`, declaration);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return byIdentity;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Resolve a declaration to its canonical identity. A same-name re-export of
|
|
51
|
+
* an intermediate rename produces an alias pointing at another alias, so a
|
|
52
|
+
* single hop isn't enough — follow the chain through declarations present in
|
|
53
|
+
* the index. The terminal is the declaration *object* when it's in the set
|
|
54
|
+
* (object identity keeps two same-`(module, name)` declarations distinct in
|
|
55
|
+
* pathological inputs), else the dangling `(module, name)` key (two aliases
|
|
56
|
+
* of the same absent canonical still resolve to one identity). The visited
|
|
57
|
+
* set guards malformed cyclic input.
|
|
58
|
+
*/
|
|
59
|
+
const resolveCanonicalIdentity = (byIdentity, modulePath, declaration) => {
|
|
60
|
+
let current = declaration;
|
|
61
|
+
const visited = new Set([`${modulePath}\n${declaration.name}`]);
|
|
62
|
+
while (current.aliasOf) {
|
|
63
|
+
const nextKey = `${current.aliasOf.module}\n${current.aliasOf.name}`;
|
|
64
|
+
if (visited.has(nextKey))
|
|
65
|
+
return nextKey;
|
|
66
|
+
visited.add(nextKey);
|
|
67
|
+
const next = byIdentity.get(nextKey);
|
|
68
|
+
if (!next)
|
|
69
|
+
return nextKey;
|
|
70
|
+
current = next;
|
|
71
|
+
}
|
|
72
|
+
return current;
|
|
73
|
+
};
|
|
35
74
|
/**
|
|
36
75
|
* Find duplicate declaration names across modules.
|
|
37
76
|
*
|
|
77
|
+
* A duplicate is two *different things* sharing a name in the flat namespace.
|
|
78
|
+
* Occurrences are compared by canonical identity — `aliasOf` chains are
|
|
79
|
+
* resolved first, so an alias and its canonical (or two aliases of the same
|
|
80
|
+
* canonical) are one thing, not a collision. Documenting a same-name re-export
|
|
81
|
+
* (which synthesizes an alias) or re-exporting a component under its own name
|
|
82
|
+
* (`export {default as Foo} from './Foo.svelte'`) therefore doesn't flag.
|
|
83
|
+
* When a name does flag, all occurrences are reported, aliases included.
|
|
84
|
+
*
|
|
38
85
|
* Callers can decide how to handle duplicates (throw, warn, ignore).
|
|
39
86
|
*
|
|
40
87
|
* @returns `Map` of declaration names to their `DuplicateDeclaration` occurrences (only includes duplicates)
|
|
@@ -54,10 +101,13 @@ const posixifyArray = (arr) => {
|
|
|
54
101
|
* ```
|
|
55
102
|
*/
|
|
56
103
|
export const findDuplicates = (modules) => {
|
|
104
|
+
const byIdentity = buildDeclarationIndex(modules);
|
|
105
|
+
const resolveCanonical = (modulePath, declaration) => resolveCanonicalIdentity(byIdentity, modulePath, declaration);
|
|
106
|
+
// Collect declaration names with their canonical identities. The default
|
|
107
|
+
// slot is module-scoped per the JS spec — every module can have its own
|
|
108
|
+
// `'default'` and they don't collide — so skip `name === 'default'`
|
|
109
|
+
// entries from this flat-namespace check.
|
|
57
110
|
const allOccurrences = new Map();
|
|
58
|
-
// Collect declaration names. The default slot is module-scoped per the JS
|
|
59
|
-
// spec — every module can have its own `'default'` and they don't collide
|
|
60
|
-
// — so skip `name === 'default'` entries from this flat-namespace check.
|
|
61
111
|
for (const mod of modules) {
|
|
62
112
|
for (const declaration of mod.declarations) {
|
|
63
113
|
if (declaration.name === 'default')
|
|
@@ -68,74 +118,90 @@ export const findDuplicates = (modules) => {
|
|
|
68
118
|
allOccurrences.get(declaration.name).push({
|
|
69
119
|
declaration,
|
|
70
120
|
module: mod.path,
|
|
121
|
+
canonical: resolveCanonical(mod.path, declaration),
|
|
71
122
|
});
|
|
72
123
|
}
|
|
73
124
|
}
|
|
74
|
-
//
|
|
125
|
+
// A name is duplicated only when its occurrences span >1 canonical identity
|
|
75
126
|
const duplicates = new Map();
|
|
76
127
|
for (const [name, occurrences] of allOccurrences) {
|
|
77
|
-
|
|
78
|
-
|
|
128
|
+
const identities = new Set(occurrences.map((o) => o.canonical));
|
|
129
|
+
if (identities.size > 1) {
|
|
130
|
+
duplicates.set(name, occurrences.map(({ declaration, module }) => ({ declaration, module })));
|
|
79
131
|
}
|
|
80
132
|
}
|
|
81
133
|
return duplicates;
|
|
82
134
|
};
|
|
135
|
+
/**
|
|
136
|
+
* Code-unit string comparator for deterministic output ordering.
|
|
137
|
+
*
|
|
138
|
+
* Unlike `localeCompare` (host-locale/ICU-dependent, so byte-identical input
|
|
139
|
+
* can serialize in different orders on different machines), code-unit order is
|
|
140
|
+
* environment-independent — and it matches the default `Array.prototype.sort`
|
|
141
|
+
* used for `alsoExportedFrom`, `dependencies`, and `dependents`.
|
|
142
|
+
*/
|
|
143
|
+
export const compareStrings = (a, b) => (a < b ? -1 : a > b ? 1 : 0);
|
|
83
144
|
/**
|
|
84
145
|
* Sort modules alphabetically by path for deterministic output and cleaner diffs.
|
|
85
146
|
*
|
|
147
|
+
* Code-unit order (`compareStrings`) so the output is environment-independent.
|
|
148
|
+
*
|
|
86
149
|
* @param modules - the modules to sort
|
|
87
150
|
* @returns a new sorted array (does not mutate input)
|
|
88
151
|
*/
|
|
89
152
|
export const sortModules = (modules) => {
|
|
90
|
-
return modules.slice().sort((a, b) => a.path
|
|
153
|
+
return modules.slice().sort((a, b) => compareStrings(a.path, b.path));
|
|
91
154
|
};
|
|
92
155
|
/**
|
|
93
|
-
* Build `alsoExportedFrom` arrays from
|
|
94
|
-
*
|
|
95
|
-
* This function resolves the two-phase re-export problem:
|
|
96
|
-
*
|
|
97
|
-
* **Problem**: When module A re-exports from module B, we discover this while
|
|
98
|
-
* analyzing A, but need to update B's declarations. However, B may already be
|
|
99
|
-
* processed or may be processed later.
|
|
156
|
+
* Build `alsoExportedFrom` arrays from the modules' forward re-export edges.
|
|
100
157
|
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
158
|
+
* Each module carries its same-name re-export edges as `ModuleJson.reExports`
|
|
159
|
+
* (collected in phase 1); this phase-2 pass inverts them onto the canonical
|
|
160
|
+
* declarations so both directions of the same fact are queryable. Edges whose
|
|
161
|
+
* canonical module or declaration is absent from `modules` are skipped — the
|
|
162
|
+
* forward entry remains without a back-link (see `ReExportJson` for the
|
|
163
|
+
* presence caveats).
|
|
103
164
|
*
|
|
104
165
|
* Component-only fields on renamed component aliases (`props`,
|
|
105
166
|
* `acceptsChildren`, etc.) are populated separately by `resolveComponentAliases`
|
|
106
167
|
* — call it after this function. They split because they touch disjoint fields
|
|
107
168
|
* and have different inputs.
|
|
108
169
|
*
|
|
109
|
-
* @param modules - the modules array with all modules (will be mutated)
|
|
110
|
-
*
|
|
111
|
-
*
|
|
170
|
+
* @param modules - the modules array with all modules (will be mutated).
|
|
171
|
+
* Must be parsed `ModuleJson`s — wire JSON strips empty arrays, so run
|
|
172
|
+
* raw JSON through `AnalyzeResultJson.parse` first or `reExports` may be
|
|
173
|
+
* `undefined`
|
|
174
|
+
* @mutates modules - unions re-exporters into `declaration.alsoExportedFrom`
|
|
112
175
|
* (deduped + sorted), so a second call with the same inputs is a no-op
|
|
113
176
|
*
|
|
114
177
|
* @example
|
|
115
178
|
* ```ts
|
|
116
179
|
* // helpers.ts exports: foo, bar
|
|
117
|
-
* // index.ts does: export {foo, bar} from './
|
|
180
|
+
* // index.ts does: export {foo, bar} from './helpers.js'
|
|
181
|
+
* // (so index.ts's ModuleJson carries reExports:
|
|
182
|
+
* // [{name: 'foo', module: 'helpers.ts'}, {name: 'bar', module: 'helpers.ts'}])
|
|
118
183
|
* //
|
|
119
184
|
* // After processing:
|
|
120
185
|
* // - helpers.ts foo declaration gets: alsoExportedFrom: ['index.ts']
|
|
121
186
|
* // - helpers.ts bar declaration gets: alsoExportedFrom: ['index.ts']
|
|
122
187
|
* ```
|
|
123
188
|
*/
|
|
124
|
-
export const mergeReExports = (modules
|
|
125
|
-
// Group
|
|
189
|
+
export const mergeReExports = (modules) => {
|
|
190
|
+
// Group edges by `(canonical module, name)`. The default slot keys as
|
|
126
191
|
// `'default'` like any other name — each module owns its own default slot,
|
|
127
192
|
// so the per-module map prevents cross-module collisions naturally.
|
|
128
193
|
const reExportMap = new Map();
|
|
129
|
-
for (const
|
|
130
|
-
const { name, originalModule }
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
194
|
+
for (const mod of modules) {
|
|
195
|
+
for (const { name, module: originalModule } of mod.reExports) {
|
|
196
|
+
if (!reExportMap.has(originalModule)) {
|
|
197
|
+
reExportMap.set(originalModule, new Map());
|
|
198
|
+
}
|
|
199
|
+
const moduleMap = reExportMap.get(originalModule);
|
|
200
|
+
if (!moduleMap.has(name)) {
|
|
201
|
+
moduleMap.set(name, []);
|
|
202
|
+
}
|
|
203
|
+
moduleMap.get(name).push(mod.path);
|
|
137
204
|
}
|
|
138
|
-
moduleMap.get(name).push(reExportingModule);
|
|
139
205
|
}
|
|
140
206
|
// Merge into original declarations
|
|
141
207
|
for (const mod of modules) {
|
|
@@ -303,3 +369,185 @@ export const computeDependents = (files) => {
|
|
|
303
369
|
};
|
|
304
370
|
});
|
|
305
371
|
};
|
|
372
|
+
/**
|
|
373
|
+
* Resolve a module's full export surface from the analyzed model, applying
|
|
374
|
+
* ES module semantics to star exports.
|
|
375
|
+
*
|
|
376
|
+
* Combines the module's own `declarations` (including synthesized aliases),
|
|
377
|
+
* `reExports` edges, `externalReExports`, and transitively-resolved
|
|
378
|
+
* `starExports` into one deduped, name-sorted list. The ES rules applied to
|
|
379
|
+
* star projection:
|
|
380
|
+
*
|
|
381
|
+
* - explicit exports (declarations, edges, externals) shadow star-projected
|
|
382
|
+
* names
|
|
383
|
+
* - a name projected by two stars that resolve to *different* canonicals is
|
|
384
|
+
* ambiguous and excluded (same canonical through a diamond is included
|
|
385
|
+
* once)
|
|
386
|
+
* - `default` is never star-projected — including canonical Svelte component
|
|
387
|
+
* declarations, which represent their file's default export. (Caveat: a
|
|
388
|
+
* star-projected re-export edge whose canonical is a component is treated
|
|
389
|
+
* as a default-slot re-export and skipped; a `<script module>` const
|
|
390
|
+
* sharing the component's exact name would be skipped with it.)
|
|
391
|
+
*
|
|
392
|
+
* A Position-3 alias and its `reExports` edge are the same fact — the
|
|
393
|
+
* declaration entry wins, inheriting the edge's `typeOnly`.
|
|
394
|
+
*
|
|
395
|
+
* Cyclic star graphs terminate by contributing nothing along the back-edge
|
|
396
|
+
* (an approximation of ES fixpoint resolution — fine in practice). Surfaces
|
|
397
|
+
* resolved inside a cycle are path-relative and not memoized, so sibling
|
|
398
|
+
* star paths resolve independently rather than inheriting them. Star
|
|
399
|
+
* targets missing from `modules` are reported in `unresolvedStarExports`
|
|
400
|
+
* rather than guessed at; `externalStarExports` aggregates external star
|
|
401
|
+
* specifiers reachable from the module, whose names are unknowable.
|
|
402
|
+
*
|
|
403
|
+
* @param modules - the analyzed modules (parsed `ModuleJson`s — run wire
|
|
404
|
+
* JSON through `AnalyzeResultJson.parse` first)
|
|
405
|
+
* @param path - the module to resolve, as a `ModuleJson.path` value
|
|
406
|
+
* @returns the resolved surface, or `null` when `path` isn't in `modules`
|
|
407
|
+
*/
|
|
408
|
+
export const resolveExportSurface = (modules, path) => {
|
|
409
|
+
const byPath = new Map(modules.map((m) => [m.path, m]));
|
|
410
|
+
if (!byPath.has(path))
|
|
411
|
+
return null;
|
|
412
|
+
const byIdentity = buildDeclarationIndex(modules);
|
|
413
|
+
const cache = new Map();
|
|
414
|
+
const visiting = new Set();
|
|
415
|
+
const emptySurface = () => ({
|
|
416
|
+
entries: new Map(),
|
|
417
|
+
unresolvedStars: new Set(),
|
|
418
|
+
externalStars: new Set(),
|
|
419
|
+
});
|
|
420
|
+
// Only surfaces resolved without hitting a cycle back-edge are memoized.
|
|
421
|
+
// A surface computed while one of its star ancestors is mid-resolution is
|
|
422
|
+
// relative to that path — it can carry names a full resolution would
|
|
423
|
+
// exclude as ambiguous (the back-edge contributed nothing to weigh them
|
|
424
|
+
// against). Caching it would leak the path-relative answer to sibling
|
|
425
|
+
// star paths; tainted surfaces are instead recomputed per consumer.
|
|
426
|
+
// Recomputation is bounded by `visiting` and only occurs inside cyclic
|
|
427
|
+
// clusters, which are pathological to begin with.
|
|
428
|
+
const resolveModule = (modulePath) => {
|
|
429
|
+
const cached = cache.get(modulePath);
|
|
430
|
+
if (cached)
|
|
431
|
+
return { surface: cached, tainted: false };
|
|
432
|
+
// Cycle break: a star back-edge contributes nothing
|
|
433
|
+
if (visiting.has(modulePath))
|
|
434
|
+
return { surface: emptySurface(), tainted: true };
|
|
435
|
+
visiting.add(modulePath);
|
|
436
|
+
const mod = byPath.get(modulePath);
|
|
437
|
+
const surface = emptySurface();
|
|
438
|
+
let tainted = false;
|
|
439
|
+
const { entries } = surface;
|
|
440
|
+
// 1. Own declarations — including synthesized aliases and `default`
|
|
441
|
+
const edgesByName = new Map(mod.reExports.map((e) => [e.name, e]));
|
|
442
|
+
for (const declaration of mod.declarations) {
|
|
443
|
+
// A Position-3 alias duplicates its edge; carry the edge's typeOnly
|
|
444
|
+
const matchingEdge = declaration.aliasOf &&
|
|
445
|
+
edgesByName.get(declaration.name)?.module === declaration.aliasOf.module
|
|
446
|
+
? edgesByName.get(declaration.name)
|
|
447
|
+
: undefined;
|
|
448
|
+
entries.set(declaration.name, {
|
|
449
|
+
entry: {
|
|
450
|
+
name: declaration.name,
|
|
451
|
+
via: 'declaration',
|
|
452
|
+
module: modulePath,
|
|
453
|
+
declaration,
|
|
454
|
+
...(matchingEdge?.typeOnly ? { typeOnly: true } : {}),
|
|
455
|
+
},
|
|
456
|
+
identity: resolveCanonicalIdentity(byIdentity, modulePath, declaration),
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
// 2. Same-name re-export edges not already covered by a declaration.
|
|
460
|
+
// Edges can collide on `name` (Svelte default re-keying — see
|
|
461
|
+
// `ReExportJson`); the surface is keyed by name, so the first edge in
|
|
462
|
+
// sort order wins and the collider is dropped
|
|
463
|
+
for (const edge of mod.reExports) {
|
|
464
|
+
if (entries.has(edge.name))
|
|
465
|
+
continue;
|
|
466
|
+
const canonical = byIdentity.get(`${edge.module}\n${edge.name}`);
|
|
467
|
+
entries.set(edge.name, {
|
|
468
|
+
entry: {
|
|
469
|
+
name: edge.name,
|
|
470
|
+
via: 'reExport',
|
|
471
|
+
module: edge.module,
|
|
472
|
+
...(canonical ? { declaration: canonical } : {}),
|
|
473
|
+
...(edge.typeOnly ? { typeOnly: true } : {}),
|
|
474
|
+
},
|
|
475
|
+
identity: canonical
|
|
476
|
+
? resolveCanonicalIdentity(byIdentity, edge.module, canonical)
|
|
477
|
+
: `${edge.module}\n${edge.name}`,
|
|
478
|
+
});
|
|
479
|
+
}
|
|
480
|
+
// 3. Direct external re-exports
|
|
481
|
+
for (const external of mod.externalReExports) {
|
|
482
|
+
if (entries.has(external.name))
|
|
483
|
+
continue;
|
|
484
|
+
entries.set(external.name, {
|
|
485
|
+
entry: {
|
|
486
|
+
name: external.name,
|
|
487
|
+
via: 'external',
|
|
488
|
+
specifier: external.specifier,
|
|
489
|
+
...(external.originalName !== undefined ? { originalName: external.originalName } : {}),
|
|
490
|
+
...(external.typeOnly ? { typeOnly: true } : {}),
|
|
491
|
+
},
|
|
492
|
+
identity: `ext\n${external.specifier}\n${external.originalName ?? external.name}`,
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
// 4. External stars — names unknowable, surface incompleteness recorded
|
|
496
|
+
for (const specifier of mod.externalStarExports) {
|
|
497
|
+
surface.externalStars.add(specifier);
|
|
498
|
+
}
|
|
499
|
+
// 5. Star projection, with ES shadowing and ambiguity rules
|
|
500
|
+
const excluded = new Set();
|
|
501
|
+
for (const target of mod.starExports) {
|
|
502
|
+
if (!byPath.has(target)) {
|
|
503
|
+
surface.unresolvedStars.add(target);
|
|
504
|
+
continue;
|
|
505
|
+
}
|
|
506
|
+
const resolved = resolveModule(target);
|
|
507
|
+
if (resolved.tainted)
|
|
508
|
+
tainted = true;
|
|
509
|
+
const sub = resolved.surface;
|
|
510
|
+
for (const star of sub.unresolvedStars)
|
|
511
|
+
surface.unresolvedStars.add(star);
|
|
512
|
+
for (const star of sub.externalStars)
|
|
513
|
+
surface.externalStars.add(star);
|
|
514
|
+
for (const { entry, identity } of sub.entries.values()) {
|
|
515
|
+
// `default` never projects — nor do canonical Svelte components,
|
|
516
|
+
// which represent their file's default export (whether reached
|
|
517
|
+
// as a declaration or through a re-export edge)
|
|
518
|
+
if (entry.name === 'default')
|
|
519
|
+
continue;
|
|
520
|
+
if (entry.declaration?.kind === 'component' && !entry.declaration.aliasOf)
|
|
521
|
+
continue;
|
|
522
|
+
if (excluded.has(entry.name))
|
|
523
|
+
continue;
|
|
524
|
+
const existing = entries.get(entry.name);
|
|
525
|
+
if (existing) {
|
|
526
|
+
// Explicit exports shadow; identical canonicals (diamond) merge
|
|
527
|
+
if (existing.entry.via !== 'star' || existing.identity === identity)
|
|
528
|
+
continue;
|
|
529
|
+
// Ambiguous between two stars — excluded per ES semantics
|
|
530
|
+
entries.delete(entry.name);
|
|
531
|
+
excluded.add(entry.name);
|
|
532
|
+
continue;
|
|
533
|
+
}
|
|
534
|
+
entries.set(entry.name, {
|
|
535
|
+
entry: { ...entry, via: 'star', starFrom: target },
|
|
536
|
+
identity,
|
|
537
|
+
});
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
visiting.delete(modulePath);
|
|
541
|
+
if (!tainted)
|
|
542
|
+
cache.set(modulePath, surface);
|
|
543
|
+
return { surface, tainted };
|
|
544
|
+
};
|
|
545
|
+
const resolved = resolveModule(path).surface;
|
|
546
|
+
return {
|
|
547
|
+
entries: Array.from(resolved.entries.values())
|
|
548
|
+
.map(({ entry }) => entry)
|
|
549
|
+
.sort((a, b) => compareStrings(a.name, b.name)),
|
|
550
|
+
unresolvedStarExports: Array.from(resolved.unresolvedStars).sort(),
|
|
551
|
+
externalStarExports: Array.from(resolved.externalStars).sort(),
|
|
552
|
+
};
|
|
553
|
+
};
|
package/dist/svelte.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"svelte.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/svelte.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAC,QAAQ,EAAsB,MAAM,2BAA2B,CAAC;AAGxE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,KAAK,EAA2C,kBAAkB,EAAC,MAAM,YAAY,CAAC;AAC7F,OAAO,KAAK,EAGX,cAAc,EACd,MAAM,wBAAwB,CAAC;AAKhC,OAAO,EAAC,KAAK,cAAc,EAA0C,MAAM,aAAa,CAAC;AACzF,OAAO,EAAC,KAAK,mBAAmB,EAAsB,MAAM,oBAAoB,CAAC;AACjF,OAAO,EAAC,KAAK,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAGjD,0FAA0F;AAC1F,KAAK,SAAS,GAAG,YAAY,CAAC,OAAO,QAAQ,CAAC,CAAC;AAE/C;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IACjC,gEAAgE;IAChE,WAAW,EAAE,MAAM,CAAC;IACpB,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,2EAA2E;IAC3E,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5B,sGAAsG;IACtG,IAAI,EAAE,IAAI,GAAG,SAAS,CAAC;CACvB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,eAAe;IAC/B,OAAO,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACvC,WAAW,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,qBAAqB,GAAI,YAAY,cAAc,KAAG,eAoDlE,CAAC;AAkHF;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,GAAI,cAAc,MAAM,KAAG,MAAM,GAAG,SAcpE,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB,GAAI,cAAc,MAAM,KAAG,MAAM,GAAG,SA0BxE,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,0BAA0B,GAAI,eAAe,MAAM,KAAG,MAAM,GAAG,SAU3E,CAAC;AA0PF;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,GAAI,YAAY,MAAM,KAAG,OAExD,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,wBAAwB,GACpC,aAAa,EAAE,CAAC,IAAI,EACpB,SAAS,EAAE,CAAC,WAAW,KACrB,KAAK,CAAC,kBAAkB,CAqB1B,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,GAAI,YAAY,MAAM,KAAG,OAKxD,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,8BAA8B,GAAI,YAAY,KAAK,CAAC,kBAAkB,CAAC,KAAG,MAGtF,CAAC;AA8NF;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,mBAAmB,GAC/B,YAAY,cAAc,GAAG;IAAC,UAAU,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CAAC,EACjE,YAAY,MAAM,EAClB,SAAS,EAAE,CAAC,WAAW,EACvB,SAAS,mBAAmB,EAC5B,aAAa,KAAK,CAAC,UAAU,CAAC,EAC9B,SAAS,EAAE,CAAC,OAAO,EACnB,aAAa,iBAAiB,KAC5B,cAAc,GAAG,
|
|
1
|
+
{"version":3,"file":"svelte.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/svelte.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAC,QAAQ,EAAsB,MAAM,2BAA2B,CAAC;AAGxE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,KAAK,EAA2C,kBAAkB,EAAC,MAAM,YAAY,CAAC;AAC7F,OAAO,KAAK,EAGX,cAAc,EACd,MAAM,wBAAwB,CAAC;AAKhC,OAAO,EAAC,KAAK,cAAc,EAA0C,MAAM,aAAa,CAAC;AACzF,OAAO,EAAC,KAAK,mBAAmB,EAAsB,MAAM,oBAAoB,CAAC;AACjF,OAAO,EAAC,KAAK,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAGjD,0FAA0F;AAC1F,KAAK,SAAS,GAAG,YAAY,CAAC,OAAO,QAAQ,CAAC,CAAC;AAE/C;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IACjC,gEAAgE;IAChE,WAAW,EAAE,MAAM,CAAC;IACpB,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,2EAA2E;IAC3E,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5B,sGAAsG;IACtG,IAAI,EAAE,IAAI,GAAG,SAAS,CAAC;CACvB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,eAAe;IAC/B,OAAO,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACvC,WAAW,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,qBAAqB,GAAI,YAAY,cAAc,KAAG,eAoDlE,CAAC;AAkHF;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,GAAI,cAAc,MAAM,KAAG,MAAM,GAAG,SAcpE,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB,GAAI,cAAc,MAAM,KAAG,MAAM,GAAG,SA0BxE,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,0BAA0B,GAAI,eAAe,MAAM,KAAG,MAAM,GAAG,SAU3E,CAAC;AA0PF;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,GAAI,YAAY,MAAM,KAAG,OAExD,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,wBAAwB,GACpC,aAAa,EAAE,CAAC,IAAI,EACpB,SAAS,EAAE,CAAC,WAAW,KACrB,KAAK,CAAC,kBAAkB,CAqB1B,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,GAAI,YAAY,MAAM,KAAG,OAKxD,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,8BAA8B,GAAI,YAAY,KAAK,CAAC,kBAAkB,CAAC,KAAG,MAGtF,CAAC;AA8NF;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,mBAAmB,GAC/B,YAAY,cAAc,GAAG;IAAC,UAAU,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CAAC,EACjE,YAAY,MAAM,EAClB,SAAS,EAAE,CAAC,WAAW,EACvB,SAAS,mBAAmB,EAC5B,aAAa,KAAK,CAAC,UAAU,CAAC,EAC9B,SAAS,EAAE,CAAC,OAAO,EACnB,aAAa,iBAAiB,KAC5B,cAAc,GAAG,SAoQnB,CAAC"}
|