repo-wrapped 0.0.3 → 0.0.5

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 (38) hide show
  1. package/dist/commands/generate.js +104 -95
  2. package/dist/constants/chronotypes.js +23 -23
  3. package/dist/constants/colors.js +18 -18
  4. package/dist/constants/index.js +18 -18
  5. package/dist/formatters/index.js +17 -17
  6. package/dist/formatters/timeFormatter.js +28 -29
  7. package/dist/generators/html/templates/achievementsSection.js +42 -43
  8. package/dist/generators/html/templates/commitQualitySection.js +25 -26
  9. package/dist/generators/html/templates/contributionGraph.js +64 -48
  10. package/dist/generators/html/templates/impactSection.js +19 -20
  11. package/dist/generators/html/templates/knowledgeSection.js +86 -87
  12. package/dist/generators/html/templates/streakSection.js +8 -9
  13. package/dist/generators/html/templates/timePatternsSection.js +45 -46
  14. package/dist/generators/html/utils/colorUtils.js +61 -21
  15. package/dist/generators/html/utils/commitMapBuilder.js +23 -24
  16. package/dist/generators/html/utils/dateRangeCalculator.js +56 -57
  17. package/dist/generators/html/utils/developerStatsCalculator.js +28 -29
  18. package/dist/generators/html/utils/scriptLoader.js +15 -16
  19. package/dist/generators/html/utils/styleLoader.js +17 -18
  20. package/dist/generators/html/utils/weekGrouper.js +27 -28
  21. package/dist/index.js +78 -78
  22. package/dist/types/index.js +2 -2
  23. package/dist/utils/achievementDefinitions.js +433 -433
  24. package/dist/utils/achievementEngine.js +169 -170
  25. package/dist/utils/commitQualityAnalyzer.js +367 -368
  26. package/dist/utils/fileHotspotAnalyzer.js +269 -270
  27. package/dist/utils/gitParser.js +136 -126
  28. package/dist/utils/htmlGenerator.js +245 -233
  29. package/dist/utils/impactAnalyzer.js +247 -248
  30. package/dist/utils/knowledgeDistributionAnalyzer.js +380 -374
  31. package/dist/utils/matrixGenerator.js +369 -350
  32. package/dist/utils/slideGenerator.js +170 -171
  33. package/dist/utils/streakCalculator.js +134 -135
  34. package/dist/utils/timePatternAnalyzer.js +304 -305
  35. package/dist/utils/wrappedDisplay.js +124 -115
  36. package/dist/utils/wrappedGenerator.js +376 -377
  37. package/dist/utils/wrappedHtmlGenerator.js +105 -106
  38. package/package.json +10 -10
