brianmmaina 1.1.5 ā 1.1.8
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/index.js +192 -63
- package/package.json +4 -1
package/index.js
CHANGED
|
@@ -6,129 +6,211 @@ import figlet from 'figlet';
|
|
|
6
6
|
import chalk from 'chalk';
|
|
7
7
|
import chalkAnimation from 'chalk-animation';
|
|
8
8
|
import boxen from 'boxen';
|
|
9
|
+
import gradient from 'gradient-string';
|
|
10
|
+
import Table from 'cli-table3';
|
|
11
|
+
import { createSpinner } from 'nanospinner';
|
|
9
12
|
|
|
10
13
|
// Placeholder URLs - replace with actual ones
|
|
11
14
|
const resumeUrl = 'https://drive.google.com/your-resume-link';
|
|
12
15
|
const githubUrl = 'https://github.com/your-github';
|
|
13
16
|
|
|
14
|
-
const
|
|
17
|
+
const sleep = (ms = 2000) => new Promise((r) => setTimeout(r, ms));
|
|
15
18
|
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
const showIntro = async () => {
|
|
20
|
+
console.clear();
|
|
21
|
+
const msg = 'Brian Maina';
|
|
22
|
+
|
|
23
|
+
return new Promise((resolve) => {
|
|
24
|
+
figlet(msg, (err, data) => {
|
|
25
|
+
console.log(gradient.pastel.multiline(data) + '\n');
|
|
26
|
+
|
|
27
|
+
const intro = gradient.cristal('Hi, I\'m Brian Maina! A passionate developer who loves coding, movies, and video games.');
|
|
28
|
+
const box = boxen(intro, {
|
|
29
|
+
padding: 1,
|
|
30
|
+
margin: 1,
|
|
31
|
+
borderStyle: 'double',
|
|
32
|
+
borderColor: 'cyan',
|
|
33
|
+
backgroundColor: '#000',
|
|
34
|
+
float: 'center'
|
|
35
|
+
});
|
|
36
|
+
console.log(box);
|
|
37
|
+
resolve();
|
|
38
|
+
});
|
|
39
|
+
});
|
|
21
40
|
};
|
|
22
41
|
|
|
23
42
|
const mainMenu = async () => {
|
|
24
|
-
console.clear();
|
|
25
|
-
console.log(boxen(intro, options));
|
|
26
|
-
|
|
27
43
|
const { choice } = await inquirer.prompt([
|
|
28
44
|
{
|
|
29
45
|
type: 'list',
|
|
30
46
|
name: 'choice',
|
|
31
|
-
message: 'What would you like to
|
|
47
|
+
message: 'What would you like to explore?',
|
|
32
48
|
choices: [
|
|
33
|
-
'View Resume',
|
|
34
|
-
'View GitHub',
|
|
35
|
-
'Play Song with Dance',
|
|
36
|
-
'Play Ping Pong',
|
|
37
|
-
'
|
|
38
|
-
|
|
49
|
+
{ name: 'š View Resume', value: 'resume' },
|
|
50
|
+
{ name: 'š View GitHub', value: 'github' },
|
|
51
|
+
{ name: 'šµ Play Song with Dance', value: 'song' },
|
|
52
|
+
{ name: 'š Play Ping Pong', value: 'pingpong' },
|
|
53
|
+
{ name: 'š¼ View Skills & Portfolio', value: 'portfolio' },
|
|
54
|
+
{ name: 'š Contact Info', value: 'contact' },
|
|
55
|
+
{ name: 'šŖ Exit', value: 'exit' }
|
|
56
|
+
],
|
|
57
|
+
pageSize: 7
|
|
39
58
|
}
|
|
40
59
|
]);
|
|
41
60
|
|
|
42
61
|
switch (choice) {
|
|
43
|
-
case '
|
|
44
|
-
await
|
|
45
|
-
console.log('Opening resume...');
|
|
62
|
+
case 'resume':
|
|
63
|
+
await viewResume();
|
|
46
64
|
break;
|
|
47
|
-
case '
|
|
48
|
-
await
|
|
49
|
-
console.log('Opening GitHub...');
|
|
65
|
+
case 'github':
|
|
66
|
+
await viewGitHub();
|
|
50
67
|
break;
|
|
51
|
-
case '
|
|
68
|
+
case 'song':
|
|
52
69
|
await playSongWithDance();
|
|
53
70
|
break;
|
|
54
|
-
case '
|
|
71
|
+
case 'pingpong':
|
|
55
72
|
await playPingPong();
|
|
56
73
|
break;
|
|
57
|
-
case '
|
|
58
|
-
|
|
74
|
+
case 'portfolio':
|
|
75
|
+
await viewPortfolio();
|
|
76
|
+
break;
|
|
77
|
+
case 'contact':
|
|
78
|
+
await viewContact();
|
|
79
|
+
break;
|
|
80
|
+
case 'exit':
|
|
81
|
+
console.log(gradient.pastel('Thanks for visiting! Goodbye! š'));
|
|
59
82
|
process.exit(0);
|
|
60
83
|
}
|
|
61
84
|
|
|
62
|
-
|
|
63
|
-
|
|
85
|
+
await sleep(1000);
|
|
86
|
+
await mainMenu();
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const viewResume = async () => {
|
|
90
|
+
const spinner = createSpinner('Opening resume...').start();
|
|
91
|
+
await sleep(1000);
|
|
92
|
+
await open(resumeUrl);
|
|
93
|
+
spinner.success({ text: 'Resume opened in browser!' });
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const viewGitHub = async () => {
|
|
97
|
+
const spinner = createSpinner('Opening GitHub...').start();
|
|
98
|
+
await sleep(1000);
|
|
99
|
+
await open(githubUrl);
|
|
100
|
+
spinner.success({ text: 'GitHub opened in browser!' });
|
|
64
101
|
};
|
|
65
102
|
|
|
66
103
|
const playSongWithDance = async () => {
|
|
67
104
|
console.clear();
|
|
68
|
-
console.log('
|
|
105
|
+
console.log(gradient.fruit('šµ Now playing: "Your Favorite Song" šµ\n'));
|
|
69
106
|
|
|
70
|
-
// Simple dancing ASCII art animation
|
|
71
107
|
const frames = [
|
|
72
108
|
`
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
109
|
+
šø
|
|
110
|
+
/|\\
|
|
111
|
+
/ | \\
|
|
112
|
+
/ | \\
|
|
113
|
+
/ | \\
|
|
114
|
+
/ | \\
|
|
115
|
+
/ | \\
|
|
116
|
+
/ | \\
|
|
76
117
|
`,
|
|
77
118
|
`
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
119
|
+
šø
|
|
120
|
+
/|\\
|
|
121
|
+
/ | \\
|
|
122
|
+
/ | \\
|
|
123
|
+
/ | \\
|
|
124
|
+
/ | \\
|
|
125
|
+
/ | \\
|
|
126
|
+
/ | \\
|
|
127
|
+
_____
|
|
128
|
+
/ \\
|
|
129
|
+
/ \\
|
|
81
130
|
`,
|
|
82
131
|
`
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
132
|
+
šø
|
|
133
|
+
/|\\
|
|
134
|
+
/ | \\
|
|
135
|
+
/ | \\
|
|
136
|
+
/ | \\
|
|
137
|
+
/ | \\
|
|
138
|
+
/ | \\
|
|
139
|
+
/ | \\
|
|
140
|
+
_____
|
|
141
|
+
/ \\
|
|
142
|
+
/ \\
|
|
143
|
+
\\ /
|
|
144
|
+
\\___/
|
|
86
145
|
`,
|
|
87
146
|
`
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
147
|
+
šø
|
|
148
|
+
/|\\
|
|
149
|
+
/ | \\
|
|
150
|
+
/ | \\
|
|
151
|
+
/ | \\
|
|
152
|
+
/ | \\
|
|
153
|
+
/ | \\
|
|
154
|
+
/ | \\
|
|
155
|
+
_____
|
|
156
|
+
/ \\
|
|
157
|
+
/ \\
|
|
158
|
+
\\ /
|
|
159
|
+
\\___/
|
|
160
|
+
| |
|
|
161
|
+
| |
|
|
91
162
|
`
|
|
92
163
|
];
|
|
93
164
|
|
|
94
165
|
let frame = 0;
|
|
166
|
+
const lyrics = [
|
|
167
|
+
"āŖ La la la la āŖ",
|
|
168
|
+
"āŖ Your favorite tune āŖ",
|
|
169
|
+
"āŖ Dancing in the terminal āŖ",
|
|
170
|
+
"āŖ So much fun! āŖ"
|
|
171
|
+
];
|
|
172
|
+
|
|
95
173
|
const interval = setInterval(() => {
|
|
96
174
|
console.clear();
|
|
97
|
-
console.log(frames[frame]);
|
|
175
|
+
console.log(gradient.fruit(frames[frame]));
|
|
176
|
+
console.log(gradient.pastel(lyrics[frame % lyrics.length]));
|
|
98
177
|
frame = (frame + 1) % frames.length;
|
|
99
|
-
},
|
|
178
|
+
}, 800);
|
|
100
179
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
}, 10000);
|
|
180
|
+
await sleep(10000);
|
|
181
|
+
clearInterval(interval);
|
|
182
|
+
console.log(gradient.cristal('\nš Song ended! Hope you enjoyed the dance! š'));
|
|
105
183
|
};
|
|
106
184
|
|
|
107
185
|
const playPingPong = async () => {
|
|
108
186
|
console.clear();
|
|
109
|
-
console.log('Ping Pong
|
|
187
|
+
console.log(gradient.fruit('š Ping Pong Championship! š\n'));
|
|
188
|
+
console.log('Controls: A/D to move paddle, Q to quit\n');
|
|
110
189
|
|
|
111
|
-
|
|
112
|
-
let paddlePos = 10;
|
|
190
|
+
let paddlePos = 15;
|
|
113
191
|
let ballX = 20;
|
|
114
192
|
let ballY = 10;
|
|
115
193
|
let ballDirX = 1;
|
|
116
194
|
let ballDirY = 1;
|
|
117
195
|
const width = 40;
|
|
118
196
|
const height = 20;
|
|
197
|
+
let score = 0;
|
|
119
198
|
|
|
120
199
|
process.stdin.setRawMode(true);
|
|
121
200
|
process.stdin.resume();
|
|
122
201
|
|
|
123
202
|
const render = () => {
|
|
124
203
|
console.clear();
|
|
204
|
+
console.log(gradient.fruit(`Score: ${score}`));
|
|
125
205
|
for (let y = 0; y < height; y++) {
|
|
126
206
|
let line = '';
|
|
127
207
|
for (let x = 0; x < width; x++) {
|
|
128
208
|
if (y === ballY && x === ballX) {
|
|
129
|
-
line += '
|
|
130
|
-
} else if (y === height - 1 && x >= paddlePos && x < paddlePos +
|
|
131
|
-
line += '
|
|
209
|
+
line += gradient.fruit('ā');
|
|
210
|
+
} else if (y === height - 1 && x >= paddlePos && x < paddlePos + 8) {
|
|
211
|
+
line += gradient.cristal('ā');
|
|
212
|
+
} else if (y === 0 || y === height - 1 || x === 0 || x === width - 1) {
|
|
213
|
+
line += 'ā';
|
|
132
214
|
} else {
|
|
133
215
|
line += ' ';
|
|
134
216
|
}
|
|
@@ -141,13 +223,14 @@ const playPingPong = async () => {
|
|
|
141
223
|
ballX += ballDirX;
|
|
142
224
|
ballY += ballDirY;
|
|
143
225
|
|
|
144
|
-
if (ballX <=
|
|
145
|
-
if (ballY <=
|
|
146
|
-
if (ballY >= height - 2 && ballX >= paddlePos && ballX < paddlePos +
|
|
226
|
+
if (ballX <= 1 || ballX >= width - 2) ballDirX *= -1;
|
|
227
|
+
if (ballY <= 1) ballDirY *= -1;
|
|
228
|
+
if (ballY >= height - 2 && ballX >= paddlePos && ballX < paddlePos + 8) {
|
|
147
229
|
ballDirY *= -1;
|
|
230
|
+
score++;
|
|
148
231
|
}
|
|
149
232
|
if (ballY >= height - 1) {
|
|
150
|
-
console.log(
|
|
233
|
+
console.log(gradient.pastel(`\nGame Over! Final Score: ${score}`));
|
|
151
234
|
clearInterval(gameLoop);
|
|
152
235
|
process.stdin.setRawMode(false);
|
|
153
236
|
process.stdin.pause();
|
|
@@ -155,20 +238,66 @@ const playPingPong = async () => {
|
|
|
155
238
|
}
|
|
156
239
|
|
|
157
240
|
render();
|
|
158
|
-
},
|
|
241
|
+
}, 150);
|
|
159
242
|
|
|
160
243
|
process.stdin.on('data', (key) => {
|
|
161
244
|
if (key[0] === 97) { // 'a'
|
|
162
|
-
paddlePos = Math.max(
|
|
245
|
+
paddlePos = Math.max(1, paddlePos - 2);
|
|
163
246
|
} else if (key[0] === 100) { // 'd'
|
|
164
|
-
paddlePos = Math.min(width -
|
|
247
|
+
paddlePos = Math.min(width - 9, paddlePos + 2);
|
|
165
248
|
} else if (key[0] === 113) { // 'q'
|
|
166
249
|
clearInterval(gameLoop);
|
|
167
250
|
process.stdin.setRawMode(false);
|
|
168
251
|
process.stdin.pause();
|
|
169
|
-
console.log('
|
|
252
|
+
console.log(gradient.pastel('\nGame quit!'));
|
|
170
253
|
}
|
|
171
254
|
});
|
|
172
255
|
};
|
|
173
256
|
|
|
174
|
-
|
|
257
|
+
const viewPortfolio = async () => {
|
|
258
|
+
console.clear();
|
|
259
|
+
console.log(gradient.fruit('š¼ My Skills & Portfolio š¼\n'));
|
|
260
|
+
|
|
261
|
+
const table = new Table({
|
|
262
|
+
head: [gradient.cristal('Skill'), gradient.cristal('Level')],
|
|
263
|
+
colWidths: [20, 20],
|
|
264
|
+
style: { head: [], border: [] }
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
table.push(
|
|
268
|
+
['JavaScript', 'āāāāā'],
|
|
269
|
+
['Node.js', 'āāāāā'],
|
|
270
|
+
['React', 'āāāā'],
|
|
271
|
+
['Python', 'āāāā'],
|
|
272
|
+
['Terminal Magic', 'āāāāā']
|
|
273
|
+
);
|
|
274
|
+
|
|
275
|
+
console.log(table.toString());
|
|
276
|
+
|
|
277
|
+
console.log('\n' + gradient.pastel('Projects:'));
|
|
278
|
+
console.log('⢠Terminal Business Card (You\'re using it!)');
|
|
279
|
+
console.log('⢠Awesome CLI Tools');
|
|
280
|
+
console.log('⢠Web Applications');
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
const viewContact = async () => {
|
|
284
|
+
console.clear();
|
|
285
|
+
console.log(gradient.fruit('š Contact Information š\n'));
|
|
286
|
+
|
|
287
|
+
const contactTable = new Table({
|
|
288
|
+
style: { head: [], border: [] }
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
contactTable.push(
|
|
292
|
+
{ 'Email': 'brian@example.com' },
|
|
293
|
+
{ 'LinkedIn': 'linkedin.com/in/brianmaina' },
|
|
294
|
+
{ 'Twitter': 'twitter.com/brianmaina' }
|
|
295
|
+
);
|
|
296
|
+
|
|
297
|
+
console.log(contactTable.toString());
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
(async () => {
|
|
301
|
+
await showIntro();
|
|
302
|
+
await mainMenu();
|
|
303
|
+
})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "brianmmaina",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.8",
|
|
4
4
|
"description": "My terminal business card",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -17,8 +17,11 @@
|
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"boxen": "^8.0.1",
|
|
19
19
|
"chalk-animation": "^2.0.3",
|
|
20
|
+
"cli-table3": "^0.6.5",
|
|
20
21
|
"figlet": "^1.10.0",
|
|
22
|
+
"gradient-string": "^3.0.0",
|
|
21
23
|
"inquirer": "^13.2.5",
|
|
24
|
+
"nanospinner": "^1.2.2",
|
|
22
25
|
"open": "^11.0.0"
|
|
23
26
|
}
|
|
24
27
|
}
|