tunecamp 1.0.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.
Files changed (132) hide show
  1. package/.env.local +2 -0
  2. package/.vercel/README.txt +11 -0
  3. package/.vercel/project.json +1 -0
  4. package/LICENSE +22 -0
  5. package/README.md +554 -0
  6. package/dist/cli.d.ts +6 -0
  7. package/dist/cli.d.ts.map +1 -0
  8. package/dist/cli.js +172 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/generator/embedGenerator.d.ts +38 -0
  11. package/dist/generator/embedGenerator.d.ts.map +1 -0
  12. package/dist/generator/embedGenerator.js +92 -0
  13. package/dist/generator/embedGenerator.js.map +1 -0
  14. package/dist/generator/feedGenerator.d.ts +50 -0
  15. package/dist/generator/feedGenerator.d.ts.map +1 -0
  16. package/dist/generator/feedGenerator.js +167 -0
  17. package/dist/generator/feedGenerator.js.map +1 -0
  18. package/dist/generator/podcastFeedGenerator.d.ts +54 -0
  19. package/dist/generator/podcastFeedGenerator.d.ts.map +1 -0
  20. package/dist/generator/podcastFeedGenerator.js +173 -0
  21. package/dist/generator/podcastFeedGenerator.js.map +1 -0
  22. package/dist/generator/proceduralCoverGenerator.d.ts +51 -0
  23. package/dist/generator/proceduralCoverGenerator.d.ts.map +1 -0
  24. package/dist/generator/proceduralCoverGenerator.js +228 -0
  25. package/dist/generator/proceduralCoverGenerator.js.map +1 -0
  26. package/dist/generator/siteGenerator.d.ts +55 -0
  27. package/dist/generator/siteGenerator.d.ts.map +1 -0
  28. package/dist/generator/siteGenerator.js +539 -0
  29. package/dist/generator/siteGenerator.js.map +1 -0
  30. package/dist/generator/templateEngine.d.ts +13 -0
  31. package/dist/generator/templateEngine.d.ts.map +1 -0
  32. package/dist/generator/templateEngine.js +146 -0
  33. package/dist/generator/templateEngine.js.map +1 -0
  34. package/dist/index.d.ts +12 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +32 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/parser/catalogParser.d.ts +13 -0
  39. package/dist/parser/catalogParser.d.ts.map +1 -0
  40. package/dist/parser/catalogParser.js +120 -0
  41. package/dist/parser/catalogParser.js.map +1 -0
  42. package/dist/tools/generate-codes.d.ts +14 -0
  43. package/dist/tools/generate-codes.d.ts.map +1 -0
  44. package/dist/tools/generate-codes.js +274 -0
  45. package/dist/tools/generate-codes.js.map +1 -0
  46. package/dist/tools/generate-sea-pair.d.ts +14 -0
  47. package/dist/tools/generate-sea-pair.d.ts.map +1 -0
  48. package/dist/tools/generate-sea-pair.js +111 -0
  49. package/dist/tools/generate-sea-pair.js.map +1 -0
  50. package/dist/types/index.d.ts +117 -0
  51. package/dist/types/index.d.ts.map +1 -0
  52. package/dist/types/index.js +5 -0
  53. package/dist/types/index.js.map +1 -0
  54. package/dist/utils/audioUtils.d.ts +9 -0
  55. package/dist/utils/audioUtils.d.ts.map +1 -0
  56. package/dist/utils/audioUtils.js +67 -0
  57. package/dist/utils/audioUtils.js.map +1 -0
  58. package/dist/utils/configUtils.d.ts +11 -0
  59. package/dist/utils/configUtils.d.ts.map +1 -0
  60. package/dist/utils/configUtils.js +50 -0
  61. package/dist/utils/configUtils.js.map +1 -0
  62. package/dist/utils/fileUtils.d.ts +14 -0
  63. package/dist/utils/fileUtils.d.ts.map +1 -0
  64. package/dist/utils/fileUtils.js +73 -0
  65. package/dist/utils/fileUtils.js.map +1 -0
  66. package/examples/artist-free/README.md +36 -0
  67. package/examples/artist-paycurtain/README.md +49 -0
  68. package/examples/label/README.md +33 -0
  69. package/gundb-keypair.json +8 -0
  70. package/logo.svg +30 -0
  71. package/package-lock.json +1176 -0
  72. package/package.json +42 -0
  73. package/public/assets/community-registry.js +291 -0
  74. package/public/assets/download-stats.js +263 -0
  75. package/public/assets/player.js +219 -0
  76. package/public/assets/style.css +1170 -0
  77. package/public/assets/theme-widget.js +353 -0
  78. package/public/assets/unlock-codes.js +225 -0
  79. package/public/atom.xml +22 -0
  80. package/public/catalog.m3u +3 -0
  81. package/public/feed.xml +22 -0
  82. package/public/image.png +0 -0
  83. package/public/index.html +249 -0
  84. package/public/logo.svg +30 -0
  85. package/public/releases/chirichetto/Homologo - Chirichetto.wav +0 -0
  86. package/public/releases/chirichetto/cover.png +0 -0
  87. package/public/releases/chirichetto/embed-code.txt +16 -0
  88. package/public/releases/chirichetto/embed-compact.txt +8 -0
  89. package/public/releases/chirichetto/embed.html +39 -0
  90. package/public/releases/chirichetto/index.html +389 -0
  91. package/public/releases/chirichetto/playlist.m3u +3 -0
  92. package/templates/dark/assets/community-registry.js +291 -0
  93. package/templates/dark/assets/download-stats.js +263 -0
  94. package/templates/dark/assets/player.js +219 -0
  95. package/templates/dark/assets/style.css +740 -0
  96. package/templates/dark/index.hbs +73 -0
  97. package/templates/dark/layout.hbs +84 -0
  98. package/templates/dark/release.hbs +212 -0
  99. package/templates/default/assets/community-registry.js +291 -0
  100. package/templates/default/assets/download-stats.js +263 -0
  101. package/templates/default/assets/player.js +219 -0
  102. package/templates/default/assets/style.css +1170 -0
  103. package/templates/default/assets/theme-widget.js +353 -0
  104. package/templates/default/assets/unlock-codes.js +225 -0
  105. package/templates/default/index.hbs +188 -0
  106. package/templates/default/layout.hbs +117 -0
  107. package/templates/default/release.hbs +553 -0
  108. package/templates/minimal/assets/community-registry.js +291 -0
  109. package/templates/minimal/assets/download-stats.js +263 -0
  110. package/templates/minimal/assets/player.js +219 -0
  111. package/templates/minimal/assets/style.css +796 -0
  112. package/templates/minimal/index.hbs +73 -0
  113. package/templates/minimal/layout.hbs +84 -0
  114. package/templates/minimal/release.hbs +212 -0
  115. package/templates/retro/assets/community-registry.js +291 -0
  116. package/templates/retro/assets/download-stats.js +263 -0
  117. package/templates/retro/assets/player.js +219 -0
  118. package/templates/retro/assets/style.css +872 -0
  119. package/templates/retro/index.hbs +73 -0
  120. package/templates/retro/layout.hbs +84 -0
  121. package/templates/retro/release.hbs +212 -0
  122. package/templates/translucent/assets/community-registry.js +291 -0
  123. package/templates/translucent/assets/download-stats.js +263 -0
  124. package/templates/translucent/assets/player.js +219 -0
  125. package/templates/translucent/assets/style.css +1352 -0
  126. package/templates/translucent/index.hbs +73 -0
  127. package/templates/translucent/layout.hbs +84 -0
  128. package/templates/translucent/release.hbs +212 -0
  129. package/website/community.html +492 -0
  130. package/website/index.html +195 -0
  131. package/website/styles.css +396 -0
  132. package/website/tunecamp.svg +30 -0