@@ -1,35 +1,35 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.generateHTML = void 0;
4
- const date_fns_1 = require("date-fns");
5
- const achievementEngine_1 = require("./achievementEngine");
6
- const commitQualityAnalyzer_1 = require("./commitQualityAnalyzer");
7
- const fileHotspotAnalyzer_1 = require("./fileHotspotAnalyzer");
8
- const impactAnalyzer_1 = require("./impactAnalyzer");
9
- const knowledgeDistributionAnalyzer_1 = require("./knowledgeDistributionAnalyzer");
10
- const streakCalculator_1 = require("./streakCalculator");
11
- const timePatternAnalyzer_1 = require("./timePatternAnalyzer");
12
- const styleLoader_1 = require("../generators/html/utils/styleLoader");
13
- const scriptLoader_1 = require("../generators/html/utils/scriptLoader");
14
- const contributionGraph_1 = require("../generators/html/templates/contributionGraph");
15
- const streakSection_1 = require("../generators/html/templates/streakSection");
16
- const timePatternsSection_1 = require("../generators/html/templates/timePatternsSection");
17
- const commitQualitySection_1 = require("../generators/html/templates/commitQualitySection");
18
- const achievementsSection_1 = require("../generators/html/templates/achievementsSection");
19
- const impactSection_1 = require("../generators/html/templates/impactSection");
20
- const knowledgeSection_1 = require("../generators/html/templates/knowledgeSection");
21
- const commitMapBuilder_1 = require("../generators/html/utils/commitMapBuilder");
22
- const developerStatsCalculator_1 = require("../generators/html/utils/developerStatsCalculator");
23
- const dateRangeCalculator_1 = require("../generators/html/utils/dateRangeCalculator");
24
- const weekGrouper_1 = require("../generators/html/utils/weekGrouper");
25
- const colorUtils_1 = require("../generators/html/utils/colorUtils");
26
- // Helper to format date range for display
27
- function formatDateRange(start, end) {
28
- return `${(0, date_fns_1.format)(start, 'MMM d, yyyy')} – ${(0, date_fns_1.format)(end, 'MMM d, yyyy')}`;
29
- }
30
- // Helper to build KPI header
31
- function buildKPIHeader(totalCommits, qualityScore, currentStreak, activeDayPercentage) {
32
- const healthScore = ((qualityScore / 10) * 0.4 + (activeDayPercentage / 100) * 0.3 + Math.min(currentStreak / 30, 1) * 0.3) * 10;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateHTML = generateHTML;
4
+ const date_fns_1 = require("date-fns");
5
+ const achievementEngine_1 = require("./achievementEngine");
6
+ const commitQualityAnalyzer_1 = require("./commitQualityAnalyzer");
7
+ const fileHotspotAnalyzer_1 = require("./fileHotspotAnalyzer");
8
+ const impactAnalyzer_1 = require("./impactAnalyzer");
9
+ const knowledgeDistributionAnalyzer_1 = require("./knowledgeDistributionAnalyzer");
10
+ const streakCalculator_1 = require("./streakCalculator");
11
+ const timePatternAnalyzer_1 = require("./timePatternAnalyzer");
12
+ const styleLoader_1 = require("../generators/html/utils/styleLoader");
13
+ const scriptLoader_1 = require("../generators/html/utils/scriptLoader");
14
+ const contributionGraph_1 = require("../generators/html/templates/contributionGraph");
15
+ const streakSection_1 = require("../generators/html/templates/streakSection");
16
+ const timePatternsSection_1 = require("../generators/html/templates/timePatternsSection");
17
+ const commitQualitySection_1 = require("../generators/html/templates/commitQualitySection");
18
+ const achievementsSection_1 = require("../generators/html/templates/achievementsSection");
19
+ const impactSection_1 = require("../generators/html/templates/impactSection");
20
+ const knowledgeSection_1 = require("../generators/html/templates/knowledgeSection");
21
+ const commitMapBuilder_1 = require("../generators/html/utils/commitMapBuilder");
22
+ const developerStatsCalculator_1 = require("../generators/html/utils/developerStatsCalculator");
23
+ const dateRangeCalculator_1 = require("../generators/html/utils/dateRangeCalculator");
24
+ const weekGrouper_1 = require("../generators/html/utils/weekGrouper");
25
+ const colorUtils_1 = require("../generators/html/utils/colorUtils");
26
+ // Helper to format date range for display
27
+ function formatDateRange(start, end) {
28
+ return `${(0, date_fns_1.format)(start, 'MMM d, yyyy')} – ${(0, date_fns_1.format)(end, 'MMM d, yyyy')}`;
29
+ }
30
+ // Helper to build KPI header
31
+ function buildKPIHeader(totalCommits, qualityScore, currentStreak, activeDayPercentage) {
32
+ const healthScore = ((qualityScore / 10) * 0.4 + (activeDayPercentage / 100) * 0.3 + Math.min(currentStreak / 30, 1) * 0.3) * 10;
33
33
  return `
34
34
  <header class="kpi-header">
35
35
  <div class="kpi-card">
@@ -53,10 +53,10 @@ function buildKPIHeader(totalCommits, qualityScore, currentStreak, activeDayPerc
53
53
  <span class="kpi-value">${activeDayPercentage.toFixed(0)}%</span>
54
54
  </div>
55
55
  </header>
56
- `;
57
- }
58
- // Helper to wrap content in collapsible section
59
- function wrapInSection(id, title, content, icon = '') {
56
+ `;
57
+ }
58
+ // Helper to wrap content in collapsible section
59
+ function wrapInSection(id, title, content, icon = '') {
60
60
  return `
61
61
  <section class="dashboard-section" id="${id}">
62
62
  <header class="section-header" role="button" aria-expanded="true">
@@ -67,85 +67,84 @@ function wrapInSection(id, title, content, icon = '') {
67
67
  ${content}
68
68
  </div>
69
69
  </section>
70
- `;
71
- }
72
- function generateHTML(commits, year, monthsToShow, repoPath, repoName, repoUrl, skipBodyCheck = false, allTime = false, deepAnalysis = false) {
73
- // Get current git user
74
- const { getCurrentGitUser } = require('./gitParser');
75
- const currentUser = getCurrentGitUser(repoPath);
76
- // Calculate date ranges
77
- const { startDate, endDate, weekStartDate, weekEndDate } = allTime
78
- ? (0, dateRangeCalculator_1.calculateDateRangesFromCommits)(commits)
79
- : (0, dateRangeCalculator_1.calculateDateRanges)(year, monthsToShow);
80
- // Create commit maps for overall and personal commits
81
- const { commitMap, commitDetailsMap } = (0, commitMapBuilder_1.createCommitMaps)(commits, startDate, endDate);
82
- const personalCommits = commits.filter(c => c.author === currentUser);
83
- const { commitMap: personalCommitMap, commitDetailsMap: personalCommitDetailsMap } = (0, commitMapBuilder_1.createCommitMaps)(personalCommits, startDate, endDate);
84
- // Calculate per-developer statistics
85
- const developerStats = (0, developerStatsCalculator_1.calculateDeveloperStats)(commits, startDate, endDate);
86
- // Calculate streak data (overall and personal)
87
- const streakData = (0, streakCalculator_1.calculateStreaks)(commits, startDate, endDate);
88
- const personalStreakData = (0, streakCalculator_1.calculateStreaks)(personalCommits, startDate, endDate);
89
- // Analyze time patterns (overall and personal)
90
- const timePattern = (0, timePatternAnalyzer_1.analyzeTimePatterns)(commits, startDate, endDate);
91
- const personalTimePattern = (0, timePatternAnalyzer_1.analyzeTimePatterns)(personalCommits, startDate, endDate);
92
- // Analyze commit quality (overall and personal)
93
- const commitQuality = (0, commitQualityAnalyzer_1.analyzeCommitQuality)(commits, { skipBodyCheck });
94
- const personalCommitQuality = (0, commitQualityAnalyzer_1.analyzeCommitQuality)(personalCommits, { skipBodyCheck });
95
- // Analyze file hotspots
96
- const fileHotspots = (0, fileHotspotAnalyzer_1.analyzeFileHotspots)(repoPath, startDate, endDate);
97
- // Analyze impact and knowledge distribution (enterprise insights)
98
- const impactAnalysis = (0, impactAnalyzer_1.analyzeImpact)(commits);
99
- const knowledgeDistribution = (0, knowledgeDistributionAnalyzer_1.analyzeKnowledgeDistribution)(commits, repoPath, deepAnalysis);
100
- const totalCommits = Array.from(commitMap.values()).reduce((sum, count) => sum + count, 0);
101
- const totalPersonalCommits = Array.from(personalCommitMap.values()).reduce((sum, count) => sum + count, 0);
102
- // Prepare analysis data for achievements (overall and personal)
103
- const analysisData = {
104
- commits,
105
- totalCommits,
106
- streakData,
107
- timePattern,
108
- commitQuality,
109
- fileHotspots,
110
- dateRange: { start: startDate, end: endDate }
111
- };
112
- const personalAnalysisData = {
113
- commits: personalCommits,
114
- totalCommits: totalPersonalCommits,
115
- streakData: personalStreakData,
116
- timePattern: personalTimePattern,
117
- commitQuality: personalCommitQuality,
118
- fileHotspots,
119
- dateRange: { start: startDate, end: endDate }
120
- };
121
- // Check achievements
122
- const achievementProgress = (0, achievementEngine_1.checkAchievements)(analysisData);
123
- const personalAchievementProgress = (0, achievementEngine_1.checkAchievements)(personalAnalysisData);
124
- return generateHTMLContent(commitMap, commitDetailsMap, developerStats, streakData, timePattern, commitQuality, fileHotspots, achievementProgress, personalCommitMap, personalCommitDetailsMap, personalStreakData, personalTimePattern, personalCommitQuality, personalAchievementProgress, weekStartDate, weekEndDate, startDate, endDate, repoName, repoUrl, currentUser, skipBodyCheck, impactAnalysis, knowledgeDistribution);
125
- }
126
- exports.generateHTML = generateHTML;
127
- function generatePersonalContent(personalCommitMap, personalCommitDetailsMap, streakData, timePattern, commitQuality, achievementProgress, weekStartDate, weekEndDate, dataStartDate, dataEndDate, currentUser, totalCommits, skipBodyCheck = false) {
128
- const weeks = (0, weekGrouper_1.groupDaysIntoWeeks)(weekStartDate, weekEndDate);
129
- const dayLabels = (0, weekGrouper_1.getDayLabels)();
130
- // Build KPI header for personal stats
131
- const kpiHeader = buildKPIHeader(totalCommits, commitQuality.overallScore, streakData.currentStreak.days, streakData.activeDayPercentage);
132
- // Generate sections using template builders
133
- const contributionGraphHtml = (0, contributionGraph_1.buildContributionGraph)({
134
- commitMap: personalCommitMap,
135
- commitDetailsMap: personalCommitDetailsMap,
136
- weeks,
137
- dayLabels,
138
- dataStartDate,
139
- dataEndDate,
140
- totalCommits,
141
- title: 'Your contributions',
142
- getColorFn: colorUtils_1.getColor
143
- });
144
- const streakSectionHtml = (0, streakSection_1.buildStreakSection)(streakData);
145
- const timePatternsHtml = (0, timePatternsSection_1.buildTimePatternsSection)(timePattern);
146
- const commitQualityHtml = (0, commitQualitySection_1.buildCommitQualitySection)(commitQuality, totalCommits, skipBodyCheck);
147
- const achievementsHtml = (0, achievementsSection_1.buildAchievementsSection)(achievementProgress);
148
- // Combine all sections with collapsible wrappers
70
+ `;
71
+ }
72
+ function generateHTML(commits, year, monthsToShow, repoPath, repoName, repoUrl, skipBodyCheck = false, allTime = false, deepAnalysis = false) {
73
+ // Get current git user
74
+ const { getCurrentGitUser } = require('./gitParser');
75
+ const currentUser = getCurrentGitUser(repoPath);
76
+ // Calculate date ranges
77
+ const { startDate, endDate, weekStartDate, weekEndDate } = allTime
78
+ ? (0, dateRangeCalculator_1.calculateDateRangesFromCommits)(commits)
79
+ : (0, dateRangeCalculator_1.calculateDateRanges)(year, monthsToShow);
80
+ // Create commit maps for overall and personal commits
81
+ const { commitMap, commitDetailsMap } = (0, commitMapBuilder_1.createCommitMaps)(commits, startDate, endDate);
82
+ const personalCommits = commits.filter(c => c.author === currentUser);
83
+ const { commitMap: personalCommitMap, commitDetailsMap: personalCommitDetailsMap } = (0, commitMapBuilder_1.createCommitMaps)(personalCommits, startDate, endDate);
84
+ // Calculate per-developer statistics
85
+ const developerStats = (0, developerStatsCalculator_1.calculateDeveloperStats)(commits, startDate, endDate);
86
+ // Calculate streak data (overall and personal)
87
+ const streakData = (0, streakCalculator_1.calculateStreaks)(commits, startDate, endDate);
88
+ const personalStreakData = (0, streakCalculator_1.calculateStreaks)(personalCommits, startDate, endDate);
89
+ // Analyze time patterns (overall and personal)
90
+ const timePattern = (0, timePatternAnalyzer_1.analyzeTimePatterns)(commits, startDate, endDate);
91
+ const personalTimePattern = (0, timePatternAnalyzer_1.analyzeTimePatterns)(personalCommits, startDate, endDate);
92
+ // Analyze commit quality (overall and personal)
93
+ const commitQuality = (0, commitQualityAnalyzer_1.analyzeCommitQuality)(commits, { skipBodyCheck });
94
+ const personalCommitQuality = (0, commitQualityAnalyzer_1.analyzeCommitQuality)(personalCommits, { skipBodyCheck });
95
+ // Analyze file hotspots
96
+ const fileHotspots = (0, fileHotspotAnalyzer_1.analyzeFileHotspots)(repoPath, startDate, endDate);
97
+ // Analyze impact and knowledge distribution (enterprise insights)
98
+ const impactAnalysis = (0, impactAnalyzer_1.analyzeImpact)(commits);
99
+ const knowledgeDistribution = (0, knowledgeDistributionAnalyzer_1.analyzeKnowledgeDistribution)(commits, repoPath, deepAnalysis);
100
+ const totalCommits = Array.from(commitMap.values()).reduce((sum, count) => sum + count, 0);
101
+ const totalPersonalCommits = Array.from(personalCommitMap.values()).reduce((sum, count) => sum + count, 0);
102
+ // Prepare analysis data for achievements (overall and personal)
103
+ const analysisData = {
104
+ commits,
105
+ totalCommits,
106
+ streakData,
107
+ timePattern,
108
+ commitQuality,
109
+ fileHotspots,
110
+ dateRange: { start: startDate, end: endDate }
111
+ };
112
+ const personalAnalysisData = {
113
+ commits: personalCommits,
114
+ totalCommits: totalPersonalCommits,
115
+ streakData: personalStreakData,
116
+ timePattern: personalTimePattern,
117
+ commitQuality: personalCommitQuality,
118
+ fileHotspots,
119
+ dateRange: { start: startDate, end: endDate }
120
+ };
121
+ // Check achievements
122
+ const achievementProgress = (0, achievementEngine_1.checkAchievements)(analysisData);
123
+ const personalAchievementProgress = (0, achievementEngine_1.checkAchievements)(personalAnalysisData);
124
+ return generateHTMLContent(commitMap, commitDetailsMap, developerStats, streakData, timePattern, commitQuality, fileHotspots, achievementProgress, personalCommitMap, personalCommitDetailsMap, personalStreakData, personalTimePattern, personalCommitQuality, personalAchievementProgress, weekStartDate, weekEndDate, startDate, endDate, repoName, repoUrl, currentUser, skipBodyCheck, impactAnalysis, knowledgeDistribution);
125
+ }
126
+ function generatePersonalContent(personalCommitMap, personalCommitDetailsMap, streakData, timePattern, commitQuality, achievementProgress, weekStartDate, weekEndDate, dataStartDate, dataEndDate, currentUser, totalCommits, skipBodyCheck = false) {
127
+ const weeks = (0, weekGrouper_1.groupDaysIntoWeeks)(weekStartDate, weekEndDate);
128
+ const dayLabels = (0, weekGrouper_1.getDayLabels)();
129
+ // Build KPI header for personal stats
130
+ const kpiHeader = buildKPIHeader(totalCommits, commitQuality.overallScore, streakData.currentStreak.days, streakData.activeDayPercentage);
131
+ // Generate sections using template builders
132
+ const contributionGraphHtml = (0, contributionGraph_1.buildContributionGraph)({
133
+ commitMap: personalCommitMap,
134
+ commitDetailsMap: personalCommitDetailsMap,
135
+ weeks,
136
+ dayLabels,
137
+ dataStartDate,
138
+ dataEndDate,
139
+ totalCommits,
140
+ title: 'Your contributions',
141
+ getColorFn: (0, colorUtils_1.createDynamicColorFn)(personalCommitMap)
142
+ });
143
+ const streakSectionHtml = (0, streakSection_1.buildStreakSection)(streakData);
144
+ const timePatternsHtml = (0, timePatternsSection_1.buildTimePatternsSection)(timePattern);
145
+ const commitQualityHtml = (0, commitQualitySection_1.buildCommitQualitySection)(commitQuality, totalCommits, skipBodyCheck);
146
+ const achievementsHtml = (0, achievementsSection_1.buildAchievementsSection)(achievementProgress);
147
+ // Combine all sections with collapsible wrappers
149
148
  return `
150
149
  ${kpiHeader}
151
150
 
@@ -154,75 +153,88 @@ function generatePersonalContent(personalCommitMap, personalCommitDetailsMap, st
154
153
  ${wrapInSection('personal-patterns', 'Time Patterns', timePatternsHtml)}
155
154
  ${wrapInSection('personal-quality', 'Commit Quality', commitQualityHtml)}
156
155
  ${wrapInSection('personal-achievements', 'Achievements', achievementsHtml)}
157
- `;
158
- }
159
- function generateHTMLContent(commitMap, commitDetailsMap, developerStats, streakData, timePattern, commitQuality, fileHotspots, achievementProgress, personalCommitMap, personalCommitDetailsMap, personalStreakData, personalTimePattern, personalCommitQuality, personalAchievementProgress, weekStartDate, weekEndDate, dataStartDate, dataEndDate, repoName, repoUrl, currentUser, skipBodyCheck = false, impactAnalysis, knowledgeDistribution) {
160
- const totalPersonalCommits = Array.from(personalCommitMap.values()).reduce((sum, count) => sum + count, 0);
161
- const weeks = (0, weekGrouper_1.groupDaysIntoWeeks)(weekStartDate, weekEndDate);
162
- // Build month labels and track month boundaries
163
- let monthLabels = '';
164
- let currentMonth = '';
165
- const monthBoundaries = new Set();
166
- weeks.forEach((week, weekIndex) => {
167
- const firstDayOfWeek = week[0];
168
- const monthName = (0, date_fns_1.format)(firstDayOfWeek, 'MMM');
169
- if (monthName !== currentMonth) {
170
- currentMonth = monthName;
171
- if (weekIndex > 0) {
172
- monthBoundaries.add(weekIndex);
173
- }
174
- }
175
- });
176
- // Build week columns
177
- let weekColumns = '';
178
- const dayLabels = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
179
- weeks.forEach((week, weekIndex) => {
180
- let weekColumn = `<div class="graph-column">`;
181
- week.forEach((day, dayOfWeek) => {
182
- const dateKey = (0, date_fns_1.format)(day, 'yyyy-MM-dd');
183
- const count = commitMap.get(dateKey) || 0;
184
- const isInRange = day >= dataStartDate && day <= dataEndDate;
185
- const color = isInRange ? (0, colorUtils_1.getColor)(count) : 'transparent';
186
- const dateStr = (0, date_fns_1.format)(day, 'MMM d, yyyy');
187
- const emptyClass = count === 0 ? ' empty' : '';
188
- const clickable = count > 0 ? ' clickable' : '';
189
- const detailsData = count > 0 ? `data-details='${JSON.stringify(commitDetailsMap.get(dateKey) || [])}'` : '';
190
- weekColumn += `<div class="day${emptyClass}${clickable}" style="background-color: ${color};" data-count="${count}" data-date="${dateStr}" ${detailsData}></div>`;
191
- });
192
- weekColumn += '</div>';
193
- weekColumns += weekColumn;
194
- });
195
- // Build day labels column
196
- let dayLabelsHtml = '<div class="day-labels">';
197
- dayLabels.forEach((label, index) => {
198
- const displayLabel = [1, 3, 5].includes(index) ? label : '';
199
- dayLabelsHtml += `<div class="day-label">${displayLabel}</div>`;
200
- });
201
- dayLabelsHtml += '</div>';
202
- // Build month labels header
203
- let monthLabelsHtml = '';
204
- currentMonth = '';
205
- weeks.forEach((week, weekIndex) => {
206
- const firstDayOfWeek = week[0];
207
- const monthName = (0, date_fns_1.format)(firstDayOfWeek, 'MMM');
208
- if (monthName !== currentMonth) {
209
- monthLabelsHtml += `<div class="month-label">${monthName}</div>`;
210
- currentMonth = monthName;
211
- }
212
- else {
213
- monthLabelsHtml += `<div class="month-label"></div>`;
214
- }
215
- });
216
- const totalCommits = Array.from(commitMap.values()).reduce((sum, count) => sum + count, 0);
217
- // Sort developers by commit count
218
- const sortedDevelopers = Array.from(developerStats.entries())
219
- .sort((a, b) => b[1].commits - a[1].commits);
220
- // Generate developer analysis HTML
221
- const developerAnalysisHtml = sortedDevelopers.map(([author, stats]) => {
222
- const percentage = ((stats.commits / totalCommits) * 100).toFixed(1);
223
- const dateRange = stats.firstCommit.toDateString() === stats.lastCommit.toDateString()
224
- ? (0, date_fns_1.format)(stats.firstCommit, 'MMM d, yyyy')
225
- : `${(0, date_fns_1.format)(stats.firstCommit, 'MMM d, yyyy')} - ${(0, date_fns_1.format)(stats.lastCommit, 'MMM d, yyyy')}`;
156
+ `;
157
+ }
158
+ function generateHTMLContent(commitMap, commitDetailsMap, developerStats, streakData, timePattern, commitQuality, fileHotspots, achievementProgress, personalCommitMap, personalCommitDetailsMap, personalStreakData, personalTimePattern, personalCommitQuality, personalAchievementProgress, weekStartDate, weekEndDate, dataStartDate, dataEndDate, repoName, repoUrl, currentUser, skipBodyCheck = false, impactAnalysis, knowledgeDistribution) {
159
+ const totalPersonalCommits = Array.from(personalCommitMap.values()).reduce((sum, count) => sum + count, 0);
160
+ const weeks = (0, weekGrouper_1.groupDaysIntoWeeks)(weekStartDate, weekEndDate);
161
+ // Create dynamic color function based on commit distribution
162
+ const getColor = (0, colorUtils_1.createDynamicColorFn)(commitMap);
163
+ // Build month labels and track month boundaries
164
+ let monthLabels = '';
165
+ let currentMonth = '';
166
+ const monthBoundaries = new Set();
167
+ weeks.forEach((week, weekIndex) => {
168
+ const firstDayOfWeek = week[0];
169
+ const monthName = (0, date_fns_1.format)(firstDayOfWeek, 'MMM');
170
+ if (monthName !== currentMonth) {
171
+ currentMonth = monthName;
172
+ if (weekIndex > 0) {
173
+ monthBoundaries.add(weekIndex);
174
+ }
175
+ }
176
+ });
177
+ // Build week columns
178
+ let weekColumns = '';
179
+ const dayLabels = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
180
+ weeks.forEach((week, weekIndex) => {
181
+ let weekColumn = `<div class="graph-column">`;
182
+ week.forEach((day, dayOfWeek) => {
183
+ const dateKey = (0, date_fns_1.format)(day, 'yyyy-MM-dd');
184
+ const count = commitMap.get(dateKey) || 0;
185
+ const isInRange = day >= dataStartDate && day <= dataEndDate;
186
+ const color = isInRange ? getColor(count) : 'transparent';
187
+ const dateStr = (0, date_fns_1.format)(day, 'MMM d, yyyy');
188
+ const emptyClass = count === 0 ? ' empty' : '';
189
+ const clickable = count > 0 ? ' clickable' : '';
190
+ const rawCommits = commitDetailsMap.get(dateKey) || [];
191
+ const sanitizedCommits = rawCommits.map(c => ({
192
+ ...c,
193
+ message: c.message
194
+ .replace(/[\r\n]+/g, ' ')
195
+ .replace(/'/g, '&#39;')
196
+ .replace(/"/g, '&quot;')
197
+ .replace(/</g, '&lt;')
198
+ .replace(/>/g, '&gt;')
199
+ .substring(0, 200)
200
+ }));
201
+ const detailsData = count > 0 ? `data-details='${JSON.stringify(sanitizedCommits)}'` : '';
202
+ weekColumn += `<div class="day${emptyClass}${clickable}" style="background-color: ${color};" data-count="${count}" data-date="${dateStr}" ${detailsData}></div>`;
203
+ });
204
+ weekColumn += '</div>';
205
+ weekColumns += weekColumn;
206
+ });
207
+ // Build day labels column
208
+ let dayLabelsHtml = '<div class="day-labels">';
209
+ dayLabels.forEach((label, index) => {
210
+ const displayLabel = [1, 3, 5].includes(index) ? label : '';
211
+ dayLabelsHtml += `<div class="day-label">${displayLabel}</div>`;
212
+ });
213
+ dayLabelsHtml += '</div>';
214
+ // Build month labels header
215
+ let monthLabelsHtml = '';
216
+ currentMonth = '';
217
+ weeks.forEach((week, weekIndex) => {
218
+ const firstDayOfWeek = week[0];
219
+ const monthName = (0, date_fns_1.format)(firstDayOfWeek, 'MMM');
220
+ if (monthName !== currentMonth) {
221
+ monthLabelsHtml += `<div class="month-label">${monthName}</div>`;
222
+ currentMonth = monthName;
223
+ }
224
+ else {
225
+ monthLabelsHtml += `<div class="month-label"></div>`;
226
+ }
227
+ });
228
+ const totalCommits = Array.from(commitMap.values()).reduce((sum, count) => sum + count, 0);
229
+ // Sort developers by commit count
230
+ const sortedDevelopers = Array.from(developerStats.entries())
231
+ .sort((a, b) => b[1].commits - a[1].commits);
232
+ // Generate developer analysis HTML
233
+ const developerAnalysisHtml = sortedDevelopers.map(([author, stats]) => {
234
+ const percentage = ((stats.commits / totalCommits) * 100).toFixed(1);
235
+ const dateRange = stats.firstCommit.toDateString() === stats.lastCommit.toDateString()
236
+ ? (0, date_fns_1.format)(stats.firstCommit, 'MMM d, yyyy')
237
+ : `${(0, date_fns_1.format)(stats.firstCommit, 'MMM d, yyyy')} - ${(0, date_fns_1.format)(stats.lastCommit, 'MMM d, yyyy')}`;
226
238
  return `
227
239
  <div class="developer-row">
228
240
  <div class="developer-info">
@@ -236,9 +248,9 @@ function generateHTMLContent(commitMap, commitDetailsMap, developerStats, streak
236
248
  <div class="developer-count">${stats.commits} commits (${percentage}%)</div>
237
249
  </div>
238
250
  </div>
239
- `;
240
- }).join('');
241
- // Build contribution graph HTML for Overall tab
251
+ `;
252
+ }).join('');
253
+ // Build contribution graph HTML for Overall tab
242
254
  const contributionGraphHtml = `
243
255
  <div class="graph-container">
244
256
  <div class="months">
@@ -260,14 +272,14 @@ function generateHTMLContent(commitMap, commitDetailsMap, developerStats, streak
260
272
  <span>More</span>
261
273
  </div>
262
274
  </div>
263
- `;
275
+ `;
264
276
  const developerSectionHtml = `
265
277
  <div class="developer-analysis">
266
278
  ${developerAnalysisHtml}
267
279
  </div>
268
- `;
269
- // Build KPI header for Overall tab
270
- const overallKpiHeader = buildKPIHeader(totalCommits, commitQuality.overallScore, streakData.currentStreak.days, streakData.activeDayPercentage);
280
+ `;
281
+ // Build KPI header for Overall tab
282
+ const overallKpiHeader = buildKPIHeader(totalCommits, commitQuality.overallScore, streakData.currentStreak.days, streakData.activeDayPercentage);
271
283
  return `<!DOCTYPE html>
272
284
  <html lang="en">
273
285
  <head>
@@ -398,46 +410,46 @@ function generateHTMLContent(commitMap, commitDetailsMap, developerStats, streak
398
410
 
399
411
  <script>
400
412
  // Embed data for export functionality
401
- window.__GITWRAPPED_DATA__ = ${JSON.stringify({
402
- repository: repoName,
403
- period: {
404
- start: dataStartDate.toISOString(),
405
- end: dataEndDate.toISOString()
406
- },
407
- author: currentUser,
408
- summary: {
409
- totalCommits: totalCommits,
410
- totalContributors: developerStats.size,
411
- activeDays: commitMap.size
412
- },
413
- streaks: {
414
- currentStreak: streakData.currentStreak.days,
415
- longestStreak: streakData.longestStreak.days,
416
- totalActiveDays: streakData.totalActiveDays,
417
- activeDayPercentage: streakData.activeDayPercentage
418
- },
419
- quality: {
420
- overallScore: commitQuality.overallScore,
421
- conventionalAdherence: commitQuality.conventionalCommits.adherence,
422
- avgSubjectLength: commitQuality.subjectQuality.avgLength
423
- },
424
- timePattern: {
425
- chronotype: timePattern.chronotype,
426
- peakHour: timePattern.peakHour.hour,
427
- consistency: timePattern.consistency?.score || 0
428
- },
429
- commits: Array.from(commitDetailsMap.values()).flat().map((c) => ({
430
- date: c.date,
431
- author: c.author,
432
- message: c.message.split('\\n')[0],
433
- hash: c.hash
434
- })),
435
- developerStats: Array.from(developerStats.entries()).map(([name, stats]) => ({
436
- name,
437
- commits: stats.commits,
438
- firstCommit: stats.firstCommit.toISOString(),
439
- lastCommit: stats.lastCommit.toISOString()
440
- }))
413
+ window.__GITWRAPPED_DATA__ = ${JSON.stringify({
414
+ repository: repoName,
415
+ period: {
416
+ start: dataStartDate.toISOString(),
417
+ end: dataEndDate.toISOString()
418
+ },
419
+ author: currentUser,
420
+ summary: {
421
+ totalCommits: totalCommits,
422
+ totalContributors: developerStats.size,
423
+ activeDays: commitMap.size
424
+ },
425
+ streaks: {
426
+ currentStreak: streakData.currentStreak.days,
427
+ longestStreak: streakData.longestStreak.days,
428
+ totalActiveDays: streakData.totalActiveDays,
429
+ activeDayPercentage: streakData.activeDayPercentage
430
+ },
431
+ quality: {
432
+ overallScore: commitQuality.overallScore,
433
+ conventionalAdherence: commitQuality.conventionalCommits.adherence,
434
+ avgSubjectLength: commitQuality.subjectQuality.avgLength
435
+ },
436
+ timePattern: {
437
+ chronotype: timePattern.chronotype,
438
+ peakHour: timePattern.peakHour.hour,
439
+ consistency: timePattern.consistency?.score || 0
440
+ },
441
+ commits: Array.from(commitDetailsMap.values()).flat().map((c) => ({
442
+ date: c.date,
443
+ author: c.author,
444
+ message: c.message.split('\\n')[0],
445
+ hash: c.hash
446
+ })),
447
+ developerStats: Array.from(developerStats.entries()).map(([name, stats]) => ({
448
+ name,
449
+ commits: stats.commits,
450
+ firstCommit: stats.firstCommit.toISOString(),
451
+ lastCommit: stats.lastCommit.toISOString()
452
+ }))
441
453
  })};
442
454
  </script>
443
455
 
@@ -445,5 +457,5 @@ function generateHTMLContent(commitMap, commitDetailsMap, developerStats, streak
445
457
  ${(0, scriptLoader_1.loadScripts)()}
446
458
  </script>
447
459
  </body>
448
- </html>`;
449
- }
460
+ </html>`;
461
+ }