@itcase/config 1.6.76 → 1.6.78
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/README.md +2 -2
- package/package.json +4 -4
- package/smart-commit/cli.js +169 -35
- package/smart-commit/dancing-banana.js +339 -224
- package/smart-commit/nyan-cat.js +327 -0
- package/smart-commit/scripts/extract-banana.py +0 -255
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
// Frames from klange/nyancat (NCSA), https://github.com/klange/nyancat
|
|
2
|
+
// Cat + shortened rainbow, no fill background.
|
|
3
|
+
// 2-space cells; shrinks to terminal width.
|
|
4
|
+
|
|
5
|
+
const RESET = '\x1b[0m'
|
|
6
|
+
const FRAME_WIDTH = 40
|
|
7
|
+
const FRAME_HEIGHT = 19
|
|
8
|
+
|
|
9
|
+
const COLORS = {
|
|
10
|
+
'#': 118,
|
|
11
|
+
$: 175,
|
|
12
|
+
'%': 175,
|
|
13
|
+
'&': 214,
|
|
14
|
+
"'": 16,
|
|
15
|
+
'*': 240,
|
|
16
|
+
'+': 226,
|
|
17
|
+
'-': 162,
|
|
18
|
+
'.': 231,
|
|
19
|
+
';': 19,
|
|
20
|
+
'=': 33,
|
|
21
|
+
'>': 196,
|
|
22
|
+
'@': 230,
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const FRAMES = [
|
|
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
|
+
",>>>>>>>>,,,,,,,,''''''''''''''',,,,,,,,",
|
|
71
|
+
">>>>>>>>>>>>>>>>'@@@@@@@@@@@@@@@',,,,,,,",
|
|
72
|
+
">&&&&&&&&>>>>>>'@@@$$$$$$$$$$$@@@',,,,,,",
|
|
73
|
+
"&&&&&&&&&&&&&&&'@@$$$$$-$$-$$$$@@',,,,,,",
|
|
74
|
+
"&&&&&&&&&&&&&&&'@$$-$$$$$$$''-$$@',,'',,",
|
|
75
|
+
"&++++++++&&&&&&'@$$$$$$$$$'**'$$@','**',",
|
|
76
|
+
"+++++++++++++++'@$$$$$-$$$'***$$@''***',",
|
|
77
|
+
"+++++++++++++++'@$$$$$$$$$'***''''****',",
|
|
78
|
+
"+########++++++'@$$$$$$$$$'***********',",
|
|
79
|
+
"##############''@$$$$$$-$'*************'",
|
|
80
|
+
"###########'''''@$-$$$$$$'***.'****.'**'",
|
|
81
|
+
"#========#'****'@$$$$$$$$'***''**'*''**'",
|
|
82
|
+
"==========='''='@@$$$-$$$'*%%********%%'",
|
|
83
|
+
"=;;;;;;;;======'@@@$$$$$$$'***''''''**',",
|
|
84
|
+
";;;;;;;;;;;;;;;''@@@@@@@@@@'*********',,",
|
|
85
|
+
";;;;;;;;;;;;;;;'*'''''''''''''''''''',,,",
|
|
86
|
+
";,,,,,,,,;;;;;;'**',**',,,,,,**','**',,,",
|
|
87
|
+
",,,,,,,,,,,,,,,''',,''',,,,,,''',,''',,,",
|
|
88
|
+
],
|
|
89
|
+
[
|
|
90
|
+
',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',
|
|
91
|
+
",>>>>>>>>,,,,,,,,''''''''''''''',,,,,,,,",
|
|
92
|
+
">>>>>>>>>>>>>>>>'@@@@@@@@@@@@@@@',,,,,,,",
|
|
93
|
+
">&&&&&&&&>>>>>>'@@@$$$$$$$$$$$@@@',,,,,,",
|
|
94
|
+
"&&&&&&&&&&&&&&&'@@$$$$$-$$-$$$$@@',,,,,,",
|
|
95
|
+
"&&&&&&&&&&&&&&&'@$$-$$$$$$$''-$$@',,'',,",
|
|
96
|
+
"&++++++++&&&&&&'@$$$$$$$$$'**'$$@','**',",
|
|
97
|
+
"+++++++++++++++'@$$$$$-$$$'***$$@''***',",
|
|
98
|
+
"+++++++++++++++'@$$$$$$$$$'***''''****',",
|
|
99
|
+
"+########++++++'@$$$$$$$$$'***********',",
|
|
100
|
+
"#############'''@$$$$$$-$'*************'",
|
|
101
|
+
"###########''**'@$-$$$$$$'***.'****.'**'",
|
|
102
|
+
"#========##****'@$$$$$$$$'***''**'*''**'",
|
|
103
|
+
"=========='*'=='@@$$$-$$$'*%%********%%'",
|
|
104
|
+
"=;;;;;;;;=='==='@@@$$$$$$$'***''''''**',",
|
|
105
|
+
";;;;;;;;;;;;;;;''@@@@@@@@@@'*********',,",
|
|
106
|
+
";;;;;;;;;;;;;;'**'''''''''''''''''''',,,",
|
|
107
|
+
";,,,,,,,,;;;;;'**','*',,,,,,'*','**',,,,",
|
|
108
|
+
",,,,,,,,,,,,,,''',,,'',,,,,,,'',,''',,,,",
|
|
109
|
+
],
|
|
110
|
+
[
|
|
111
|
+
',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',
|
|
112
|
+
">>,,,,,,,,>>>>>>>''''''''''''''',,,,,,,,",
|
|
113
|
+
">>>>>>>>>>>>>>>>'@@@@@@@@@@@@@@@',,,,,,,",
|
|
114
|
+
"&&>>>>>>>>&&&&&'@@@$$$$$$$$$$$@@@',,,,,,",
|
|
115
|
+
"&&&&&&&&&&&&&&&'@@$$$$$-$$-$$$$@@',,,,,,",
|
|
116
|
+
"&&&&&&&&&&&&&&&'@$$-$$$$$$''$-$$@','',,,",
|
|
117
|
+
"++&&&&&&&&+++++'@$$$$$$$$'**'$$$@''**',,",
|
|
118
|
+
"+++++++++++++++'@$$$$$-$$'***$$$@'***',,",
|
|
119
|
+
"++++++++++'''++'@$$$$$$$$'***''''****',,",
|
|
120
|
+
"##+++++++'**''''@$$$$$$$$'***********',,",
|
|
121
|
+
"#########'****''@$$$$$$-'*************',",
|
|
122
|
+
"##########''''*'@$-$$$$$'***.'****.'**',",
|
|
123
|
+
"==########==='''@$$$$$$$'***''**'*''**',",
|
|
124
|
+
"==============='@@$$$-$$'*%%********%%',",
|
|
125
|
+
";;========;;;;''@@@$$$$$$'***''''''**',,",
|
|
126
|
+
";;;;;;;;;;;;;''''@@@@@@@@@'*********',,,",
|
|
127
|
+
";;;;;;;;;;;;'***'''''''''''''''''''',,,,",
|
|
128
|
+
",,;;;;;;;;,,'**','**,,,,,,'**,'**',,,,,,",
|
|
129
|
+
",,,,,,,,,,,,''',,,'',,,,,,,'',,''',,,,,,",
|
|
130
|
+
],
|
|
131
|
+
[
|
|
132
|
+
',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',
|
|
133
|
+
">>,,,,,,,,>>>>>>>''''''''''''''',,,,,,,,",
|
|
134
|
+
">>>>>>>>>>>>>>>>'@@@@@@@@@@@@@@@',,,,,,,",
|
|
135
|
+
"&&>>>>>>>>&&&&&'@@@$$$$$$$$$$$@@@',,,,,,",
|
|
136
|
+
"&&&&&&&&&&&&&&&'@@$$$$$-$$''$$$@@','',,,",
|
|
137
|
+
"&&&&&&&&&&&&&&&'@$$-$$$$$'**'-$$@''**',,",
|
|
138
|
+
"++&&&&&&&&+++++'@$$$$$$$$'***$$$@'***',,",
|
|
139
|
+
"+++++++++++'+++'@$$$$$-$$'***''''****',,",
|
|
140
|
+
"++++++++++'*'++'@$$$$$$$$'***********',,",
|
|
141
|
+
"##++++++++'*''''@$$$$$$$'*************',",
|
|
142
|
+
"###########****'@$$$$$$-'***.'****.'**',",
|
|
143
|
+
"###########''**'@$-$$$$$'***''**'*''**',",
|
|
144
|
+
"==########==='''@$$$$$$$'*%%********%%',",
|
|
145
|
+
"==============='@@$$$-$$$'***''''''**',,",
|
|
146
|
+
";;========;;;;''@@@$$$$$$$'*********',,,",
|
|
147
|
+
";;;;;;;;;;;;;'*''@@@@@@@@@@''''''''',,,,",
|
|
148
|
+
";;;;;;;;;;;;'***''''''''''''''''*',,,,,,",
|
|
149
|
+
",,;;;;;;;;,,'**','**,,,,,,'**,'**',,,,,,",
|
|
150
|
+
",,,,,,,,,,,,''',,''',,,,,,''',,''',,,,,,",
|
|
151
|
+
],
|
|
152
|
+
[
|
|
153
|
+
",,,,,,,,,,,,,,,,,''''''''''''''',,,,,,,,",
|
|
154
|
+
",>>>>>>>>,,,,,,,'@@@@@@@@@@@@@@@',,,,,,,",
|
|
155
|
+
">>>>>>>>>>>>>>>'@@@$$$$$$$$$$$@@@',,,,,,",
|
|
156
|
+
">&&&&&&&&>>>>>>'@@$$$$$-$$-$$$$@@',,,,,,",
|
|
157
|
+
"&&&&&&&&&&&&&&&'@$$-$$$$$$''$-$$@','',,,",
|
|
158
|
+
"&&&&&&&&&&&&&&&'@$$$$$$$$'**'$$$@''**',,",
|
|
159
|
+
"&++++++++&'''&&'@$$$$$-$$'***$$$@'***',,",
|
|
160
|
+
"++++++++++'*''+'@$$$$$$$$'***''''****',,",
|
|
161
|
+
"++++++++++'**'''@$$$$$$$$'***********',,",
|
|
162
|
+
"+########++'**''@$$$$$$-'*************',",
|
|
163
|
+
"###########''**'@$-$$$$$'***.'****.'**',",
|
|
164
|
+
"############''''@$$$$$$$'***''**'*''**',",
|
|
165
|
+
"#========#####''@@$$$-$$'*%%********%%',",
|
|
166
|
+
"==============='@@@$$$$$$'***''''''**',,",
|
|
167
|
+
"=;;;;;;;;====='''@@@@@@@@@'*********',,,",
|
|
168
|
+
";;;;;;;;;;;;;'***''''''''''''''''''',,,,",
|
|
169
|
+
";;;;;;;;;;;;;'**'','*',,,,,'**,'**',,,,,",
|
|
170
|
+
";,,,,,,,,;;;;'''',,'',,,,,,,'',,'',,,,,,",
|
|
171
|
+
',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',
|
|
172
|
+
],
|
|
173
|
+
[
|
|
174
|
+
",,,,,,,,,,,,,,,,,''''''''''''''',,,,,,,,",
|
|
175
|
+
",>>>>>>>>,,,,,,,'@@@@@@@@@@@@@@@',,,,,,,",
|
|
176
|
+
">>>>>>>>>>>>>>>'@@@$$$$$$$$$$$@@@',,,,,,",
|
|
177
|
+
">&&&&&&&&>>>>>>'@@$$$$$-$$-$$$$@@',,,,,,",
|
|
178
|
+
"&&&&&&&&&&&&&&&'@$$-$$$$$$$''-$$@',,'',,",
|
|
179
|
+
"&&&&&&&&&&&&&&&'@$$$$$$$$$'**'$$@','**',",
|
|
180
|
+
"&++++++++&&&&&&'@$$$$$-$$$'***$$@''***',",
|
|
181
|
+
"+++++++++++'+++'@$$$$$$$$$'***''''****',",
|
|
182
|
+
"++++++++++'*'++'@$$$$$$$$$'***********',",
|
|
183
|
+
"+########+'*''''@$$$$$$-$'*************'",
|
|
184
|
+
"###########****'@$-$$$$$$'***.'****.'**'",
|
|
185
|
+
"###########''**'@$$$$$$$$'***''**'*''**'",
|
|
186
|
+
"#========####'''@@$$$-$$$'*%%********%%'",
|
|
187
|
+
"==============='@@@$$$$$$$'***''''''**',",
|
|
188
|
+
"=;;;;;;;;======''@@@@@@@@@@'*********',,",
|
|
189
|
+
";;;;;;;;;;;;;;'**'''''''''''''''''''',,,",
|
|
190
|
+
";;;;;;;;;;;;;;'**','*',,,,,,**','**',,,,",
|
|
191
|
+
";,,,,,,,,;;;;;''',,,'',,,,,,''',,''',,.,",
|
|
192
|
+
',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',
|
|
193
|
+
],
|
|
194
|
+
[
|
|
195
|
+
',,,,,,,,,,,,,,,,,,,.,,,,,,,,,,,,,,,,,,,,',
|
|
196
|
+
">>,,,,,,,,>>>>>>>''''''''''''''',,,,,,,,",
|
|
197
|
+
">>>>>>>>>>>>>>>>'@@@@@@@@@@@@@@@',,,,,,,",
|
|
198
|
+
"&&>>>>>>>>&&&&&'@@@$$$$$$$$$$$@@@',,,,,,",
|
|
199
|
+
"&&&&&&&&&&&&&&&'@@$$$$$-$$-$$$$@@',,,,,,",
|
|
200
|
+
"&&&&&&&&&&&&&&&'@$$-$$$$$$$''-$$@',,'',,",
|
|
201
|
+
"++&&&&&&&&+++++'@$$$$$$$$$'**'$$@','**',",
|
|
202
|
+
"+++++++++++++++'@$$$$$-$$$'***$$@''***',",
|
|
203
|
+
"+++++++++++++++'@$$$$$$$$$'***''''****',",
|
|
204
|
+
"##++++++++#####'@$$$$$$$$$'***********',",
|
|
205
|
+
"##############''@$$$$$$-$'*************'",
|
|
206
|
+
"###########'''''@$-$$$$$$'***.'****.'**'",
|
|
207
|
+
"==########'****'@$$$$$$$$'***''**'*''**'",
|
|
208
|
+
"==========='''='@@$$$-$$$'*%%********%%'",
|
|
209
|
+
";;========;;;;;'@@@$$$$$$$'***''''''**',",
|
|
210
|
+
";;;;;;;;;;;;;;;''@@@@@@@@@@'*********',,",
|
|
211
|
+
";;;;;;;;;;;;;;;'*'''''''''''''''''''',,,",
|
|
212
|
+
",,;;;;;;;;,,,,,'**',**',,,,,,**'.'**',,,",
|
|
213
|
+
",,,,,,,,,,,,,,,''',,''',,,,,,''',,''',,,",
|
|
214
|
+
],
|
|
215
|
+
[
|
|
216
|
+
',,,,,,,,,,.,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',
|
|
217
|
+
">>,,,,,,,,>>>>>>>''''''''''''''',,,,,,,,",
|
|
218
|
+
">>>>>>>>>>>>>>>>'@@@@@@@@@@@@@@@',,,,,,,",
|
|
219
|
+
"&&>>>>>>>>&&&&&'@@@$$$$$$$$$$$@@@',,,,,,",
|
|
220
|
+
"&&&&&&&&&&&&&&&'@@$$$$$-$$-$$$$@@',,,,,,",
|
|
221
|
+
"&&&&&&&&&&&&&&&'@$$-$$$$$$$''-$$@',,'',,",
|
|
222
|
+
"++&&&&&&&&+++++'@$$$$$$$$$'**'$$@','**',",
|
|
223
|
+
"+++++++++++++++'@$$$$$-$$$'***$$@''***',",
|
|
224
|
+
"+++++++++++++++'@$$$$$$$$$'***''''****',",
|
|
225
|
+
"##++++++++#####'@$$$$$$$$$'***********',",
|
|
226
|
+
"#############'''@$$$$$$-$'*************'",
|
|
227
|
+
"###########''**'@$-$$$$$$'***.'****.'**'",
|
|
228
|
+
"==########=****'@$$$$$$$$'***''**'*''**'",
|
|
229
|
+
"=========='*'=='@@$$$-$$$'*%%********%%'",
|
|
230
|
+
";;========;';;;'@@@$$$$$$$'***''''''**',",
|
|
231
|
+
";;;;;;;;;;;;;;;''@@@@@@@@@@'*********',,",
|
|
232
|
+
";;;;;;;;;;;;;;'**'''''''''''''''''''',,,",
|
|
233
|
+
",,;;;;;;;;,,,,'**','*',,..,.**','**',,,,",
|
|
234
|
+
",,,,,,,,,,,,,,''',,,'',,,,.,''',,''',,,,",
|
|
235
|
+
],
|
|
236
|
+
[
|
|
237
|
+
',,.,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',
|
|
238
|
+
",>>>>>>>>,,,,,,,,''''''''''''''',,,,,,,,",
|
|
239
|
+
">>>>>>>>>>>>>>>>'@@@@@@@@@@@@@@@',,,,,,,",
|
|
240
|
+
">&&&&&&&&>>>>>>'@@@$$$$$$$$$$$@@@',,,,,,",
|
|
241
|
+
"&&&&&&&&&&&&&&&'@@$$$$$-$$-$$$$@@',,,,,,",
|
|
242
|
+
"&&&&&&&&&&&&&&&'@$$-$$$$$$''$-$$@','',,,",
|
|
243
|
+
"&++++++++&&&&&&'@$$$$$$$$'**'$$$@''**',,",
|
|
244
|
+
"+++++++++++++++'@$$$$$-$$'***$$$@'***',,",
|
|
245
|
+
"++++++++++'''++'@$$$$$$$$'***''''****',,",
|
|
246
|
+
"+########'**''''@$$$$$$$$'***********',,",
|
|
247
|
+
"#########'****''@$$$$$$-'*************',",
|
|
248
|
+
"##########''''*'@$-$$$$$'***.'****.'**',",
|
|
249
|
+
"#========####'''@$$$$$$$'***''**'*''**',",
|
|
250
|
+
"==============='@@$$$-$$'*%%********%%',",
|
|
251
|
+
"=;;;;;;;;=====''@@@$$$$$$'***''''''**',,",
|
|
252
|
+
";;;;;;;;;;;;;''''@@@@@@@@@'*********',,,",
|
|
253
|
+
";;;;;;;;;;;;'***'''''''''''''''''''',,,,",
|
|
254
|
+
";,,,,,,,,;;;'**'.'**..,,,,'**''**',,,,,,",
|
|
255
|
+
",,,,,,,,,,,,''',,,'',,,,,,,''',''',,,,,,",
|
|
256
|
+
],
|
|
257
|
+
[
|
|
258
|
+
',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,',
|
|
259
|
+
",>>>>>>>>,,,,,,,,''''''''''''''',,,,,,,,",
|
|
260
|
+
">>>>>>>>>>>>>>>>'@@@@@@@@@@@@@@@',,,,,,,",
|
|
261
|
+
">&&&&&&&&>>>>>>'@@@$$$$$$$$$$$@@@',,,,,,",
|
|
262
|
+
"&&&&&&&&&&&&&&&'@@$$$$$-$$''$$$@@','',,,",
|
|
263
|
+
"&&&&&&&&&&&&&&&'@$$-$$$$$'**'-$$@''**',,",
|
|
264
|
+
"&++++++++&&&&&&'@$$$$$$$$'***$$$@'***',,",
|
|
265
|
+
"+++++++++++'+++'@$$$$$-$$'***''''****',,",
|
|
266
|
+
"++++++++++'*'++'@$$$$$$$$'***********',,",
|
|
267
|
+
"+########+'*''''@$$$$$$$'*************',",
|
|
268
|
+
"###########****'@$$$$$$-'***.'****.'**',",
|
|
269
|
+
"###########''**'@$-$$$$$'***''**'*''**',",
|
|
270
|
+
"#========####'''@$$$$$$$'*%%********%%',",
|
|
271
|
+
"==============='@@$$$-$$$'***''''''**',,",
|
|
272
|
+
"=;;;;;;;;=.===''@@@$$$$$$$'*********',,,",
|
|
273
|
+
";;;;;;;;;;;;.'*''@@@@@@@@@@''''''''',,,,",
|
|
274
|
+
";;;;;;;;;;;;'***''''''''''''''''*',,,,,,",
|
|
275
|
+
";,,,,,,,.;;;'**','**,,,,,,'**''**',,,,,,",
|
|
276
|
+
",,,,,,,,,,,,''',,''',,,,,,''',,''',,,,,,",
|
|
277
|
+
],
|
|
278
|
+
]
|
|
279
|
+
|
|
280
|
+
function pickColumns(srcWidth, maxCells) {
|
|
281
|
+
if (srcWidth <= maxCells) {
|
|
282
|
+
return Array.from({ length: srcWidth }, (_, i) => i)
|
|
283
|
+
}
|
|
284
|
+
return Array.from({ length: maxCells }, (_, i) =>
|
|
285
|
+
Math.round((i * (srcWidth - 1)) / (maxCells - 1)),
|
|
286
|
+
)
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
function renderRow(row, columns) {
|
|
290
|
+
const padded = row.padEnd(FRAME_WIDTH, ',').slice(0, FRAME_WIDTH)
|
|
291
|
+
const indexes = pickColumns(FRAME_WIDTH, columns)
|
|
292
|
+
let line = ''
|
|
293
|
+
let last = -1
|
|
294
|
+
for (const x of indexes) {
|
|
295
|
+
const cell = padded[x]
|
|
296
|
+
const code = cell === ',' ? undefined : COLORS[cell]
|
|
297
|
+
if (code === undefined) {
|
|
298
|
+
if (last !== -1) {
|
|
299
|
+
line += RESET
|
|
300
|
+
last = -1
|
|
301
|
+
}
|
|
302
|
+
line += ' '
|
|
303
|
+
continue
|
|
304
|
+
}
|
|
305
|
+
if (code !== last) {
|
|
306
|
+
line += `\x1b[48;5;${code}m`
|
|
307
|
+
last = code
|
|
308
|
+
}
|
|
309
|
+
line += ' '
|
|
310
|
+
}
|
|
311
|
+
if (last !== -1) line += RESET
|
|
312
|
+
return line
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
export function getNyanFrame(index, terminalColumns = 80) {
|
|
316
|
+
const maxCells = Math.max(12, Math.floor((terminalColumns - 1) / 2))
|
|
317
|
+
const frame = FRAMES[index % FRAMES.length]
|
|
318
|
+
const lines = frame.map((row) => renderRow(row, maxCells))
|
|
319
|
+
while (lines.length < FRAME_HEIGHT) {
|
|
320
|
+
lines.push('')
|
|
321
|
+
}
|
|
322
|
+
return lines.slice(0, FRAME_HEIGHT).join('\n')
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
export function getNyanFrameCount() {
|
|
326
|
+
return FRAMES.length
|
|
327
|
+
}
|
|
@@ -1,255 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""Extract dancing-banana.js frames from the classic GIF."""
|
|
3
|
-
|
|
4
|
-
from __future__ import annotations
|
|
5
|
-
|
|
6
|
-
from collections import deque
|
|
7
|
-
from pathlib import Path
|
|
8
|
-
|
|
9
|
-
from PIL import Image
|
|
10
|
-
|
|
11
|
-
OUT = Path(__file__).resolve().parents[1] / 'dancing-banana.js'
|
|
12
|
-
BG = (255, 255, 255)
|
|
13
|
-
TARGET_W = 24
|
|
14
|
-
|
|
15
|
-
CHAR = {
|
|
16
|
-
(0, 0, 0): 'B',
|
|
17
|
-
(255, 255, 0): 'Y',
|
|
18
|
-
(206, 206, 0): 'y',
|
|
19
|
-
(156, 156, 0): 'd',
|
|
20
|
-
(255, 0, 0): 'R',
|
|
21
|
-
(255, 255, 255): 'W',
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
JS_TEMPLATE = '''\
|
|
25
|
-
// Extracted from the classic dancing banana GIF (Trym Stene, 1999).
|
|
26
|
-
// 8 frames, {w}×{h}px — fixed canvas, solid 2-space blocks.
|
|
27
|
-
|
|
28
|
-
const RESET = '\\x1b[0m'
|
|
29
|
-
const FRAME_WIDTH = {w}
|
|
30
|
-
const FRAME_HEIGHT = {h}
|
|
31
|
-
|
|
32
|
-
const COLORS = {{
|
|
33
|
-
B: 236,
|
|
34
|
-
R: 196,
|
|
35
|
-
W: 255,
|
|
36
|
-
E: 255,
|
|
37
|
-
Y: 226,
|
|
38
|
-
d: 136,
|
|
39
|
-
y: 214,
|
|
40
|
-
}}
|
|
41
|
-
|
|
42
|
-
const FRAMES = [
|
|
43
|
-
{frames}
|
|
44
|
-
]
|
|
45
|
-
|
|
46
|
-
function renderRow(row) {{
|
|
47
|
-
const padded = row.padEnd(FRAME_WIDTH, '.').slice(0, FRAME_WIDTH)
|
|
48
|
-
let line = ''
|
|
49
|
-
for (const cell of padded) {{
|
|
50
|
-
if (cell === '.') {{
|
|
51
|
-
line += ' '
|
|
52
|
-
continue
|
|
53
|
-
}}
|
|
54
|
-
const code = COLORS[cell]
|
|
55
|
-
if (code === undefined) {{
|
|
56
|
-
line += ' '
|
|
57
|
-
continue
|
|
58
|
-
}}
|
|
59
|
-
const bold = cell === 'E' ? '\\x1b[1m' : ''
|
|
60
|
-
line += `${{bold}}\\x1b[48;5;${{code}}m ${{RESET}}`
|
|
61
|
-
}}
|
|
62
|
-
return line
|
|
63
|
-
}}
|
|
64
|
-
|
|
65
|
-
export function getBananaFrame(index) {{
|
|
66
|
-
const frame = FRAMES[index % FRAMES.length]
|
|
67
|
-
const lines = frame.map(renderRow)
|
|
68
|
-
while (lines.length < FRAME_HEIGHT) {{
|
|
69
|
-
lines.push(' '.repeat(FRAME_WIDTH * 2))
|
|
70
|
-
}}
|
|
71
|
-
return lines.slice(0, FRAME_HEIGHT).join('\\n')
|
|
72
|
-
}}
|
|
73
|
-
|
|
74
|
-
export function getBananaFrameCount() {{
|
|
75
|
-
return FRAMES.length
|
|
76
|
-
}}
|
|
77
|
-
'''
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
def remove_bg(frame: Image.Image) -> Image.Image:
|
|
81
|
-
px = frame.load()
|
|
82
|
-
w, h = frame.size
|
|
83
|
-
seen = [[False] * w for _ in range(h)]
|
|
84
|
-
q: deque[tuple[int, int]] = deque()
|
|
85
|
-
|
|
86
|
-
for x in range(w):
|
|
87
|
-
for y in (0, h - 1):
|
|
88
|
-
if px[x, y][:3] == BG:
|
|
89
|
-
q.append((x, y))
|
|
90
|
-
seen[y][x] = True
|
|
91
|
-
|
|
92
|
-
for y in range(h):
|
|
93
|
-
for x in (0, w - 1):
|
|
94
|
-
if not seen[y][x] and px[x, y][:3] == BG:
|
|
95
|
-
q.append((x, y))
|
|
96
|
-
seen[y][x] = True
|
|
97
|
-
|
|
98
|
-
while q:
|
|
99
|
-
x, y = q.popleft()
|
|
100
|
-
px[x, y] = (255, 255, 255, 0)
|
|
101
|
-
for nx, ny in ((x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)):
|
|
102
|
-
if 0 <= nx < w and 0 <= ny < h and not seen[ny][nx] and px[nx, ny][:3] == BG:
|
|
103
|
-
seen[ny][nx] = True
|
|
104
|
-
q.append((nx, ny))
|
|
105
|
-
|
|
106
|
-
return frame
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
def color_key(px: tuple[int, int, int, int]) -> str:
|
|
110
|
-
if px[3] < 128:
|
|
111
|
-
return '.'
|
|
112
|
-
rgb = px[:3]
|
|
113
|
-
if rgb in CHAR:
|
|
114
|
-
return CHAR[rgb]
|
|
115
|
-
nearest = min(CHAR, key=lambda c: sum((a - b) ** 2 for a, b in zip(rgb, c)))
|
|
116
|
-
return CHAR[nearest]
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
def trim_frames(frames: list[list[str]]) -> tuple[int, int, list[list[str]]]:
|
|
120
|
-
h = len(frames[0])
|
|
121
|
-
w = len(frames[0][0])
|
|
122
|
-
|
|
123
|
-
while h and all(frames[f][0][c] == '.' for f in range(len(frames)) for c in range(w)):
|
|
124
|
-
for f in range(len(frames)):
|
|
125
|
-
frames[f].pop(0)
|
|
126
|
-
h -= 1
|
|
127
|
-
|
|
128
|
-
while h and all(frames[f][h - 1][c] == '.' for f in range(len(frames)) for c in range(w)):
|
|
129
|
-
for f in range(len(frames)):
|
|
130
|
-
frames[f].pop()
|
|
131
|
-
h -= 1
|
|
132
|
-
|
|
133
|
-
while w and all(frames[f][r][0] == '.' for f in range(len(frames)) for r in range(h)):
|
|
134
|
-
for f in range(len(frames)):
|
|
135
|
-
frames[f] = [row[1:] for row in frames[f]]
|
|
136
|
-
w -= 1
|
|
137
|
-
|
|
138
|
-
while w and all(frames[f][r][w - 1] == '.' for f in range(len(frames)) for r in range(h)):
|
|
139
|
-
for f in range(len(frames)):
|
|
140
|
-
frames[f] = [row[:-1] for row in frames[f]]
|
|
141
|
-
w -= 1
|
|
142
|
-
|
|
143
|
-
return w, h, frames
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
def content_bounds(frames: list[list[str]]) -> tuple[int, int, int, int]:
|
|
147
|
-
top = len(frames[0])
|
|
148
|
-
bottom = 0
|
|
149
|
-
left = len(frames[0][0])
|
|
150
|
-
right = 0
|
|
151
|
-
|
|
152
|
-
for frame in frames:
|
|
153
|
-
for y, row in enumerate(frame):
|
|
154
|
-
for x, cell in enumerate(row):
|
|
155
|
-
if cell != '.':
|
|
156
|
-
top = min(top, y)
|
|
157
|
-
bottom = max(bottom, y)
|
|
158
|
-
left = min(left, x)
|
|
159
|
-
right = max(right, x)
|
|
160
|
-
|
|
161
|
-
return top, bottom, left, right
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
def normalize_canvas(frames: list[list[str]]) -> tuple[int, int, list[list[str]]]:
|
|
165
|
-
top, bottom, left, right = content_bounds(frames)
|
|
166
|
-
canvas_h = bottom - top + 1
|
|
167
|
-
canvas_w = right - left + 1
|
|
168
|
-
|
|
169
|
-
normalized: list[list[str]] = []
|
|
170
|
-
for frame in frames:
|
|
171
|
-
rows = [row[left : right + 1] for row in frame[top : bottom + 1]]
|
|
172
|
-
normalized.append([row.ljust(canvas_w, '.')[:canvas_w] for row in rows])
|
|
173
|
-
|
|
174
|
-
return canvas_w, canvas_h, normalized
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
def enhance_eyes(frames: list[list[str]]) -> list[list[str]]:
|
|
178
|
-
h = len(frames[0])
|
|
179
|
-
w = len(frames[0][0])
|
|
180
|
-
out: list[list[list[str]]] = [[list(row) for row in frame] for frame in frames]
|
|
181
|
-
|
|
182
|
-
for grid in out:
|
|
183
|
-
for y in range(h):
|
|
184
|
-
for x in range(w):
|
|
185
|
-
if grid[y][x] != 'W':
|
|
186
|
-
continue
|
|
187
|
-
if y < int(h * 0.42) or y > int(h * 0.75):
|
|
188
|
-
continue
|
|
189
|
-
neighbors = []
|
|
190
|
-
for nx, ny in ((x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)):
|
|
191
|
-
if 0 <= nx < w and 0 <= ny < h:
|
|
192
|
-
neighbors.append(grid[ny][nx])
|
|
193
|
-
if any(n in 'YyBR' for n in neighbors):
|
|
194
|
-
grid[y][x] = 'E'
|
|
195
|
-
|
|
196
|
-
return [[''.join(row) for row in grid] for grid in out]
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
def main() -> None:
|
|
200
|
-
gif_path = Path(
|
|
201
|
-
'/Users/Arkasha/.cursor/projects/Volumes-Work-ITCase-itcase-ui/assets/'
|
|
202
|
-
'dancing-banana-gif-809950cd-831b-4c1e-8547-2d3612956da9.gif',
|
|
203
|
-
)
|
|
204
|
-
img = Image.open(gif_path)
|
|
205
|
-
|
|
206
|
-
minx, miny, maxx, maxy = 9999, 9999, 0, 0
|
|
207
|
-
frames_raw: list[Image.Image] = []
|
|
208
|
-
|
|
209
|
-
for i in range(img.n_frames):
|
|
210
|
-
img.seek(i)
|
|
211
|
-
frame = remove_bg(img.convert('RGBA'))
|
|
212
|
-
frames_raw.append(frame)
|
|
213
|
-
fw, fh = frame.size
|
|
214
|
-
for y in range(fh):
|
|
215
|
-
for x in range(fw):
|
|
216
|
-
if frame.getpixel((x, y))[3] >= 128:
|
|
217
|
-
minx = min(minx, x)
|
|
218
|
-
miny = min(miny, y)
|
|
219
|
-
maxx = max(maxx, x)
|
|
220
|
-
maxy = max(maxy, y)
|
|
221
|
-
|
|
222
|
-
crop_h = maxy - miny + 1
|
|
223
|
-
target_h = max(8, round(crop_h * TARGET_W / (maxx - minx + 1)))
|
|
224
|
-
|
|
225
|
-
frames: list[list[str]] = []
|
|
226
|
-
for frame in frames_raw:
|
|
227
|
-
cropped = frame.crop((minx, miny, maxx + 1, maxy + 1))
|
|
228
|
-
small = cropped.resize((TARGET_W, target_h), Image.NEAREST)
|
|
229
|
-
rows = []
|
|
230
|
-
for y in range(target_h):
|
|
231
|
-
rows.append(''.join(color_key(small.getpixel((x, y))) for x in range(TARGET_W)))
|
|
232
|
-
frames.append(rows)
|
|
233
|
-
|
|
234
|
-
w, h, frames = trim_frames(frames)
|
|
235
|
-
w, h, frames = normalize_canvas(frames)
|
|
236
|
-
frames = enhance_eyes(frames)
|
|
237
|
-
|
|
238
|
-
frame_blocks = []
|
|
239
|
-
for frame in frames:
|
|
240
|
-
frame_blocks.append(' [')
|
|
241
|
-
for row in frame:
|
|
242
|
-
frame_blocks.append(f" '{row}',")
|
|
243
|
-
frame_blocks.append(' ],')
|
|
244
|
-
|
|
245
|
-
OUT.write_text(
|
|
246
|
-
JS_TEMPLATE.format(
|
|
247
|
-
w=w,
|
|
248
|
-
h=h,
|
|
249
|
-
frames='\n'.join(frame_blocks),
|
|
250
|
-
),
|
|
251
|
-
)
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
if __name__ == '__main__':
|
|
255
|
-
main()
|