@@ -0,0 +1,173 @@
1
+ /**
2
+ * Podcast RSS Feed Generator for Tunecamp
3
+ * Creates podcast-specific RSS feeds for episodic content
4
+ */
5
+ import path from "path";
6
+ /**
7
+ * Generates podcast-specific RSS 2.0 feeds
8
+ */
9
+ export class PodcastFeedGenerator {
10
+ catalog;
11
+ options;
12
+ constructor(catalog, options) {
13
+ this.catalog = catalog;
14
+ this.options = options;
15
+ }
16
+ /**
17
+ * Get the full URL for a path
18
+ */
19
+ getUrl(relativePath) {
20
+ const base = this.options.siteUrl.replace(/\/$/, "");
21
+ const basePath = this.options.basePath || "";
22
+ return `${base}${basePath}/${relativePath}`.replace(/([^:]\/)\/+/g, "$1");
23
+ }
24
+ /**
25
+ * Format date for RSS (RFC 822)
26
+ */
27
+ formatRssDate(dateStr) {
28
+ const date = new Date(dateStr);
29
+ return date.toUTCString();
30
+ }
31
+ /**
32
+ * Escape XML special characters
33
+ */
34
+ escapeXml(str) {
35
+ return str
36
+ .replace(/&/g, "&")
37
+ .replace(/</g, "&lt;")
38
+ .replace(/>/g, "&gt;")
39
+ .replace(/"/g, "&quot;")
40
+ .replace(/'/g, "&apos;");
41
+ }
42
+ /**
43
+ * Format duration in HH:MM:SS format for iTunes
44
+ */
45
+ formatItunesDuration(seconds) {
46
+ if (!seconds)
47
+ return "00:00:00";
48
+ const h = Math.floor(seconds / 3600);
49
+ const m = Math.floor((seconds % 3600) / 60);
50
+ const s = Math.floor(seconds % 60);
51
+ return `${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`;
52
+ }
53
+ /**
54
+ * Get MIME type for audio file
55
+ */
56
+ getAudioMimeType(filename) {
57
+ const ext = path.extname(filename).toLowerCase();
58
+ const mimeTypes = {
59
+ '.mp3': 'audio/mpeg',
60
+ '.m4a': 'audio/mp4',
61
+ '.aac': 'audio/aac',
62
+ '.ogg': 'audio/ogg',
63
+ '.opus': 'audio/opus',
64
+ '.flac': 'audio/flac',
65
+ '.wav': 'audio/wav',
66
+ };
67
+ return mimeTypes[ext] || 'audio/mpeg';
68
+ }
69
+ /**
70
+ * Generate Podcast RSS feed
71
+ * Each track becomes an episode
72
+ */
73
+ generatePodcastFeed() {
74
+ const title = this.escapeXml(this.options.podcastTitle || this.catalog.config.title);
75
+ const description = this.escapeXml(this.options.podcastDescription || this.catalog.config.description || "Music podcast");
76
+ const link = this.getUrl("");
77
+ const feedUrl = this.getUrl("podcast.xml");
78
+ const author = this.escapeXml(this.options.podcastAuthor || this.catalog.artist?.name || "Unknown");
79
+ const email = this.options.podcastEmail || "";
80
+ const category = this.options.podcastCategory || "Music";
81
+ const explicit = this.options.explicit ? "true" : "false";
82
+ const now = new Date().toUTCString();
83
+ // Get image URL
84
+ let imageUrl = this.getUrl("logo.svg");
85
+ if (this.options.podcastImage) {
86
+ imageUrl = this.getUrl(this.options.podcastImage);
87
+ }
88
+ else if (this.catalog.artist?.photo) {
89
+ imageUrl = this.getUrl(this.catalog.artist.photo);
90
+ }
91
+ // Collect all episodes (tracks from all releases)
92
+ const episodes = [];
93
+ for (const release of this.catalog.releases) {
94
+ if (release.config.unlisted)
95
+ continue;
96
+ for (const track of release.tracks) {
97
+ episodes.push({
98
+ track,
99
+ release,
100
+ pubDate: release.config.date,
101
+ });
102
+ }
103
+ }
104
+ // Sort episodes by date (newest first)
105
+ episodes.sort((a, b) => new Date(b.pubDate).getTime() - new Date(a.pubDate).getTime());
106
+ const items = episodes.map((ep, index) => this.generateEpisodeItem(ep.track, ep.release, episodes.length - index)).join("\n");
107
+ return `<?xml version="1.0" encoding="UTF-8"?>
108
+ <rss version="2.0"
109
+ xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
110
+ xmlns:podcast="https://podcastindex.org/namespace/1.0"
111
+ xmlns:atom="http://www.w3.org/2005/Atom"
112
+ xmlns:content="http://purl.org/rss/1.0/modules/content/">
113
+ <channel>
114
+ <title>${title}</title>
115
+ <link>${link}</link>
116
+ <description>${description}</description>
117
+ <language>${this.catalog.config.language || "en"}</language>
118
+ <lastBuildDate>${now}</lastBuildDate>
119
+ <generator>Tunecamp Podcast Generator</generator>
120
+ <atom:link href="${feedUrl}" rel="self" type="application/rss+xml"/>
121
+
122
+ <!-- iTunes Podcast Tags -->
123
+ <itunes:author>${author}</itunes:author>
124
+ <itunes:summary>${description}</itunes:summary>
125
+ <itunes:type>episodic</itunes:type>
126
+ <itunes:explicit>${explicit}</itunes:explicit>
127
+ <itunes:category text="${this.escapeXml(category)}"/>
128
+ <itunes:image href="${imageUrl}"/>
129
+ ${email ? `<itunes:owner><itunes:name>${author}</itunes:name><itunes:email>${email}</itunes:email></itunes:owner>` : ''}
130
+
131
+ <!-- Podcast 2.0 Tags -->
132
+ <podcast:locked>no</podcast:locked>
133
+
134
+ ${items}
135
+ </channel>
136
+ </rss>`;
137
+ }
138
+ /**
139
+ * Generate a single episode item
140
+ */
141
+ generateEpisodeItem(track, release, episodeNumber) {
142
+ const title = this.escapeXml(`${track.title} (from ${release.config.title})`);
143
+ const description = this.escapeXml(track.description || release.config.description || `Episode ${episodeNumber}`);
144
+ const audioUrl = this.getUrl(`releases/${release.slug}/${path.basename(track.file)}`);
145
+ const pageUrl = this.getUrl(`releases/${release.slug}/index.html`);
146
+ const pubDate = this.formatRssDate(release.config.date);
147
+ const duration = this.formatItunesDuration(track.duration);
148
+ const mimeType = this.getAudioMimeType(track.file);
149
+ const guid = `${release.slug}-${path.basename(track.file, path.extname(track.file))}`;
150
+ const artist = this.catalog.artist?.name || "Unknown Artist";
151
+ // Get cover image
152
+ let imageUrl = "";
153
+ if (release.coverPath) {
154
+ imageUrl = this.getUrl(`releases/${release.slug}/${path.basename(release.coverPath)}`);
155
+ }
156
+ return ` <item>
157
+ <title>${title}</title>
158
+ <link>${pageUrl}</link>
159
+ <description><![CDATA[${description}]]></description>
160
+ <pubDate>${pubDate}</pubDate>
161
+ <guid isPermaLink="false">${guid}</guid>
162
+ <enclosure url="${audioUrl}" type="${mimeType}" length="0"/>
163
+
164
+ <itunes:title>${this.escapeXml(track.title)}</itunes:title>
165
+ <itunes:author>${this.escapeXml(artist)}</itunes:author>
166
+ <itunes:duration>${duration}</itunes:duration>
167
+ <itunes:episodeType>full</itunes:episodeType>
168
+ <itunes:episode>${episodeNumber}</itunes:episode>
169
+ ${imageUrl ? `<itunes:image href="${imageUrl}"/>` : ''}
170
+ </item>`;
171
+ }
172
+ }
173
+ //# sourceMappingURL=podcastFeedGenerator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"podcastFeedGenerator.js","sourceRoot":"","sources":["../../src/generator/podcastFeedGenerator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Procedural Cover Generator for Tunecamp
3
+ * Creates AI-free, algorithmically generated cover art
4
+ */
5
+ /**
6
+ * Generate SVG cover art based on release metadata
7
+ * Uses hash-based deterministic generation for consistency
8
+ */
9
+ export declare class ProceduralCoverGenerator {
10
+ /**
11
+ * Simple hash function for strings
12
+ */
13
+ private hash;
14
+ /**
15
+ * Generate HSL color from hash
16
+ */
17
+ private hashToHsl;
18
+ /**
19
+ * Generate procedural cover SVG
20
+ */
21
+ generateCover(title: string, artistName: string, releaseDate?: string, genres?: string[]): string;
22
+ /**
23
+ * Wave pattern
24
+ */
25
+ private generateWavePattern;
26
+ /**
27
+ * Circle pattern
28
+ */
29
+ private generateCirclePattern;
30
+ /**
31
+ * Grid pattern
32
+ */
33
+ private generateGridPattern;
34
+ /**
35
+ * Gradient pattern with shapes
36
+ */
37
+ private generateGradientPattern;
38
+ /**
39
+ * Geometric pattern
40
+ */
41
+ private generateGeometricPattern;
42
+ /**
43
+ * Get contrasting text color
44
+ */
45
+ private getContrastColor;
46
+ /**
47
+ * Escape XML special characters
48
+ */
49
+ private escapeXml;
50
+ }
51
+ //# sourceMappingURL=proceduralCoverGenerator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proceduralCoverGenerator.d.ts","sourceRoot":"","sources":["../../src/generator/proceduralCoverGenerator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,qBAAa,wBAAwB;IACjC;;OAEG;IACH,OAAO,CAAC,IAAI;IAUZ;;OAEG;IACH,OAAO,CAAC,SAAS;IAOjB;;OAEG;IACH,aAAa,CACT,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,EAClB,WAAW,CAAC,EAAE,MAAM,EACpB,MAAM,CAAC,EAAE,MAAM,EAAE,GAClB,MAAM;IA0ET;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAyB3B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAiB7B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAmB3B;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAiB/B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IA8BhC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAKxB;;OAEG;IACH,OAAO,CAAC,SAAS;CAQpB"}
@@ -0,0 +1,228 @@
1
+ /**
2
+ * Procedural Cover Generator for Tunecamp
3
+ * Creates AI-free, algorithmically generated cover art
4
+ */
5
+ /**
6
+ * Generate SVG cover art based on release metadata
7
+ * Uses hash-based deterministic generation for consistency
8
+ */
9
+ export class ProceduralCoverGenerator {
10
+ /**
11
+ * Simple hash function for strings
12
+ */
13
+ hash(str) {
14
+ let hash = 0;
15
+ for (let i = 0; i < str.length; i++) {
16
+ const char = str.charCodeAt(i);
17
+ hash = ((hash << 5) - hash) + char;
18
+ hash = hash & hash; // Convert to 32bit integer
19
+ }
20
+ return Math.abs(hash);
21
+ }
22
+ /**
23
+ * Generate HSL color from hash
24
+ */
25
+ hashToHsl(hash, offset = 0) {
26
+ const h = ((hash + offset * 137) % 360);
27
+ const s = 60 + (hash % 30); // 60-90%
28
+ const l = 40 + ((hash >> 4) % 25); // 40-65%
29
+ return `hsl(${h}, ${s}%, ${l}%)`;
30
+ }
31
+ /**
32
+ * Generate procedural cover SVG
33
+ */
34
+ generateCover(title, artistName, releaseDate, genres) {
35
+ const seed = this.hash(title + artistName + (releaseDate || ""));
36
+ const width = 500;
37
+ const height = 500;
38
+ // Choose a pattern based on hash
39
+ const patternType = seed % 5;
40
+ let pattern;
41
+ switch (patternType) {
42
+ case 0:
43
+ pattern = this.generateWavePattern(seed, width, height);
44
+ break;
45
+ case 1:
46
+ pattern = this.generateCirclePattern(seed, width, height);
47
+ break;
48
+ case 2:
49
+ pattern = this.generateGridPattern(seed, width, height);
50
+ break;
51
+ case 3:
52
+ pattern = this.generateGradientPattern(seed, width, height);
53
+ break;
54
+ default:
55
+ pattern = this.generateGeometricPattern(seed, width, height);
56
+ }
57
+ // Background gradient
58
+ const bgColor1 = this.hashToHsl(seed, 0);
59
+ const bgColor2 = this.hashToHsl(seed, 100);
60
+ // Text styling
61
+ const textColor = this.getContrastColor(seed);
62
+ const titleSize = Math.min(36, Math.max(24, 500 / (title.length * 0.7)));
63
+ return `<?xml version="1.0" encoding="UTF-8"?>
64
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${width} ${height}" width="${width}" height="${height}">
65
+ <defs>
66
+ <linearGradient id="bg" x1="0%" y1="0%" x2="100%" y2="100%">
67
+ <stop offset="0%" style="stop-color:${bgColor1}"/>
68
+ <stop offset="100%" style="stop-color:${bgColor2}"/>
69
+ </linearGradient>
70
+ <filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
71
+ <feDropShadow dx="0" dy="2" stdDeviation="3" flood-opacity="0.3"/>
72
+ </filter>
73
+ </defs>
74
+
75
+ <!-- Background -->
76
+ <rect width="100%" height="100%" fill="url(#bg)"/>
77
+
78
+ <!-- Pattern -->
79
+ ${pattern}
80
+
81
+ <!-- Text overlay with shadow -->
82
+ <g filter="url(#shadow)">
83
+ <text x="${width / 2}" y="${height - 100}"
84
+ font-family="system-ui, -apple-system, sans-serif"
85
+ font-size="${titleSize}"
86
+ font-weight="700"
87
+ fill="${textColor}"
88
+ text-anchor="middle">
89
+ ${this.escapeXml(title)}
90
+ </text>
91
+ <text x="${width / 2}" y="${height - 60}"
92
+ font-family="system-ui, -apple-system, sans-serif"
93
+ font-size="18"
94
+ fill="${textColor}"
95
+ text-anchor="middle"
96
+ opacity="0.8">
97
+ ${this.escapeXml(artistName)}
98
+ </text>
99
+ </g>
100
+ </svg>`;
101
+ }
102
+ /**
103
+ * Wave pattern
104
+ */
105
+ generateWavePattern(seed, w, h) {
106
+ const color1 = this.hashToHsl(seed, 50);
107
+ const color2 = this.hashToHsl(seed, 150);
108
+ const waves = [];
109
+ const numWaves = 4 + (seed % 4);
110
+ for (let i = 0; i < numWaves; i++) {
111
+ const amplitude = 30 + (seed >> (i * 2)) % 40;
112
+ const freq = 0.02 + ((seed >> (i * 3)) % 20) / 1000;
113
+ const yOffset = (h / (numWaves + 1)) * (i + 1);
114
+ const opacity = 0.3 + (i * 0.1);
115
+ let d = `M 0 ${yOffset}`;
116
+ for (let x = 0; x <= w; x += 10) {
117
+ const y = yOffset + Math.sin(x * freq + i) * amplitude;
118
+ d += ` L ${x} ${y}`;
119
+ }
120
+ d += ` L ${w} ${h} L 0 ${h} Z`;
121
+ waves.push(`<path d="${d}" fill="${i % 2 === 0 ? color1 : color2}" opacity="${opacity}"/>`);
122
+ }
123
+ return waves.join("\n ");
124
+ }
125
+ /**
126
+ * Circle pattern
127
+ */
128
+ generateCirclePattern(seed, w, h) {
129
+ const circles = [];
130
+ const numCircles = 5 + (seed % 8);
131
+ for (let i = 0; i < numCircles; i++) {
132
+ const cx = ((seed >> (i * 5)) % w);
133
+ const cy = ((seed >> (i * 3 + 1)) % h);
134
+ const r = 30 + ((seed >> (i * 2)) % 80);
135
+ const color = this.hashToHsl(seed + i * 47, i * 30);
136
+ const opacity = 0.2 + (i % 4) * 0.1;
137
+ circles.push(`<circle cx="${cx}" cy="${cy}" r="${r}" fill="${color}" opacity="${opacity}"/>`);
138
+ }
139
+ return circles.join("\n ");
140
+ }
141
+ /**
142
+ * Grid pattern
143
+ */
144
+ generateGridPattern(seed, w, h) {
145
+ const rects = [];
146
+ const cellSize = 50 + (seed % 50);
147
+ const cols = Math.ceil(w / cellSize);
148
+ const rows = Math.ceil(h / cellSize);
149
+ for (let row = 0; row < rows; row++) {
150
+ for (let col = 0; col < cols; col++) {
151
+ if ((seed + row * cols + col) % 3 === 0) {
152
+ const color = this.hashToHsl(seed + row * cols + col, 0);
153
+ const opacity = 0.1 + ((seed >> ((row + col) % 16)) % 3) * 0.1;
154
+ rects.push(`<rect x="${col * cellSize}" y="${row * cellSize}" width="${cellSize}" height="${cellSize}" fill="${color}" opacity="${opacity}"/>`);
155
+ }
156
+ }
157
+ }
158
+ return rects.join("\n ");
159
+ }
160
+ /**
161
+ * Gradient pattern with shapes
162
+ */
163
+ generateGradientPattern(seed, w, h) {
164
+ const color1 = this.hashToHsl(seed, 200);
165
+ const color2 = this.hashToHsl(seed, 300);
166
+ const rotation = seed % 360;
167
+ return `
168
+ <defs>
169
+ <radialGradient id="overlay">
170
+ <stop offset="0%" style="stop-color:${color1};stop-opacity:0.4"/>
171
+ <stop offset="100%" style="stop-color:${color2};stop-opacity:0.1"/>
172
+ </radialGradient>
173
+ </defs>
174
+ <circle cx="${w * 0.3}" cy="${h * 0.4}" r="${w * 0.6}" fill="url(#overlay)"/>
175
+ <circle cx="${w * 0.7}" cy="${h * 0.6}" r="${w * 0.4}" fill="url(#overlay)"/>
176
+ `;
177
+ }
178
+ /**
179
+ * Geometric pattern
180
+ */
181
+ generateGeometricPattern(seed, w, h) {
182
+ const shapes = [];
183
+ const numShapes = 6 + (seed % 6);
184
+ for (let i = 0; i < numShapes; i++) {
185
+ const x = ((seed >> (i * 4)) % w);
186
+ const y = ((seed >> (i * 3 + 2)) % h);
187
+ const size = 40 + ((seed >> (i * 2)) % 60);
188
+ const color = this.hashToHsl(seed + i * 71, i * 45);
189
+ const opacity = 0.15 + (i % 3) * 0.1;
190
+ const rotation = (seed + i * 30) % 360;
191
+ // Alternate between triangles, hexagons, and diamonds
192
+ if (i % 3 === 0) {
193
+ // Triangle
194
+ const points = `${x},${y - size / 2} ${x - size / 2},${y + size / 2} ${x + size / 2},${y + size / 2}`;
195
+ shapes.push(`<polygon points="${points}" fill="${color}" opacity="${opacity}" transform="rotate(${rotation} ${x} ${y})"/>`);
196
+ }
197
+ else if (i % 3 === 1) {
198
+ // Diamond
199
+ const points = `${x},${y - size / 2} ${x + size / 2},${y} ${x},${y + size / 2} ${x - size / 2},${y}`;
200
+ shapes.push(`<polygon points="${points}" fill="${color}" opacity="${opacity}"/>`);
201
+ }
202
+ else {
203
+ // Hexagon approximation
204
+ shapes.push(`<circle cx="${x}" cy="${y}" r="${size / 2}" fill="${color}" opacity="${opacity}"/>`);
205
+ }
206
+ }
207
+ return shapes.join("\n ");
208
+ }
209
+ /**
210
+ * Get contrasting text color
211
+ */
212
+ getContrastColor(seed) {
213
+ const lightness = 40 + ((seed >> 4) % 25);
214
+ return lightness > 50 ? "#1e293b" : "#f8fafc";
215
+ }
216
+ /**
217
+ * Escape XML special characters
218
+ */
219
+ escapeXml(str) {
220
+ return str
221
+ .replace(/&/g, "&amp;")
222
+ .replace(/</g, "&lt;")
223
+ .replace(/>/g, "&gt;")
224
+ .replace(/"/g, "&quot;")
225
+ .replace(/'/g, "&apos;");
226
+ }
227
+ }
228
+ //# sourceMappingURL=proceduralCoverGenerator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proceduralCoverGenerator.js","sourceRoot":"","sources":["../../src/generator/proceduralCoverGenerator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ import { Catalog, BuildOptions } from "../types/index.js";
2
+ /**
3
+ * Generates static HTML site from catalog
4
+ */
5
+ export declare class SiteGenerator {
6
+ private catalog;
7
+ private options;
8
+ private templateEngine;
9
+ private templateDir;
10
+ constructor(catalog: Catalog, options: BuildOptions);
11
+ generate(): Promise<void>;
12
+ private loadTemplates;
13
+ private copyAssets;
14
+ private generateIndexPage;
15
+ private generateReleasesPages;
16
+ private generateReleasePage;
17
+ private copyMediaFiles;
18
+ /**
19
+ * Generate RSS and Atom feeds
20
+ */
21
+ private generateFeeds;
22
+ /**
23
+ * Generate M3U playlists for releases and catalog
24
+ */
25
+ private generateM3uPlaylists;
26
+ /**
27
+ * Generate M3U playlist for a single release
28
+ */
29
+ private generateReleaseM3u;
30
+ /**
31
+ * Generate M3U playlist for entire catalog
32
+ */
33
+ private generateCatalogM3u;
34
+ /**
35
+ * Generate artist pages for label mode
36
+ */
37
+ private generateArtistPages;
38
+ /**
39
+ * Generate embed pages for each release
40
+ */
41
+ private generateEmbedPages;
42
+ /**
43
+ * Generate standalone embed HTML page
44
+ */
45
+ private generateEmbedHtmlPage;
46
+ /**
47
+ * Generate podcast RSS feed
48
+ */
49
+ private generatePodcastFeed;
50
+ /**
51
+ * Generate procedural SVG covers for releases without cover art
52
+ */
53
+ private generateProceduralCovers;
54
+ }
55
+ //# sourceMappingURL=siteGenerator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"siteGenerator.d.ts","sourceRoot":"","sources":["../../src/generator/siteGenerator.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,YAAY,EAAyB,MAAM,mBAAmB,CAAC;AAajF;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,WAAW,CAAS;gBAEhB,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY;IAY7C,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;YA6CjB,aAAa;YAgBb,UAAU;YAUV,iBAAiB;YA+DjB,qBAAqB;YAMrB,mBAAmB;YA8EnB,cAAc;IA+F5B;;OAEG;YACW,aAAa;IAoB3B;;OAEG;YACW,oBAAoB;IAkBlC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAiB1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA2B1B;;OAEG;YACW,mBAAmB;IAkEjC;;OAEG;YACW,kBAAkB;IAwBhC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAgD7B;;OAEG;YACW,mBAAmB;IAsBjC;;OAEG;YACW,wBAAwB;CA6BvC"}