File Coverage

blib/lib/App/GitKtti.pm
Criterion Covered Total %
statement 15 412 3.6
branch 0 134 0.0
condition 0 59 0.0
subroutine 5 51 9.8
pod 0 46 0.0
total 20 702 2.8


line stmt bran cond sub pod time code
1             package App::GitKtti;
2              
3 2     2   207227 use strict;
  2         5  
  2         116  
4 2     2   12 use warnings;
  2         3  
  2         122  
5 2     2   1112 use POSIX qw(strftime);
  2         19137  
  2         11  
6 2     2   3382 use Cwd qw(getcwd);
  2         5  
  2         414  
7              
8             our $VERSION = '2.0.3';
9              
10             =head1 NAME
11              
12             App::GitKtti - Git flow helper scripts for safe branch management
13              
14             =head1 SYNOPSIS
15              
16             use App::GitKtti;
17            
18             # Use the command-line tools:
19             # gitktti-checkout
20             # gitktti-delete
21             # gitktti-fix
22             # gitktti-fixend
23             # gitktti-move
24             # gitktti-tag
25             # gitktti-tests
26              
27             =head1 DESCRIPTION
28              
29             The gitktti scripts are provided to help developers safely use git flow.
30             This module provides a collection of tools for managing git branches
31             following git-flow methodology.
32              
33             =head1 FEATURES
34              
35             =over 4
36              
37             =item * Safe branch operations with validation
38              
39             =item * Colorized output for better readability
40              
41             =item * Support for feature, hotfix, and release workflows
42              
43             =item * Automatic branch cleanup and management
44              
45             =back
46              
47             =head1 AUTHOR
48              
49             saumon
50              
51             =head1 LICENSE
52              
53             This library is free software; you can redistribute it and/or modify
54             it under the same terms as Perl itself.
55              
56             =cut
57              
58             # Codes de couleurs ANSI
59             use constant {
60 2         13757 RESET => "\033[0m",
61             BOLD => "\033[1m",
62             DIM => "\033[2m",
63              
64             # Couleurs de texte
65             BLACK => "\033[30m",
66             RED => "\033[31m",
67             GREEN => "\033[32m",
68             YELLOW => "\033[33m",
69             BLUE => "\033[34m",
70             MAGENTA => "\033[35m",
71             CYAN => "\033[36m",
72             WHITE => "\033[37m",
73              
74             # Couleurs vives
75             BRIGHT_RED => "\033[91m",
76             BRIGHT_GREEN => "\033[92m",
77             BRIGHT_YELLOW => "\033[93m",
78             BRIGHT_BLUE => "\033[94m",
79             BRIGHT_MAGENTA => "\033[95m",
80             BRIGHT_CYAN => "\033[96m",
81             BRIGHT_WHITE => "\033[97m",
82              
83             # Couleurs de fond
84             BG_RED => "\033[41m",
85             BG_GREEN => "\033[42m",
86             BG_YELLOW => "\033[43m",
87             BG_BLUE => "\033[44m",
88 2     2   15 };
  2         3  
