@flighthq/vite-plugin-manifest 0.5.1-next.1680.bdc44c6
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.md +9 -0
- package/README.md +17 -0
- package/dist/contentAnalyzers.d.ts +18 -0
- package/dist/contentAnalyzers.d.ts.map +1 -0
- package/dist/contentAnalyzers.js +18 -0
- package/dist/contentAnalyzers.js.map +1 -0
- package/dist/contract.d.ts +5 -0
- package/dist/contract.d.ts.map +1 -0
- package/dist/contract.js +5 -0
- package/dist/contract.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/manifestModuleSource.d.ts +41 -0
- package/dist/manifestModuleSource.d.ts.map +1 -0
- package/dist/manifestModuleSource.js +125 -0
- package/dist/manifestModuleSource.js.map +1 -0
- package/dist/manifestPlugin.d.ts +45 -0
- package/dist/manifestPlugin.d.ts.map +1 -0
- package/dist/manifestPlugin.js +102 -0
- package/dist/manifestPlugin.js.map +1 -0
- package/dist/requirementOptionFields.d.ts +32 -0
- package/dist/requirementOptionFields.d.ts.map +1 -0
- package/dist/requirementOptionFields.js +76 -0
- package/dist/requirementOptionFields.js.map +1 -0
- package/package.json +64 -0
- package/src/contentAnalyzers.test.ts +59 -0
- package/src/manifestComposition.test.ts +33 -0
- package/src/manifestModuleSource.test.ts +179 -0
- package/src/manifestPlugin.test.ts +166 -0
- package/src/manifestTreeShaking.test.ts +172 -0
- package/src/manifestTypedConsumer.test.ts +114 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2013-2026 Joshua Granick and other contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# @flighthq/vite-plugin-manifest
|
|
2
|
+
|
|
3
|
+
Vite plugin serving generated Flight registration source from analyzed content
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm install @flighthq/vite-plugin-manifest
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Import the supported application-facing API from `@flighthq/vite-plugin-manifest`. The `@flighthq/vite-plugin-manifest/contract` export is the wider package-to-package contract used to compose Flight itself.
|
|
12
|
+
|
|
13
|
+
This package is part of the locked-version Flight SDK graph. Applications may instead install and import `@flighthq/sdk` when package-level tree shaking is sufficient.
|
|
14
|
+
|
|
15
|
+
- [Flight project](https://github.com/flighthq/flight)
|
|
16
|
+
- [Source for @flighthq/vite-plugin-manifest@0.5.1-next.1680.bdc44c6](https://github.com/flighthq/flight/tree/bdc44c63675b7c50301154e66b79e2d29d6262da/packages/vite-plugin-manifest)
|
|
17
|
+
- [License](https://github.com/flighthq/flight/blob/bdc44c63675b7c50301154e66b79e2d29d6262da/LICENSE.md)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { RequirementSet } from '@flighthq/types/contract';
|
|
2
|
+
/**
|
|
3
|
+
* Reads one content file and reports what it requires.
|
|
4
|
+
*
|
|
5
|
+
* The plugin owns no format knowledge: an analyzer is a function the format package already exports,
|
|
6
|
+
* and this signature is only the shape they share. A new format is added by registering its analyzer
|
|
7
|
+
* here or by passing one in `analyzers`, never by teaching this package to read bytes.
|
|
8
|
+
*/
|
|
9
|
+
export type ContentAnalyzer = (source: Uint8Array) => RequirementSet;
|
|
10
|
+
/**
|
|
11
|
+
* The formats Flight analyzes out of the box, keyed by lowercase file extension.
|
|
12
|
+
*
|
|
13
|
+
* These are the format packages' own exports called directly. Duplicating their logic here would let
|
|
14
|
+
* a build's idea of what a file needs drift from what the importer actually reads — the two must be
|
|
15
|
+
* the same walk or the manifest is a guess.
|
|
16
|
+
*/
|
|
17
|
+
export declare const DEFAULT_CONTENT_ANALYZERS: Readonly<Record<string, ContentAnalyzer>>;
|
|
18
|
+
//# sourceMappingURL=contentAnalyzers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contentAnalyzers.d.ts","sourceRoot":"","sources":["../src/contentAnalyzers.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE/D;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,MAAM,EAAE,UAAU,KAAK,cAAc,CAAC;AAErE;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAO9E,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { parseAwd2Requirements } from '@flighthq/scene3d-formats/contract';
|
|
2
|
+
import { parseSwfRequirements } from '@flighthq/swf/contract';
|
|
3
|
+
/**
|
|
4
|
+
* The formats Flight analyzes out of the box, keyed by lowercase file extension.
|
|
5
|
+
*
|
|
6
|
+
* These are the format packages' own exports called directly. Duplicating their logic here would let
|
|
7
|
+
* a build's idea of what a file needs drift from what the importer actually reads — the two must be
|
|
8
|
+
* the same walk or the manifest is a guess.
|
|
9
|
+
*/
|
|
10
|
+
export const DEFAULT_CONTENT_ANALYZERS = Object.freeze({
|
|
11
|
+
// Away3D writes `.awd`; `.awd2` is accepted too because the format is AWD2 and projects name the
|
|
12
|
+
// file either way. Both resolve to the same analyzer, so the choice of suffix never changes what a
|
|
13
|
+
// build reads.
|
|
14
|
+
'.awd': (source) => parseAwd2Requirements(source, null, null),
|
|
15
|
+
'.awd2': (source) => parseAwd2Requirements(source, null, null),
|
|
16
|
+
'.swf': (source) => parseSwfRequirements(source, null, null),
|
|
17
|
+
});
|
|
18
|
+
//# sourceMappingURL=contentAnalyzers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contentAnalyzers.js","sourceRoot":"","sources":["../src/contentAnalyzers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAY9D;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAA8C,MAAM,CAAC,MAAM,CAAC;IAChG,iGAAiG;IACjG,mGAAmG;IACnG,eAAe;IACf,MAAM,EAAE,CAAC,MAAkB,EAAE,EAAE,CAAC,qBAAqB,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC;IACzE,OAAO,EAAE,CAAC,MAAkB,EAAE,EAAE,CAAC,qBAAqB,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC;IAC1E,MAAM,EAAE,CAAC,MAAkB,EAAE,EAAE,CAAC,oBAAoB,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC;CACzE,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC"}
|
package/dist/contract.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { RequirementCatalogEntry } from '@flighthq/types/contract';
|
|
2
|
+
/** The backends a manifest module always exports a fragment for, and the export name each one uses. */
|
|
3
|
+
export declare const MANIFEST_BACKEND_EXPORTS: Readonly<Record<string, string>>;
|
|
4
|
+
/**
|
|
5
|
+
* The catalog backend whose rows become `parserOptions` rather than a render-state fragment.
|
|
6
|
+
*
|
|
7
|
+
* A row's DESTINATION is its backend, not its facet: the same `document.format` requirement resolves
|
|
8
|
+
* to a tag handler for the parser and to a node renderer for `canvas`, and only the catalog author
|
|
9
|
+
* knows which row is which. Routing by facet alone would send both to the same place.
|
|
10
|
+
*/
|
|
11
|
+
export declare const MANIFEST_PARSER_BACKEND = "parser";
|
|
12
|
+
/** One resolved row: the catalog entry, and the requirement kind it satisfies. */
|
|
13
|
+
export interface ManifestModuleEntry {
|
|
14
|
+
readonly entry: Readonly<RequirementCatalogEntry>;
|
|
15
|
+
readonly kind: string;
|
|
16
|
+
}
|
|
17
|
+
/** What the emitter produced, and every row it could not place. */
|
|
18
|
+
export interface ManifestModuleResult {
|
|
19
|
+
/** Rows dropped with the reason, so a caller reports them instead of losing them silently. */
|
|
20
|
+
readonly problems: readonly string[];
|
|
21
|
+
readonly source: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Emits the per-file manifest module for one content file.
|
|
25
|
+
*
|
|
26
|
+
* Flat named exports — `canvasOptions`, `glOptions`, `wgpuOptions`, `domOptions`, `parserOptions` — so
|
|
27
|
+
* an application writes `import { glOptions } from './asset.swf?manifest'` and spreads it straight
|
|
28
|
+
* into `createGlRenderState`. Flat flat named bindings are what make the module shakable: a bundler
|
|
29
|
+
* that sees only `glOptions` imported can drop every other fragment AND the implementation modules
|
|
30
|
+
* only they referenced, which it could not do if the fragments hung off one default object.
|
|
31
|
+
*
|
|
32
|
+
* Every referenced symbol gets a precise named import from the module the catalog row names. There is
|
|
33
|
+
* no barrel import and no dynamic lookup, so the import graph states exactly which implementations
|
|
34
|
+
* this one file needs.
|
|
35
|
+
*
|
|
36
|
+
* Deterministic: imports are grouped by module with modules and symbols sorted, map entries are
|
|
37
|
+
* emitted in sorted kind order, and array entries keep catalog order. The same inputs always produce
|
|
38
|
+
* byte-identical source.
|
|
39
|
+
*/
|
|
40
|
+
export declare function generateManifestModuleSource(rows: readonly ManifestModuleEntry[], extension: string): ManifestModuleResult;
|
|
41
|
+
//# sourceMappingURL=manifestModuleSource.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifestModuleSource.d.ts","sourceRoot":"","sources":["../src/manifestModuleSource.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAIxE,uGAAuG;AACvG,eAAO,MAAM,wBAAwB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAKpE,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,WAAW,CAAC;AAEhD,kFAAkF;AAClF,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,uBAAuB,CAAC,CAAC;IAClD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,mEAAmE;AACnE,MAAM,WAAW,oBAAoB;IACnC,8FAA8F;IAC9F,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,SAAS,mBAAmB,EAAE,EACpC,SAAS,EAAE,MAAM,GAChB,oBAAoB,CAuDtB"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { BACKEND_OPTION_FIELDS, PARSER_HANDLER_FIELDS, REQUIREMENT_OPTION_FIELDS } from './requirementOptionFields';
|
|
2
|
+
/** The backends a manifest module always exports a fragment for, and the export name each one uses. */
|
|
3
|
+
export const MANIFEST_BACKEND_EXPORTS = Object.freeze({
|
|
4
|
+
canvas: 'canvasOptions',
|
|
5
|
+
dom: 'domOptions',
|
|
6
|
+
gl: 'glOptions',
|
|
7
|
+
wgpu: 'wgpuOptions',
|
|
8
|
+
});
|
|
9
|
+
/**
|
|
10
|
+
* The catalog backend whose rows become `parserOptions` rather than a render-state fragment.
|
|
11
|
+
*
|
|
12
|
+
* A row's DESTINATION is its backend, not its facet: the same `document.format` requirement resolves
|
|
13
|
+
* to a tag handler for the parser and to a node renderer for `canvas`, and only the catalog author
|
|
14
|
+
* knows which row is which. Routing by facet alone would send both to the same place.
|
|
15
|
+
*/
|
|
16
|
+
export const MANIFEST_PARSER_BACKEND = 'parser';
|
|
17
|
+
/**
|
|
18
|
+
* Emits the per-file manifest module for one content file.
|
|
19
|
+
*
|
|
20
|
+
* Flat named exports — `canvasOptions`, `glOptions`, `wgpuOptions`, `domOptions`, `parserOptions` — so
|
|
21
|
+
* an application writes `import { glOptions } from './asset.swf?manifest'` and spreads it straight
|
|
22
|
+
* into `createGlRenderState`. Flat flat named bindings are what make the module shakable: a bundler
|
|
23
|
+
* that sees only `glOptions` imported can drop every other fragment AND the implementation modules
|
|
24
|
+
* only they referenced, which it could not do if the fragments hung off one default object.
|
|
25
|
+
*
|
|
26
|
+
* Every referenced symbol gets a precise named import from the module the catalog row names. There is
|
|
27
|
+
* no barrel import and no dynamic lookup, so the import graph states exactly which implementations
|
|
28
|
+
* this one file needs.
|
|
29
|
+
*
|
|
30
|
+
* Deterministic: imports are grouped by module with modules and symbols sorted, map entries are
|
|
31
|
+
* emitted in sorted kind order, and array entries keep catalog order. The same inputs always produce
|
|
32
|
+
* byte-identical source.
|
|
33
|
+
*/
|
|
34
|
+
export function generateManifestModuleSource(rows, extension) {
|
|
35
|
+
const importsByModule = new Map();
|
|
36
|
+
const byBackend = new Map();
|
|
37
|
+
const parserRows = [];
|
|
38
|
+
const problems = [];
|
|
39
|
+
for (const row of rows) {
|
|
40
|
+
if (row.entry.backend === MANIFEST_PARSER_BACKEND) {
|
|
41
|
+
addImport(importsByModule, row.entry.implementationImport, row.entry.implementationSymbol);
|
|
42
|
+
parserRows.push(row);
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
// Two ways a render-backend row cannot be placed, and NEITHER is a silent skip. A facet with no
|
|
46
|
+
// render-state field at all (compression, physics, resource mime type) has nowhere to go; and a
|
|
47
|
+
// field this particular backend does not declare — blendRealizations on WGPU, say — would emit a
|
|
48
|
+
// fragment that spreads into nothing. Both are reported so the build can see what it lost.
|
|
49
|
+
const field = REQUIREMENT_OPTION_FIELDS[row.entry.facet];
|
|
50
|
+
if (field === undefined) {
|
|
51
|
+
problems.push(`facet ${row.entry.facet} has no render-state options field: dropped ${row.kind} for ${row.entry.backend}`);
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
const accepted = BACKEND_OPTION_FIELDS[row.entry.backend];
|
|
55
|
+
if (accepted === undefined) {
|
|
56
|
+
problems.push(`unknown backend ${row.entry.backend}: dropped ${row.entry.facet} ${row.kind}`);
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
if (!accepted.has(field)) {
|
|
60
|
+
problems.push(`backend ${row.entry.backend} has no ${field} field: dropped ${row.entry.facet} ${row.kind}`);
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
addImport(importsByModule, row.entry.implementationImport, row.entry.implementationSymbol);
|
|
64
|
+
let list = byBackend.get(row.entry.backend);
|
|
65
|
+
if (list === undefined) {
|
|
66
|
+
list = [];
|
|
67
|
+
byBackend.set(row.entry.backend, list);
|
|
68
|
+
}
|
|
69
|
+
list.push(row);
|
|
70
|
+
}
|
|
71
|
+
const lines = [
|
|
72
|
+
'// GENERATED by @flighthq/vite-plugin-manifest. Do not edit.',
|
|
73
|
+
`// Requirements of one ${extension} file, resolved for every backend in the catalog.`,
|
|
74
|
+
];
|
|
75
|
+
const importLines = [...importsByModule.keys()]
|
|
76
|
+
.sort()
|
|
77
|
+
.map((module) => `import { ${[...importsByModule.get(module)].sort().join(', ')} } from '${module}';`);
|
|
78
|
+
if (importLines.length > 0)
|
|
79
|
+
lines.push('', ...importLines);
|
|
80
|
+
for (const backend of Object.keys(MANIFEST_BACKEND_EXPORTS).sort()) {
|
|
81
|
+
lines.push('', ...backendFragment(MANIFEST_BACKEND_EXPORTS[backend], byBackend.get(backend) ?? []));
|
|
82
|
+
}
|
|
83
|
+
lines.push('', ...parserFragment(parserRows, PARSER_HANDLER_FIELDS[extension] ?? 'handlers'));
|
|
84
|
+
return { problems, source: `${lines.join('\n')}\n` };
|
|
85
|
+
}
|
|
86
|
+
function addImport(importsByModule, module, symbol) {
|
|
87
|
+
let symbols = importsByModule.get(module);
|
|
88
|
+
if (symbols === undefined) {
|
|
89
|
+
symbols = new Set();
|
|
90
|
+
importsByModule.set(module, symbols);
|
|
91
|
+
}
|
|
92
|
+
symbols.add(symbol);
|
|
93
|
+
}
|
|
94
|
+
function backendFragment(exportName, rows) {
|
|
95
|
+
const byField = new Map();
|
|
96
|
+
for (const row of rows) {
|
|
97
|
+
const field = REQUIREMENT_OPTION_FIELDS[row.entry.facet];
|
|
98
|
+
let list = byField.get(field);
|
|
99
|
+
if (list === undefined) {
|
|
100
|
+
list = [];
|
|
101
|
+
byField.set(field, list);
|
|
102
|
+
}
|
|
103
|
+
list.push(row);
|
|
104
|
+
}
|
|
105
|
+
// An empty fragment is still exported. A backend this content needs nothing for must spread to
|
|
106
|
+
// nothing rather than fail to import, so an application can spread every fragment unconditionally.
|
|
107
|
+
if (byField.size === 0)
|
|
108
|
+
return [`export const ${exportName} = {};`];
|
|
109
|
+
const fields = [...byField.keys()].sort().map((field) => {
|
|
110
|
+
const entries = [...byField.get(field)]
|
|
111
|
+
.sort((a, b) => a.kind.localeCompare(b.kind))
|
|
112
|
+
.map((row) => ` ['${row.kind}', ${row.entry.implementationSymbol}],`);
|
|
113
|
+
return ` ${field}: new Map([\n${entries.join('\n')}\n ]),`;
|
|
114
|
+
});
|
|
115
|
+
return [`export const ${exportName} = {`, ...fields, '};'];
|
|
116
|
+
}
|
|
117
|
+
function parserFragment(rows, field) {
|
|
118
|
+
if (rows.length === 0)
|
|
119
|
+
return ['export const parserOptions = {};'];
|
|
120
|
+
// Catalog order is preserved rather than sorted: a handler list is ordered, and reordering it
|
|
121
|
+
// changes which handler claims a contested tag and whether AWD2's build phases see their inputs.
|
|
122
|
+
const handlers = rows.map((row) => ` ${row.entry.implementationSymbol},`);
|
|
123
|
+
return [`export const parserOptions = {`, ` ${field}: [`, ...handlers, ' ],', '};'];
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=manifestModuleSource.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifestModuleSource.js","sourceRoot":"","sources":["../src/manifestModuleSource.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { NonEntityCreateResult, RequirementCatalog } from '@flighthq/types/contract';
|
|
2
|
+
/** The import suffix that asks this plugin for a file's manifest instead of the file itself. */
|
|
3
|
+
export declare const MANIFEST_QUERY_SUFFIX = "?manifest";
|
|
4
|
+
/** What `createManifestPlugin` accepts. Every input is explicit; nothing is discovered by convention. */
|
|
5
|
+
export interface ManifestPluginOptions {
|
|
6
|
+
/** The catalog mapping a requirement to the implementation that satisfies it, for every backend. */
|
|
7
|
+
readonly catalog: Readonly<RequirementCatalog>;
|
|
8
|
+
/**
|
|
9
|
+
* Called for every unsupported format, unreadable file, analyzer failure and unresolved requirement.
|
|
10
|
+
* Defaults to a warning on the `flight-manifest` channel through `@flighthq/log`. A requirement the
|
|
11
|
+
* build cannot place is reported rather than skipped: silently dropping one is how a bundle ends up
|
|
12
|
+
* missing an implementation it needed.
|
|
13
|
+
*/
|
|
14
|
+
readonly onDiagnostic?: (message: string) => void;
|
|
15
|
+
}
|
|
16
|
+
/** The subset of Vite's plugin surface this factory produces. Structural, so Vite is a peer, not a dep. */
|
|
17
|
+
export interface ManifestPlugin {
|
|
18
|
+
/**
|
|
19
|
+
* Runs in Vite's `pre` stage. Without it Vite's own asset handling claims `./asset.swf?manifest`
|
|
20
|
+
* first and hands rollup the binary to parse as JavaScript — the plugin must see the id before the
|
|
21
|
+
* default resolver treats the path as a file to serve.
|
|
22
|
+
*/
|
|
23
|
+
readonly enforce: 'pre';
|
|
24
|
+
readonly handleHotUpdate: (context: {
|
|
25
|
+
readonly file: string;
|
|
26
|
+
}) => void;
|
|
27
|
+
readonly load: (id: string) => Promise<string | null>;
|
|
28
|
+
readonly name: string;
|
|
29
|
+
readonly resolveId: (id: string, importer?: string) => string | null;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Creates the plugin. Explicit factory, no default export and no module-level state: importing this
|
|
33
|
+
* package configures nothing.
|
|
34
|
+
*
|
|
35
|
+
* It intercepts a per-file import — `import { glOptions } from './asset.swf?manifest'` — reads THAT
|
|
36
|
+
* file, picks the analyzer by extension, resolves the requirements against the catalog for every
|
|
37
|
+
* backend, and serves a module of flat per-backend fragments. Per-file rather than project-wide
|
|
38
|
+
* because the import graph is then the truth: a document nothing imports contributes nothing, and a
|
|
39
|
+
* bundler can see which implementations each document actually pulled in.
|
|
40
|
+
*
|
|
41
|
+
* The pipeline is the SDK's own — `parse*Requirements` to read content, the catalog to resolve. This
|
|
42
|
+
* package contributes the Vite lifecycle and the module text, nothing else.
|
|
43
|
+
*/
|
|
44
|
+
export declare function createManifestPlugin(options: Readonly<ManifestPluginOptions>): NonEntityCreateResult<ManifestPlugin, 'descriptor'>;
|
|
45
|
+
//# sourceMappingURL=manifestPlugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifestPlugin.d.ts","sourceRoot":"","sources":["../src/manifestPlugin.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,qBAAqB,EAAe,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAUvG,gGAAgG;AAChG,eAAO,MAAM,qBAAqB,cAAc,CAAC;AAEjD,yGAAyG;AACzG,MAAM,WAAW,qBAAqB;IACpC,oGAAoG;IACpG,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IAC/C;;;;;OAKG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACnD;AAED,2GAA2G;AAC3G,MAAM,WAAW,cAAc;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;IACxB,QAAQ,CAAC,eAAe,EAAE,CAAC,OAAO,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACvE,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACtD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CACtE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,QAAQ,CAAC,qBAAqB,CAAC,GACvC,qBAAqB,CAAC,cAAc,EAAE,YAAY,CAAC,CAyErD"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { dirname, extname, isAbsolute, resolve } from 'node:path';
|
|
3
|
+
import { logWarn } from '@flighthq/log/contract';
|
|
4
|
+
import { createRequirementCodegenPlan } from '@flighthq/requirement-codegen/contract';
|
|
5
|
+
import { DEFAULT_CONTENT_ANALYZERS } from './contentAnalyzers';
|
|
6
|
+
import { generateManifestModuleSource, MANIFEST_BACKEND_EXPORTS, MANIFEST_PARSER_BACKEND, } from './manifestModuleSource';
|
|
7
|
+
/** The import suffix that asks this plugin for a file's manifest instead of the file itself. */
|
|
8
|
+
export const MANIFEST_QUERY_SUFFIX = '?manifest';
|
|
9
|
+
/**
|
|
10
|
+
* Creates the plugin. Explicit factory, no default export and no module-level state: importing this
|
|
11
|
+
* package configures nothing.
|
|
12
|
+
*
|
|
13
|
+
* It intercepts a per-file import — `import { glOptions } from './asset.swf?manifest'` — reads THAT
|
|
14
|
+
* file, picks the analyzer by extension, resolves the requirements against the catalog for every
|
|
15
|
+
* backend, and serves a module of flat per-backend fragments. Per-file rather than project-wide
|
|
16
|
+
* because the import graph is then the truth: a document nothing imports contributes nothing, and a
|
|
17
|
+
* bundler can see which implementations each document actually pulled in.
|
|
18
|
+
*
|
|
19
|
+
* The pipeline is the SDK's own — `parse*Requirements` to read content, the catalog to resolve. This
|
|
20
|
+
* package contributes the Vite lifecycle and the module text, nothing else.
|
|
21
|
+
*/
|
|
22
|
+
export function createManifestPlugin(options) {
|
|
23
|
+
const report = options.onDiagnostic ?? ((message) => logWarn(message, MANIFEST_LOG_CHANNEL));
|
|
24
|
+
// Keyed by the absolute content path, so invalidation is per imported source: editing one document
|
|
25
|
+
// rebuilds that document's module and leaves every other file's cached module untouched.
|
|
26
|
+
const sourceByPath = new Map();
|
|
27
|
+
async function build(path) {
|
|
28
|
+
const extension = extname(path).toLowerCase();
|
|
29
|
+
const analyze = DEFAULT_CONTENT_ANALYZERS[extension];
|
|
30
|
+
if (analyze === undefined) {
|
|
31
|
+
report(`unsupported content format, no analyzer for ${extension}: ${path}`);
|
|
32
|
+
return generateManifestModuleSource([], extension).source;
|
|
33
|
+
}
|
|
34
|
+
let requirements;
|
|
35
|
+
try {
|
|
36
|
+
requirements = analyze(new Uint8Array(await readFile(path)));
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
report(`analyzer failed for ${path}: ${error.message}`);
|
|
40
|
+
return generateManifestModuleSource([], extension).source;
|
|
41
|
+
}
|
|
42
|
+
// Resolution is the codegen kernel's job, not this plugin's. Every backend is planned, not a
|
|
43
|
+
// configured one: the module exports a fragment per backend and the application's import decides
|
|
44
|
+
// which survive the bundle. The parser is planned alongside them because parserOptions is one of
|
|
45
|
+
// those exports.
|
|
46
|
+
const rows = [];
|
|
47
|
+
const unresolvedEverywhere = new Map();
|
|
48
|
+
const resolvedSomewhere = new Set();
|
|
49
|
+
for (const backend of MANIFEST_RESOLVED_BACKENDS) {
|
|
50
|
+
const plan = createRequirementCodegenPlan(options.catalog, requirements, backend);
|
|
51
|
+
for (const entry of plan.entries) {
|
|
52
|
+
rows.push({ entry, kind: entry.kind });
|
|
53
|
+
resolvedSomewhere.add(`${entry.facet}\u0000${entry.kind}`);
|
|
54
|
+
}
|
|
55
|
+
for (const requirement of plan.unresolved) {
|
|
56
|
+
unresolvedEverywhere.set(`${requirement.facet}\u0000${requirement.key}`, requirement);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// Reported only when NO backend could place it. A requirement satisfied by GL but absent from the
|
|
60
|
+
// WGPU catalog is a normal per-backend gap, not a hole in the content's coverage.
|
|
61
|
+
for (const [identity, requirement] of unresolvedEverywhere) {
|
|
62
|
+
if (resolvedSomewhere.has(identity))
|
|
63
|
+
continue;
|
|
64
|
+
report(`no catalog entry for ${requirement.facet} ${requirement.key}: ${path}`);
|
|
65
|
+
}
|
|
66
|
+
const generated = generateManifestModuleSource(rows, extension);
|
|
67
|
+
for (const problem of generated.problems)
|
|
68
|
+
report(`${problem}: ${path}`);
|
|
69
|
+
return generated.source;
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
enforce: 'pre',
|
|
73
|
+
handleHotUpdate: (context) => {
|
|
74
|
+
sourceByPath.delete(context.file);
|
|
75
|
+
},
|
|
76
|
+
load: async (id) => {
|
|
77
|
+
if (!id.startsWith(MANIFEST_RESOLVED_PREFIX))
|
|
78
|
+
return null;
|
|
79
|
+
const path = id.slice(MANIFEST_RESOLVED_PREFIX.length);
|
|
80
|
+
let source = sourceByPath.get(path);
|
|
81
|
+
if (source === undefined) {
|
|
82
|
+
source = await build(path);
|
|
83
|
+
sourceByPath.set(path, source);
|
|
84
|
+
}
|
|
85
|
+
return source;
|
|
86
|
+
},
|
|
87
|
+
name: 'flight-manifest',
|
|
88
|
+
resolveId: (id, importer) => {
|
|
89
|
+
if (!id.endsWith(MANIFEST_QUERY_SUFFIX))
|
|
90
|
+
return null;
|
|
91
|
+
const request = id.slice(0, -MANIFEST_QUERY_SUFFIX.length);
|
|
92
|
+
const base = importer === undefined ? process.cwd() : dirname(importer);
|
|
93
|
+
return `${MANIFEST_RESOLVED_PREFIX}${isAbsolute(request) ? request : resolve(base, request)}`;
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
// Rollup treats a leading NUL as "this id belongs to a plugin", which keeps the resolved id out of
|
|
98
|
+
// filesystem resolution while still carrying the path the module was built from.
|
|
99
|
+
const MANIFEST_RESOLVED_PREFIX = '\0flight-manifest:';
|
|
100
|
+
const MANIFEST_LOG_CHANNEL = 'flight-manifest';
|
|
101
|
+
const MANIFEST_RESOLVED_BACKENDS = [...Object.keys(MANIFEST_BACKEND_EXPORTS), MANIFEST_PARSER_BACKEND].sort();
|
|
102
|
+
//# sourceMappingURL=manifestPlugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifestPlugin.js","sourceRoot":"","sources":["../src/manifestPlugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The render-state options field that collects each facet's implementations.
|
|
3
|
+
*
|
|
4
|
+
* A catalog row names a facet, a kind and an implementation, but not the options field that holds it —
|
|
5
|
+
* deliberately, because a row is a fact about ownership and should not encode one consumer's option
|
|
6
|
+
* shape. This table is where the plugin decides.
|
|
7
|
+
*
|
|
8
|
+
* `document.format` maps to `nodeRenderers` for a render backend: a document's content kinds are the
|
|
9
|
+
* nodes the importer produces, so that is the field a renderer needs them in.
|
|
10
|
+
*/
|
|
11
|
+
export declare const REQUIREMENT_OPTION_FIELDS: Readonly<Record<string, string>>;
|
|
12
|
+
/**
|
|
13
|
+
* The kind-keyed fields each backend's options type ACTUALLY declares, taken from the types package.
|
|
14
|
+
*
|
|
15
|
+
* Backend sets are not interchangeable and the differences are real: `GlRenderStateOptions` has
|
|
16
|
+
* `blendRealizations`, `pbrExtensions` and `customEffectShaders`; `WgpuRenderStateOptions` has NONE of
|
|
17
|
+
* those three. Emitting one into the other would produce a fragment that typechecks nowhere and
|
|
18
|
+
* silently does nothing when spread, so routing is per backend and a row naming a field its backend
|
|
19
|
+
* does not accept is REPORTED rather than emitted.
|
|
20
|
+
*
|
|
21
|
+
* All four backends now take ONE options object, and every set below is derived from the options type
|
|
22
|
+
* that backend actually declares rather than from a guess about which fields it ought to have.
|
|
23
|
+
* `CanvasRenderStateOptions` carries the registries and texture resolvers directly, so a canvas
|
|
24
|
+
* fragment spreads into `createCanvasRenderState(options)` like every other backend's. DOM's registry
|
|
25
|
+
* fields are seeded into the runtime at construction. Neither canvas nor DOM declares
|
|
26
|
+
* `blendRealizations`, and DOM declares no material or effect tables, so a row naming one is reported
|
|
27
|
+
* rather than emitted into a field that does not exist.
|
|
28
|
+
*/
|
|
29
|
+
export declare const BACKEND_OPTION_FIELDS: Readonly<Record<string, ReadonlySet<string>>>;
|
|
30
|
+
/** The parser options field each content format spreads its ordered handler list into. */
|
|
31
|
+
export declare const PARSER_HANDLER_FIELDS: Readonly<Record<string, string>>;
|
|
32
|
+
//# sourceMappingURL=requirementOptionFields.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requirementOptionFields.d.ts","sourceRoot":"","sources":["../src/requirementOptionFields.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQrE,CAAC;AAEH;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,qBAAqB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CA+B9E,CAAC;AAEH,0FAA0F;AAC1F,eAAO,MAAM,qBAAqB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAIjE,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { RequirementFacet } from '@flighthq/types/contract';
|
|
2
|
+
/**
|
|
3
|
+
* The render-state options field that collects each facet's implementations.
|
|
4
|
+
*
|
|
5
|
+
* A catalog row names a facet, a kind and an implementation, but not the options field that holds it —
|
|
6
|
+
* deliberately, because a row is a fact about ownership and should not encode one consumer's option
|
|
7
|
+
* shape. This table is where the plugin decides.
|
|
8
|
+
*
|
|
9
|
+
* `document.format` maps to `nodeRenderers` for a render backend: a document's content kinds are the
|
|
10
|
+
* nodes the importer produces, so that is the field a renderer needs them in.
|
|
11
|
+
*/
|
|
12
|
+
export const REQUIREMENT_OPTION_FIELDS = Object.freeze({
|
|
13
|
+
[RequirementFacet.DocumentFormat]: 'nodeRenderers',
|
|
14
|
+
[RequirementFacet.SceneBlendMode]: 'blendRealizations',
|
|
15
|
+
[RequirementFacet.SceneMaterialKind]: 'materialRenderers',
|
|
16
|
+
[RequirementFacet.SceneModifierKind]: 'modifierSnippets',
|
|
17
|
+
[RequirementFacet.SceneNodeKind]: 'nodeRenderers',
|
|
18
|
+
[RequirementFacet.SceneShapeCommand]: 'canvasShapeCommands',
|
|
19
|
+
[RequirementFacet.SceneTextureSourceKind]: 'textureResolvers',
|
|
20
|
+
});
|
|
21
|
+
/**
|
|
22
|
+
* The kind-keyed fields each backend's options type ACTUALLY declares, taken from the types package.
|
|
23
|
+
*
|
|
24
|
+
* Backend sets are not interchangeable and the differences are real: `GlRenderStateOptions` has
|
|
25
|
+
* `blendRealizations`, `pbrExtensions` and `customEffectShaders`; `WgpuRenderStateOptions` has NONE of
|
|
26
|
+
* those three. Emitting one into the other would produce a fragment that typechecks nowhere and
|
|
27
|
+
* silently does nothing when spread, so routing is per backend and a row naming a field its backend
|
|
28
|
+
* does not accept is REPORTED rather than emitted.
|
|
29
|
+
*
|
|
30
|
+
* All four backends now take ONE options object, and every set below is derived from the options type
|
|
31
|
+
* that backend actually declares rather than from a guess about which fields it ought to have.
|
|
32
|
+
* `CanvasRenderStateOptions` carries the registries and texture resolvers directly, so a canvas
|
|
33
|
+
* fragment spreads into `createCanvasRenderState(options)` like every other backend's. DOM's registry
|
|
34
|
+
* fields are seeded into the runtime at construction. Neither canvas nor DOM declares
|
|
35
|
+
* `blendRealizations`, and DOM declares no material or effect tables, so a row naming one is reported
|
|
36
|
+
* rather than emitted into a field that does not exist.
|
|
37
|
+
*/
|
|
38
|
+
export const BACKEND_OPTION_FIELDS = Object.freeze({
|
|
39
|
+
// Derived from the landed CanvasRenderStateOptions: it extends RenderStateOptions and
|
|
40
|
+
// CanvasRenderOptions and adds effects and materialRenderers, so these are its kind-keyed fields.
|
|
41
|
+
canvas: new Set(['canvasShapeCommands', 'effectPaddingResolvers', 'effects', 'materialRenderers', 'nodeRenderers']),
|
|
42
|
+
// D3: DomRenderOptions declares registry fields, seeded into the runtime at construction.
|
|
43
|
+
dom: new Set(['canvasShapeCommands', 'effectPaddingResolvers', 'nodeRenderers', 'textureResolvers']),
|
|
44
|
+
gl: new Set([
|
|
45
|
+
'blendRealizations',
|
|
46
|
+
'canvasShapeCommands',
|
|
47
|
+
'customEffectShaders',
|
|
48
|
+
'customMaterialShaders',
|
|
49
|
+
'effectPaddingResolvers',
|
|
50
|
+
'effects',
|
|
51
|
+
'materialRenderers',
|
|
52
|
+
'modifierSnippets',
|
|
53
|
+
'nodeRenderers',
|
|
54
|
+
'pbrExtensions',
|
|
55
|
+
'textureResolvers',
|
|
56
|
+
'velocityWriters',
|
|
57
|
+
]),
|
|
58
|
+
wgpu: new Set([
|
|
59
|
+
'canvasShapeCommands',
|
|
60
|
+
'customMaterialShaders',
|
|
61
|
+
'effectPaddingResolvers',
|
|
62
|
+
'effects',
|
|
63
|
+
'materialRenderers',
|
|
64
|
+
'modifierSnippets',
|
|
65
|
+
'nodeRenderers',
|
|
66
|
+
'textureResolvers',
|
|
67
|
+
'velocityWriters',
|
|
68
|
+
]),
|
|
69
|
+
});
|
|
70
|
+
/** The parser options field each content format spreads its ordered handler list into. */
|
|
71
|
+
export const PARSER_HANDLER_FIELDS = Object.freeze({
|
|
72
|
+
'.awd': 'blocks',
|
|
73
|
+
'.awd2': 'blocks',
|
|
74
|
+
'.swf': 'tags',
|
|
75
|
+
});
|
|
76
|
+
//# sourceMappingURL=requirementOptionFields.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requirementOptionFields.js","sourceRoot":"","sources":["../src/requirementOptionFields.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE5D;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAqC,MAAM,CAAC,MAAM,CAAC;IACvF,CAAC,gBAAgB,CAAC,cAAc,CAAC,EAAE,eAAe;IAClD,CAAC,gBAAgB,CAAC,cAAc,CAAC,EAAE,mBAAmB;IACtD,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,EAAE,mBAAmB;IACzD,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,EAAE,kBAAkB;IACxD,CAAC,gBAAgB,CAAC,aAAa,CAAC,EAAE,eAAe;IACjD,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,EAAE,qBAAqB;IAC3D,CAAC,gBAAgB,CAAC,sBAAsB,CAAC,EAAE,kBAAkB;CAC9D,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAkD,MAAM,CAAC,MAAM,CAAC;IAChG,sFAAsF;IACtF,kGAAkG;IAClG,MAAM,EAAE,IAAI,GAAG,CAAC,CAAC,qBAAqB,EAAE,wBAAwB,EAAE,SAAS,EAAE,mBAAmB,EAAE,eAAe,CAAC,CAAC;IACnH,0FAA0F;IAC1F,GAAG,EAAE,IAAI,GAAG,CAAC,CAAC,qBAAqB,EAAE,wBAAwB,EAAE,eAAe,EAAE,kBAAkB,CAAC,CAAC;IACpG,EAAE,EAAE,IAAI,GAAG,CAAC;QACV,mBAAmB;QACnB,qBAAqB;QACrB,qBAAqB;QACrB,uBAAuB;QACvB,wBAAwB;QACxB,SAAS;QACT,mBAAmB;QACnB,kBAAkB;QAClB,eAAe;QACf,eAAe;QACf,kBAAkB;QAClB,iBAAiB;KAClB,CAAC;IACF,IAAI,EAAE,IAAI,GAAG,CAAC;QACZ,qBAAqB;QACrB,uBAAuB;QACvB,wBAAwB;QACxB,SAAS;QACT,mBAAmB;QACnB,kBAAkB;QAClB,eAAe;QACf,kBAAkB;QAClB,iBAAiB;KAClB,CAAC;CACH,CAAC,CAAC;AAEH,0FAA0F;AAC1F,MAAM,CAAC,MAAM,qBAAqB,GAAqC,MAAM,CAAC,MAAM,CAAC;IACnF,MAAM,EAAE,QAAQ;IAChB,OAAO,EAAE,QAAQ;IACjB,MAAM,EAAE,MAAM;CACf,CAAC,CAAC"}
|