repo-wrapped 0.0.2 → 0.0.4
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/commands/generate.js +104 -95
- package/dist/constants/chronotypes.js +23 -23
- package/dist/constants/colors.js +18 -18
- package/dist/constants/index.js +18 -18
- package/dist/formatters/index.js +17 -17
- package/dist/formatters/timeFormatter.js +28 -29
- package/dist/generators/html/templates/achievementsSection.js +42 -43
- package/dist/generators/html/templates/commitQualitySection.js +25 -26
- package/dist/generators/html/templates/contributionGraph.js +47 -48
- package/dist/generators/html/templates/impactSection.js +19 -20
- package/dist/generators/html/templates/knowledgeSection.js +86 -87
- package/dist/generators/html/templates/streakSection.js +8 -9
- package/dist/generators/html/templates/timePatternsSection.js +45 -46
- package/dist/generators/html/utils/colorUtils.js +21 -21
- package/dist/generators/html/utils/commitMapBuilder.js +23 -24
- package/dist/generators/html/utils/dateRangeCalculator.js +56 -57
- package/dist/generators/html/utils/developerStatsCalculator.js +28 -29
- package/dist/generators/html/utils/scriptLoader.js +15 -16
- package/dist/generators/html/utils/styleLoader.js +17 -18
- package/dist/generators/html/utils/weekGrouper.js +27 -28
- package/dist/index.js +99 -77
- package/dist/types/index.js +2 -2
- package/dist/utils/achievementDefinitions.js +433 -433
- package/dist/utils/achievementEngine.js +169 -170
- package/dist/utils/commitQualityAnalyzer.js +367 -368
- package/dist/utils/fileHotspotAnalyzer.js +269 -270
- package/dist/utils/gitParser.js +136 -125
- package/dist/utils/htmlGenerator.js +232 -233
- package/dist/utils/impactAnalyzer.js +247 -248
- package/dist/utils/knowledgeDistributionAnalyzer.js +373 -374
- package/dist/utils/matrixGenerator.js +349 -350
- package/dist/utils/slideGenerator.js +170 -171
- package/dist/utils/streakCalculator.js +134 -135
- package/dist/utils/timePatternAnalyzer.js +304 -305
- package/dist/utils/wrappedDisplay.js +124 -115
- package/dist/utils/wrappedGenerator.js +376 -377
- package/dist/utils/wrappedHtmlGenerator.js +105 -106
- package/package.json +10 -10
|
@@ -1,95 +1,104 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
(
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.generateMatrix = generateMatrix;
|
|
40
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
41
|
+
const child_process_1 = require("child_process");
|
|
42
|
+
const fs = __importStar(require("fs"));
|
|
43
|
+
const ora_1 = __importDefault(require("ora"));
|
|
44
|
+
const os = __importStar(require("os"));
|
|
45
|
+
const path = __importStar(require("path"));
|
|
46
|
+
const gitParser_1 = require("../utils/gitParser");
|
|
47
|
+
const htmlGenerator_1 = require("../utils/htmlGenerator");
|
|
48
|
+
const matrixGenerator_1 = require("../utils/matrixGenerator");
|
|
49
|
+
async function generateMatrix(repoPath, options) {
|
|
50
|
+
const spinner = (0, ora_1.default)('Analyzing git repository...').start();
|
|
51
|
+
try {
|
|
52
|
+
const absolutePath = path.resolve(repoPath);
|
|
53
|
+
const year = parseInt(options.year);
|
|
54
|
+
const monthsToShow = parseInt(options.months);
|
|
55
|
+
if (!options.all && (monthsToShow < 1 || monthsToShow > 12)) {
|
|
56
|
+
spinner.fail(chalk_1.default.red('Invalid months value. Please provide a value between 1 and 12.'));
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
spinner.text = 'Fetching commit history...';
|
|
60
|
+
const commits = (0, gitParser_1.parseGitCommits)(absolutePath);
|
|
61
|
+
if (commits.length === 0) {
|
|
62
|
+
spinner.warn(chalk_1.default.yellow('No commits found in the repository.'));
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
spinner.text = 'Generating visualization...';
|
|
66
|
+
if (options.html) {
|
|
67
|
+
// Generate HTML output
|
|
68
|
+
const repoName = (0, gitParser_1.getRepositoryName)(absolutePath);
|
|
69
|
+
const repoUrl = (0, gitParser_1.getRepositoryUrl)(absolutePath);
|
|
70
|
+
const skipBodyCheck = !options.bodyCheck;
|
|
71
|
+
const deepAnalysis = options.deepAnalysis ?? false;
|
|
72
|
+
const html = (0, htmlGenerator_1.generateHTML)(commits, year, monthsToShow, absolutePath, repoName, repoUrl, skipBodyCheck, options.all, deepAnalysis);
|
|
73
|
+
const outputPath = path.join(os.tmpdir(), `git-wrapped-${Date.now()}.html`);
|
|
74
|
+
fs.writeFileSync(outputPath, html);
|
|
75
|
+
spinner.succeed(chalk_1.default.green('HTML file generated successfully!'));
|
|
76
|
+
console.log();
|
|
77
|
+
console.log(chalk_1.default.cyan('Opening in browser...'));
|
|
78
|
+
console.log(chalk_1.default.dim(`File: ${outputPath}`));
|
|
79
|
+
// Open in default browser
|
|
80
|
+
const command = process.platform === 'win32'
|
|
81
|
+
? `start "" "${outputPath}"`
|
|
82
|
+
: process.platform === 'darwin'
|
|
83
|
+
? `open "${outputPath}"`
|
|
84
|
+
: `xdg-open "${outputPath}"`;
|
|
85
|
+
(0, child_process_1.exec)(command);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
// Generate terminal output
|
|
89
|
+
const repoName = (0, gitParser_1.getRepositoryName)(absolutePath);
|
|
90
|
+
const repoUrl = (0, gitParser_1.getRepositoryUrl)(absolutePath);
|
|
91
|
+
const matrix = (0, matrixGenerator_1.generateCommitMatrix)(commits, year, monthsToShow, absolutePath, repoName, repoUrl);
|
|
92
|
+
spinner.succeed(chalk_1.default.green('✓ Analysis complete!'));
|
|
93
|
+
console.log(matrix);
|
|
94
|
+
console.log();
|
|
95
|
+
console.log(chalk_1.default.cyan('💡 Tip:'), chalk_1.default.dim('Run with'), chalk_1.default.white('--html'), chalk_1.default.dim('to see interactive details and per-developer analytics'));
|
|
96
|
+
console.log(chalk_1.default.dim(' Example:'), chalk_1.default.white(`git-wrapped generate ${repoPath} --html`));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
spinner.fail(chalk_1.default.red('Failed to generate visualization'));
|
|
101
|
+
console.error(chalk_1.default.red('\nError:'), error.message);
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ANALYSIS_CHRONOTYPE_EMOJIS = exports.WRAPPED_CHRONOTYPE_LABELS = exports.WRAPPED_CHRONOTYPE_EMOJIS = void 0;
|
|
4
|
-
// Chronotype definitions for YearInCodeSummary (morning/day/evening/night)
|
|
5
|
-
exports.WRAPPED_CHRONOTYPE_EMOJIS = {
|
|
6
|
-
morning: '☀️',
|
|
7
|
-
day: '📅',
|
|
8
|
-
evening: '🌆',
|
|
9
|
-
night: '🌙'
|
|
10
|
-
};
|
|
11
|
-
exports.WRAPPED_CHRONOTYPE_LABELS = {
|
|
12
|
-
morning: 'Morning Person',
|
|
13
|
-
day: 'Daytime Coder',
|
|
14
|
-
evening: 'Evening Developer',
|
|
15
|
-
night: 'Night Owl'
|
|
16
|
-
};
|
|
17
|
-
// Chronotype definitions for TimePattern analysis (early-bird/night-owl/balanced/vampire)
|
|
18
|
-
exports.ANALYSIS_CHRONOTYPE_EMOJIS = {
|
|
19
|
-
'early-bird': '🐦',
|
|
20
|
-
'night-owl': '🦉',
|
|
21
|
-
'vampire': '🧛',
|
|
22
|
-
'balanced': '⚖️'
|
|
23
|
-
};
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ANALYSIS_CHRONOTYPE_EMOJIS = exports.WRAPPED_CHRONOTYPE_LABELS = exports.WRAPPED_CHRONOTYPE_EMOJIS = void 0;
|
|
4
|
+
// Chronotype definitions for YearInCodeSummary (morning/day/evening/night)
|
|
5
|
+
exports.WRAPPED_CHRONOTYPE_EMOJIS = {
|
|
6
|
+
morning: '☀️',
|
|
7
|
+
day: '📅',
|
|
8
|
+
evening: '🌆',
|
|
9
|
+
night: '🌙'
|
|
10
|
+
};
|
|
11
|
+
exports.WRAPPED_CHRONOTYPE_LABELS = {
|
|
12
|
+
morning: 'Morning Person',
|
|
13
|
+
day: 'Daytime Coder',
|
|
14
|
+
evening: 'Evening Developer',
|
|
15
|
+
night: 'Night Owl'
|
|
16
|
+
};
|
|
17
|
+
// Chronotype definitions for TimePattern analysis (early-bird/night-owl/balanced/vampire)
|
|
18
|
+
exports.ANALYSIS_CHRONOTYPE_EMOJIS = {
|
|
19
|
+
'early-bird': '🐦',
|
|
20
|
+
'night-owl': '🦉',
|
|
21
|
+
'vampire': '🧛',
|
|
22
|
+
'balanced': '⚖️'
|
|
23
|
+
};
|
package/dist/constants/colors.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CONTRIBUTION_LEVELS = exports.GITHUB_COLORS = void 0;
|
|
4
|
-
// GitHub contribution colors
|
|
5
|
-
exports.GITHUB_COLORS = {
|
|
6
|
-
EMPTY: 'rgba(235, 237, 240, 0.1)',
|
|
7
|
-
LEVEL_1: '#9be9a8',
|
|
8
|
-
LEVEL_2: '#40c463',
|
|
9
|
-
LEVEL_3: '#30a14e',
|
|
10
|
-
LEVEL_4: '#216e39',
|
|
11
|
-
BORDER: '#21262d'
|
|
12
|
-
};
|
|
13
|
-
// Contribution thresholds
|
|
14
|
-
exports.CONTRIBUTION_LEVELS = {
|
|
15
|
-
LEVEL_1: 3,
|
|
16
|
-
LEVEL_2: 6,
|
|
17
|
-
LEVEL_3: 9
|
|
18
|
-
};
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CONTRIBUTION_LEVELS = exports.GITHUB_COLORS = void 0;
|
|
4
|
+
// GitHub contribution colors
|
|
5
|
+
exports.GITHUB_COLORS = {
|
|
6
|
+
EMPTY: 'rgba(235, 237, 240, 0.1)',
|
|
7
|
+
LEVEL_1: '#9be9a8',
|
|
8
|
+
LEVEL_2: '#40c463',
|
|
9
|
+
LEVEL_3: '#30a14e',
|
|
10
|
+
LEVEL_4: '#216e39',
|
|
11
|
+
BORDER: '#21262d'
|
|
12
|
+
};
|
|
13
|
+
// Contribution thresholds
|
|
14
|
+
exports.CONTRIBUTION_LEVELS = {
|
|
15
|
+
LEVEL_1: 3,
|
|
16
|
+
LEVEL_2: 6,
|
|
17
|
+
LEVEL_3: 9
|
|
18
|
+
};
|
package/dist/constants/index.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./colors"), exports);
|
|
18
|
-
__exportStar(require("./chronotypes"), exports);
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./colors"), exports);
|
|
18
|
+
__exportStar(require("./chronotypes"), exports);
|
package/dist/formatters/index.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./timeFormatter"), exports);
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./timeFormatter"), exports);
|
|
@@ -1,29 +1,28 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Formats an hour (0-23) to a short AM/PM string (without :00)
|
|
19
|
-
*/
|
|
20
|
-
function formatHourShort(hour) {
|
|
21
|
-
if (hour === 0)
|
|
22
|
-
return '12 AM';
|
|
23
|
-
if (hour < 12)
|
|
24
|
-
return `${hour} AM`;
|
|
25
|
-
if (hour === 12)
|
|
26
|
-
return '12 PM';
|
|
27
|
-
return `${hour - 12} PM`;
|
|
28
|
-
}
|
|
29
|
-
exports.formatHourShort = formatHourShort;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.formatHour = formatHour;
|
|
4
|
+
exports.formatHourShort = formatHourShort;
|
|
5
|
+
/**
|
|
6
|
+
* Formats an hour (0-23) to a human-readable AM/PM string
|
|
7
|
+
*/
|
|
8
|
+
function formatHour(hour) {
|
|
9
|
+
if (hour === 0)
|
|
10
|
+
return '12:00 AM';
|
|
11
|
+
if (hour < 12)
|
|
12
|
+
return `${hour}:00 AM`;
|
|
13
|
+
if (hour === 12)
|
|
14
|
+
return '12:00 PM';
|
|
15
|
+
return `${hour - 12}:00 PM`;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Formats an hour (0-23) to a short AM/PM string (without :00)
|
|
19
|
+
*/
|
|
20
|
+
function formatHourShort(hour) {
|
|
21
|
+
if (hour === 0)
|
|
22
|
+
return '12 AM';
|
|
23
|
+
if (hour < 12)
|
|
24
|
+
return `${hour} AM`;
|
|
25
|
+
if (hour === 12)
|
|
26
|
+
return '12 PM';
|
|
27
|
+
return `${hour - 12} PM`;
|
|
28
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.buildAchievementsSection =
|
|
4
|
-
// Helper: Build SVG progress ring
|
|
5
|
-
function buildProgressRing(progress, size = 50) {
|
|
6
|
-
const radius = (size / 2) - 4;
|
|
7
|
-
const circumference = 2 * Math.PI * radius;
|
|
8
|
-
const offset = circumference * (1 - progress / 100);
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildAchievementsSection = buildAchievementsSection;
|
|
4
|
+
// Helper: Build SVG progress ring
|
|
5
|
+
function buildProgressRing(progress, size = 50) {
|
|
6
|
+
const radius = (size / 2) - 4;
|
|
7
|
+
const circumference = 2 * Math.PI * radius;
|
|
8
|
+
const offset = circumference * (1 - progress / 100);
|
|
9
9
|
return `
|
|
10
10
|
<svg class="progress-ring" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
|
|
11
11
|
<circle class="progress-ring-bg" cx="${size / 2}" cy="${size / 2}" r="${radius}"
|
|
@@ -17,12 +17,12 @@ function buildProgressRing(progress, size = 50) {
|
|
|
17
17
|
stroke-linecap="round"
|
|
18
18
|
transform="rotate(-90 ${size / 2} ${size / 2})" />
|
|
19
19
|
</svg>
|
|
20
|
-
`;
|
|
21
|
-
}
|
|
22
|
-
// Helper: Build individual achievement card
|
|
23
|
-
function buildAchievementCard(achievement) {
|
|
24
|
-
const cardClass = achievement.isUnlocked ? 'unlocked' : 'locked';
|
|
25
|
-
const showProgress = !achievement.isUnlocked && achievement.progress > 0;
|
|
20
|
+
`;
|
|
21
|
+
}
|
|
22
|
+
// Helper: Build individual achievement card
|
|
23
|
+
function buildAchievementCard(achievement) {
|
|
24
|
+
const cardClass = achievement.isUnlocked ? 'unlocked' : 'locked';
|
|
25
|
+
const showProgress = !achievement.isUnlocked && achievement.progress > 0;
|
|
26
26
|
return `
|
|
27
27
|
<div class="achievement-card ${cardClass}">
|
|
28
28
|
${showProgress ? `
|
|
@@ -42,29 +42,29 @@ function buildAchievementCard(achievement) {
|
|
|
42
42
|
<div class="achievement-progress-text">${achievement.progress.toFixed(0)}%</div>
|
|
43
43
|
` : ''}
|
|
44
44
|
</div>
|
|
45
|
-
`;
|
|
46
|
-
}
|
|
47
|
-
// Helper: Generate growth narrative
|
|
48
|
-
function buildGrowthNarrative(progress) {
|
|
49
|
-
const { unlockedCount, totalCount, completionPercentage, categories, nextMilestones } = progress;
|
|
50
|
-
// Find strongest category
|
|
51
|
-
let strongestCategory = '';
|
|
52
|
-
let strongestCount = 0;
|
|
53
|
-
if (categories && categories.length > 0) {
|
|
54
|
-
for (const cat of categories) {
|
|
55
|
-
if (cat.unlocked > strongestCount) {
|
|
56
|
-
strongestCount = cat.unlocked;
|
|
57
|
-
strongestCategory = cat.name;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
// Get next milestone info
|
|
62
|
-
let nextMilestoneText = '';
|
|
63
|
-
if (nextMilestones && nextMilestones.length > 0) {
|
|
64
|
-
const next = nextMilestones[0];
|
|
65
|
-
const remaining = 100 - next.progress;
|
|
66
|
-
nextMilestoneText = `Next milestone: <strong>${next.name}</strong> — ${remaining.toFixed(0)}% to go.`;
|
|
67
|
-
}
|
|
45
|
+
`;
|
|
46
|
+
}
|
|
47
|
+
// Helper: Generate growth narrative
|
|
48
|
+
function buildGrowthNarrative(progress) {
|
|
49
|
+
const { unlockedCount, totalCount, completionPercentage, categories, nextMilestones } = progress;
|
|
50
|
+
// Find strongest category
|
|
51
|
+
let strongestCategory = '';
|
|
52
|
+
let strongestCount = 0;
|
|
53
|
+
if (categories && categories.length > 0) {
|
|
54
|
+
for (const cat of categories) {
|
|
55
|
+
if (cat.unlocked > strongestCount) {
|
|
56
|
+
strongestCount = cat.unlocked;
|
|
57
|
+
strongestCategory = cat.name;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Get next milestone info
|
|
62
|
+
let nextMilestoneText = '';
|
|
63
|
+
if (nextMilestones && nextMilestones.length > 0) {
|
|
64
|
+
const next = nextMilestones[0];
|
|
65
|
+
const remaining = 100 - next.progress;
|
|
66
|
+
nextMilestoneText = `Next milestone: <strong>${next.name}</strong> — ${remaining.toFixed(0)}% to go.`;
|
|
67
|
+
}
|
|
68
68
|
return `
|
|
69
69
|
<div class="growth-narrative">
|
|
70
70
|
<h3>Your Developer Journey</h3>
|
|
@@ -74,9 +74,9 @@ function buildGrowthNarrative(progress) {
|
|
|
74
74
|
${nextMilestoneText}
|
|
75
75
|
</p>
|
|
76
76
|
</div>
|
|
77
|
-
`;
|
|
78
|
-
}
|
|
79
|
-
function buildAchievementsSection(achievementProgress) {
|
|
77
|
+
`;
|
|
78
|
+
}
|
|
79
|
+
function buildAchievementsSection(achievementProgress) {
|
|
80
80
|
return `
|
|
81
81
|
<div class="achievements-section">
|
|
82
82
|
<h2>Achievements</h2>
|
|
@@ -151,6 +151,5 @@ function buildAchievementsSection(achievementProgress) {
|
|
|
151
151
|
</div>
|
|
152
152
|
` : ''}
|
|
153
153
|
</div>
|
|
154
|
-
`;
|
|
155
|
-
}
|
|
156
|
-
exports.buildAchievementsSection = buildAchievementsSection;
|
|
154
|
+
`;
|
|
155
|
+
}
|
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.buildCommitQualitySection =
|
|
4
|
-
function getQualityLabel(score) {
|
|
5
|
-
if (score >= 9)
|
|
6
|
-
return 'Exceptional';
|
|
7
|
-
if (score >= 8)
|
|
8
|
-
return 'Excellent';
|
|
9
|
-
if (score >= 7)
|
|
10
|
-
return 'Good';
|
|
11
|
-
if (score >= 6)
|
|
12
|
-
return 'Fair';
|
|
13
|
-
return 'Needs Attention';
|
|
14
|
-
}
|
|
15
|
-
function getQualityIndicator(value, threshold) {
|
|
16
|
-
if (value >= threshold * 0.8)
|
|
17
|
-
return '✓';
|
|
18
|
-
if (value >= threshold * 0.5)
|
|
19
|
-
return '○';
|
|
20
|
-
return '–';
|
|
21
|
-
}
|
|
22
|
-
function buildCommitQualitySection(commitQuality, totalCommits, skipBodyCheck = false) {
|
|
23
|
-
const qualityLabel = getQualityLabel(commitQuality.overallScore);
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildCommitQualitySection = buildCommitQualitySection;
|
|
4
|
+
function getQualityLabel(score) {
|
|
5
|
+
if (score >= 9)
|
|
6
|
+
return 'Exceptional';
|
|
7
|
+
if (score >= 8)
|
|
8
|
+
return 'Excellent';
|
|
9
|
+
if (score >= 7)
|
|
10
|
+
return 'Good';
|
|
11
|
+
if (score >= 6)
|
|
12
|
+
return 'Fair';
|
|
13
|
+
return 'Needs Attention';
|
|
14
|
+
}
|
|
15
|
+
function getQualityIndicator(value, threshold) {
|
|
16
|
+
if (value >= threshold * 0.8)
|
|
17
|
+
return '✓';
|
|
18
|
+
if (value >= threshold * 0.5)
|
|
19
|
+
return '○';
|
|
20
|
+
return '–';
|
|
21
|
+
}
|
|
22
|
+
function buildCommitQualitySection(commitQuality, totalCommits, skipBodyCheck = false) {
|
|
23
|
+
const qualityLabel = getQualityLabel(commitQuality.overallScore);
|
|
24
24
|
return `
|
|
25
25
|
<div class="commit-quality-section">
|
|
26
26
|
<h2>Commit Quality</h2>
|
|
@@ -84,6 +84,5 @@ function buildCommitQualitySection(commitQuality, totalCommits, skipBodyCheck =
|
|
|
84
84
|
</div>
|
|
85
85
|
` : ''}
|
|
86
86
|
</div>
|
|
87
|
-
`;
|
|
88
|
-
}
|
|
89
|
-
exports.buildCommitQualitySection = buildCommitQualitySection;
|
|
87
|
+
`;
|
|
88
|
+
}
|