pagespeed-quest 0.10.0 → 0.12.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/CHANGELOG.md +24 -0
- package/README.ja.md +47 -0
- package/README.md +49 -0
- package/build/cli.d.ts +8 -0
- package/build/cli.js +263 -0
- package/build/command.js +3 -229
- package/build/lighthouse-summary.d.ts +3 -1
- package/build/lighthouse-summary.js +31 -46
- package/build/lighthouse.d.ts +0 -1
- package/build/lighthouse.js +6 -2
- package/build/llm.d.ts +20 -0
- package/build/llm.js +42 -0
- package/llmdocs/00-guide.md +146 -0
- package/llmdocs/10-inventory.md +157 -0
- package/llmdocs/20-experiments.md +93 -0
- package/llmdocs/30-measuring.md +158 -0
- package/llmdocs/90-commands.md +188 -0
- package/package.json +13 -7
- package/scripts/build-llm-docs.js +79 -0
- package/scripts/postinstall.js +2 -3
- package/scripts/validate-plugin-skills.js +117 -0
- package/build/docs/assets/css/main.css +0 -1
- package/build/docs/assets/images/icons.png +0 -0
- package/build/docs/assets/images/icons@2x.png +0 -0
- package/build/docs/assets/images/widgets.png +0 -0
- package/build/docs/assets/images/widgets@2x.png +0 -0
- package/build/docs/assets/js/main.js +0 -51
- package/build/docs/classes/inventoryrepository.html +0 -305
- package/build/docs/classes/playbackproxy.html +0 -524
- package/build/docs/classes/proxy.html +0 -474
- package/build/docs/classes/recordingproxy.html +0 -532
- package/build/docs/classes/testproxy.html +0 -497
- package/build/docs/classes/throttle.html +0 -425
- package/build/docs/classes/throttlinglog.html +0 -174
- package/build/docs/classes/throttlingtransform.html +0 -6297
- package/build/docs/globals.html +0 -1131
- package/build/docs/index.html +0 -348
- package/build/docs/interfaces/beautifyresult.html +0 -174
- package/build/docs/interfaces/contentencodingpair.html +0 -174
- package/build/docs/interfaces/inventory.html +0 -174
- package/build/docs/interfaces/lighthouseoptions.html +0 -230
- package/build/docs/interfaces/playbacktransaction.html +0 -272
- package/build/docs/interfaces/proxyoptions.html +0 -423
- package/build/docs/interfaces/recordingsession.html +0 -174
- package/build/docs/interfaces/recordingtransaction.html +0 -286
- package/build/docs/interfaces/resource.html +0 -314
- package/build/docs/interfaces/transaction.html +0 -258
- package/build/docs/interfaces/withproxyoptions.html +0 -418
- package/build/logger.d.ts +0 -2
- package/build/logger.js +0 -15
- package/build/proxy.d.ts +0 -35
- package/build/proxy.js +0 -96
- package/build/throttling.d.ts +0 -33
- package/build/throttling.js +0 -89
package/build/command.js
CHANGED
|
@@ -1,230 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import { Dependency } from './dependency.js';
|
|
6
|
-
import { execLighthouse } from './lighthouse.js';
|
|
7
|
-
import { execLoadshow } from './loadshow.js';
|
|
8
|
-
import { execWebshotCapture, execWebshotCompare } from './webshot.js';
|
|
9
|
-
import { InventoryRepository, withPlaybackProxy, withRecordingProxy } from './index.js';
|
|
10
|
-
const dependency = new Dependency();
|
|
11
|
-
function collect(value, previous) {
|
|
12
|
-
return previous.concat([value]);
|
|
13
|
-
}
|
|
14
|
-
const main = new Command();
|
|
15
|
-
main.option('-i, --inventory <dir>', 'Inventory directory', './inventory');
|
|
16
|
-
function registerLighthouseCommands(main) {
|
|
17
|
-
const lighthouse = main.command('lighthouse');
|
|
18
|
-
lighthouse.description('Run Lighthouse (performance category) via a proxy');
|
|
19
|
-
lighthouse.option('-a, --artifacts <dir>', 'Artifacts directory', './artifacts');
|
|
20
|
-
lighthouse.option('-l, --laud', 'Show browser and open the report after completion', false);
|
|
21
|
-
lighthouse.option('-t, --timeout <ms>', 'Timeout milliseconds', '30000');
|
|
22
|
-
const recording = lighthouse.command('recording');
|
|
23
|
-
recording.description('Record contents by lighthouse');
|
|
24
|
-
recording.option('-d, --device <mobile|desktop>', 'Device type', 'mobile');
|
|
25
|
-
recording.option('-x, --exclude <pattern>', 'Regex patterns to exclude URLs from recording (repeatable)', collect, []);
|
|
26
|
-
recording.argument('<url>', 'Url to measure performance');
|
|
27
|
-
recording.action(async (url) => {
|
|
28
|
-
const inventoryRepository = new InventoryRepository(main.opts().inventory || './inventory');
|
|
29
|
-
const deviceType = recording.opts().device || 'mobile';
|
|
30
|
-
const artifactsDir = lighthouse.opts().artifacts || './artifacts';
|
|
31
|
-
const laud = !!lighthouse.opts().laud;
|
|
32
|
-
const timeout = Number(lighthouse.opts().timeout || '30000');
|
|
33
|
-
const excludePatterns = recording.opts().exclude || [];
|
|
34
|
-
await withRecordingProxy({
|
|
35
|
-
entryUrl: url,
|
|
36
|
-
deviceType,
|
|
37
|
-
inventoryRepository,
|
|
38
|
-
excludePatterns: excludePatterns.length > 0 ? excludePatterns : undefined,
|
|
39
|
-
}, dependency, async (proxy) => {
|
|
40
|
-
await execLighthouse({
|
|
41
|
-
url,
|
|
42
|
-
proxyPort: proxy.port,
|
|
43
|
-
deviceType,
|
|
44
|
-
view: laud,
|
|
45
|
-
artifactsDir,
|
|
46
|
-
headless: !laud,
|
|
47
|
-
timeout,
|
|
48
|
-
}, dependency);
|
|
49
|
-
dependency.logger?.info('Lighthouse completed. Saving inventory...');
|
|
50
|
-
});
|
|
51
|
-
});
|
|
52
|
-
const playback = lighthouse.command('playback');
|
|
53
|
-
playback.description('Playback contents for lighthouse');
|
|
54
|
-
playback.action(async () => {
|
|
55
|
-
const inventoryDir = main.opts().inventory || './inventory';
|
|
56
|
-
const inventoryRepository = new InventoryRepository(inventoryDir);
|
|
57
|
-
const artifactsDir = lighthouse.opts().artifacts || './artifacts';
|
|
58
|
-
const laud = !!lighthouse.opts().laud;
|
|
59
|
-
const timeout = Number(lighthouse.opts().timeout || '30000');
|
|
60
|
-
// Load inventory for traffic statistics
|
|
61
|
-
const inventory = await inventoryRepository.loadInventory();
|
|
62
|
-
await withPlaybackProxy({
|
|
63
|
-
inventoryRepository,
|
|
64
|
-
}, dependency, async (proxy) => {
|
|
65
|
-
await execLighthouse({
|
|
66
|
-
url: proxy.entryUrl,
|
|
67
|
-
proxyPort: proxy.port,
|
|
68
|
-
deviceType: proxy.deviceType,
|
|
69
|
-
view: laud,
|
|
70
|
-
artifactsDir,
|
|
71
|
-
headless: !laud,
|
|
72
|
-
timeout,
|
|
73
|
-
inventoryDir,
|
|
74
|
-
resources: inventory.resources,
|
|
75
|
-
}, dependency);
|
|
76
|
-
dependency.logger?.info('Lighthouse completed');
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
function registerLoadshowCommands(main) {
|
|
81
|
-
const loadshow = main.command('loadshow');
|
|
82
|
-
loadshow.description('Run loadshow via a proxy');
|
|
83
|
-
loadshow.option('-a, --artifacts <dir>', 'Artifacts directory', './artifacts');
|
|
84
|
-
loadshow.option('-c, --credit <string>', 'Credit string');
|
|
85
|
-
loadshow.option('-t, --timeout <ms>', 'Timeout milliseconds', '30000');
|
|
86
|
-
const recording = loadshow.command('recording');
|
|
87
|
-
recording.description('Record contents by loadshow');
|
|
88
|
-
recording.option('-d, --device <mobile|desktop>', 'Device type', 'mobile');
|
|
89
|
-
recording.option('-x, --exclude <pattern>', 'Regex patterns to exclude URLs from recording (repeatable)', collect, []);
|
|
90
|
-
recording.argument('<url>', 'Url to measure performance');
|
|
91
|
-
recording.action(async (url) => {
|
|
92
|
-
const inventoryRepository = new InventoryRepository(main.opts().inventory || './inventory');
|
|
93
|
-
const deviceType = recording.opts().device || 'mobile';
|
|
94
|
-
const artifactsDir = loadshow.opts().artifacts || './artifacts';
|
|
95
|
-
const credit = loadshow.opts().credit || '';
|
|
96
|
-
const timeout = Number(loadshow.opts().timeout || '30000');
|
|
97
|
-
const excludePatterns = recording.opts().exclude || [];
|
|
98
|
-
await withRecordingProxy({
|
|
99
|
-
entryUrl: url,
|
|
100
|
-
deviceType,
|
|
101
|
-
inventoryRepository,
|
|
102
|
-
excludePatterns: excludePatterns.length > 0 ? excludePatterns : undefined,
|
|
103
|
-
}, dependency, async (proxy) => {
|
|
104
|
-
await execLoadshow({ url, proxyPort: proxy.port, deviceType, artifactsDir, credit, timeout }, dependency);
|
|
105
|
-
dependency.logger?.info('Loadshow completed. Saving inventory...');
|
|
106
|
-
});
|
|
107
|
-
});
|
|
108
|
-
const playback = loadshow.command('playback');
|
|
109
|
-
playback.description('Playback contents for loadshow');
|
|
110
|
-
playback.action(async () => {
|
|
111
|
-
const inventoryRepository = new InventoryRepository(main.opts().inventory || './inventory');
|
|
112
|
-
const artifactsDir = loadshow.opts().artifacts || './artifacts';
|
|
113
|
-
const credit = loadshow.opts().credit || '';
|
|
114
|
-
const timeout = Number(loadshow.opts().timeout || '30000');
|
|
115
|
-
await withPlaybackProxy({
|
|
116
|
-
inventoryRepository,
|
|
117
|
-
}, dependency, async (proxy) => {
|
|
118
|
-
await execLoadshow({
|
|
119
|
-
url: proxy.entryUrl,
|
|
120
|
-
proxyPort: proxy.port,
|
|
121
|
-
deviceType: proxy.deviceType,
|
|
122
|
-
artifactsDir,
|
|
123
|
-
credit,
|
|
124
|
-
timeout,
|
|
125
|
-
}, dependency);
|
|
126
|
-
dependency.logger?.info('Loadshow completed');
|
|
127
|
-
});
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
function registerProxyCommands(main) {
|
|
131
|
-
const proxy = main.command('proxy');
|
|
132
|
-
proxy.option('-p, --port <number>', 'Proxy port', '8080');
|
|
133
|
-
proxy.option('-r, --record <url>', 'Recording URL to start the proxy as recording mode', '');
|
|
134
|
-
proxy.option('-x, --exclude <pattern>', 'Regex patterns to exclude URLs from recording (repeatable)', collect, []);
|
|
135
|
-
proxy.action(async () => {
|
|
136
|
-
const inventoryRepository = new InventoryRepository(main.opts().inventory || './inventory');
|
|
137
|
-
const port = Number(proxy.opts().port || '8080');
|
|
138
|
-
if (proxy.opts().record) {
|
|
139
|
-
const url = proxy.opts().record;
|
|
140
|
-
if (!url) {
|
|
141
|
-
throw new Error('Recording URL must be specified with --record option.');
|
|
142
|
-
}
|
|
143
|
-
const excludePatterns = proxy.opts().exclude || [];
|
|
144
|
-
// Recordingモード
|
|
145
|
-
await withRecordingProxy({
|
|
146
|
-
inventoryRepository,
|
|
147
|
-
port,
|
|
148
|
-
entryUrl: url,
|
|
149
|
-
excludePatterns: excludePatterns.length > 0 ? excludePatterns : undefined,
|
|
150
|
-
}, dependency, async () => {
|
|
151
|
-
dependency.logger?.info(`Recording proxy started on port ${port}. Press Ctrl+C to stop.`);
|
|
152
|
-
// Wait for Ctrl+C signal
|
|
153
|
-
return new Promise((resolve) => {
|
|
154
|
-
process.on('SIGINT', () => {
|
|
155
|
-
dependency.logger?.info('Saving the inventory...');
|
|
156
|
-
resolve();
|
|
157
|
-
});
|
|
158
|
-
});
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
else {
|
|
162
|
-
// Playbackモード
|
|
163
|
-
// eslint-disable-next-line no-constant-condition
|
|
164
|
-
while (true) {
|
|
165
|
-
await withPlaybackProxy({ inventoryRepository, port }, dependency, async () => {
|
|
166
|
-
const watcher = Watch(inventoryRepository.dirPath, { recursive: true });
|
|
167
|
-
return new Promise((ok) => {
|
|
168
|
-
watcher.on('change', () => {
|
|
169
|
-
watcher.close();
|
|
170
|
-
dependency.logger?.info('Inventory changed. Restarting proxy...');
|
|
171
|
-
ok();
|
|
172
|
-
});
|
|
173
|
-
});
|
|
174
|
-
});
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
function registerCaptureCommands(main) {
|
|
180
|
-
const visualTest = main.command('capture');
|
|
181
|
-
visualTest.description('Capture a screenshot via playback proxy and optionally compare with a baseline');
|
|
182
|
-
visualTest.option('-a, --artifacts <dir>', 'Artifacts directory', './artifacts');
|
|
183
|
-
visualTest.option('-t, --timeout <ms>', 'Timeout milliseconds', '30000');
|
|
184
|
-
visualTest.option('--compare <file>', 'Baseline PNG file to compare against');
|
|
185
|
-
visualTest.option('--baseline-label <label>', 'Label for the baseline image', '前回');
|
|
186
|
-
visualTest.option('--current-label <label>', 'Label for the current image', '今回');
|
|
187
|
-
visualTest.action(async () => {
|
|
188
|
-
const inventoryRepository = new InventoryRepository(main.opts().inventory || './inventory');
|
|
189
|
-
const artifactsDir = visualTest.opts().artifacts || './artifacts';
|
|
190
|
-
const timeout = Number(visualTest.opts().timeout || '30000');
|
|
191
|
-
const compareFile = visualTest.opts().compare;
|
|
192
|
-
const baselineLabel = visualTest.opts().baselineLabel || '前回';
|
|
193
|
-
const currentLabel = visualTest.opts().currentLabel || '今回';
|
|
194
|
-
await withPlaybackProxy({
|
|
195
|
-
inventoryRepository,
|
|
196
|
-
fullThrottle: true,
|
|
197
|
-
}, dependency, async (proxy) => {
|
|
198
|
-
const outputPath = Path.join(artifactsDir, 'capture.png');
|
|
199
|
-
await dependency.mkdirp(artifactsDir);
|
|
200
|
-
await execWebshotCapture({
|
|
201
|
-
url: proxy.entryUrl,
|
|
202
|
-
proxyPort: proxy.port,
|
|
203
|
-
preset: proxy.deviceType === 'desktop' ? 'desktop' : 'mobile',
|
|
204
|
-
output: outputPath,
|
|
205
|
-
timeout,
|
|
206
|
-
}, dependency);
|
|
207
|
-
dependency.logger?.info(`Screenshot saved to ${outputPath}`);
|
|
208
|
-
if (compareFile) {
|
|
209
|
-
const diffOutput = Path.join(artifactsDir, 'capture-diff.png');
|
|
210
|
-
const digestTxt = Path.join(artifactsDir, 'capture-diff.txt');
|
|
211
|
-
await execWebshotCompare({
|
|
212
|
-
baseline: compareFile,
|
|
213
|
-
current: outputPath,
|
|
214
|
-
output: diffOutput,
|
|
215
|
-
digestTxt,
|
|
216
|
-
baselineLabel,
|
|
217
|
-
currentLabel,
|
|
218
|
-
}, dependency);
|
|
219
|
-
dependency.logger?.info(`Diff image saved to ${diffOutput}`);
|
|
220
|
-
dependency.logger?.info(`Diff digest saved to ${digestTxt}`);
|
|
221
|
-
}
|
|
222
|
-
});
|
|
223
|
-
});
|
|
224
|
-
}
|
|
225
|
-
registerLighthouseCommands(main);
|
|
226
|
-
registerLoadshowCommands(main);
|
|
227
|
-
registerProxyCommands(main);
|
|
228
|
-
registerCaptureCommands(main);
|
|
229
|
-
main.parse(process.argv);
|
|
230
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbWFuZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb21tYW5kLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFFQSxPQUFPLElBQUksTUFBTSxNQUFNLENBQUE7QUFFdkIsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFdBQVcsQ0FBQTtBQUNuQyxPQUFPLEtBQUssTUFBTSxZQUFZLENBQUE7QUFFOUIsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGlCQUFpQixDQUFBO0FBQzVDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQTtBQUNoRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFBO0FBRTVDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGNBQWMsQ0FBQTtBQUVyRSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsaUJBQWlCLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxZQUFZLENBQUE7QUFFdkYsTUFBTSxVQUFVLEdBQUcsSUFBSSxVQUFVLEVBQUUsQ0FBQTtBQUVuQyxTQUFTLE9BQU8sQ0FBQyxLQUFhLEVBQUUsUUFBa0I7SUFDaEQsT0FBTyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQTtBQUNqQyxDQUFDO0FBRUQsTUFBTSxJQUFJLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQTtBQUMxQixJQUFJLENBQUMsTUFBTSxDQUFDLHVCQUF1QixFQUFFLHFCQUFxQixFQUFFLGFBQWEsQ0FBQyxDQUFBO0FBRTFFLFNBQVMsMEJBQTBCLENBQUMsSUFBYTtJQUMvQyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxDQUFBO0lBQzdDLFVBQVUsQ0FBQyxXQUFXLENBQUMsbURBQW1ELENBQUMsQ0FBQTtJQUMzRSxVQUFVLENBQUMsTUFBTSxDQUFDLHVCQUF1QixFQUFFLHFCQUFxQixFQUFFLGFBQWEsQ0FBQyxDQUFBO0lBQ2hGLFVBQVUsQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLG1EQUFtRCxFQUFFLEtBQUssQ0FBQyxDQUFBO0lBQzNGLFVBQVUsQ0FBQyxNQUFNLENBQUMsb0JBQW9CLEVBQUUsc0JBQXNCLEVBQUUsT0FBTyxDQUFDLENBQUE7SUFFeEUsTUFBTSxTQUFTLEdBQUcsVUFBVSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQTtJQUNqRCxTQUFTLENBQUMsV0FBVyxDQUFDLCtCQUErQixDQUFDLENBQUE7SUFDdEQsU0FBUyxDQUFDLE1BQU0sQ0FBQywrQkFBK0IsRUFBRSxhQUFhLEVBQUUsUUFBUSxDQUFDLENBQUE7SUFDMUUsU0FBUyxDQUFDLE1BQU0sQ0FBQyx5QkFBeUIsRUFBRSw0REFBNEQsRUFBRSxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUE7SUFDdEgsU0FBUyxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsNEJBQTRCLENBQUMsQ0FBQTtJQUN6RCxTQUFTLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxHQUFXLEVBQUUsRUFBRTtRQUNyQyxNQUFNLG1CQUFtQixHQUFHLElBQUksbUJBQW1CLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLFNBQVMsSUFBSSxhQUFhLENBQUMsQ0FBQTtRQUMzRixNQUFNLFVBQVUsR0FBZSxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUMsTUFBTSxJQUFJLFFBQVEsQ0FBQTtRQUNsRSxNQUFNLFlBQVksR0FBRyxVQUFVLENBQUMsSUFBSSxFQUFFLENBQUMsU0FBUyxJQUFJLGFBQWEsQ0FBQTtRQUNqRSxNQUFNLElBQUksR0FBRyxDQUFDLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDLElBQUksQ0FBQTtRQUNyQyxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQTtRQUM1RCxNQUFNLGVBQWUsR0FBYSxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUMsT0FBTyxJQUFJLEVBQUUsQ0FBQTtRQUVoRSxNQUFNLGtCQUFrQixDQUN0QjtZQUNFLFFBQVEsRUFBRSxHQUFHO1lBQ2IsVUFBVTtZQUNWLG1CQUFtQjtZQUNuQixlQUFlLEVBQUUsZUFBZSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsU0FBUztTQUMxRSxFQUNELFVBQVUsRUFDVixLQUFLLEVBQUUsS0FBSyxFQUFFLEVBQUU7WUFDZCxNQUFNLGNBQWMsQ0FDbEI7Z0JBQ0UsR0FBRztnQkFDSCxTQUFTLEVBQUUsS0FBSyxDQUFDLElBQUk7Z0JBQ3JCLFVBQVU7Z0JBQ1YsSUFBSSxFQUFFLElBQUk7Z0JBQ1YsWUFBWTtnQkFDWixRQUFRLEVBQUUsQ0FBQyxJQUFJO2dCQUNmLE9BQU87YUFDUixFQUNELFVBQVUsQ0FDWCxDQUFBO1lBQ0QsVUFBVSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsMkNBQTJDLENBQUMsQ0FBQTtRQUN0RSxDQUFDLENBQ0YsQ0FBQTtJQUNILENBQUMsQ0FBQyxDQUFBO0lBRUYsTUFBTSxRQUFRLEdBQUcsVUFBVSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQTtJQUMvQyxRQUFRLENBQUMsV0FBVyxDQUFDLGtDQUFrQyxDQUFDLENBQUE7SUFDeEQsUUFBUSxDQUFDLE1BQU0sQ0FBQyxLQUFLLElBQUksRUFBRTtRQUN6QixNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsU0FBUyxJQUFJLGFBQWEsQ0FBQTtRQUMzRCxNQUFNLG1CQUFtQixHQUFHLElBQUksbUJBQW1CLENBQUMsWUFBWSxDQUFDLENBQUE7UUFDakUsTUFBTSxZQUFZLEdBQUcsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDLFNBQVMsSUFBSSxhQUFhLENBQUE7UUFDakUsTUFBTSxJQUFJLEdBQUcsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUE7UUFDckMsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxPQUFPLElBQUksT0FBTyxDQUFDLENBQUE7UUFFNUQsd0NBQXdDO1FBQ3hDLE1BQU0sU0FBUyxHQUFHLE1BQU0sbUJBQW1CLENBQUMsYUFBYSxFQUFFLENBQUE7UUFFM0QsTUFBTSxpQkFBaUIsQ0FDckI7WUFDRSxtQkFBbUI7U0FDcEIsRUFDRCxVQUFVLEVBQ1YsS0FBSyxFQUFFLEtBQUssRUFBRSxFQUFFO1lBQ2QsTUFBTSxjQUFjLENBQ2xCO2dCQUNFLEdBQUcsRUFBRSxLQUFLLENBQUMsUUFBUTtnQkFDbkIsU0FBUyxFQUFFLEtBQUssQ0FBQyxJQUFJO2dCQUNyQixVQUFVLEVBQUUsS0FBSyxDQUFDLFVBQVU7Z0JBQzVCLElBQUksRUFBRSxJQUFJO2dCQUNWLFlBQVk7Z0JBQ1osUUFBUSxFQUFFLENBQUMsSUFBSTtnQkFDZixPQUFPO2dCQUNQLFlBQVk7Z0JBQ1osU0FBUyxFQUFFLFNBQVMsQ0FBQyxTQUFTO2FBQy9CLEVBQ0QsVUFBVSxDQUNYLENBQUE7WUFDRCxVQUFVLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFBO1FBQ2pELENBQUMsQ0FDRixDQUFBO0lBQ0gsQ0FBQyxDQUFDLENBQUE7QUFDSixDQUFDO0FBRUQsU0FBUyx3QkFBd0IsQ0FBQyxJQUFhO0lBQzdDLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUE7SUFDekMsUUFBUSxDQUFDLFdBQVcsQ0FBQywwQkFBMEIsQ0FBQyxDQUFBO0lBQ2hELFFBQVEsQ0FBQyxNQUFNLENBQUMsdUJBQXVCLEVBQUUscUJBQXFCLEVBQUUsYUFBYSxDQUFDLENBQUE7SUFDOUUsUUFBUSxDQUFDLE1BQU0sQ0FBQyx1QkFBdUIsRUFBRSxlQUFlLENBQUMsQ0FBQTtJQUN6RCxRQUFRLENBQUMsTUFBTSxDQUFDLG9CQUFvQixFQUFFLHNCQUFzQixFQUFFLE9BQU8sQ0FBQyxDQUFBO0lBRXRFLE1BQU0sU0FBUyxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUE7SUFDL0MsU0FBUyxDQUFDLFdBQVcsQ0FBQyw2QkFBNkIsQ0FBQyxDQUFBO0lBQ3BELFNBQVMsQ0FBQyxNQUFNLENBQUMsK0JBQStCLEVBQUUsYUFBYSxFQUFFLFFBQVEsQ0FBQyxDQUFBO0lBQzFFLFNBQVMsQ0FBQyxNQUFNLENBQUMseUJBQXlCLEVBQUUsNERBQTRELEVBQUUsT0FBTyxFQUFFLEVBQUUsQ0FBQyxDQUFBO0lBQ3RILFNBQVMsQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLDRCQUE0QixDQUFDLENBQUE7SUFDekQsU0FBUyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsR0FBVyxFQUFFLEVBQUU7UUFDckMsTUFBTSxtQkFBbUIsR0FBRyxJQUFJLG1CQUFtQixDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxTQUFTLElBQUksYUFBYSxDQUFDLENBQUE7UUFDM0YsTUFBTSxVQUFVLEdBQWUsU0FBUyxDQUFDLElBQUksRUFBRSxDQUFDLE1BQU0sSUFBSSxRQUFRLENBQUE7UUFDbEUsTUFBTSxZQUFZLEdBQUcsUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDLFNBQVMsSUFBSSxhQUFhLENBQUE7UUFDL0QsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDLE1BQU0sSUFBSSxFQUFFLENBQUE7UUFDM0MsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxPQUFPLElBQUksT0FBTyxDQUFDLENBQUE7UUFDMUQsTUFBTSxlQUFlLEdBQWEsU0FBUyxDQUFDLElBQUksRUFBRSxDQUFDLE9BQU8sSUFBSSxFQUFFLENBQUE7UUFFaEUsTUFBTSxrQkFBa0IsQ0FDdEI7WUFDRSxRQUFRLEVBQUUsR0FBRztZQUNiLFVBQVU7WUFDVixtQkFBbUI7WUFDbkIsZUFBZSxFQUFFLGVBQWUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLFNBQVM7U0FDMUUsRUFDRCxVQUFVLEVBQ1YsS0FBSyxFQUFFLEtBQUssRUFBRSxFQUFFO1lBQ2QsTUFBTSxZQUFZLENBQUMsRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLEVBQUUsVUFBVSxDQUFDLENBQUE7WUFDekcsVUFBVSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMseUNBQXlDLENBQUMsQ0FBQTtRQUNwRSxDQUFDLENBQ0YsQ0FBQTtJQUNILENBQUMsQ0FBQyxDQUFBO0lBRUYsTUFBTSxRQUFRLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQTtJQUM3QyxRQUFRLENBQUMsV0FBVyxDQUFDLGdDQUFnQyxDQUFDLENBQUE7SUFDdEQsUUFBUSxDQUFDLE1BQU0sQ0FBQyxLQUFLLElBQUksRUFBRTtRQUN6QixNQUFNLG1CQUFtQixHQUFHLElBQUksbUJBQW1CLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLFNBQVMsSUFBSSxhQUFhLENBQUMsQ0FBQTtRQUMzRixNQUFNLFlBQVksR0FBRyxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUMsU0FBUyxJQUFJLGFBQWEsQ0FBQTtRQUMvRCxNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUMsTUFBTSxJQUFJLEVBQUUsQ0FBQTtRQUMzQyxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQTtRQUUxRCxNQUFNLGlCQUFpQixDQUNyQjtZQUNFLG1CQUFtQjtTQUNwQixFQUNELFVBQVUsRUFDVixLQUFLLEVBQUUsS0FBSyxFQUFFLEVBQUU7WUFDZCxNQUFNLFlBQVksQ0FDaEI7Z0JBQ0UsR0FBRyxFQUFFLEtBQUssQ0FBQyxRQUFRO2dCQUNuQixTQUFTLEVBQUUsS0FBSyxDQUFDLElBQUk7Z0JBQ3JCLFVBQVUsRUFBRSxLQUFLLENBQUMsVUFBVTtnQkFDNUIsWUFBWTtnQkFDWixNQUFNO2dCQUNOLE9BQU87YUFDUixFQUNELFVBQVUsQ0FDWCxDQUFBO1lBQ0QsVUFBVSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsb0JBQW9CLENBQUMsQ0FBQTtRQUMvQyxDQUFDLENBQ0YsQ0FBQTtJQUNILENBQUMsQ0FBQyxDQUFBO0FBQ0osQ0FBQztBQUVELFNBQVMscUJBQXFCLENBQUMsSUFBYTtJQUMxQyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFBO0lBQ25DLEtBQUssQ0FBQyxNQUFNLENBQUMscUJBQXFCLEVBQUUsWUFBWSxFQUFFLE1BQU0sQ0FBQyxDQUFBO0lBQ3pELEtBQUssQ0FBQyxNQUFNLENBQUMsb0JBQW9CLEVBQUUsb0RBQW9ELEVBQUUsRUFBRSxDQUFDLENBQUE7SUFDNUYsS0FBSyxDQUFDLE1BQU0sQ0FBQyx5QkFBeUIsRUFBRSw0REFBNEQsRUFBRSxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUE7SUFFbEgsS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLElBQUksRUFBRTtRQUN0QixNQUFNLG1CQUFtQixHQUFHLElBQUksbUJBQW1CLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLFNBQVMsSUFBSSxhQUFhLENBQUMsQ0FBQTtRQUMzRixNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDLElBQUksSUFBSSxNQUFNLENBQUMsQ0FBQTtRQUVoRCxJQUFJLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUN4QixNQUFNLEdBQUcsR0FBRyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsTUFBTSxDQUFBO1lBQy9CLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztnQkFDVCxNQUFNLElBQUksS0FBSyxDQUFDLHVEQUF1RCxDQUFDLENBQUE7WUFDMUUsQ0FBQztZQUVELE1BQU0sZUFBZSxHQUFhLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxPQUFPLElBQUksRUFBRSxDQUFBO1lBRTVELGVBQWU7WUFDZixNQUFNLGtCQUFrQixDQUN0QjtnQkFDRSxtQkFBbUI7Z0JBQ25CLElBQUk7Z0JBQ0osUUFBUSxFQUFFLEdBQUc7Z0JBQ2IsZUFBZSxFQUFFLGVBQWUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLFNBQVM7YUFDMUUsRUFDRCxVQUFVLEVBQ1YsS0FBSyxJQUFJLEVBQUU7Z0JBQ1QsVUFBVSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsbUNBQW1DLElBQUkseUJBQXlCLENBQUMsQ0FBQTtnQkFFekYseUJBQXlCO2dCQUN6QixPQUFPLElBQUksT0FBTyxDQUFPLENBQUMsT0FBTyxFQUFFLEVBQUU7b0JBQ25DLE9BQU8sQ0FBQyxFQUFFLENBQUMsUUFBUSxFQUFFLEdBQUcsRUFBRTt3QkFDeEIsVUFBVSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMseUJBQXlCLENBQUMsQ0FBQTt3QkFDbEQsT0FBTyxFQUFFLENBQUE7b0JBQ1gsQ0FBQyxDQUFDLENBQUE7Z0JBQ0osQ0FBQyxDQUFDLENBQUE7WUFDSixDQUFDLENBQ0YsQ0FBQTtRQUNILENBQUM7YUFBTSxDQUFDO1lBQ04sY0FBYztZQUNkLGlEQUFpRDtZQUNqRCxPQUFPLElBQUksRUFBRSxDQUFDO2dCQUNaLE1BQU0saUJBQWlCLENBQUMsRUFBRSxtQkFBbUIsRUFBRSxJQUFJLEVBQUUsRUFBRSxVQUFVLEVBQUUsS0FBSyxJQUFJLEVBQUU7b0JBQzVFLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxPQUFPLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQTtvQkFDdkUsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFO3dCQUN4QixPQUFPLENBQUMsRUFBRSxDQUFDLFFBQVEsRUFBRSxHQUFHLEVBQUU7NEJBQ3hCLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQTs0QkFDZixVQUFVLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFBOzRCQUNqRSxFQUFFLEVBQUUsQ0FBQTt3QkFDTixDQUFDLENBQUMsQ0FBQTtvQkFDSixDQUFDLENBQUMsQ0FBQTtnQkFDSixDQUFDLENBQUMsQ0FBQTtZQUNKLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUE7QUFDSixDQUFDO0FBRUQsU0FBUyx1QkFBdUIsQ0FBQyxJQUFhO0lBQzVDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUE7SUFDMUMsVUFBVSxDQUFDLFdBQVcsQ0FBQyxnRkFBZ0YsQ0FBQyxDQUFBO0lBQ3hHLFVBQVUsQ0FBQyxNQUFNLENBQUMsdUJBQXVCLEVBQUUscUJBQXFCLEVBQUUsYUFBYSxDQUFDLENBQUE7SUFDaEYsVUFBVSxDQUFDLE1BQU0sQ0FBQyxvQkFBb0IsRUFBRSxzQkFBc0IsRUFBRSxPQUFPLENBQUMsQ0FBQTtJQUN4RSxVQUFVLENBQUMsTUFBTSxDQUFDLGtCQUFrQixFQUFFLHNDQUFzQyxDQUFDLENBQUE7SUFDN0UsVUFBVSxDQUFDLE1BQU0sQ0FBQywwQkFBMEIsRUFBRSw4QkFBOEIsRUFBRSxJQUFJLENBQUMsQ0FBQTtJQUNuRixVQUFVLENBQUMsTUFBTSxDQUFDLHlCQUF5QixFQUFFLDZCQUE2QixFQUFFLElBQUksQ0FBQyxDQUFBO0lBRWpGLFVBQVUsQ0FBQyxNQUFNLENBQUMsS0FBSyxJQUFJLEVBQUU7UUFDM0IsTUFBTSxtQkFBbUIsR0FBRyxJQUFJLG1CQUFtQixDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxTQUFTLElBQUksYUFBYSxDQUFDLENBQUE7UUFDM0YsTUFBTSxZQUFZLEdBQUcsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDLFNBQVMsSUFBSSxhQUFhLENBQUE7UUFDakUsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxPQUFPLElBQUksT0FBTyxDQUFDLENBQUE7UUFDNUQsTUFBTSxXQUFXLEdBQUcsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDLE9BQTZCLENBQUE7UUFDbkUsTUFBTSxhQUFhLEdBQUcsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDLGFBQWEsSUFBSSxJQUFJLENBQUE7UUFDN0QsTUFBTSxZQUFZLEdBQUcsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDLFlBQVksSUFBSSxJQUFJLENBQUE7UUFFM0QsTUFBTSxpQkFBaUIsQ0FDckI7WUFDRSxtQkFBbUI7WUFDbkIsWUFBWSxFQUFFLElBQUk7U0FDbkIsRUFDRCxVQUFVLEVBQ1YsS0FBSyxFQUFFLEtBQUssRUFBRSxFQUFFO1lBQ2QsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsYUFBYSxDQUFDLENBQUE7WUFFekQsTUFBTSxVQUFVLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFBO1lBRXJDLE1BQU0sa0JBQWtCLENBQ3RCO2dCQUNFLEdBQUcsRUFBRSxLQUFLLENBQUMsUUFBUTtnQkFDbkIsU0FBUyxFQUFFLEtBQUssQ0FBQyxJQUFJO2dCQUNyQixNQUFNLEVBQUUsS0FBSyxDQUFDLFVBQVUsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsUUFBUTtnQkFDN0QsTUFBTSxFQUFFLFVBQVU7Z0JBQ2xCLE9BQU87YUFDUixFQUNELFVBQVUsQ0FDWCxDQUFBO1lBQ0QsVUFBVSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsdUJBQXVCLFVBQVUsRUFBRSxDQUFDLENBQUE7WUFFNUQsSUFBSSxXQUFXLEVBQUUsQ0FBQztnQkFDaEIsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsa0JBQWtCLENBQUMsQ0FBQTtnQkFDOUQsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsa0JBQWtCLENBQUMsQ0FBQTtnQkFFN0QsTUFBTSxrQkFBa0IsQ0FDdEI7b0JBQ0UsUUFBUSxFQUFFLFdBQVc7b0JBQ3JCLE9BQU8sRUFBRSxVQUFVO29CQUNuQixNQUFNLEVBQUUsVUFBVTtvQkFDbEIsU0FBUztvQkFDVCxhQUFhO29CQUNiLFlBQVk7aUJBQ2IsRUFDRCxVQUFVLENBQ1gsQ0FBQTtnQkFDRCxVQUFVLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyx1QkFBdUIsVUFBVSxFQUFFLENBQUMsQ0FBQTtnQkFDNUQsVUFBVSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsd0JBQXdCLFNBQVMsRUFBRSxDQUFDLENBQUE7WUFDOUQsQ0FBQztRQUNILENBQUMsQ0FDRixDQUFBO0lBQ0gsQ0FBQyxDQUFDLENBQUE7QUFDSixDQUFDO0FBRUQsMEJBQTBCLENBQUMsSUFBSSxDQUFDLENBQUE7QUFDaEMsd0JBQXdCLENBQUMsSUFBSSxDQUFDLENBQUE7QUFDOUIscUJBQXFCLENBQUMsSUFBSSxDQUFDLENBQUE7QUFDM0IsdUJBQXVCLENBQUMsSUFBSSxDQUFDLENBQUE7QUFFN0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUEifQ==
|
|
2
|
+
import { createProgram } from './cli.js';
|
|
3
|
+
createProgram().parse(process.argv);
|
|
4
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbWFuZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb21tYW5kLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFFQSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sVUFBVSxDQUFBO0FBRXhDLGFBQWEsRUFBRSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUEifQ==
|
|
@@ -9,6 +9,9 @@ export interface LighthouseAudit {
|
|
|
9
9
|
score: number | null;
|
|
10
10
|
numericValue?: number;
|
|
11
11
|
displayValue?: string;
|
|
12
|
+
details?: {
|
|
13
|
+
items?: unknown[];
|
|
14
|
+
};
|
|
12
15
|
}
|
|
13
16
|
/**
|
|
14
17
|
* Lighthouse JSON report structure (partial)
|
|
@@ -26,7 +29,6 @@ export interface LighthouseReport {
|
|
|
26
29
|
export interface GenerateLighthouseSummaryInput {
|
|
27
30
|
jsonPath: string;
|
|
28
31
|
outputPath: string;
|
|
29
|
-
inventoryDir?: string;
|
|
30
32
|
resources?: Resource[];
|
|
31
33
|
}
|
|
32
34
|
/**
|
|
@@ -12,9 +12,21 @@ const PERFORMANCE_METRICS = [
|
|
|
12
12
|
{ id: 'speed-index', abbr: 'SI', unit: 'ms', weight: 0.1 },
|
|
13
13
|
];
|
|
14
14
|
/**
|
|
15
|
-
* Maps
|
|
15
|
+
* Maps a Lighthouse request to a resource type category
|
|
16
16
|
*/
|
|
17
|
-
function getResourceType(mime) {
|
|
17
|
+
function getResourceType(resourceType, mime) {
|
|
18
|
+
switch (resourceType) {
|
|
19
|
+
case 'Document':
|
|
20
|
+
return 'document';
|
|
21
|
+
case 'Stylesheet':
|
|
22
|
+
return 'stylesheet';
|
|
23
|
+
case 'Script':
|
|
24
|
+
return 'script';
|
|
25
|
+
case 'Image':
|
|
26
|
+
return 'image';
|
|
27
|
+
case 'Font':
|
|
28
|
+
return 'font';
|
|
29
|
+
}
|
|
18
30
|
if (!mime)
|
|
19
31
|
return 'other';
|
|
20
32
|
if (mime.includes('html'))
|
|
@@ -41,57 +53,30 @@ function formatBytes(bytes) {
|
|
|
41
53
|
return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
|
|
42
54
|
}
|
|
43
55
|
/**
|
|
44
|
-
* Calculates traffic statistics by resource type
|
|
56
|
+
* Calculates traffic statistics by resource type from what the browser
|
|
57
|
+
* actually received in this run (Lighthouse's `network-requests` audit)
|
|
45
58
|
*/
|
|
46
|
-
|
|
59
|
+
function calculateResourceStats(report) {
|
|
47
60
|
const statsMap = new Map();
|
|
48
61
|
// Initialize all resource types
|
|
49
62
|
const types = ['document', 'stylesheet', 'script', 'image', 'font', 'other'];
|
|
50
63
|
for (const type of types) {
|
|
51
64
|
statsMap.set(type, { type, count: 0, trafficSize: 0, resourceSize: 0 });
|
|
52
65
|
}
|
|
53
|
-
|
|
54
|
-
|
|
66
|
+
const items = (report.audits?.['network-requests']?.details?.items ?? []);
|
|
67
|
+
for (const item of items) {
|
|
68
|
+
// data: and blob: URLs never crossed the network
|
|
69
|
+
if (!item.url || !/^https?:/.test(item.url))
|
|
55
70
|
continue;
|
|
56
|
-
const
|
|
57
|
-
const stat = statsMap.get(type);
|
|
71
|
+
const stat = statsMap.get(getResourceType(item.resourceType, item.mimeType));
|
|
58
72
|
if (!stat)
|
|
59
73
|
continue;
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const resourceSize = fileStat.size;
|
|
64
|
-
// Traffic size: if content-encoding exists, estimate compressed size
|
|
65
|
-
// Otherwise use resource size
|
|
66
|
-
// Note: The file is stored decompressed, so we estimate traffic size
|
|
67
|
-
// based on typical compression ratios for each type
|
|
68
|
-
let trafficSize = resourceSize;
|
|
69
|
-
if (resource.contentEncoding) {
|
|
70
|
-
// For compressed resources, estimate traffic size based on typical ratios
|
|
71
|
-
// These are rough estimates - actual values would require re-compression
|
|
72
|
-
const compressionRatios = {
|
|
73
|
-
document: 0.2,
|
|
74
|
-
stylesheet: 0.15,
|
|
75
|
-
script: 0.25,
|
|
76
|
-
image: 0.95, // Images are usually already compressed
|
|
77
|
-
font: 0.7,
|
|
78
|
-
other: 0.5,
|
|
79
|
-
};
|
|
80
|
-
trafficSize = Math.round(resourceSize * compressionRatios[type]);
|
|
81
|
-
}
|
|
82
|
-
stat.count++;
|
|
83
|
-
stat.trafficSize += trafficSize;
|
|
84
|
-
stat.resourceSize += resourceSize;
|
|
85
|
-
}
|
|
86
|
-
catch {
|
|
87
|
-
// File not found or other error - skip
|
|
88
|
-
}
|
|
74
|
+
stat.count++;
|
|
75
|
+
stat.trafficSize += item.transferSize ?? 0;
|
|
76
|
+
stat.resourceSize += item.resourceSize ?? 0;
|
|
89
77
|
}
|
|
90
78
|
// Filter out types with no resources and sort by fixed order
|
|
91
|
-
const
|
|
92
|
-
const stats = Array.from(statsMap.values())
|
|
93
|
-
.filter((s) => s.count > 0)
|
|
94
|
-
.sort((a, b) => typeOrder.indexOf(a.type) - typeOrder.indexOf(b.type));
|
|
79
|
+
const stats = types.map((type) => statsMap.get(type)).filter((s) => s.count > 0);
|
|
95
80
|
const totals = stats.reduce((acc, s) => ({
|
|
96
81
|
trafficSize: acc.trafficSize + s.trafficSize,
|
|
97
82
|
resourceSize: acc.resourceSize + s.resourceSize,
|
|
@@ -158,10 +143,10 @@ export async function generateLighthouseSummary(opts, dependency) {
|
|
|
158
143
|
lines.push(`- **Overall** ${formatScore(overallScore)}`);
|
|
159
144
|
lines.push('');
|
|
160
145
|
// Section 3: Resource Traffic (if inventory data is provided)
|
|
161
|
-
if (opts.resources
|
|
162
|
-
const { stats, totals } =
|
|
146
|
+
if (opts.resources) {
|
|
147
|
+
const { stats, totals } = calculateResourceStats(report);
|
|
163
148
|
if (stats.length > 0) {
|
|
164
|
-
// Traffic section (
|
|
149
|
+
// Traffic section (bytes received, after compression and headers)
|
|
165
150
|
lines.push('## Traffic: Type / Count / Size / Bytes');
|
|
166
151
|
lines.push('');
|
|
167
152
|
for (const stat of stats) {
|
|
@@ -169,7 +154,7 @@ export async function generateLighthouseSummary(opts, dependency) {
|
|
|
169
154
|
}
|
|
170
155
|
lines.push(`- **total** / ${stats.reduce((sum, s) => sum + s.count, 0)} / ${formatBytes(totals.trafficSize)} / ${totals.trafficSize}`);
|
|
171
156
|
lines.push('');
|
|
172
|
-
// Resource section (
|
|
157
|
+
// Resource section (decoded body size)
|
|
173
158
|
lines.push('## Resource: Type / Count / Size / Bytes');
|
|
174
159
|
lines.push('');
|
|
175
160
|
for (const stat of stats) {
|
|
@@ -186,4 +171,4 @@ export async function generateLighthouseSummary(opts, dependency) {
|
|
|
186
171
|
await fs.writeFile(opts.outputPath, lines.join('\n'), 'utf-8');
|
|
187
172
|
dependency.logger?.info(`Lighthouse summary saved to ${opts.outputPath}`);
|
|
188
173
|
}
|
|
189
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
174
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlnaHRob3VzZS1zdW1tYXJ5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2xpZ2h0aG91c2Utc3VtbWFyeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxhQUFhLENBQUE7QUFDNUIsT0FBTyxJQUFJLE1BQU0sTUFBTSxDQUFBO0FBK0J2Qjs7O0dBR0c7QUFDSCxNQUFNLG1CQUFtQixHQUFHO0lBQzFCLEVBQUUsRUFBRSxFQUFFLDBCQUEwQixFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO0lBQ3pFLEVBQUUsRUFBRSxFQUFFLHlCQUF5QixFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO0lBQ3RFLEVBQUUsRUFBRSxFQUFFLHFCQUFxQixFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFO0lBQ25FLEVBQUUsRUFBRSxFQUFFLHdCQUF3QixFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFO0lBQ3RFLEVBQUUsRUFBRSxFQUFFLGFBQWEsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRTtDQUMzRCxDQUFBO0FBb0NEOztHQUVHO0FBQ0gsU0FBUyxlQUFlLENBQUMsWUFBZ0MsRUFBRSxJQUF3QjtJQUNqRixRQUFRLFlBQVksRUFBRSxDQUFDO1FBQ3JCLEtBQUssVUFBVTtZQUNiLE9BQU8sVUFBVSxDQUFBO1FBQ25CLEtBQUssWUFBWTtZQUNmLE9BQU8sWUFBWSxDQUFBO1FBQ3JCLEtBQUssUUFBUTtZQUNYLE9BQU8sUUFBUSxDQUFBO1FBQ2pCLEtBQUssT0FBTztZQUNW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
|
package/build/lighthouse.d.ts
CHANGED
|
@@ -9,7 +9,6 @@ export interface ExecLighthouseInput {
|
|
|
9
9
|
headless: boolean;
|
|
10
10
|
timeout: number;
|
|
11
11
|
captureScoreAndMetrics?: boolean;
|
|
12
|
-
inventoryDir?: string;
|
|
13
12
|
resources?: Resource[];
|
|
14
13
|
}
|
|
15
14
|
export declare function execLighthouse(opts: ExecLighthouseInput, dependency: Pick<DependencyInterface, 'mkdirp' | 'executeLighthouse' | 'logger'>): Promise<void>;
|
package/build/lighthouse.js
CHANGED
|
@@ -15,7 +15,12 @@ export async function execLighthouse(opts, dependency) {
|
|
|
15
15
|
`--form-factor=${deviceType}`,
|
|
16
16
|
// Set screen emulation to match form factor
|
|
17
17
|
`--screenEmulation.mobile=${deviceType === 'mobile' ? 'true' : 'false'}`,
|
|
18
|
+
// Report the load as observed. The proxy already reproduces each resource's
|
|
19
|
+
// timing; Lighthouse's default 'simulate' method would discard that and
|
|
20
|
+
// re-derive the metrics from its own network model, which ignores the proxy.
|
|
21
|
+
'--throttling-method=provided',
|
|
18
22
|
// Disable throttling as Rust proxy handles timing accurately
|
|
23
|
+
'--throttling.requestLatencyMs=0',
|
|
19
24
|
'--throttling.rttMs=0',
|
|
20
25
|
'--throttling.throughputKbps=0',
|
|
21
26
|
'--throttling.downloadThroughputKbps=0',
|
|
@@ -52,7 +57,6 @@ export async function execLighthouse(opts, dependency) {
|
|
|
52
57
|
await generateLighthouseSummary({
|
|
53
58
|
jsonPath,
|
|
54
59
|
outputPath: summaryPath,
|
|
55
|
-
inventoryDir: opts.inventoryDir,
|
|
56
60
|
resources: opts.resources,
|
|
57
61
|
}, dependency);
|
|
58
62
|
}
|
|
@@ -61,4 +65,4 @@ export async function execLighthouse(opts, dependency) {
|
|
|
61
65
|
}
|
|
62
66
|
}
|
|
63
67
|
}
|
|
64
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
68
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlnaHRob3VzZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9saWdodGhvdXNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sSUFBSSxNQUFNLE1BQU0sQ0FBQTtBQUd2QixPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQTtBQUNoRSxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQTtBQWVuRSxNQUFNLENBQUMsS0FBSyxVQUFVLGNBQWMsQ0FDbEMsSUFBeUIsRUFDekIsVUFBZ0Y7SUFFaEYsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLFlBQVksSUFBSSxhQUFhLENBQUE7SUFDdkQsTUFBTSxVQUFVLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFBO0lBRXJDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLElBQUksUUFBUSxDQUFBO0lBQzlDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLFlBQVksQ0FBQyxDQUFBO0lBQ3hELE1BQU0sSUFBSSxHQUFhO1FBQ3JCLElBQUksQ0FBQyxHQUFHO1FBQ1IsZUFBZTtRQUNmLG9CQUFvQjtRQUNwQixpQkFBaUIsVUFBVSxFQUFFO1FBQzdCLCtCQUErQjtRQUMvQixpQkFBaUIsVUFBVSxFQUFFO1FBQzdCLDRDQUE0QztRQUM1Qyw0QkFBNEIsVUFBVSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUU7UUFDeEUsNEVBQTRFO1FBQzVFLHdFQUF3RTtRQUN4RSw2RUFBNkU7UUFDN0UsOEJBQThCO1FBQzlCLDZEQUE2RDtRQUM3RCxpQ0FBaUM7UUFDakMsc0JBQXNCO1FBQ3RCLCtCQUErQjtRQUMvQix1Q0FBdUM7UUFDdkMscUNBQXFDO1FBQ3JDLHNDQUFzQztLQUN2QyxDQUFBO0lBRUQsSUFBSSxDQUFDLElBQUksQ0FBQyx1QkFBdUIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUE7SUFFaEQsTUFBTSxXQUFXLEdBQWEsQ0FBQyw2QkFBNkIsRUFBRSxtQ0FBbUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUE7SUFDbEgsSUFBSSxJQUFJLENBQUMsUUFBUTtRQUFFLFdBQVcsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUE7SUFDakQsSUFBSSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsV0FBVyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUE7SUFFcEQsSUFBSSxJQUFJLENBQUMsSUFBSTtRQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUE7SUFFbEMsTUFBTSxVQUFVLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLENBQUE7SUFFeEMsb0RBQW9EO0lBQ3BELElBQUksSUFBSSxDQUFDLHNCQUFzQixLQUFLLEtBQUssRUFBRSxDQUFDO1FBQzFDLE1BQU0sUUFBUSxHQUFHLEdBQUcsVUFBVSxjQUFjLENBQUE7UUFDNUMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsdUJBQXVCLENBQUMsQ0FBQTtRQUVuRSxJQUFJLENBQUM7WUFDSCxNQUFNLHVCQUF1QixDQUMzQjtnQkFDRSxRQUFRO2dCQUNSLFVBQVUsRUFBRSxVQUFVO2FBQ3ZCLEVBQ0QsVUFBVSxDQUNYLENBQUE7UUFDSCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLFVBQVUsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLG1EQUFtRCxLQUFLLEVBQUUsQ0FBQyxDQUFBO1FBQ3JGLENBQUM7SUFDSCxDQUFDO0lBRUQsNEJBQTRCO0lBQzVCLElBQUksSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3RCLE1BQU0sUUFBUSxHQUFHLEdBQUcsVUFBVSxjQUFjLENBQUE7UUFDNUMsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsWUFBWSxDQUFDLENBQUE7UUFFekQsSUFBSSxDQUFDO1lBQ0gsTUFBTSx5QkFBeUIsQ0FDN0I7Z0JBQ0UsUUFBUTtnQkFDUixVQUFVLEVBQUUsV0FBVztnQkFDdkIsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTO2FBQzFCLEVBQ0QsVUFBVSxDQUNYLENBQUE7UUFDSCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLFVBQVUsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLDBDQUEwQyxLQUFLLEVBQUUsQ0FBQyxDQUFBO1FBQzVFLENBQUM7SUFDSCxDQUFDO0FBQ0gsQ0FBQyJ9
|
package/build/llm.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Directory holding the single source of knowledge served to AI agents.
|
|
3
|
+
*
|
|
4
|
+
* The Markdown files are shipped with the npm package (see the `files` field in
|
|
5
|
+
* package.json) so that `psq llm` works offline and always matches the version
|
|
6
|
+
* of the package that is installed. They are also what context7 crawls.
|
|
7
|
+
*/
|
|
8
|
+
export declare const LlmDocsDir: string;
|
|
9
|
+
/** Version of the installed package, used by `psq --version`. */
|
|
10
|
+
export declare function packageVersion(): string;
|
|
11
|
+
export interface LlmDocChapter {
|
|
12
|
+
/** File name without the numeric prefix and extension, e.g. `guide` */
|
|
13
|
+
name: string;
|
|
14
|
+
/** First level-1 heading of the chapter */
|
|
15
|
+
title: string;
|
|
16
|
+
/** Markdown body, heading included */
|
|
17
|
+
content: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function loadLlmDocs(dir?: string): Promise<LlmDocChapter[]>;
|
|
20
|
+
export declare function renderLlmDocs(format?: 'markdown' | 'json', dir?: string): Promise<string>;
|
package/build/llm.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import Fs from 'fs';
|
|
2
|
+
import Fsp from 'fs/promises';
|
|
3
|
+
import Path from 'path';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = Path.dirname(__filename);
|
|
7
|
+
/**
|
|
8
|
+
* Directory holding the single source of knowledge served to AI agents.
|
|
9
|
+
*
|
|
10
|
+
* The Markdown files are shipped with the npm package (see the `files` field in
|
|
11
|
+
* package.json) so that `psq llm` works offline and always matches the version
|
|
12
|
+
* of the package that is installed. They are also what context7 crawls.
|
|
13
|
+
*/
|
|
14
|
+
export const LlmDocsDir = Path.resolve(__dirname, '..', 'llmdocs');
|
|
15
|
+
/** Version of the installed package, used by `psq --version`. */
|
|
16
|
+
export function packageVersion() {
|
|
17
|
+
const packageJsonPath = Path.resolve(__dirname, '..', 'package.json');
|
|
18
|
+
const packageJson = JSON.parse(Fs.readFileSync(packageJsonPath, 'utf8'));
|
|
19
|
+
return packageJson.version;
|
|
20
|
+
}
|
|
21
|
+
function titleOf(markdown, fallback) {
|
|
22
|
+
const heading = markdown.split(/\r?\n/).find((line) => line.startsWith('# '));
|
|
23
|
+
return heading ? heading.slice(2).trim() : fallback;
|
|
24
|
+
}
|
|
25
|
+
export async function loadLlmDocs(dir = LlmDocsDir) {
|
|
26
|
+
const entries = await Fsp.readdir(dir);
|
|
27
|
+
const files = entries.filter((name) => name.endsWith('.md')).sort();
|
|
28
|
+
const chapters = [];
|
|
29
|
+
for (const file of files) {
|
|
30
|
+
const content = await Fsp.readFile(Path.join(dir, file), 'utf8');
|
|
31
|
+
const name = Path.basename(file, '.md').replace(/^\d+-/, '');
|
|
32
|
+
chapters.push({ name, title: titleOf(content, name), content: content.trimEnd() });
|
|
33
|
+
}
|
|
34
|
+
return chapters;
|
|
35
|
+
}
|
|
36
|
+
export async function renderLlmDocs(format = 'markdown', dir) {
|
|
37
|
+
const chapters = await loadLlmDocs(dir);
|
|
38
|
+
if (format === 'json')
|
|
39
|
+
return `${JSON.stringify(chapters, null, 2)}\n`;
|
|
40
|
+
return `${chapters.map((chapter) => chapter.content).join('\n\n---\n\n')}\n`;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGxtLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2xsbS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxJQUFJLENBQUE7QUFDbkIsT0FBTyxHQUFHLE1BQU0sYUFBYSxDQUFBO0FBQzdCLE9BQU8sSUFBSSxNQUFNLE1BQU0sQ0FBQTtBQUN2QixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sS0FBSyxDQUFBO0FBRW5DLE1BQU0sVUFBVSxHQUFHLGFBQWEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFBO0FBQ2pELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUE7QUFFMUM7Ozs7OztHQU1HO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQTtBQUVsRSxpRUFBaUU7QUFDakUsTUFBTSxVQUFVLGNBQWM7SUFDNUIsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsSUFBSSxFQUFFLGNBQWMsQ0FBQyxDQUFBO0lBQ3JFLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxlQUFlLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQTtJQUN4RSxPQUFPLFdBQVcsQ0FBQyxPQUFpQixDQUFBO0FBQ3RDLENBQUM7QUFXRCxTQUFTLE9BQU8sQ0FBQyxRQUFnQixFQUFFLFFBQWdCO0lBQ2pELE1BQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUE7SUFDN0UsT0FBTyxPQUFPLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQTtBQUNyRCxDQUFDO0FBRUQsTUFBTSxDQUFDLEtBQUssVUFBVSxXQUFXLENBQUMsTUFBYyxVQUFVO0lBQ3hELE1BQU0sT0FBTyxHQUFHLE1BQU0sR0FBRyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQTtJQUN0QyxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUE7SUFFbkUsTUFBTSxRQUFRLEdBQW9CLEVBQUUsQ0FBQTtJQUNwQyxLQUFLLE1BQU0sSUFBSSxJQUFJLEtBQUssRUFBRSxDQUFDO1FBQ3pCLE1BQU0sT0FBTyxHQUFHLE1BQU0sR0FBRyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQTtRQUNoRSxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxDQUFBO1FBQzVELFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLEVBQUUsT0FBTyxFQUFFLE9BQU8sQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUE7SUFDcEYsQ0FBQztJQUVELE9BQU8sUUFBUSxDQUFBO0FBQ2pCLENBQUM7QUFFRCxNQUFNLENBQUMsS0FBSyxVQUFVLGFBQWEsQ0FBQyxTQUE4QixVQUFVLEVBQUUsR0FBWTtJQUN4RixNQUFNLFFBQVEsR0FBRyxNQUFNLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQTtJQUN2QyxJQUFJLE1BQU0sS0FBSyxNQUFNO1FBQUUsT0FBTyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFBO0lBQ3RFLE9BQU8sR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUE7QUFDOUUsQ0FBQyJ9
|