basecampjs 0.0.13 → 0.0.14
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/dist/build/assets.d.ts +36 -0
- package/dist/build/assets.d.ts.map +1 -0
- package/dist/build/assets.js +272 -0
- package/dist/build/assets.js.map +1 -0
- package/dist/build/data.d.ts +6 -0
- package/dist/build/data.d.ts.map +1 -0
- package/dist/build/data.js +33 -0
- package/dist/build/data.js.map +1 -0
- package/dist/build/pages.d.ts +19 -0
- package/dist/build/pages.d.ts.map +1 -0
- package/dist/build/pages.js +110 -0
- package/dist/build/pages.js.map +1 -0
- package/dist/build/pipeline.d.ts +6 -0
- package/dist/build/pipeline.d.ts.map +1 -0
- package/dist/build/pipeline.js +98 -0
- package/dist/build/pipeline.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +140 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +11 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +60 -0
- package/dist/config.js.map +1 -0
- package/dist/dev/server.d.ts +6 -0
- package/dist/dev/server.d.ts.map +1 -0
- package/dist/dev/server.js +64 -0
- package/dist/dev/server.js.map +1 -0
- package/dist/dev/watcher.d.ts +5 -0
- package/dist/dev/watcher.d.ts.map +1 -0
- package/dist/dev/watcher.js +49 -0
- package/dist/dev/watcher.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/render/engines.d.ts +30 -0
- package/dist/render/engines.d.ts.map +1 -0
- package/dist/render/engines.js +102 -0
- package/dist/render/engines.js.map +1 -0
- package/dist/scaffolding.d.ts +25 -0
- package/dist/scaffolding.d.ts.map +1 -0
- package/dist/scaffolding.js +596 -0
- package/dist/scaffolding.js.map +1 -0
- package/dist/types.d.ts +91 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/fs.d.ts +29 -0
- package/dist/utils/fs.d.ts.map +1 -0
- package/dist/utils/fs.js +104 -0
- package/dist/utils/fs.js.map +1 -0
- package/dist/utils/logger.d.ts +9 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +21 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/paths.d.ts +17 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +55 -0
- package/dist/utils/paths.js.map +1 -0
- package/package.json +36 -6
- package/src/build/assets.ts +314 -0
- package/src/build/data.ts +32 -0
- package/src/build/pages.ts +143 -0
- package/src/build/pipeline.ts +111 -0
- package/src/cli.ts +155 -0
- package/src/config.ts +61 -0
- package/src/dev/server.ts +66 -0
- package/src/dev/watcher.ts +52 -0
- package/src/index.ts +45 -0
- package/src/render/engines.ts +139 -0
- package/src/scaffolding.ts +656 -0
- package/src/types.ts +110 -0
- package/src/utils/fs.ts +109 -0
- package/src/utils/logger.ts +27 -0
- package/src/utils/paths.ts +56 -0
- package/index.js +0 -1532
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { CampsiteConfig, ProcessedImage, AssetMap } from "../types.js";
|
|
2
|
+
interface ImageSettings {
|
|
3
|
+
quality: number;
|
|
4
|
+
formats: string[];
|
|
5
|
+
preserveOriginal: boolean;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Check if an image should be processed for compression
|
|
9
|
+
*/
|
|
10
|
+
export declare function shouldProcessImage(filePath: string, config: CampsiteConfig): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Process a single image file (convert to specified formats)
|
|
13
|
+
*/
|
|
14
|
+
export declare function processImage(inputPath: string, _outDir: string, settings: ImageSettings): Promise<ProcessedImage[]>;
|
|
15
|
+
/**
|
|
16
|
+
* Process all images in output directory
|
|
17
|
+
*/
|
|
18
|
+
export declare function processImages(outDir: string, config: CampsiteConfig): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Minify all CSS files in output directory
|
|
21
|
+
*/
|
|
22
|
+
export declare function minifyCSSFiles(outDir: string): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Minify all HTML files in output directory
|
|
25
|
+
*/
|
|
26
|
+
export declare function minifyHTMLFiles(outDir: string, config: CampsiteConfig): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Add content hashes to CSS and JS filenames for cache busting
|
|
29
|
+
*/
|
|
30
|
+
export declare function cacheBustAssets(outDir: string): Promise<AssetMap>;
|
|
31
|
+
/**
|
|
32
|
+
* Generate sitemap.xml for all HTML files
|
|
33
|
+
*/
|
|
34
|
+
export declare function generateSitemap(outDir: string, siteUrl: string): Promise<string>;
|
|
35
|
+
export {};
|
|
36
|
+
//# sourceMappingURL=assets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../src/build/assets.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,QAAQ,EAAc,MAAM,aAAa,CAAC;AAExF,UAAU,aAAa;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAKpF;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAyCzH;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAqDzF;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAclE;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAuB3F;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAkFvE;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA8CtF"}
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import { readFile, rename, rm, stat, writeFile } from "fs/promises";
|
|
2
|
+
import { basename, dirname, extname, join, relative } from "path";
|
|
3
|
+
import { createHash } from "crypto";
|
|
4
|
+
import { minify as minifyCss } from "csso";
|
|
5
|
+
import { minify as minifyHtml } from "html-minifier-terser";
|
|
6
|
+
import sharp from "sharp";
|
|
7
|
+
import { walkFiles, getExt, formatBytes } from "../utils/fs.js";
|
|
8
|
+
import { kolor } from "../utils/logger.js";
|
|
9
|
+
/**
|
|
10
|
+
* Check if an image should be processed for compression
|
|
11
|
+
*/
|
|
12
|
+
export function shouldProcessImage(filePath, config) {
|
|
13
|
+
if (!config.compressPhotos)
|
|
14
|
+
return false;
|
|
15
|
+
const ext = getExt(filePath);
|
|
16
|
+
const inputFormats = config.compressionSettings?.inputFormats || [".jpg", ".jpeg", ".png"];
|
|
17
|
+
return inputFormats.includes(ext);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Process a single image file (convert to specified formats)
|
|
21
|
+
*/
|
|
22
|
+
export async function processImage(inputPath, _outDir, settings) {
|
|
23
|
+
const ext = extname(inputPath);
|
|
24
|
+
const baseName = basename(inputPath, ext);
|
|
25
|
+
const dir = dirname(inputPath);
|
|
26
|
+
const results = [];
|
|
27
|
+
const quality = settings.quality || 80;
|
|
28
|
+
const formats = settings.formats || [".webp"];
|
|
29
|
+
for (const format of formats) {
|
|
30
|
+
try {
|
|
31
|
+
const outputName = `${baseName}${format}`;
|
|
32
|
+
const outputPath = join(dir, outputName);
|
|
33
|
+
const sharpInstance = sharp(inputPath);
|
|
34
|
+
if (format === ".webp") {
|
|
35
|
+
await sharpInstance.webp({ quality }).toFile(outputPath);
|
|
36
|
+
}
|
|
37
|
+
else if (format === ".avif") {
|
|
38
|
+
await sharpInstance.avif({ quality }).toFile(outputPath);
|
|
39
|
+
}
|
|
40
|
+
else if (format === ".jpg" || format === ".jpeg") {
|
|
41
|
+
await sharpInstance.jpeg({ quality }).toFile(outputPath);
|
|
42
|
+
}
|
|
43
|
+
else if (format === ".png") {
|
|
44
|
+
await sharpInstance.png({ quality }).toFile(outputPath);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
const stats = await stat(outputPath);
|
|
50
|
+
results.push({
|
|
51
|
+
path: outputPath,
|
|
52
|
+
format,
|
|
53
|
+
size: stats.size
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
58
|
+
console.error(kolor.red(`Failed to convert ${basename(inputPath)} to ${format}: ${message}`));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return results;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Process all images in output directory
|
|
65
|
+
*/
|
|
66
|
+
export async function processImages(outDir, config) {
|
|
67
|
+
if (!config.compressPhotos)
|
|
68
|
+
return;
|
|
69
|
+
const settings = {
|
|
70
|
+
quality: config.compressionSettings?.quality || 80,
|
|
71
|
+
formats: config.compressionSettings?.formats || [".webp"],
|
|
72
|
+
preserveOriginal: config.compressionSettings?.preserveOriginal !== false
|
|
73
|
+
};
|
|
74
|
+
console.log(kolor.cyan("🖼️ Processing images..."));
|
|
75
|
+
const files = await walkFiles(outDir);
|
|
76
|
+
const imageFiles = files.filter((file) => shouldProcessImage(file, config));
|
|
77
|
+
if (imageFiles.length === 0) {
|
|
78
|
+
console.log(kolor.dim("No images found to process"));
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
let totalGenerated = 0;
|
|
82
|
+
let totalOriginalSize = 0;
|
|
83
|
+
let totalConvertedSize = 0;
|
|
84
|
+
await Promise.all(imageFiles.map(async (file) => {
|
|
85
|
+
const originalStats = await stat(file);
|
|
86
|
+
totalOriginalSize += originalStats.size;
|
|
87
|
+
const results = await processImage(file, outDir, settings);
|
|
88
|
+
if (results.length > 0) {
|
|
89
|
+
const formats = results.map(r => r.format.slice(1)).join(", ");
|
|
90
|
+
const rel = relative(outDir, file);
|
|
91
|
+
console.log(kolor.dim(` ${rel} → ${formats}`));
|
|
92
|
+
results.forEach(r => {
|
|
93
|
+
totalConvertedSize += r.size;
|
|
94
|
+
totalGenerated++;
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
// Remove original if preserveOriginal is false
|
|
98
|
+
if (!settings.preserveOriginal && results.length > 0) {
|
|
99
|
+
await rm(file, { force: true });
|
|
100
|
+
}
|
|
101
|
+
}));
|
|
102
|
+
const savedBytes = totalOriginalSize - totalConvertedSize;
|
|
103
|
+
const savedPercent = totalOriginalSize > 0 ? ((savedBytes / totalOriginalSize) * 100).toFixed(1) : 0;
|
|
104
|
+
console.log(kolor.green(`✓ Generated ${totalGenerated} image(s)`));
|
|
105
|
+
if (!settings.preserveOriginal) {
|
|
106
|
+
console.log(kolor.green(` Saved ${formatBytes(savedBytes)} (${savedPercent}% reduction)`));
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Minify all CSS files in output directory
|
|
111
|
+
*/
|
|
112
|
+
export async function minifyCSSFiles(outDir) {
|
|
113
|
+
const files = await walkFiles(outDir);
|
|
114
|
+
const cssFiles = files.filter((file) => getExt(file) === ".css");
|
|
115
|
+
await Promise.all(cssFiles.map(async (file) => {
|
|
116
|
+
try {
|
|
117
|
+
const css = await readFile(file, "utf8");
|
|
118
|
+
const { css: minified } = minifyCss(css);
|
|
119
|
+
await writeFile(file, minified, "utf8");
|
|
120
|
+
}
|
|
121
|
+
catch (err) {
|
|
122
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
123
|
+
console.error(kolor.red(`Failed to minify CSS ${relative(outDir, file)}: ${message}`));
|
|
124
|
+
}
|
|
125
|
+
}));
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Minify all HTML files in output directory
|
|
129
|
+
*/
|
|
130
|
+
export async function minifyHTMLFiles(outDir, config) {
|
|
131
|
+
const files = await walkFiles(outDir);
|
|
132
|
+
const htmlFiles = files.filter((file) => getExt(file) === ".html");
|
|
133
|
+
await Promise.all(htmlFiles.map(async (file) => {
|
|
134
|
+
try {
|
|
135
|
+
const html = await readFile(file, "utf8");
|
|
136
|
+
const minified = await minifyHtml(html, {
|
|
137
|
+
collapseWhitespace: true,
|
|
138
|
+
removeComments: true,
|
|
139
|
+
minifyCSS: !!config.minifyCSS,
|
|
140
|
+
minifyJS: true,
|
|
141
|
+
keepClosingSlash: true,
|
|
142
|
+
removeRedundantAttributes: true,
|
|
143
|
+
removeScriptTypeAttributes: true,
|
|
144
|
+
removeStyleLinkTypeAttributes: true
|
|
145
|
+
});
|
|
146
|
+
await writeFile(file, minified, "utf8");
|
|
147
|
+
}
|
|
148
|
+
catch (err) {
|
|
149
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
150
|
+
console.error(kolor.red(`Failed to minify HTML ${relative(outDir, file)}: ${message}`));
|
|
151
|
+
}
|
|
152
|
+
}));
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Add content hashes to CSS and JS filenames for cache busting
|
|
156
|
+
*/
|
|
157
|
+
export async function cacheBustAssets(outDir) {
|
|
158
|
+
const assetMap = {}; // original path -> hashed path
|
|
159
|
+
const files = await walkFiles(outDir);
|
|
160
|
+
const assetFiles = files.filter((file) => {
|
|
161
|
+
const ext = getExt(file);
|
|
162
|
+
return ext === ".css" || ext === ".js";
|
|
163
|
+
});
|
|
164
|
+
// Hash and rename each asset
|
|
165
|
+
for (const file of assetFiles) {
|
|
166
|
+
try {
|
|
167
|
+
const content = await readFile(file);
|
|
168
|
+
const hash = createHash("sha256").update(content).digest("hex").slice(0, 10);
|
|
169
|
+
const ext = extname(file);
|
|
170
|
+
const base = basename(file, ext);
|
|
171
|
+
const dir = dirname(file);
|
|
172
|
+
const hashedName = `${base}-${hash}${ext}`;
|
|
173
|
+
const hashedPath = join(dir, hashedName);
|
|
174
|
+
await rename(file, hashedPath);
|
|
175
|
+
// Store mapping of original relative path to hashed relative path
|
|
176
|
+
const originalRel = relative(outDir, file).replace(/\\/g, "/");
|
|
177
|
+
const hashedRel = relative(outDir, hashedPath).replace(/\\/g, "/");
|
|
178
|
+
assetMap[originalRel] = hashedRel;
|
|
179
|
+
// Log the cache-busted file
|
|
180
|
+
console.log(kolor.dim(` ${originalRel}`) + kolor.cyan(` → `) + kolor.green(hashedRel));
|
|
181
|
+
}
|
|
182
|
+
catch (err) {
|
|
183
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
184
|
+
console.error(kolor.red(`Failed to cache-bust ${relative(outDir, file)}: ${message}`));
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
// Update HTML files to reference hashed assets
|
|
188
|
+
const htmlFiles = files.filter((file) => getExt(file) === ".html");
|
|
189
|
+
for (const htmlFile of htmlFiles) {
|
|
190
|
+
try {
|
|
191
|
+
let html = await readFile(htmlFile, "utf8");
|
|
192
|
+
let updated = false;
|
|
193
|
+
// Update <link> tags (CSS)
|
|
194
|
+
for (const [original, hashed] of Object.entries(assetMap)) {
|
|
195
|
+
if (original.endsWith(".css")) {
|
|
196
|
+
// Match href="/path" or href="path" but ensure we stay within the tag
|
|
197
|
+
const escaped = original.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
198
|
+
const pattern = new RegExp(`(<link[^>]*?\\shref=["'])/?${escaped}(["'])`, "gi");
|
|
199
|
+
const newHtml = html.replace(pattern, `$1/${hashed}$2`);
|
|
200
|
+
if (newHtml !== html) {
|
|
201
|
+
html = newHtml;
|
|
202
|
+
updated = true;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
// Update <script> tags (JS)
|
|
207
|
+
for (const [original, hashed] of Object.entries(assetMap)) {
|
|
208
|
+
if (original.endsWith(".js")) {
|
|
209
|
+
// Match src="/path" or src="path" but ensure we stay within the tag
|
|
210
|
+
const escaped = original.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
211
|
+
const pattern = new RegExp(`(<script[^>]*?\\ssrc=["'])/?${escaped}(["'])`, "gi");
|
|
212
|
+
const newHtml = html.replace(pattern, `$1/${hashed}$2`);
|
|
213
|
+
if (newHtml !== html) {
|
|
214
|
+
html = newHtml;
|
|
215
|
+
updated = true;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
if (updated) {
|
|
220
|
+
await writeFile(htmlFile, html, "utf8");
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
catch (err) {
|
|
224
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
225
|
+
console.error(kolor.red(`Failed to update asset references in ${relative(outDir, htmlFile)}: ${message}`));
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return assetMap;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Generate sitemap.xml for all HTML files
|
|
232
|
+
*/
|
|
233
|
+
export async function generateSitemap(outDir, siteUrl) {
|
|
234
|
+
const htmlFiles = await walkFiles(outDir);
|
|
235
|
+
const urls = [];
|
|
236
|
+
for (const file of htmlFiles) {
|
|
237
|
+
if (getExt(file) !== ".html")
|
|
238
|
+
continue;
|
|
239
|
+
// Get relative path from output directory
|
|
240
|
+
const rel = relative(outDir, file);
|
|
241
|
+
// Convert file path to URL path
|
|
242
|
+
let urlPath = rel.replace(/\\/g, "/");
|
|
243
|
+
// Convert index.html to directory path
|
|
244
|
+
if (urlPath === "index.html") {
|
|
245
|
+
urlPath = "";
|
|
246
|
+
}
|
|
247
|
+
else if (urlPath.endsWith("/index.html")) {
|
|
248
|
+
urlPath = urlPath.slice(0, -11); // Remove "/index.html"
|
|
249
|
+
}
|
|
250
|
+
else if (urlPath.endsWith(".html")) {
|
|
251
|
+
urlPath = urlPath.slice(0, -5); // Remove ".html"
|
|
252
|
+
}
|
|
253
|
+
// Get file modification time for lastmod
|
|
254
|
+
const stats = await stat(file);
|
|
255
|
+
const lastmod = stats.mtime.toISOString().split("T")[0];
|
|
256
|
+
// Build full URL
|
|
257
|
+
const fullUrl = siteUrl.replace(/\/$/, "") + "/" + urlPath;
|
|
258
|
+
urls.push({ loc: fullUrl, lastmod });
|
|
259
|
+
}
|
|
260
|
+
// Generate XML sitemap
|
|
261
|
+
let xml = '<?xml version="1.0" encoding="UTF-8"?>\n';
|
|
262
|
+
xml += '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n';
|
|
263
|
+
for (const url of urls) {
|
|
264
|
+
xml += " <url>\n";
|
|
265
|
+
xml += ` <loc>${url.loc}</loc>\n`;
|
|
266
|
+
xml += ` <lastmod>${url.lastmod}</lastmod>\n`;
|
|
267
|
+
xml += " </url>\n";
|
|
268
|
+
}
|
|
269
|
+
xml += "</urlset>\n";
|
|
270
|
+
return xml;
|
|
271
|
+
}
|
|
272
|
+
//# sourceMappingURL=assets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assets.js","sourceRoot":"","sources":["../../src/build/assets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAC3C,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAS3C;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAgB,EAAE,MAAsB;IACzE,IAAI,CAAC,MAAM,CAAC,cAAc;QAAE,OAAO,KAAK,CAAC;IACzC,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC7B,MAAM,YAAY,GAAG,MAAM,CAAC,mBAAmB,EAAE,YAAY,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAC3F,OAAO,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AACpC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,SAAiB,EAAE,OAAe,EAAE,QAAuB;IAC5F,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAC/B,MAAM,QAAQ,GAAG,QAAQ,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IAC1C,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAE/B,MAAM,OAAO,GAAqB,EAAE,CAAC;IACrC,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,IAAI,EAAE,CAAC;IACvC,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC;IAE9C,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,GAAG,QAAQ,GAAG,MAAM,EAAE,CAAC;YAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;YAEzC,MAAM,aAAa,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;YAEvC,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;gBACvB,MAAM,aAAa,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAC3D,CAAC;iBAAM,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;gBAC9B,MAAM,aAAa,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAC3D,CAAC;iBAAM,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;gBACnD,MAAM,aAAa,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAC3D,CAAC;iBAAM,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;gBAC7B,MAAM,aAAa,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAC1D,CAAC;iBAAM,CAAC;gBACN,SAAS;YACX,CAAC;YAED,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,CAAC;YACrC,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,UAAU;gBAChB,MAAM;gBACN,IAAI,EAAE,KAAK,CAAC,IAAI;aACjB,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,qBAAqB,QAAQ,CAAC,SAAS,CAAC,OAAO,MAAM,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC;QAChG,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAAc,EAAE,MAAsB;IACxE,IAAI,CAAC,MAAM,CAAC,cAAc;QAAE,OAAO;IAEnC,MAAM,QAAQ,GAAkB;QAC9B,OAAO,EAAE,MAAM,CAAC,mBAAmB,EAAE,OAAO,IAAI,EAAE;QAClD,OAAO,EAAE,MAAM,CAAC,mBAAmB,EAAE,OAAO,IAAI,CAAC,OAAO,CAAC;QACzD,gBAAgB,EAAE,MAAM,CAAC,mBAAmB,EAAE,gBAAgB,KAAK,KAAK;KACzE,CAAC;IAEF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,CAAC;IAErD,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC;IACtC,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,kBAAkB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IAE5E,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC,CAAC;QACrD,OAAO;IACT,CAAC;IAED,IAAI,cAAc,GAAG,CAAC,CAAC;IACvB,IAAI,iBAAiB,GAAG,CAAC,CAAC;IAC1B,IAAI,kBAAkB,GAAG,CAAC,CAAC;IAE3B,MAAM,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QAC9C,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;QACvC,iBAAiB,IAAI,aAAa,CAAC,IAAI,CAAC;QAExC,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QAE3D,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC/D,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YACnC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,MAAM,OAAO,EAAE,CAAC,CAAC,CAAC;YAEhD,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;gBAClB,kBAAkB,IAAI,CAAC,CAAC,IAAI,CAAC;gBAC7B,cAAc,EAAE,CAAC;YACnB,CAAC,CAAC,CAAC;QACL,CAAC;QAED,+CAA+C;QAC/C,IAAI,CAAC,QAAQ,CAAC,gBAAgB,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrD,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAClC,CAAC;IACH,CAAC,CAAC,CAAC,CAAC;IAEJ,MAAM,UAAU,GAAG,iBAAiB,GAAG,kBAAkB,CAAC;IAC1D,MAAM,YAAY,GAAG,iBAAiB,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,GAAG,iBAAiB,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAErG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,eAAe,cAAc,WAAW,CAAC,CAAC,CAAC;IACnE,IAAI,CAAC,QAAQ,CAAC,gBAAgB,EAAE,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,WAAW,CAAC,UAAU,CAAC,KAAK,YAAY,cAAc,CAAC,CAAC,CAAC;IAC9F,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,MAAc;IACjD,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC;IACtC,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,CAAC;IAEjE,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QAC5C,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACzC,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;YACzC,MAAM,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC1C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,wBAAwB,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC;QACzF,CAAC;IACH,CAAC,CAAC,CAAC,CAAC;AACN,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAAc,EAAE,MAAsB;IAC1E,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC;IACtC,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,CAAC;IAEnE,MAAM,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QAC7C,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAC1C,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,IAAI,EAAE;gBACtC,kBAAkB,EAAE,IAAI;gBACxB,cAAc,EAAE,IAAI;gBACpB,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS;gBAC7B,QAAQ,EAAE,IAAI;gBACd,gBAAgB,EAAE,IAAI;gBACtB,yBAAyB,EAAE,IAAI;gBAC/B,0BAA0B,EAAE,IAAI;gBAChC,6BAA6B,EAAE,IAAI;aACpC,CAAC,CAAC;YACH,MAAM,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC1C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,yBAAyB,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC;QAC1F,CAAC;IACH,CAAC,CAAC,CAAC,CAAC;AACN,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAAc;IAClD,MAAM,QAAQ,GAAa,EAAE,CAAC,CAAC,+BAA+B;IAC9D,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC;IACtC,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;QACvC,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QACzB,OAAO,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,KAAK,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,6BAA6B;IAC7B,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;YACrC,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC7E,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;YAC1B,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YACjC,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;YAC1B,MAAM,UAAU,GAAG,GAAG,IAAI,IAAI,IAAI,GAAG,GAAG,EAAE,CAAC;YAC3C,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;YAEzC,MAAM,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;YAE/B,kEAAkE;YAClE,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YAC/D,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YACnE,QAAQ,CAAC,WAAW,CAAC,GAAG,SAAS,CAAC;YAElC,4BAA4B;YAC5B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,WAAW,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;QAC1F,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,wBAAwB,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC;QACzF,CAAC;IACH,CAAC;IAED,+CAA+C;IAC/C,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,CAAC;IAEnE,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,IAAI,CAAC;YACH,IAAI,IAAI,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAC5C,IAAI,OAAO,GAAG,KAAK,CAAC;YAEpB,2BAA2B;YAC3B,KAAK,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC1D,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC9B,sEAAsE;oBACtE,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;oBAChE,MAAM,OAAO,GAAG,IAAI,MAAM,CAAC,8BAA8B,OAAO,QAAQ,EAAE,IAAI,CAAC,CAAC;oBAEhF,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,MAAM,IAAI,CAAC,CAAC;oBACxD,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;wBACrB,IAAI,GAAG,OAAO,CAAC;wBACf,OAAO,GAAG,IAAI,CAAC;oBACjB,CAAC;gBACH,CAAC;YACH,CAAC;YAED,4BAA4B;YAC5B,KAAK,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC1D,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC7B,oEAAoE;oBACpE,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;oBAChE,MAAM,OAAO,GAAG,IAAI,MAAM,CAAC,+BAA+B,OAAO,QAAQ,EAAE,IAAI,CAAC,CAAC;oBAEjF,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,MAAM,IAAI,CAAC,CAAC;oBACxD,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;wBACrB,IAAI,GAAG,OAAO,CAAC;wBACf,OAAO,GAAG,IAAI,CAAC;oBACjB,CAAC;gBACH,CAAC;YACH,CAAC;YAED,IAAI,OAAO,EAAE,CAAC;gBACZ,MAAM,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,wCAAwC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC;QAC7G,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAAc,EAAE,OAAe;IACnE,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAiB,EAAE,CAAC;IAE9B,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,OAAO;YAAE,SAAS;QAEvC,0CAA0C;QAC1C,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAEnC,gCAAgC;QAChC,IAAI,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAEtC,uCAAuC;QACvC,IAAI,OAAO,KAAK,YAAY,EAAE,CAAC;YAC7B,OAAO,GAAG,EAAE,CAAC;QACf,CAAC;aAAM,IAAI,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;YAC3C,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,uBAAuB;QAC1D,CAAC;aAAM,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACrC,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB;QACnD,CAAC;QAED,yCAAyC;QACzC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAExD,iBAAiB;QACjB,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,GAAG,OAAO,CAAC;QAE3D,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IACvC,CAAC;IAED,uBAAuB;IACvB,IAAI,GAAG,GAAG,0CAA0C,CAAC;IACrD,GAAG,IAAI,gEAAgE,CAAC;IAExE,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,GAAG,IAAI,WAAW,CAAC;QACnB,GAAG,IAAI,YAAY,GAAG,CAAC,GAAG,UAAU,CAAC;QACrC,GAAG,IAAI,gBAAgB,GAAG,CAAC,OAAO,cAAc,CAAC;QACjD,GAAG,IAAI,YAAY,CAAC;IACtB,CAAC;IAED,GAAG,IAAI,aAAa,CAAC;IAErB,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data.d.ts","sourceRoot":"","sources":["../../src/build/data.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;GAEG;AACH,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAqBhF"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { existsSync } from "fs";
|
|
2
|
+
import { readFile } from "fs/promises";
|
|
3
|
+
import { basename, relative } from "path";
|
|
4
|
+
import { walkFiles, getExt } from "../utils/fs.js";
|
|
5
|
+
import { kolor } from "../utils/logger.js";
|
|
6
|
+
/**
|
|
7
|
+
* Load JSON data/collections from one or more directories
|
|
8
|
+
*/
|
|
9
|
+
export async function loadData(dataDirs) {
|
|
10
|
+
const collections = {};
|
|
11
|
+
// Support both string and array input
|
|
12
|
+
const dirs = Array.isArray(dataDirs) ? dataDirs : [dataDirs];
|
|
13
|
+
for (const dataDir of dirs) {
|
|
14
|
+
if (!existsSync(dataDir))
|
|
15
|
+
continue;
|
|
16
|
+
const files = await walkFiles(dataDir);
|
|
17
|
+
for (const file of files) {
|
|
18
|
+
if (getExt(file) !== ".json")
|
|
19
|
+
continue;
|
|
20
|
+
const name = basename(file, ".json");
|
|
21
|
+
try {
|
|
22
|
+
const raw = await readFile(file, "utf8");
|
|
23
|
+
collections[name] = JSON.parse(raw);
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
27
|
+
console.error(kolor.red(`Failed to load data ${relative(dataDir, file)}: ${message}`));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return collections;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=data.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data.js","sourceRoot":"","sources":["../../src/build/data.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAG3C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,QAA2B;IACxD,MAAM,WAAW,GAAgB,EAAE,CAAC;IACpC,sCAAsC;IACtC,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAE7D,KAAK,MAAM,OAAO,IAAI,IAAI,EAAE,CAAC;QAC3B,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;YAAE,SAAS;QACnC,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,CAAC;QACvC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,OAAO;gBAAE,SAAS;YACvC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACrC,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBACzC,WAAW,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACtC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACjE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,uBAAuB,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC;YACzF,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import matter from "gray-matter";
|
|
2
|
+
import type { CampsiteConfig, PageFrontmatter, PageContext, Collections, RenderOptions } from "../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Read and parse frontmatter from a file
|
|
5
|
+
*/
|
|
6
|
+
export declare function readWithFrontmatter(filePath: string): Promise<matter.GrayMatterFile<string>>;
|
|
7
|
+
/**
|
|
8
|
+
* Build page context object for template rendering
|
|
9
|
+
*/
|
|
10
|
+
export declare function pageContext(frontmatter: PageFrontmatter, html: string, config: CampsiteConfig, relPath: string, data: Collections, path?: string): PageContext;
|
|
11
|
+
/**
|
|
12
|
+
* Determine if markdown rendering should be applied
|
|
13
|
+
*/
|
|
14
|
+
export declare function shouldRenderMarkdown(frontmatter: PageFrontmatter | undefined, _config: CampsiteConfig, defaultValue: boolean): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Render a single page file
|
|
17
|
+
*/
|
|
18
|
+
export declare function renderPage(filePath: string, options: RenderOptions): Promise<void>;
|
|
19
|
+
//# sourceMappingURL=pages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pages.d.ts","sourceRoot":"","sources":["../../src/build/pages.ts"],"names":[],"mappings":"AAGA,OAAO,MAAM,MAAM,aAAa,CAAC;AAMjC,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5G;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAGlG;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,WAAW,EAAE,eAAe,EAC5B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,WAAW,EACjB,IAAI,GAAE,MAAY,GACjB,WAAW,CAcb;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,eAAe,GAAG,SAAS,EACxC,OAAO,EAAE,cAAc,EACvB,YAAY,EAAE,OAAO,GACpB,OAAO,CAGT;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAkFxF"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { cp, readFile, writeFile } from "fs/promises";
|
|
2
|
+
import { dirname, join, relative } from "path";
|
|
3
|
+
import matter from "gray-matter";
|
|
4
|
+
import { ensureDir, getExt } from "../utils/fs.js";
|
|
5
|
+
import { toUrlPath, normalizeUrl } from "../utils/paths.js";
|
|
6
|
+
import { md, loadMustachePartials, renderWithLayout, Mustache } from "../render/engines.js";
|
|
7
|
+
/**
|
|
8
|
+
* Read and parse frontmatter from a file
|
|
9
|
+
*/
|
|
10
|
+
export async function readWithFrontmatter(filePath) {
|
|
11
|
+
const raw = await readFile(filePath, "utf8");
|
|
12
|
+
return matter(raw);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Build page context object for template rendering
|
|
16
|
+
*/
|
|
17
|
+
export function pageContext(frontmatter, html, config, relPath, data, path = "/") {
|
|
18
|
+
// Helper function to check if a URL is active/current
|
|
19
|
+
const isActive = (url) => {
|
|
20
|
+
if (!url)
|
|
21
|
+
return false;
|
|
22
|
+
return normalizeUrl(path) === normalizeUrl(url);
|
|
23
|
+
};
|
|
24
|
+
return {
|
|
25
|
+
site: { name: config.siteName, config },
|
|
26
|
+
page: { ...frontmatter, content: html, source: relPath, path },
|
|
27
|
+
collections: data,
|
|
28
|
+
isActive,
|
|
29
|
+
...data
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Determine if markdown rendering should be applied
|
|
34
|
+
*/
|
|
35
|
+
export function shouldRenderMarkdown(frontmatter, _config, defaultValue) {
|
|
36
|
+
if (typeof frontmatter?.markdown === "boolean")
|
|
37
|
+
return frontmatter.markdown;
|
|
38
|
+
return defaultValue;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Render a single page file
|
|
42
|
+
*/
|
|
43
|
+
export async function renderPage(filePath, options) {
|
|
44
|
+
const { pagesDir, layoutsDir, outDir, env, liquidEnv, config, data, partialsDir } = options;
|
|
45
|
+
const rel = relative(pagesDir, filePath);
|
|
46
|
+
const ext = getExt(filePath);
|
|
47
|
+
const outRel = rel.replace(/\.liquid(\.html)?$/i, ".html").replace(ext, ".html");
|
|
48
|
+
const outPath = join(outDir, outRel);
|
|
49
|
+
const path = toUrlPath(outRel);
|
|
50
|
+
await ensureDir(dirname(outPath));
|
|
51
|
+
// Load Mustache partials if needed
|
|
52
|
+
const fileContent = await readFile(filePath, "utf8");
|
|
53
|
+
const partials = (ext === ".mustache" || fileContent.match(/layout:.*\.mustache/))
|
|
54
|
+
? await loadMustachePartials(partialsDir)
|
|
55
|
+
: {};
|
|
56
|
+
// Helper function to finalize and write the rendered page
|
|
57
|
+
const finalizePage = async (pageHtml, frontmatter) => {
|
|
58
|
+
const ctx = pageContext(frontmatter, pageHtml, config, rel, data, path);
|
|
59
|
+
const rendered = await renderWithLayout(frontmatter.layout, pageHtml, ctx, env, liquidEnv, layoutsDir, partials);
|
|
60
|
+
await writeFile(outPath, rendered, "utf8");
|
|
61
|
+
};
|
|
62
|
+
if (ext === ".md") {
|
|
63
|
+
const parsed = await readWithFrontmatter(filePath);
|
|
64
|
+
const html = md.render(parsed.content);
|
|
65
|
+
await finalizePage(html, parsed.data);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (ext === ".njk") {
|
|
69
|
+
const parsed = await readWithFrontmatter(filePath);
|
|
70
|
+
const ctx = pageContext(parsed.data, parsed.content, config, rel, data, path);
|
|
71
|
+
// Note: path option not officially in types but supported by nunjucks
|
|
72
|
+
let pageHtml = env.renderString(parsed.content, ctx);
|
|
73
|
+
if (shouldRenderMarkdown(parsed.data, config, false)) {
|
|
74
|
+
pageHtml = md.render(pageHtml);
|
|
75
|
+
}
|
|
76
|
+
await finalizePage(pageHtml, parsed.data);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (ext === ".liquid" || filePath.toLowerCase().endsWith(".liquid.html")) {
|
|
80
|
+
const parsed = await readWithFrontmatter(filePath);
|
|
81
|
+
const ctx = pageContext(parsed.data, parsed.content, config, rel, data, path);
|
|
82
|
+
let pageHtml = await liquidEnv.parseAndRender(parsed.content, ctx);
|
|
83
|
+
if (shouldRenderMarkdown(parsed.data, config, false)) {
|
|
84
|
+
pageHtml = md.render(pageHtml);
|
|
85
|
+
}
|
|
86
|
+
await finalizePage(pageHtml, parsed.data);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
if (ext === ".mustache") {
|
|
90
|
+
const parsed = await readWithFrontmatter(filePath);
|
|
91
|
+
const ctx = pageContext(parsed.data, parsed.content, config, rel, data, path);
|
|
92
|
+
let pageHtml = Mustache.render(parsed.content, ctx, partials);
|
|
93
|
+
if (shouldRenderMarkdown(parsed.data, config, false)) {
|
|
94
|
+
pageHtml = md.render(pageHtml);
|
|
95
|
+
}
|
|
96
|
+
await finalizePage(pageHtml, parsed.data);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
if (ext === ".html") {
|
|
100
|
+
const parsed = await readWithFrontmatter(filePath);
|
|
101
|
+
let pageHtml = parsed.content;
|
|
102
|
+
if (shouldRenderMarkdown(parsed.data, config, false)) {
|
|
103
|
+
pageHtml = md.render(pageHtml);
|
|
104
|
+
}
|
|
105
|
+
await finalizePage(pageHtml, parsed.data);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
await cp(filePath, outPath);
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=pages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pages.js","sourceRoot":"","sources":["../../src/build/pages.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/build/pipeline.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD;;GAEG;AACH,wBAAsB,KAAK,CAAC,MAAM,GAAE,MAAsB,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+FrG"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { existsSync } from "fs";
|
|
2
|
+
import { writeFile } from "fs/promises";
|
|
3
|
+
import { join, relative, resolve } from "path";
|
|
4
|
+
import { loadConfig } from "../config.js";
|
|
5
|
+
import { cleanDir, copyPublic, walkFiles } from "../utils/fs.js";
|
|
6
|
+
import { kolor } from "../utils/logger.js";
|
|
7
|
+
import { createNunjucksEnv, createLiquidEnv } from "../render/engines.js";
|
|
8
|
+
import { loadData } from "./data.js";
|
|
9
|
+
import { renderPage } from "./pages.js";
|
|
10
|
+
import { processImages, minifyCSSFiles, minifyHTMLFiles, cacheBustAssets, generateSitemap } from "./assets.js";
|
|
11
|
+
/**
|
|
12
|
+
* Main build function - orchestrates the entire build pipeline
|
|
13
|
+
*/
|
|
14
|
+
export async function build(cwdArg = process.cwd(), options = {}) {
|
|
15
|
+
const config = await loadConfig(cwdArg);
|
|
16
|
+
const srcDir = resolve(cwdArg, config.srcDir || "src");
|
|
17
|
+
const pagesDir = join(srcDir, "pages");
|
|
18
|
+
const layoutsDir = join(srcDir, "layouts");
|
|
19
|
+
const partialsDir = join(srcDir, "partials");
|
|
20
|
+
const dataDir = join(srcDir, "data");
|
|
21
|
+
const collectionsDir = join(srcDir, "collections");
|
|
22
|
+
const publicDir = resolve(cwdArg, "public");
|
|
23
|
+
const outDir = resolve(cwdArg, config.outDir || "dist");
|
|
24
|
+
const env = createNunjucksEnv(layoutsDir, pagesDir, srcDir, partialsDir);
|
|
25
|
+
// Allow user config to extend the Nunjucks environment (e.g., custom filters)
|
|
26
|
+
if (config?.hooks?.nunjucksEnv && typeof config.hooks.nunjucksEnv === "function") {
|
|
27
|
+
try {
|
|
28
|
+
config.hooks.nunjucksEnv(env);
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
32
|
+
console.error(kolor.red(`Failed to apply nunjucksEnv hook: ${message}`));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const liquidEnv = createLiquidEnv(layoutsDir, pagesDir, srcDir, partialsDir);
|
|
36
|
+
// Allow user config to extend the Liquid environment (e.g., custom filters)
|
|
37
|
+
if (config?.hooks?.liquidEnv && typeof config.hooks.liquidEnv === "function") {
|
|
38
|
+
try {
|
|
39
|
+
config.hooks.liquidEnv(liquidEnv);
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
43
|
+
console.error(kolor.red(`Failed to apply liquidEnv hook: ${message}`));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const data = await loadData([dataDir, collectionsDir]);
|
|
47
|
+
await cleanDir(outDir);
|
|
48
|
+
await copyPublic(publicDir, outDir, config.excludeFiles);
|
|
49
|
+
// Only compress photos during production builds, not during dev mode
|
|
50
|
+
const shouldCompressPhotos = options.skipImageCompression !== true && config.compressPhotos;
|
|
51
|
+
if (shouldCompressPhotos) {
|
|
52
|
+
await processImages(outDir, config);
|
|
53
|
+
}
|
|
54
|
+
const files = await walkFiles(pagesDir);
|
|
55
|
+
if (files.length === 0) {
|
|
56
|
+
console.log(kolor.yellow("No pages found in src/pages."));
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
await Promise.all(files.map((file) => renderPage(file, { pagesDir, layoutsDir, outDir, env, liquidEnv, config, data, partialsDir })));
|
|
60
|
+
// Skip minification and cache busting in dev mode for faster rebuilds
|
|
61
|
+
const isDevMode = options.devMode === true;
|
|
62
|
+
if (!isDevMode && config.minifyCSS) {
|
|
63
|
+
await minifyCSSFiles(outDir);
|
|
64
|
+
console.log(kolor.green("CSS minified"));
|
|
65
|
+
}
|
|
66
|
+
if (!isDevMode && config.minifyHTML) {
|
|
67
|
+
await minifyHTMLFiles(outDir, config);
|
|
68
|
+
console.log(kolor.green("HTML minified"));
|
|
69
|
+
}
|
|
70
|
+
if (!isDevMode && config.cacheBustAssets) {
|
|
71
|
+
console.log(kolor.cyan("Cache-busting assets..."));
|
|
72
|
+
const assetMap = await cacheBustAssets(outDir);
|
|
73
|
+
const assetCount = Object.keys(assetMap).length;
|
|
74
|
+
if (assetCount > 0) {
|
|
75
|
+
console.log(kolor.green(`✓ Cache-busted ${assetCount} asset(s)`));
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
console.log(kolor.yellow("No assets found to cache-bust"));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// Generate robots.txt dynamically if it doesn't exist in public directory
|
|
82
|
+
const publicRobotsTxt = join(publicDir, "robots.txt");
|
|
83
|
+
const distRobotsTxt = join(outDir, "robots.txt");
|
|
84
|
+
if (!existsSync(publicRobotsTxt) && !existsSync(distRobotsTxt)) {
|
|
85
|
+
const robotsTxt = `User-agent: *\nAllow: /\n\nSitemap: ${config.siteUrl}/sitemap.xml\n`;
|
|
86
|
+
await writeFile(distRobotsTxt, robotsTxt, "utf8");
|
|
87
|
+
}
|
|
88
|
+
// Generate sitemap.xml dynamically if it doesn't exist in public directory
|
|
89
|
+
const publicSitemap = join(publicDir, "sitemap.xml");
|
|
90
|
+
const distSitemap = join(outDir, "sitemap.xml");
|
|
91
|
+
if (!existsSync(publicSitemap) && !existsSync(distSitemap)) {
|
|
92
|
+
const sitemapXml = await generateSitemap(outDir, config.siteUrl);
|
|
93
|
+
await writeFile(distSitemap, sitemapXml, "utf8");
|
|
94
|
+
console.log(kolor.green("✓ Generated sitemap.xml"));
|
|
95
|
+
}
|
|
96
|
+
console.log(kolor.green(`Built ${files.length} page(s) → ${relative(cwdArg, outDir)}`));
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../src/build/pipeline.ts"],"names":[],"mappings":"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"}
|