89              
90             sub showVersion {
91 0     0 0   showLogo();
92 0           print(BRIGHT_MAGENTA . BOLD . "πŸš€ gitktti " . BRIGHT_WHITE . "v" . $VERSION . RESET . " " . DIM . "by saumonβ„’" . RESET . "\n\n");
93             }
94              
95             # Fonctions d'affichage colorΓ©
96             sub printSuccess {
97 0     0 0   my $message = $_[0];
98 0           print(BRIGHT_GREEN . "βœ… " . $message . RESET . "\n");
99             }
100              
101             sub printError {
102 0     0 0   my $message = $_[0];
103 0           print(BRIGHT_RED . "❌ " . $message . RESET . "\n");
104             }
105              
106             sub printWarning {
107 0     0 0   my $message = $_[0];
108 0           print(BRIGHT_YELLOW . "⚠️ " . $message . RESET . "\n");
109             }
110              
111             sub printInfo {
112 0     0 0   my $message = $_[0];
113 0           print(BRIGHT_BLUE . "ℹ️ " . $message . RESET . "\n");
114             }
115              
116             sub printCommand {
117 0     0 0   my $command = $_[0];
118 0           print(DIM . "\$ " . RESET . CYAN . $command . RESET . "\n");
119             }
120              
121             sub printSection {
122 0     0 0   my $title = $_[0];
123 0           my $title_length = length($title);
124 0           my $separator = "═" x ($title_length + 2);
125              
126 0           print("\n" . BRIGHT_MAGENTA . "β•”" . $separator . "β•—" . RESET . "\n");
127 0           print(BRIGHT_MAGENTA . "β•‘ " . BOLD . BRIGHT_WHITE . $title . RESET . BRIGHT_MAGENTA . " β•‘" . RESET . "\n");
128 0           print(BRIGHT_MAGENTA . "β•š" . $separator . "╝" . RESET . "\n");
129             }
130              
131             sub printSubSection {
132 0     0 0   my $title = $_[0];
133 0           print("\n" . BRIGHT_CYAN . "β–Ά " . BOLD . $title . RESET . "\n");
134             }
135              
136             sub printBranch {
137 0     0 0   my $branch = $_[0];
138 0   0       my $type = $_[1] || "default";
139              
140 0           my $color = CYAN;
141 0           my $icon = "🌿";
142              
143 0 0 0       if ($type eq "master" || $type eq "main") {
    0 0        
    0          
    0          
    0          
144 0           $color = BRIGHT_RED;
145 0           $icon = "🏠";
146             } elsif ($type eq "develop" || $type eq "dev") {
147 0           $color = BRIGHT_GREEN;
148 0           $icon = "πŸ”¨";
149             } elsif ($type eq "feature") {
150 0           $color = BRIGHT_BLUE;
151 0           $icon = "✨";
152             } elsif ($type eq "hotfix") {
153 0           $color = BRIGHT_YELLOW;
154 0           $icon = "πŸ”₯";
155             } elsif ($type eq "release") {
156 0           $color = BRIGHT_MAGENTA;
157 0           $icon = "πŸš€";
158             }
159              
160 0           print($color . $icon . " " . BOLD . $branch . RESET);
161             }
162              
163             sub printTag {
164 0     0 0   my $tag = $_[0];
165 0           print(BRIGHT_YELLOW . "🏷️ " . BOLD . $tag . RESET);
166             }
167              
168             ##############################################################################
169             ## Fonction launch
170             ## Permet d executer une commande shell. Prend en entree la commande
171             ## a executer et retourne une liste contenant le resultat d execution de la
172             ## fonction.
173             ##############################################################################
174             sub launch {
175 0     0 0   my $command = $_[0];
176 0           my $ref_state = $_[1];
177 0           my @out = ();
178              
179 0           $$ref_state = 99;
180              
181 0 0         if ( length($command) == 0 ) {
182 0           printError("launch : command is empty !");
183 0           return @out;
184             }
185              
186 0           printCommand($command);
187              
188 0 0         open my $cmd_fh, '-|', "$command 2>&1" or die "launch : ERROR !";
189 0           my $output = "";
190 0           my @lines = ();
191 0           while(my $ligne = <$cmd_fh>) {
192 0           chomp($ligne);
193 0           push(@out, $ligne);
194 0           push(@lines, $ligne);
195             }
196 0           close($cmd_fh);
197              
198             # Affichage de la sortie avec indentation et couleur grise
199 0 0         if (@lines > 0) {
200 0           foreach my $line (@lines) {
201 0           print(DIM . " β”‚ " . $line . RESET . "\n");
202             }
203             # Supprimer le dernier \n pour ajouter le symbole de statut
204 0           print("\033[1A"); # Remonter d'une ligne
205 0           print("\033[K"); # Effacer la ligne
206 0           my $last_line = $lines[-1];
207 0           print(DIM . " β”‚ " . $last_line . RESET);
208             }
209              
210             ## Get output state
211 0           $$ref_state = $? >> 8;
212              
213 0 0         if ( $$ref_state ne 0 ) {
214             # Ajouter le X rouge et le code d'erreur Γ  la fin de la sortie
215 0 0         if (@lines > 0) {
216 0           print(BRIGHT_RED . " βœ— (" . $$ref_state . ")" . RESET . "\n");
217             } else {
218 0           print(DIM . " β”‚ " . BRIGHT_RED . "Command failed " . RESET . BRIGHT_RED . "βœ— (" . $$ref_state . ")" . RESET . "\n");
219             }
220             } else {
221             # Ajouter le checkmark Γ  la fin de la sortie
222 0 0         if (@lines > 0) {
223 0           print(BRIGHT_GREEN . " βœ”" . RESET . "\n");
224             } else {
225 0           print(DIM . " β”‚ " . BRIGHT_GREEN . "Command executed successfully " . RESET . BRIGHT_GREEN . "βœ”" . RESET . "\n");
226             }
227             }
228              
229 0           print("\n");
230 0           return @out;
231             }
232              
233             sub isResponseYes {
234 0     0 0   my $question = $_[0];
235 0           my $rep = "";
236              
237             do
238 0   0       {
239 0           $rep = lc(getResponse($question . " " . BRIGHT_GREEN . "(y)" . RESET . "/" . BRIGHT_RED . "(n)" . RESET));
240             }
241             while ( $rep !~ /^y$/ && $rep !~ /^n$/ );
242              
243 0 0         if ( $rep eq 'y' ) {
244 0           return 1;
245             }
246             else {
247 0           return 0;
248             }
249             }
250              
251             sub getResponse {
252 0     0 0   my $question = $_[0];
253 0           my $default = $_[1];
254 0           my $rep = "";
255              
256 0           print("\n");
257 0           print(BRIGHT_CYAN . "❓ " . BOLD . $question . RESET);
258 0 0 0       if ( defined($default) && length($default) > 0 ) {
259 0           print(" " . DIM . "[default: " . BRIGHT_WHITE . $default . RESET . DIM . "]" . RESET);
260             }
261 0           print("\n" . BRIGHT_CYAN . "➀ " . RESET);
262              
263 0           $rep = ;
264 0           print("\n");
265              
266 0           chomp($rep);
267              
268 0 0 0       if ( defined($default) && length($default) > 0 && length($rep) == 0 ) {
      0        
269 0           $rep = $default;
270             }
271              
272 0           return($rep);
273             }
274              
275             sub getSelectResponse {
276              
277 0     0 0   my $rep = "";
278 0           my $i_rep = 0;
279 0           my $nb_elts = scalar @_;
280 0           my $max_len_rep = 0;
281              
282 0 0         if ( $nb_elts <= 1 ) {
283 0           die("ERROR: getSelectResponse, missing args !");
284             }
285              
286 0           my $question = $_[0];
287              
288 0           print("\n");
289 0           printSubSection($question);
290              
291 0           for(my $i = 1; $i < $nb_elts; $i++) {
292 0           my @list = split(/\|/, $_[$i]);
293 0           my $len = length($list[0]);
294 0 0         if ( $len > $max_len_rep ) { $max_len_rep = $len };
  0            
295             }
296              
297 0           for(my $i = 1; $i < $nb_elts; $i++) {
298 0           my @list = split(/\|/, $_[$i]);
299 0           my $number = BRIGHT_CYAN . sprintf("%2d", $i) . RESET;
300 0           my $option = BRIGHT_WHITE . BOLD . RPad($list[0], $max_len_rep, ' ') . RESET;
301 0           my $line = " " . $number . ") " . $option;
302              
303 0 0         if ( scalar @list > 1 ) {
304 0           $line .= " " . DIM . "(" . $list[1] . ")" . RESET;
305             }
306              
307 0           print($line . "\n");
308             }
309              
310 0   0       do {
      0        
311 0           print("\n" . BRIGHT_CYAN . "🎯 Your choice: " . RESET);
312 0           $i_rep = ;
313             }
314             while ( $i_rep !~ /^\d+$/ || ($i_rep < 1) || ($i_rep > ($nb_elts - 1)) );
315              
316 0 0 0       if ( ($i_rep >= 1) && ($i_rep < $nb_elts) ) {
317 0           my @list = split(/\|/, $_[$i_rep]);
318 0           $rep = $list[0];
319 0           printSuccess("You have chosen: " . BOLD . $rep . RESET);
320             }
321              
322 0           print("\n");
323              
324 0           chomp($rep);
325              
326 0           return($rep);
327             }
328              
329             #---------------------------------------------------------------------
330             # LPad
331             #---------------------------------------------------------------------
332             # Pads a string on the left end to a specified length with a specified
333             # character and returns the result. Default pad char is space.
334             #---------------------------------------------------------------------
335              
336             sub LPad {
337 0     0 0   my ($str, $len, $chr) = @_;
338 0 0         $chr = " " unless (defined($chr));
339 0           return substr(($chr x $len) . $str, -1 * $len, $len);
340             } # LPad
341              
342             #---------------------------------------------------------------------
343             # RPad
344             #---------------------------------------------------------------------
345             # Pads a string on the right end to a specified length with a specified
346             # character and returns the result. Default pad char is space.
347             #---------------------------------------------------------------------
348              
349             sub RPad {
350 0     0 0   my ($str, $len, $chr) = @_;
351 0 0         $chr = " " unless (defined($chr));
352 0           return substr($str . ($chr x $len), 0, $len);
353             } # RPad
354              
355             sub directoryExists {
356 0     0 0   my $path = $_[0];
357 0           my $directory = $_[1];
358 0           my $found = 0;
359              
360 0 0         opendir(my $dh, $path) or die("ERROR: directoryExists, bad path given !");
361              
362 0   0       while ( !$found && (my $file = readdir($dh)) ) {
363 0 0 0       if ( -d "$path/$file" && $file =~ /^$directory$/ ) {
364 0           $found = 1;
365             }
366             }
367 0           closedir($dh);
368              
369 0           return $found;
370             }
371              
372             sub git_getTrackedRemoteBranch {
373 0     0 0   my $ref_ret = $_[0];
374 0           my %index_remotebranch = ();
375              
376 0           $index_remotebranch{"remote"} = "";
377 0           $index_remotebranch{"branch"} = "";
378              
379 0           my @remotebranch = launch('git rev-parse --abbrev-ref --symbolic-full-name @{u}', $ref_ret);
380              
381 0 0 0       if($$ref_ret == 0 && @remotebranch >= 1 && $remotebranch[0] =~ /^(\w+)\/(.+)$/) {
      0        
382 0           $index_remotebranch{"remote"} = $1;
383 0           $index_remotebranch{"branch"} = $2;
384             }
385              
386 0           return %index_remotebranch
387             }
388              
389             sub git_getGitRootDirectory {
390              
391 0     0 0   my $ret = 99;
392 0           my $directory = "";
393              
394 0           $directory = (launch('git rev-parse --show-toplevel', \$ret))[0];
395              
396             ## Exit if checkout fails
397 0 0         if ( $ret ne 0 ) {
398 0           print("ERROR: getGitRootDirectory failed ! Aborted !\n");
399 0           exit(2);
400             }
401              
402 0           return $directory;
403             }
404              
405             sub git_isRepoClean {
406 0     0 0   my $ret = 99;
407 0           my $clean = 1;
408              
409 0           my @files = launch('git status --porcelain', \$ret);
410              
411 0 0         if(@files > 0) {
412 0           $clean = 0;
413             }
414              
415 0           return $clean;
416             }
417              
418             sub trim {
419 0     0 0   my $s = shift;
420 0           $s =~ s/^\s+|\s+$//g;
421 0           return $s
422             }
423              
424             sub super_scp {
425 0     0 0   my $rep_src = $_[0];
426 0           my $rep_dest = $_[1];
427 0           my $srv_user = $_[2];
428 0           my $srv_ip = $_[3];
429 0           my $ret = 99;
430              
431 0           print("SRC : $rep_src\n");
432 0           print("DEST : $rep_dest\n");
433 0           print("USER : $srv_user\n");
434 0           print("HOST : $srv_ip\n");
435              
436 0 0         if ( isResponseYes("Synchronize [SRC] to [DEST] ? (with 'scp')") ) {
437              
438             # Without redirecting to /dev/tty I get no output...
439 0           launch("scp -r $rep_src $srv_user\@$srv_ip:$rep_dest >/dev/tty", \$ret);
440              
441             ## Exit if scp fails
442 0 0         if ( $ret ne 0 ) {
443 0           print("ERROR: scp failed ! Aborted !\n");
444 0           exit(2);
445             }
446             }
447             }
448              
449             sub super_rsync_ssh {
450 0     0 0   my $rep_src = $_[0];
451 0           my $rep_dest = $_[1];
452 0           my $srv_user = $_[2];
453 0           my $srv_ip = $_[3];
454 0           my $use_delete = $_[4];
455 0           my $opt_delete = "";
456 0           my $ret = 99;
457              
458 0           print("SRC : $rep_src\n");
459 0           print("DEST : $rep_dest\n");
460 0           print("USER : $srv_user\n");
461 0           print("HOST : $srv_ip\n");
462              
463 0 0         if ( isResponseYes("Synchronize [SRC] to [DEST] ? (with 'rsync')") ) {
464              
465             ## Warning: using [--delete] can be dangerous !!!
466 0 0 0       if ( $use_delete && isResponseYes("Use option [--delete] ? (WARNING: can be dangerous) !") ) {
467 0           $opt_delete = "--delete";
468             }
469              
470 0           launch("rsync -e ssh -avz --progress $opt_delete $rep_src $srv_user\@$srv_ip:$rep_dest", \$ret);
471              
472             ## Exit if rsync fails
473 0 0         if ( $ret ne 0 ) {
474 0           print("ERROR: rsync failed ! Aborted !\n");
475 0           exit(2);
476             }
477             }
478             }
479              
480             sub super_rsync_ssh_with_exclude {
481 0     0 0   my $rep_src = $_[0];
482 0           my $rep_dest = $_[1];
483 0           my $srv_user = $_[2];
484 0           my $srv_ip = $_[3];
485 0           my $use_delete = $_[4];
486 0           my $use_fakesuper = $_[5];
487 0           my $skip_confirm = $_[6];
488 0           my $ref_list_exclude = $_[7];
489 0           my $opt_delete = "";
490 0           my $opt_fakesuper = "";
491 0           my $opt_exclude = "";
492 0           my $ret = 99;
493 0           my $go = 0;
494              
495 0           print("SRC : $rep_src\n");
496 0           print("DEST : $rep_dest\n");
497              
498 0           foreach my $exclude (@{$ref_list_exclude}) {
  0            
499 0           print("EXCL : $exclude\n");
500              
501 0           $opt_exclude .= "--exclude '$exclude' ";
502             }
503              
504 0 0         if ( $use_fakesuper ) {
505 0           $opt_fakesuper = "--rsync-path='rsync --fake-super' ";
506             }
507              
508 0           print("USER : $srv_user\n");
509 0           print("HOST : $srv_ip\n");
510              
511 0 0         if ( $skip_confirm ) {
512 0           $go = 1;
513             }
514             else {
515 0           $go = isResponseYes("Synchronize [SRC] to [DEST] ? (with 'rsync')");
516             }
517              
518 0 0         if ( $go ) {
519              
520             ## Warning: using [--delete] can be dangerous !!!
521 0 0 0       if ( $use_delete && isResponseYes("Use option [--delete] ? (WARNING: can be dangerous) !") ) {
522 0           $opt_delete = "--delete ";
523             }
524              
525             ## Launch rsync command
526 0           launch("rsync -avzhe ssh " . $opt_fakesuper . $opt_delete . $opt_exclude . "$rep_src $srv_user\@$srv_ip:$rep_dest", \$ret);
527              
528             # Exit if rsync fails
529 0 0         if ( $ret ne 0 ) {
530 0           print("ERROR: rsync failed ! Aborted !\n");
531 0           exit(2);
532             }
533             }
534             }
535              
536             sub git_checkoutBranch {
537 0     0 0   my $arg_branch = $_[0];
538 0           my $ret = 99;
539              
540 0 0         if (isResponseYes("Checkout branch " . BOLD . $arg_branch . RESET . "?") ) {
541              
542 0           launch("git checkout $arg_branch", \$ret);
543              
544             ## Exit if checkout fails
545 0 0         if ( $ret ne 0 ) {
546 0           printError("checkout failed ! Aborted !");
547 0           exit(2);
548             }
549             }
550             }
551              
552             sub git_checkoutBranchNoConfirm {
553 0     0 0   my $arg_branch = $_[0];
554 0           my $ret = 99;
555              
556 0           launch("git checkout $arg_branch", \$ret);
557              
558             ## Exit if checkout fails
559 0 0         if ( $ret ne 0 ) {
560 0           printError("checkout failed ! Aborted !");
561 0           exit(2);
562             }
563             }
564              
565             sub git_deleteLocalBranch {
566 0     0 0   my $arg_branch = $_[0];
567 0           my $ret = 99;
568 0           my $done = 0;
569              
570 0 0         if (isResponseYes("Delete local branch " . BOLD . $arg_branch . RESET . "?") ) {
571              
572             ## Delete current branch
573 0           launch("git branch -D $arg_branch", \$ret);
574              
575             ## Exit if command fails
576 0 0         if ( $ret ne 0 ) {
577 0           printError("delete failed ! Aborted !");
578 0           exit(2);
579             }
580              
581 0           $done = 1;
582             }
583              
584 0           return $done;
585             }
586              
587             sub git_getLocalBranches {
588 0     0 0   my $ref_ret = $_[0];
589 0           return (launch("git branch | awk -F ' +' '! /\\(no branch\\)/ {print \$2}'", $ref_ret));
590             }
591              
592             sub git_getLocalBranchesFilter {
593 0     0 0   return launch("git branch | awk -F ' +' '! /\\(no branch\\)/ {print \$2}' | grep -E \"$_[0]\"", $_[1]);
594             }
595              
596             sub git_getRemoteBranchesFilter {
597              
598 0     0 0   my $arg_remote = $_[0];
599 0           my $arg_filter = $_[1];
600 0           my $ref_ret = $_[2];
601 0           my @branches = ();
602              
603 0 0         if ( $arg_remote ne "" ) {
604 0           push(@branches, launch("git branch --remote | awk -F ' +' '! /\\(no branch\\)/ {print \$2}' | grep -E \"$arg_filter\"", $ref_ret));
605             }
606              
607 0           return @branches;
608             }
609              
610             sub git_getAllBranchesFilter {
611              
612 0     0 0   my $arg_remote = $_[0];
613 0           my $arg_filter = $_[1];
614 0           my $ref_ret = $_[2];
615 0           my @branches = ();
616              
617 0           push(@branches, git_getRemoteBranchesFilter($arg_remote, $arg_filter, $ref_ret));
618 0           push(@branches, git_getLocalBranchesFilter($arg_filter, $ref_ret));
619              
620 0           return @branches;
621             }
622              
623             sub git_getCurrentBranch {
624 0     0 0   my $ref_ret = $_[0];
625 0           return (launch('git rev-parse --abbrev-ref HEAD', $ref_ret))[0];
626             }
627              
628             sub git_fetch {
629 0     0 0   my $ref_ret = $_[0];
630 0           launch("git fetch", $ref_ret);
631             }
632              
633             sub git_getLastTagFromAllBranches {
634 0     0 0   my $ref_ret = $_[0];
635 0           my @out = launch('git describe --tags $(git rev-list --tags --max-count=1)', $ref_ret);
636              
637 0 0         if(@out > 0) {
638 0           return $out[0];
639             }
640             else {
641 0           return "";
642             }
643             }
644              
645             sub git_getLastTagFromCurrentBranch {
646 0     0 0   my $ref_ret = $_[0];
647 0           my @out = launch('git describe --abbrev=0 --tags', $ref_ret);
648              
649 0 0         if(@out > 0) {
650 0           return $out[0];
651             }
652             else {
653 0           return "";
654             }
655             }
656              
657             sub git_cleanLocalTags {
658 0     0 0   my $ref_ret = $_[0];
659 0           return (launch('git tag -l | xargs git tag -d', $ref_ret))[0];
660             }
661              
662             sub git_fetchTags {
663 0     0 0   my $ref_ret = $_[0];
664 0           return (launch('git fetch --tags', $ref_ret))[0];
665             }
666              
667             sub git_fetchPrune {
668 0     0 0   my $ref_ret = $_[0];
669 0           return (launch('git fetch --all --prune', $ref_ret))[0];
670             }
671              
672             sub git_remotePrune {
673 0     0 0   my $arg_remote = $_[0];
674 0           my $ref_ret = $_[1];
675 0           return (launch("git remote prune $arg_remote", $ref_ret))[0];
676             }
677              
678             ## ATTENTION :
679             ## - ne marche pas a 100% (va a l'encontre de la logique git)
680             ## - des commits avec des [ ] cassent la fonction
681             ## Exemple : "[G401-439] Page not found"
682             ## warning, this one is hard like chuck norris's dick
683             sub git_getParentBranch {
684 0     0 0   my $ref_ret = $_[0];
685             ## git show-branch -a | grep '\*' | grep -v `git rev-parse --abbrev-ref HEAD` | head -n1 | sed 's/.*\[\(.*\)\].*/\1/' | sed 's/[\^~].*//'
686             #return (launch("git show-branch -a | grep '\\*' | grep -v `git rev-parse --abbrev-ref HEAD` | head -n1 | sed 's/.*\\[\\(.*\\)\\].*/\\1/' | sed 's/[\\^~].*//'", $ref_ret))[0];
687              
688             ## git show-branch | sed "s/].*//" | grep "\*" | grep -v "$(git rev-parse --abbrev-ref HEAD)" | head -n1 | sed "s/^.*\[//"
689             #return (launch("git show-branch | sed \"s/].*//\" | grep \"\\*\" | grep -v \"$(git rev-parse --abbrev-ref HEAD)\" | head -n1 | sed \"s/^.*\\[//\"", $ref_ret))[0];
690              
691             ## git show-branch | grep '*' | grep -v "$(git rev-parse --abbrev-ref HEAD)" | head -n1 | sed 's/.*\[\(.*\)\].*/\1/' | sed 's/[\^~].*//'
692 0           return (launch("git show-branch | grep '*' | grep -v \"\$(git rev-parse --abbrev-ref HEAD)\" | head -n1 | sed 's/.*\\[\\(.*\\)\\].*/\\1/' | sed 's/[\\^~].*//'", $ref_ret))[0];
693             }
694              
695             sub git_tagBranch {
696 0     0 0   my $branch = $_[0];
697 0           my $tagname = $_[1];
698 0           my $lasttag = $_[2];
699              
700 0           my $ret = 99;
701 0           my $tagging_done = 0;
702 0           my $question = "Create tag " . BOLD . $tagname . RESET . " on branch " . BOLD . $branch . RESET;
703              
704 0 0         if ( $tagname eq "" ) {
705 0           printError("git_tagBranch, no tagname provided !");
706 0           exit(2);
707             }
708              
709 0 0         if ( $lasttag ne "" ) {
710 0           $question .= " (old tag is " . DIM . $lasttag . RESET . ")";
711             }
712              
713             ## Check current branch name
714 0 0         if(git_getCurrentBranch(\$ret) !~ /^$branch$/) {
715 0           printError("git_tagBranch, bad branch ! (you should be on branch '$branch')");
716 0           exit(2);
717             }
718              
719 0           $question .= "?";
720              
721 0 0         if (isResponseYes($question) ) {
722             ## Tags current branch...
723 0           launch("git tag -a $tagname -m 'version $tagname'", \$ret);
724              
725             ## Exit if tagging fails
726 0 0         if ( $ret ne 0 ) {
727 0           printError("tagging failed ! Aborted !");
728 0           exit(2);
729             }
730             else {
731 0           printSuccess("Tag " . BOLD . $tagname . RESET . " created !");
732 0           $tagging_done = 1;
733             }
734              
735             ## Get tracked remote branch...
736 0           my %tracked_branch = git_getTrackedRemoteBranch(\$ret);
737              
738 0 0 0       if ( $tracked_branch{"remote"} ne "" && $tracked_branch{"branch"} ne "" ) {
739 0 0         if (isResponseYes("Push tag " . BOLD . $tagname . RESET . "?") ) {
740             ## Pushes tag to remote...
741 0           launch("git push --follow-tags", \$ret);
742              
743             ## Exit if checkout fails
744 0 0         if ( $ret ne 0 ) {
745 0           printError("push failed ! Aborted !");
746 0           exit(2);
747             }
748             }
749             }
750             else {
751 0           printInfo("No remote, no push, no chocolate !");
752             }
753             }
754             else {
755 0           printWarning("Tagging aborted !");
756             }
757              
758 0           return $tagging_done;
759             }
760              
761             sub git_pullCurrentBranch {
762 0     0 0   my $arg_remote = $_[0];
763 0           my $arg_tracking_remote_branch = $_[1];
764              
765 0           my $ret = 99;
766              
767 0 0 0       if ( $arg_remote ne "" && $arg_tracking_remote_branch ne "" ) {
768              
769             ## Pulls branch...
770 0           launch("git pull", \$ret);
771              
772             ## Exit if pull fails
773 0 0         if ( $ret ne 0 ) {
774 0           printError("pull failed ! Aborted !");
775 0           exit(2);
776             }
777             }
778             # else {
779             # printInfo("pullCurrentBranch : no remote, no pull, no chocolate...");
780             # }
781             }
782              
783             sub git_deleteCurrentBranch {
784 0     0 0   my $arg_current_branch = $_[0];
785 0           my $arg_remote = $_[1];
786 0           my $arg_tracking_remote_branch = $_[2];
787              
788 0           my $ret = 99;
789              
790 0 0         if (isResponseYes("Delete branch " . BOLD . $arg_current_branch . RESET . "?") ) {
791              
792             ## Delete current branch
793 0           launch("git branch -d $arg_current_branch", \$ret);
794              
795             ## Delete remote branch
796 0 0 0       if ( $arg_remote ne "" && $arg_tracking_remote_branch ne "" ) {
797 0 0         if (isResponseYes("Delete tracking remote branch " . BOLD . $arg_remote . "/" . $arg_tracking_remote_branch . RESET . "?") ) {
798 0           launch("git push " . $arg_remote . " --delete " . $arg_tracking_remote_branch, \$ret);
799             }
800             }
801             }
802             }
803              
804             sub git_mergeIntoBranch {
805 0     0 0   my $arg_branch_into = $_[0];
806 0           my $arg_branch_to_merge = $_[1];
807              
808 0           my $ret = 99;
809 0           my $merge_done = 0;
810              
811 0 0         if (isResponseYes("Merge branch " . BOLD . $arg_branch_to_merge . RESET . " into " . BOLD . $arg_branch_into . RESET . "?") ) {
812 0           launch("git checkout $arg_branch_into", \$ret);
813              
814             ## Exit if checkout fails
815 0 0         if ( $ret ne 0 ) {
816 0           printError("checkout failed ! Aborted !");
817 0           exit(2);
818             }
819              
820             ## Get tracked remote branch...
821 0           my %tracked_branch_into = git_getTrackedRemoteBranch(\$ret);
822              
823             ## Pull it
824 0           git_pullCurrentBranch($tracked_branch_into{"remote"}, $tracked_branch_into{"branch"});
825              
826 0           launch("git merge --no-ff $arg_branch_to_merge", \$ret);
827              
828             ## Exit if merge fails
829 0 0         if ( $ret ne 0 ) {
830 0           printError("merge failed ! Aborted !");
831 0           exit(2);
832             }
833             else {
834 0           $merge_done = 1;
835             }
836              
837 0 0 0       if ( $tracked_branch_into{"remote"} ne "" && $tracked_branch_into{"branch"} ne "" ) {
838 0 0         if (isResponseYes("Push " . BOLD . $arg_branch_into . RESET . "?") ) {
839 0           launch("git push", \$ret);
840              
841             ## Exit if push fails
842 0 0         if ( $ret ne 0 ) {
843 0           printError("push failed ! Aborted !");
844 0           exit(2);
845             }
846             }
847             }
848             }
849              
850 0           return $merge_done;
851             }
852              
853             sub git_duplicateRepository {
854 0     0 0   my $old_repository = $_[0];
855 0           my $new_repository = $_[1];
856              
857 0           my $ret = 99;
858 0           my $temp_repo = "";
859              
860 0 0         if ( $old_repository eq "" ) {
861 0           print("ERROR: old_repository is empty !\n");
862 0           exit(2);
863             }
864              
865 0 0         if ( $new_repository eq "" ) {
866 0           print("ERROR: new_repository is empty !\n");
867 0           exit(2);
868             }
869              
870 0           $temp_repo = "TEMPREPO_" . strftime("%Y%m%d_%H%M%S", localtime);
871              
872             ## Step 1: clone old repository
873 0           launch("git clone --bare $old_repository $temp_repo", \$ret);
874              
875 0 0         if ( $ret ne 0 ) {
876 0           print("ERROR: clone failed ! Aborted !\n");
877 0           exit(2);
878             }
879              
880             ### Step 2: push to new repository
881 0           chdir($temp_repo);
882 0           print("now here : " . getcwd() . "\n");
883              
884 0           launch("git push --mirror $new_repository", \$ret);
885              
886 0 0         if ( $ret ne 0 ) {
887 0           print("ERROR: push failed ! Aborted !\n");
888 0           exit(2);
889             }
890              
891             ## Step 3: clean temp repositoy
892 0           chdir("..");
893 0           print("now here : " . getcwd() . "\n");
894              
895 0           launch("rm -rf $temp_repo", \$ret);
896              
897 0 0         if ( $ret ne 0 ) {
898 0           print("ERROR: cd failed ! Aborted !\n");
899 0           exit(2);
900             }
901              
902 0           print("Repository successfuly duplicated !\n");
903 0           print("From [$old_repository]\n");
904 0           print("To [$new_repository]\n");
905             }
906              
907             sub showLogo {
908 0     0 0   print "\033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;6;6;6m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m
909             \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;37;24;64m.\033[0m\033[38;2;89;56;163m,\033[0m\033[38;2;117;73;217m:\033[0m\033[38;2;122;77;229m:\033[0m\033[38;2;106;68;198m;\033[0m\033[38;2;64;42;118m.\033[0m\033[38;2;5;3;8m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m
910             \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;2;2;2m \033[0m\033[38;2;44;28;78m.\033[0m\033[38;2;99;64;183m;\033[0m\033[38;2;123;79;233m:\033[0m\033[38;2;122;80;234mc\033[0m\033[38;2;122;81;234mc\033[0m\033[38;2;121;81;234mc\033[0m\033[38;2;121;82;234mc\033[0m\033[38;2;120;82;235mc\033[0m\033[38;2;113;77;220m:\033[0m\033[38;2;68;47;130m.\033[0m\033[38;2;9;7;17m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m
911             \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;14;14;14m \033[0m\033[38;2;53;34;96m.\033[0m\033[38;2;122;81;234mc\033[0m\033[38;2;121;82;234mc\033[0m\033[38;2;120;83;234mc\033[0m\033[38;2;120;84;235mc\033[0m\033[38;2;119;84;234mc\033[0m\033[38;2;59;42;115m.\033[0m\033[38;2;118;86;235mc\033[0m\033[38;2;117;87;236mc\033[0m\033[38;2;117;88;236mc\033[0m\033[38;2;116;88;237mc\033[0m\033[38;2;113;86;229mc\033[0m\033[38;2;70;54;142m'\033[0m\033[38;2;14;11;27m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m
912             \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;1;1;1m \033[0m\033[38;2;42;27;76m.\033[0m\033[38;2;8;5;14m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;11;11;11m \033[0m\033[38;2;59;59;59m \033[0m\033[38;2;50;35;98m.\033[0m\033[38;2;118;86;236mc\033[0m\033[38;2;117;87;235mc\033[0m\033[38;2;109;81;217m:\033[0m\033[38;2;56;43;107m.\033[0m\033[38;2;112;87;224mc\033[0m\033[38;2;114;91;237mc\033[0m\033[38;2;113;93;237mc\033[0m\033[38;2;112;94;238mc\033[0m\033[38;2;112;95;238mc\033[0m\033[38;2;111;96;239mc\033[0m\033[38;2;110;95;235mc\033[0m\033[38;2;73;64;154m,\033[0m\033[38;2;17;15;35m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m
913             \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;1;1;2m \033[0m\033[38;2;53;36;97m.\033[0m\033[38;2;108;73;204m;\033[0m\033[38;2;122;84;236mc\033[0m\033[38;2;118;81;227m:\033[0m\033[38;2;74;52;141m'\033[0m\033[38;2;15;10;26m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;9;9;9m \033[0m\033[38;2;57;57;57m \033[0m\033[38;2;40;31;80m.\033[0m\033[38;2;114;92;238mc\033[0m\033[38;2;113;94;237mc\033[0m\033[38;2;112;96;238mc\033[0m\033[38;2;111;98;239mc\033[0m\033[38;2;110;99;239mc\033[0m\033[38;2;110;101;240mc\033[0m\033[38;2;109;102;240mc\033[0m\033[38;2;108;103;240mc\033[0m\033[38;2;107;104;241mc\033[0m\033[38;2;107;105;241mc\033[0m\033[38;2;106;104;240mc\033[0m\033[38;2;74;74;165m,\033[0m\033[38;2;21;21;45m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m
914             \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;3;2;4m \033[0m\033[38;2;56;39;105m.\033[0m\033[38;2;110;76;210m:\033[0m\033[38;2;122;86;237mc\033[0m\033[38;2;121;87;237mc\033[0m\033[38;2;120;88;237mc\033[0m\033[38;2;119;89;238mc\033[0m\033[38;2;119;90;238mc\033[0m\033[38;2;117;88;234mc\033[0m\033[38;2;77;60;154m,\033[0m\033[38;2;18;14;34m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;8;8;8m \033[0m\033[38;2;23;23;23m \033[0m\033[38;2;13;13;13m \033[0m\033[38;2;23;23;23m \033[0m\033[38;2;52;52;52m \033[0m\033[38;2;47;44;102m.\033[0m\033[38;2;107;105;241mc\033[0m\033[38;2;106;107;241ml\033[0m\033[38;2;105;108;241ml\033[0m\033[38;2;104;109;241ml\033[0m\033[38;2;80;83;183m;\033[0m\033[38;2;104;111;242ml\033[0m\033[38;2;103;113;243ml\033[0m\033[38;2;101;114;243ml\033[0m\033[38;2;73;86;177m;\033[0m\033[38;2;24;30;58m.\033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m
915             \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;6;4;10m \033[0m\033[38;2;62;44;116m.\033[0m\033[38;2;112;80;215m:\033[0m\033[38;2;121;88;237mc\033[0m\033[38;2;120;89;238mc\033[0m\033[38;2;119;91;238mc\033[0m\033[38;2;117;91;237mc\033[0m\033[38;2;60;47;120m.\033[0m\033[38;2;115;94;238mc\033[0m\033[38;2;115;96;239mc\033[0m\033[38;2;113;97;239mc\033[0m\033[38;2;112;98;239mc\033[0m\033[38;2;63;55;133m'\033[0m\033[38;2;1;1;1m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;8;8;18m \033[0m\033[38;2;104;110;241ml\033[0m\033[38;2;104;111;242ml\033[0m\033[38;2;103;112;242ml\033[0m\033[38;2;87;93;200m:\033[0m\033[38;2;3;3;7m \033[0m\033[38;2;83;93;194m:\033[0m\033[38;2;99;119;243ml\033[0m\033[38;2;98;122;245ml\033[0m\033[38;2;96;125;245ml\033[0m\033[38;2;94;127;245ml\033[0m\033[38;2;70;99;186m:\033[0m\033[38;2;29;42;76m.\033[0m\033[38;2;1;1;1m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m
916             \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;8;6;15m \033[0m\033[38;2;68;48;129m'\033[0m\033[38;2;116;83;225m:\033[0m\033[38;2;120;89;238mc\033[0m\033[38;2;119;90;238mc\033[0m\033[38;2;118;92;238mc\033[0m\033[38;2;117;93;239mc\033[0m\033[38;2;116;95;239mc\033[0m\033[38;2;92;75;184m;\033[0m\033[38;2;8;7;16m \033[0m\033[38;2;96;83;198m:\033[0m\033[38;2;112;102;240mc\033[0m\033[38;2;110;104;241mc\033[0m\033[38;2;108;106;241ml\033[0m\033[38;2;98;98;220mc\033[0m\033[38;2;19;19;41m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;32;32;32m \033[0m\033[38;2;12;13;28m \033[0m\033[38;2;100;117;243ml\033[0m\033[38;2;99;120;244ml\033[0m\033[38;2;98;121;245ml\033[0m\033[38;2;86;106;209mc\033[0m\033[38;2;97;124;245ml\033[0m\033[38;2;95;127;245ml\033[0m\033[38;2;94;129;246ml\033[0m\033[38;2;92;132;246ml\033[0m\033[38;2;91;134;247mo\033[0m\033[38;2;89;137;248mo\033[0m\033[38;2;87;140;249mo\033[0m\033[38;2;69;117;202mc\033[0m\033[38;2;29;52;86m.\033[0m\033[38;2;2;2;2m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m
917             \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;15;11;26m \033[0m\033[38;2;75;53;141m'\033[0m\033[38;2;117;84;229mc\033[0m\033[38;2;120;89;238mc\033[0m\033[38;2;119;90;238mc\033[0m\033[38;2;118;92;239mc\033[0m\033[38;2;117;93;239mc\033[0m\033[38;2;116;95;239mc\033[0m\033[38;2;114;97;240mc\033[0m\033[38;2;113;100;240mc\033[0m\033[38;2;111;101;240mc\033[0m\033[38;2;105;97;224mc\033[0m\033[38;2;109;106;241ml\033[0m\033[38;2;107;108;242ml\033[0m\033[38;2;106;110;242ml\033[0m\033[38;2;104;113;242ml\033[0m\033[38;2;103;114;242ml\033[0m\033[38;2;102;115;242ml\033[0m\033[38;2;71;81;165m;\033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;1;1;2m \033[0m\033[38;2;35;41;85m.\033[0m\033[38;2;2;2;2m \033[0m\033[38;2;2;2;2m \033[0m\033[38;2;43;43;43m \033[0m\033[38;2;101;101;101m \033[0m\033[38;2;90;118;231mc\033[0m\033[38;2;94;129;246ml\033[0m\033[38;2;93;131;246ml\033[0m\033[38;2;92;133;246mo\033[0m\033[38;2;91;134;247mo\033[0m\033[38;2;70;105;190m:\033[0m\033[38;2;15;22;40m \033[0m\033[38;2;86;142;248mo\033[0m\033[38;2;83;147;249mo\033[0m\033[38;2;82;150;249mo\033[0m\033[38;2;79;153;250mo\033[0m\033[38;2;67;135;215ml\033[0m\033[38;2;32;67;104m.\033[0m\033[38;2;1;2;3m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m
918             \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;19;14;34m \033[0m\033[38;2;81;57;153m'\033[0m\033[38;2;120;86;234mc\033[0m\033[38;2;120;88;238mc\033[0m\033[38;2;119;90;239mc\033[0m\033[38;2;118;91;239mc\033[0m\033[38;2;117;94;239mc\033[0m\033[38;2;115;95;239mc\033[0m\033[38;2;88;73;181m;\033[0m\033[38;2;97;84;204m:\033[0m\033[38;2;112;101;240mc\033[0m\033[38;2;110;104;241ml\033[0m\033[38;2;108;107;241ml\033[0m\033[38;2;106;109;242ml\033[0m\033[38;2;105;112;242ml\033[0m\033[38;2;104;114;243ml\033[0m\033[38;2;102;116;243ml\033[0m\033[38;2;101;117;243ml\033[0m\033[38;2;100;119;244ml\033[0m\033[38;2;98;121;244ml\033[0m\033[38;2;80;99;195m:\033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;1;2;3m \033[0m\033[38;2;94;122;246ml\033[0m\033[38;2;80;107;207mc\033[0m\033[38;2;37;50;94m.\033[0m\033[38;2;1;1;1m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;35;35;35m \033[0m\033[38;2;97;97;97m \033[0m\033[38;2;126;126;126m \033[0m\033[38;2;120;120;120m \033[0m\033[38;2;30;48;85m.\033[0m\033[38;2;84;142;246mo\033[0m\033[38;2;77;133;226ml\033[0m\033[38;2;81;150;250mo\033[0m\033[38;2;79;153;250mo\033[0m\033[38;2;78;156;250mo\033[0m\033[38;2;76;160;251md\033[0m\033[38;2;74;162;251md\033[0m\033[38;2;72;165;252md\033[0m\033[38;2;64;149;225ml\033[0m\033[38;2;32;76;113m'\033[0m\033[38;2;2;3;5m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m
919             \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;2;2;4m \033[0m\033[38;2;83;57;155m,\033[0m\033[38;2;121;85;236mc\033[0m\033[38;2;120;87;239mc\033[0m\033[38;2;118;89;239mc\033[0m\033[38;2;117;91;239mc\033[0m\033[38;2;116;93;240mc\033[0m\033[38;2;115;95;240mc\033[0m\033[38;2;114;97;240mc\033[0m\033[38;2;107;91;220mc\033[0m\033[38;2;18;15;35m \033[0m\033[38;2;23;20;46m \033[0m\033[38;2;108;101;230mc\033[0m\033[38;2;108;108;242ml\033[0m\033[38;2;106;111;242ml\033[0m\033[38;2;104;114;243ml\033[0m\033[38;2;103;116;243ml\033[0m\033[38;2;101;118;243ml\033[0m\033[38;2;99;115;237ml\033[0m\033[38;2;70;81;163m;\033[0m\033[38;2;98;123;244ml\033[0m\033[38;2;96;125;245ml\033[0m\033[38;2;77;103;195m:\033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;2;2;3m \033[0m\033[38;2;91;127;247ml\033[0m\033[38;2;91;132;247ml\033[0m\033[38;2;90;134;247mo\033[0m\033[38;2;78;118;215mc\033[0m\033[38;2;17;26;47m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;6;6;6m \033[0m\033[38;2;43;43;43m \033[0m\033[38;2;30;57;93m.\033[0m\033[38;2;77;157;251mo\033[0m\033[38;2;75;159;251mo\033[0m\033[38;2;73;162;251md\033[0m\033[38;2;71;165;251md\033[0m\033[38;2;70;168;252md\033[0m\033[38;2;68;170;253md\033[0m\033[38;2;67;172;253md\033[0m\033[38;2;65;173;253md\033[0m\033[38;2;60;159;231mo\033[0m\033[38;2;22;55;79m.\033[0m\033[38;2;0;0;0m \033[0m
920             \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;10;7;19m \033[0m\033[38;2;121;86;238mc\033[0m\033[38;2;119;88;239mc\033[0m\033[38;2;117;90;239mc\033[0m\033[38;2;116;93;240mc\033[0m\033[38;2;115;95;241mc\033[0m\033[38;2;113;97;241mc\033[0m\033[38;2;112;99;241mc\033[0m\033[38;2;111;102;241mc\033[0m\033[38;2;110;103;241mc\033[0m\033[38;2;99;93;214m:\033[0m\033[38;2;99;97;218mc\033[0m\033[38;2;107;110;242ml\033[0m\033[38;2;104;113;242ml\033[0m\033[38;2;103;115;243ml\033[0m\033[38;2;102;118;244ml\033[0m\033[38;2;92;109;222mc\033[0m\033[38;2;99;122;245ml\033[0m\033[38;2;98;124;245ml\033[0m\033[38;2;96;125;244ml\033[0m\033[38;2;94;128;246ml\033[0m\033[38;2;93;130;246ml\033[0m\033[38;2;75;106;196m:\033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;1;2;3m \033[0m\033[38;2;88;131;247ml\033[0m\033[38;2;89;137;248mo\033[0m\033[38;2;87;139;248mo\033[0m\033[38;2;86;142;249mo\033[0m\033[38;2;12;19;33m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;10;19;29m \033[0m\033[38;2;73;162;252md\033[0m\033[38;2;71;165;252md\033[0m\033[38;2;61;152;229mo\033[0m\033[38;2;118;118;118m \033[0m\033[38;2;54;145;211ml\033[0m\033[38;2;64;176;254md\033[0m\033[38;2;63;177;254md\033[0m\033[38;2;62;178;254md\033[0m\033[38;2;61;178;253md\033[0m\033[38;2;41;114;162m;\033[0m\033[38;2;0;0;0m \033[0m
921             \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;6;6;6m \033[0m\033[38;2;67;67;67m \033[0m\033[38;2;65;51;133m'\033[0m\033[38;2;115;95;240mc\033[0m\033[38;2;113;97;240mc\033[0m\033[38;2;112;99;241mc\033[0m\033[38;2;110;102;241mc\033[0m\033[38;2;108;104;242mc\033[0m\033[38;2;107;107;242ml\033[0m\033[38;2;106;109;242ml\033[0m\033[38;2;105;111;242ml\033[0m\033[38;2;104;113;243ml\033[0m\033[38;2;103;115;243ml\033[0m\033[38;2;102;117;244ml\033[0m\033[38;2;100;119;244ml\033[0m\033[38;2;98;117;238ml\033[0m\033[38;2;31;36;71m.\033[0m\033[38;2;88;110;216mc\033[0m\033[38;2;95;128;245ml\033[0m\033[38;2;93;130;246ml\033[0m\033[38;2;92;133;246mo\033[0m\033[38;2;90;134;246mo\033[0m\033[38;2;73;110;197m:\033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;1;2;3m \033[0m\033[38;2;86;135;248mo\033[0m\033[38;2;87;140;248mo\033[0m\033[38;2;85;143;249mo\033[0m\033[38;2;84;146;249mo\033[0m\033[38;2;66;118;199mc\033[0m\033[38;2;13;23;38m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;11;21;33m \033[0m\033[38;2;57;127;197mc\033[0m\033[38;2;69;167;253md\033[0m\033[38;2;67;170;253md\033[0m\033[38;2;59;154;223mo\033[0m\033[38;2;31;81;115m'\033[0m\033[38;2;55;153;217ml\033[0m\033[38;2;61;179;254md\033[0m\033[38;2;60;180;254md\033[0m\033[38;2;59;180;253md\033[0m\033[38;2;0;1;2m \033[0m\033[38;2;37;37;37m \033[0m\033[38;2;0;0;0m \033[0m
922             \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;14;14;14m \033[0m\033[38;2;66;66;66m \033[0m\033[38;2;54;49;117m.\033[0m\033[38;2;109;103;242mc\033[0m\033[38;2;107;106;242ml\033[0m\033[38;2;105;108;242ml\033[0m\033[38;2;104;111;242ml\033[0m\033[38;2;103;113;243ml\033[0m\033[38;2;102;115;243ml\033[0m\033[38;2;101;117;243ml\033[0m\033[38;2;100;119;244ml\033[0m\033[38;2;99;122;244ml\033[0m\033[38;2;97;124;245ml\033[0m\033[38;2;96;126;245ml\033[0m\033[38;2;93;124;238ml\033[0m\033[38;2;93;131;245ml\033[0m\033[38;2;92;133;246mo\033[0m\033[38;2;91;135;246mo\033[0m\033[38;2;89;137;247mo\033[0m\033[38;2;88;138;247mo\033[0m\033[38;2;72;113;198mc\033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;1;2;3m \033[0m\033[38;2;84;138;248mo\033[0m\033[38;2;85;142;248mo\033[0m\033[38;2;27;45;78m.\033[0m\033[38;2;63;113;190m:\033[0m\033[38;2;80;151;250mo\033[0m\033[38;2;78;153;250mo\033[0m\033[38;2;66;132;212ml\033[0m\033[38;2;56;114;181m:\033[0m\033[38;2;53;113;177m:\033[0m\033[38;2;60;134;208mc\033[0m\033[38;2;70;164;251md\033[0m\033[38;2;68;168;253md\033[0m\033[38;2;66;172;253md\033[0m\033[38;2;64;175;253md\033[0m\033[38;2;62;178;253md\033[0m\033[38;2;60;179;254md\033[0m\033[38;2;59;181;254md\033[0m\033[38;2;56;176;245md\033[0m\033[38;2;115;115;115m \033[0m\033[38;2;43;43;43m \033[0m\033[38;2;1;1;1m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m
923             \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;11;11;11m \033[0m\033[38;2;61;61;61m \033[0m\033[38;2;35;37;81m.\033[0m\033[38;2;103;112;243ml\033[0m\033[38;2;102;115;243ml\033[0m\033[38;2;100;118;244ml\033[0m\033[38;2;99;120;245ml\033[0m\033[38;2;98;122;244ml\033[0m\033[38;2;44;55;109m.\033[0m\033[38;2;2;3;5m \033[0m\033[38;2;94;125;239ml\033[0m\033[38;2;93;131;246ml\033[0m\033[38;2;91;133;246mo\033[0m\033[38;2;90;136;247mo\033[0m\033[38;2;89;138;247mo\033[0m\033[38;2;88;140;247mo\033[0m\033[38;2;86;141;248mo\033[0m\033[38;2;53;89;154m;\033[0m\033[38;2;92;92;92m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;15;15;15m \033[0m\033[38;2;111;111;111m \033[0m\033[38;2;73;131;224ml\033[0m\033[38;2;76;139;232ml\033[0m\033[38;2;79;151;249mo\033[0m\033[38;2;78;155;251mo\033[0m\033[38;2;76;157;251mo\033[0m\033[38;2;74;160;251md\033[0m\033[38;2;65;147;228mo\033[0m\033[38;2;70;166;252md\033[0m\033[38;2;68;169;253md\033[0m\033[38;2;66;172;253md\033[0m\033[38;2;65;174;253md\033[0m\033[38;2;63;176;254md\033[0m\033[38;2;61;179;254md\033[0m\033[38;2;59;181;254md\033[0m\033[38;2;49;154;215ml\033[0m\033[38;2;111;111;111m \033[0m\033[38;2;38;38;38m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m
924             \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;7;7;7m \033[0m\033[38;2;57;57;57m \033[0m\033[38;2;27;32;65m.\033[0m\033[38;2;98;123;245ml\033[0m\033[38;2;96;125;245ml\033[0m\033[38;2;95;128;246ml\033[0m\033[38;2;91;124;237ml\033[0m\033[38;2;77;107;198m:\033[0m\033[38;2;92;134;247mo\033[0m\033[38;2;91;136;248mo\033[0m\033[38;2;89;139;248mo\033[0m\033[38;2;88;142;248mo\033[0m\033[38;2;86;144;249mo\033[0m\033[38;2;84;145;248mo\033[0m\033[38;2;53;93;157m;\033[0m\033[38;2;22;22;22m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;45;45;45m \033[0m\033[38;2;71;141;229ml\033[0m\033[38;2;76;158;252mo\033[0m\033[38;2;75;160;252md\033[0m\033[38;2;73;163;252md\033[0m\033[38;2;23;54;81m.\033[0m\033[38;2;57;57;57m \033[0m\033[38;2;13;34;49m \033[0m\033[38;2;65;175;253md\033[0m\033[38;2;63;177;254md\033[0m\033[38;2;62;179;254md\033[0m\033[38;2;61;180;254md\033[0m\033[38;2;46;142;199mc\033[0m\033[38;2;105;105;105m \033[0m\033[38;2;34;34;34m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m
925             \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;5;5;5m \033[0m\033[38;2;53;53;53m \033[0m\033[38;2;12;17;32m \033[0m\033[38;2;92;133;246mo\033[0m\033[38;2;91;136;247mo\033[0m\033[38;2;89;138;247mo\033[0m\033[38;2;88;140;248mo\033[0m\033[38;2;87;142;249mo\033[0m\033[38;2;74;123;212mc\033[0m\033[38;2;84;147;249mo\033[0m\033[38;2;82;149;249mo\033[0m\033[38;2;81;152;249mo\033[0m\033[38;2;66;127;206mc\033[0m\033[38;2;3;3;3m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;4;8;12m \033[0m\033[38;2;72;157;245mo\033[0m\033[38;2;72;164;252md\033[0m\033[38;2;70;166;253md\033[0m\033[38;2;69;169;253md\033[0m\033[38;2;63;163;241mo\033[0m\033[38;2;41;104;149m;\033[0m\033[38;2;59;163;235mo\033[0m\033[38;2;62;177;254md\033[0m\033[38;2;61;179;254md\033[0m\033[38;2;39;119;167m:\033[0m\033[38;2;96;96;96m \033[0m\033[38;2;28;28;28m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m
926             \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;2;2;2m \033[0m\033[38;2;47;47;47m \033[0m\033[38;2;5;9;15m \033[0m\033[38;2;85;144;248mo\033[0m\033[38;2;84;146;249mo\033[0m\033[38;2;82;148;249mo\033[0m\033[38;2;56;101;165m;\033[0m\033[38;2;78;146;240mo\033[0m\033[38;2;78;155;250mo\033[0m\033[38;2;76;158;250mo\033[0m\033[38;2;75;160;251md\033[0m\033[38;2;58;127;197mc\033[0m\033[38;2;29;65;98m.\033[0m\033[38;2;16;35;54m.\033[0m\033[38;2;13;28;42m \033[0m\033[38;2;18;41;61m.\033[0m\033[38;2;33;78;118m'\033[0m\033[38;2;61;148;224ml\033[0m\033[38;2;68;168;253md\033[0m\033[38;2;68;169;253md\033[0m\033[38;2;67;171;253md\033[0m\033[38;2;65;173;253md\033[0m\033[38;2;64;175;253md\033[0m\033[38;2;62;177;253md\033[0m\033[38;2;61;178;254md\033[0m\033[38;2;36;110;155m;\033[0m\033[38;2;89;89;89m \033[0m\033[38;2;20;20;20m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m
927             \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;1;1;1m \033[0m\033[38;2;44;44;44m \033[0m\033[38;2;0;1;1m \033[0m\033[38;2;77;154;250mo\033[0m\033[38;2;76;157;251mo\033[0m\033[38;2;75;159;251mo\033[0m\033[38;2;74;161;251md\033[0m\033[38;2;72;163;252md\033[0m\033[38;2;71;165;252md\033[0m\033[38;2;69;167;252md\033[0m\033[38;2;68;169;253md\033[0m\033[38;2;66;170;253md\033[0m\033[38;2;66;171;253md\033[0m\033[38;2;65;172;254md\033[0m\033[38;2;65;173;254md\033[0m\033[38;2;64;173;253md\033[0m\033[38;2;30;79;116m'\033[0m\033[38;2;64;174;253md\033[0m\033[38;2;63;175;254md\033[0m\033[38;2;62;177;254md\033[0m\033[38;2;61;179;254md\033[0m\033[38;2;33;99;140m,\033[0m\033[38;2;89;89;89m \033[0m\033[38;2;19;19;19m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m
928             \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;41;41;41m \033[0m\033[38;2;109;109;109m \033[0m\033[38;2;65;154;236mo\033[0m\033[38;2;69;167;252md\033[0m\033[38;2;67;169;253md\033[0m\033[38;2;66;171;253md\033[0m\033[38;2;64;173;253md\033[0m\033[38;2;63;175;254md\033[0m\033[38;2;33;92;133m,\033[0m\033[38;2;61;176;253md\033[0m\033[38;2;61;177;254md\033[0m\033[38;2;61;177;254md\033[0m\033[38;2;60;176;251md\033[0m\033[38;2;46;126;178m:\033[0m\033[38;2;61;177;251md\033[0m\033[38;2;59;179;254md\033[0m\033[38;2;28;87;123m'\033[0m\033[38;2;84;84;84m \033[0m\033[38;2;17;17;17m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m
929             \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;35;35;35m \033[0m\033[38;2;102;102;102m \033[0m\033[38;2;50;138;201mc\033[0m\033[38;2;61;176;253md\033[0m\033[38;2;60;177;254md\033[0m\033[38;2;57;170;241mo\033[0m\033[38;2;23;65;91m.\033[0m\033[38;2;51;154;217ml\033[0m\033[38;2;58;179;254md\033[0m\033[38;2;58;180;254md\033[0m\033[38;2;57;180;253md\033[0m\033[38;2;57;180;253md\033[0m\033[38;2;20;63;88m.\033[0m\033[38;2;76;76;76m \033[0m\033[38;2;13;13;13m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m
930             \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;28;28;28m \033[0m\033[38;2;95;95;95m \033[0m\033[38;2;38;116;165m:\033[0m\033[38;2;57;180;254md\033[0m\033[38;2;57;181;254md\033[0m\033[38;2;56;181;254md\033[0m\033[38;2;56;181;254md\033[0m\033[38;2;56;181;254md\033[0m\033[38;2;13;41;58m.\033[0m\033[38;2;66;66;66m \033[0m\033[38;2;7;7;7m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m
931             \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;20;20;20m \033[0m\033[38;2;87;87;87m \033[0m\033[38;2;120;120;120m \033[0m\033[38;2;126;126;126m \033[0m\033[38;2;108;108;108m \033[0m\033[38;2;58;58;58m \033[0m\033[38;2;4;4;4m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m
932             \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m\033[38;2;0;0;0m \033[0m
933             ";
934             }
935              
936             1;