### ----------------------------------------------------
### -- App::pack.raku
### -- Licenses: GPL-3.0-or-later
### -- Authors: Francis Grizzly Smit <grizzly@smit.id.au>
### -- File: rakulib/Pack.rakumod
### ----------------------------------------------------
### -- Chunk 3 of 4
 } else {
                        return t.color(0, 255, 255) ~ ~$value;
                    }
                }
                when 'comment' { return t.color(0, 0, 255) ~ ~$value; }
                default        { return t.color(255, 0, 0) ~ '';      }
            } # given $field #
        } elsif $colour {
            given $field {
                when 'key'     { return t.color(0, 0, 255) ~ '#' ~ ~$value; }
                when 'path'    { 
                    my Str:D $type = %row«type»;
                    if $type eq 'commeted-dir' {
                        return t.color(0, 0, 255) ~ ~$value;
                    } else {
                        return t.color(0, 0, 255) ~ ~$value;
                    }
                }
                when 'comment' { return t.color(0, 0, 255) ~ ~$value; }
                default        { return t.color(255, 0, 0) ~ '';      }
            }
        } else {
            given $field {
                when 'key'     { return '#' ~ ~$value; }
                when 'path'    { 
                    my Str:D $type = %row«type»;
                    if $type eq 'commeted-dir' {
                        return ~$value;
                    } else {
                        return ~$value;
                    }
                }
                when 'comment' { return ~$value; }
                default        { return '';      }
            }
        }
    } #`««« sub field-value(Int:D $idx, Str:D $field, $value, Bool:D $colour, Bool:D $syntax, Str:D @fields, %row --> Str:D) »»»
    sub between(Int:D $idx, Str:D $field, Bool:D $colour, Bool:D $syntax, Str:D @fields, %row --> Str:D) {
        if $syntax {
                given $field {
                    when 'key'     {
                        my Str:D $type = %row«type»;
                        if $type eq 'commeted-dir' {
                            return t.color(255, 0, 0) ~ '  => ';
                        } else {
                            return t.color(255, 0, 0) ~ ' --> ';
                        }
                    }
                    when 'path'    { return t.color(0, 0, 255) ~ ' # '; }
                    when 'comment' { return t.color(0, 0, 255) ~ '  ';  }
                    default        { return t.color(255, 0, 0) ~ '';    }
                }
        } elsif $colour {
                given $field {
                    when 'key'     {
                        my Str:D $type = %row«type»;
                        if $type eq 'commeted-dir' {
                            return t.color(0, 0, 255) ~ '  => ';
                        } else {
                            return t.color(0, 0, 255) ~ ' --> ';
                        }
                    }
                    when 'path'    { return t.color(0, 0, 255) ~ ' # '; }
                    when 'comment' { return t.color(0, 0, 255) ~ '  ';  }
                    default        { return t.color(255, 0, 0) ~ '';    }
                }
        } else {
                given $field {
                    when 'key'     {
                        my Str:D $type = %row«type»;
                        if $type eq 'commeted-dir' {
                            return '  => ';
                        } else {
                            return ' --> ';
                        }
                    }
                    when 'path'    { return ' # '; }
                    when 'comment' { return '  ';  }
                    default        { return '';    }
                }
        }
    } #`««« sub between(Int:D $idx, Str:D $field, Bool:D $colour, Bool:D $syntax, Str:D @fields, %row --> Str:D) »»»
    sub row-formatting(Int:D $cnt, Bool:D $colour, Bool:D $syntax --> Str:D) {
        if $colour {
            if $syntax { 
                return t.bg-color(255, 0, 255) ~ t.bold ~ t.bright-blue if $cnt == -3; # three heading lines. #
                return t.bg-color(0, 0, 127) ~ t.bold ~ t.bright-blue if $cnt == -2;
                return t.bg-color(255, 0, 255) ~ t.bold ~ t.bright-blue if $cnt == -1;
                return (($cnt % 2 == 0) ?? t.bg-yellow !! t.bg-color(0,195,0)) ~ t.bold ~ t.bright-blue;
            } else {
                return t.bg-color(255, 0, 255) ~ t.bold ~ t.bright-blue if $cnt == -3;
                return t.bg-color(0, 0, 127) ~ t.bold ~ t.bright-blue if $cnt == -2;
                return t.bg-color(255, 0, 255) ~ t.bold ~ t.bright-blue if $cnt == -1;
                return (($cnt % 2 == 0) ?? t.bg-yellow !! t.bg-color(0,195,0)) ~ t.bold ~ t.bright-blue;
            }
        } else {
            return '';
        }
    } #`««« sub row-formatting(Int:D $cnt, Bool:D $colour, Bool:D $syntax --> Str:D) »»»
    return list-by($prefix, $colour, $syntax, $page-length,
                  $pattern, @fields, %defaults, @data,
                  :&include-row, 
                  :&head-value, 
                  :&head-between,
                  :&field-value, 
                  :&between,
                  :&row-formatting);
} # sub list-commented(Str:D $prefix, Bool:D $colour, Bool:D $syntax, Int:D $page-length, Regex:D $pattern --> Bool) is export #

sub empty-trash( --> Bool) is export {
    my IO::Handle:D $input  = "$config/pack.p_ck".IO.open:     :r, :nl-in("\n")   :chomp;
    my IO::Handle:D $output = "$config/pack.p_ck.new".IO.open: :w, :nl-out("\n"), :chomp(True);
    my Int:D $key-width        = 0;
    my Int:D $dir-width       = 0;
    my Int:D $comment-width    = 0;
    my Str $ln;
    $ln = $input.get;
    while !$input.eof {
        if $ln ~~ rx/ ^ '#' ** {2 .. ∞} / {
        } elsif $ln ~~ rx/^ \s* $<key> = [ \w* [ <-[\h]>+ \w* ]* ] \h* $<type> = [ '-->' || ' =>' ] \h* $<path> = [ <-[ # ]>+ ] \h* [ '#' \h* $<comment> = [ .* ] ]?  $/ {
            my Str:D $path = ~$<path>;
            $path         .=trim;
            $key-width         = max($key-width,     wcswidth(~$<key>));
            $dir-width        = max($dir-width,    wcswidth($path));
            with $<comment> {
                $comment-width = max($comment-width, wcswidth(~$<comment>));
            }
        } elsif $ln ~~ rx/^ \h+ '#' \h* $<key> = [ \w* [ <-[\h]>+ \w* ]* ] \h* $<type> = [ '-->' || ' =>' || 'sep' ] \h* $<path> = [ <-[ # ]>+ ] \h* [ [ '#' \h* $<comment> = [ .* ] ]? ]?  $/ {
            my Str:D $path = ~$<path>;
            $path         .=trim;
            $key-width         = max($key-width,     wcswidth('#' ~ ~$<key>));
            $dir-width        = max($dir-width,    wcswidth($path));
            with $<comment> {
                $comment-width = max($comment-width, wcswidth(~$<comment>));
            }
        }
        $ln = $input.get;
    } # while !$input.eof #
    if $ln {
        if $ln ~~ rx/ ^ '#' ** {2 .. ∞} / {
        } elsif $ln ~~ rx/^ \s* $<key> = [ \w* [ <-[\h]>+ \w* ]* ] \h* $<type> = [ '-->' || ' =>' ] \h* $<path> = [ <-[ : # ]>+ ] \h* [ '#' \h* $<comment> = [ .* ] ]?  $/ {
            my Str:D $path = ~$<path>;
            $path         .=trim;
            $key-width         = max($key-width,     wcswidth(~$<key>));
            $dir-width        = max($dir-width,    wcswidth($path));
            with $<comment> {
                $comment-width = max($comment-width, wcswidth(~$<comment>));
            }
        } elsif $ln ~~ rx/^ \h* '#' \h* $<key> = [ \w* [ <-[\h]>+ \w* ]* ] \h* $<type> = [ '-->' || ' =>' || 'sep' ] \h* $<path> = [ <-[ # ]>+ ] \h* [ '#' \h* $<comment> = [ .* ] ]? $/ {
            my Str:D $path = ~$<path>;
            $path         .=trim;
            $key-width         = max($key-width,     wcswidth('#' ~ ~$<key>));
            $dir-width        = max($dir-width,    wcswidth($path));
            with $<comment> {
                $comment-width = max($comment-width, wcswidth(~$<comment>));
            }
        }
    } # $ln #
    #$key-width     += 2;
    #$dir-width    += 2;
    #$comment-width += 2;
    $key-width = 20 if $key-width < 20;
    $dir-width = 70 if $dir-width < 70;
    $input.seek(0, SeekFromBeginning);
    $ln = $input.get;
    while !$input.eof {
        if $ln ~~ rx/ ^ '#' ** {2 .. ∞} / {
            $output.say: $ln
        } elsif $ln ~~ rx/^ \h* $<key> = [ \w+ [ <-[\h]>+ \w* ]* ] \h* $<type> = [ '-->' || ' =>' ] \h* $<path> = [ <-[ : # ]>+ ] \h* [ '#' \h* $<comment> = [ .* ] ]?  $/ {
            my Str:D $path = ~$<path>;
            $path         .=trim;
            my Str $line = sprintf "%-*s %-3s %-*s", $key-width, ~$<key>, ~$<type>, $dir-width, $path;
            with $<comment> {
                $line ~= " # $<comment>";
            }
            $output.say: $line;
        } elsif $ln ~~ rx/^ \h* '#' \h* $<key> = [ \w+ [ <-[\h]>+ \w* ]* ] \h* $<type> = [ '-->' || ' =>' ] \h* $<path> = [ <-[ : # ]>+ ] \h* [ '#' \h* $<comment> = [ .* ] ]?  $/ {
            # do nothing we want to delete this #
        } else {
            $output.say: $ln
        }
        $ln = $input.get;
    } # while !$input.eof #
    if $ln {
        if $ln ~~ rx/ ^ '#' ** {2 .. ∞} / {
            $output.say: $ln
        } elsif $ln ~~ rx/^ \h* $<key> = [ \w+ [ <-[\h]>+ \w+ ]* ] \h* $<type> = [ '-->' || ' =>' ] \h* $<path> = [ <-[ : # ]>+ ] \h* [ '#' \h* $<comment> = [ .* ] ]?  $/ {
            my Str:D $path = ~$<path>;
            $path         .=trim;
            my Str $line = sprintf "%-*s %-3s %-*s", $key-width, ~$<key>, ~$<type>, $dir-width, $path;
            with $<comment> {
                $line ~= " # $<comment>";
            }
            $output.say: $line;
        } elsif $ln ~~ rx/^ \h* '#' \h* $<key> = [ \w+ [ <-[\h]>+ \w+ ]* ] \h* $<type> = [ '-->' || ' =>' || 'sep' ] \h* $<path> = [ <-[ : # ]>+ ] \h* [ '#' \h* $<comment> = [ .* ] ]?  $/ {
            # do nothing we want to delete this #
        } else {
            $output.say: $ln
        }
    } # $ln #
    $input.close;
    $output.close;
    if "$config/pack.p_ck.new".IO.move: "$config/pack.p_ck" {
        return True;
    } else {
        die "move failed";
    }
} # sub empty-trash( --> Bool) is export #

sub undelete(Str:D $key-to-find --> Bool) is export {
    if %the-lot{$key-to-find}:exists {
        "key $key-to-find exists delete undelete would override it.".say;
        return False;
    }
    my IO::Handle:D $input  = "$config/pack.p_ck".IO.open:     :r, :nl-in("\n")   :chomp;
    my IO::Handle:D $output = "$config/pack.p_ck.new".IO.open: :w, :nl-out("\n"), :chomp(True);
    my Int:D $key-width        = 0;
    my Int:D $path-width       = 0;
    my Int:D $comment-width    = 0;
    my Str $ln;
    $ln = $input.get;
    while !$input.eof {
        if $ln ~~ rx/ ^ '#' ** {2 .. ∞} / {
        } elsif $ln ~~ rx/^ \s* $<key> = [ \w* [ <-[\h]>+ \w* ]* ] \h* $<type> = [ '-->' || ' =>' ] \h* $<path> = [ <-[ # ]>+ ] \h* [ '#' \h* $<comment> = [ .* ] ]?  $/ {
            my Str:D $path = ~$<path>;
            $path         .=trim;
            $key-width         = max($key-width,     wcswidth(~$<key>));
            $path-width        = max($path-width,    wcswidth($path));
            with $<comment> {
                $comment-width = max($comment-width, wcswidth(~$<comment>));
            }
        } elsif $ln ~~ rx/^ \h+ '#' \h* $<key> = [ \w* [ <-[\h]>+ \w* ]* ] \h* $<type> = [ '-->' || ' =>' || 'sep' ] \h* $<path> = [ <-[ : # ]>+ ] \h* [ '#' \h* $<comment> = [ .* ] ]? $/ {
            my Str:D $path = ~$<path>;
            $path         .=trim;
            $key-width         = max($key-width,     wcswidth('#' ~ ~$<key>));
            $path-width        = max($path-width,    wcswidth($path));
            with $<comment> {
                $comment-width = max($comment-width, wcswidth(~$<comment>));
            }
        }
        $ln = $input.get;
    } # while !$input.eof #
    if $ln {
        if $ln ~~ rx/ ^ '#' ** {2 .. ∞} / {
        } elsif $ln ~~ rx/^ \s* $<key> = [ \w* [ <-[\h]>+ \w* ]* ] \h* $<type> = [ '-->' || ' =>' ] \h* $<path> = [ <-[ : # ]>+ ] \h* [ '#' \h* $<comment> = [ .* ] ]?  $/ {
            my Str:D $path = ~$<path>;
            $path         .=trim;
            $key-width         = max($key-width,     wcswidth(~$<key>));
            $path-width        = max($path-width,    wcswidth($path));
            with $<comment> {
                $comment-width = max($comment-width, wcswidth(~$<comment>));
            }
        } elsif $ln ~~ rx/^ \h* '#' \h* $<key> = [ \w* [ <-[\h]>+ \w* ]* ] \h* $<type> = [ '-->' || ' =>' || 'sep' ] \h* $<path> = [ <-[ : # ]>+ ] \h* [ '#' \h* $<comment> = [ .* ] ]? $/ {
            my Str:D $path = ~$<path>;
            $path         .=trim;
            $key-width         = max($key-width,     wcswidth('#' ~ ~$<key>));
            $path-width        = max($path-width,    wcswidth($path));
            with $<comment> {
                $comment-width = max($comment-width, wcswidth(~$<comment>));
            }
        }
    } # $ln #
    #$key-width     += 2;
    #$path-width    += 2;
    #$comment-width += 2;
    $key-width = 20 if $key-width < 20;
    $path-width = 70 if $path-width < 70;
    $input.seek(0, SeekFromBeginning);
    $ln = $input.get;
    while !$input.eof {
        if $ln ~~ rx/ ^ '#' ** {2 .. ∞} / {
            $output.say: $ln
        } elsif $ln ~~ rx/^ \h* $<key> = [ \w+ [ <-[\h]>+ \w* ]* ] \h* $<type> = [ '-->' || ' =>' ] \h* $<path> = [ <-[ : # ]>+ ] \h* [ '#' \h* $<comment> = [ .* ] ]?  $/ {
            my Str:D $path = ~$<path>;
            $path         .=trim;
            my Str $line = sprintf "%-*s %-3s %-*s", $key-width, ~$<key>, ~$<type>, $path-width, $path;
            with $<comment> {
                $line ~= " # $<comment>";
            }
            $output.say: $line;
        } elsif $ln ~~ rx/^ \h* '#' \h* $<key> = [ \w+ [ <-[\h]>+ \w* ]* ] \h* $<type> = [ '-->' || ' =>' ] \h* $<path> = [ <-[ : # ]>+ ] \h* [ '#' \h* $<comment> = [ .* ] ]?  $/ {
            my Str:D $path = ~$<path>;
            $path         .=trim;
            my Str $line;
            if $key-to-find.trim eq (~$<key>).trim {
                $line = sprintf "%-*s %-3s %-*s", $key-width, ~$<key>, ~$<type>, $path-width, $path;
            } else {
                $line = sprintf "#%-*s %-3s %-*s", $key-width - 1, ~$<key>, ~$<type>, $path-width, $path;
            }
            with $<comment> {
                $line ~= " # $<comment>";
            }
            $output.say: $line;
        } else {
            $output.say: $ln
        }
        $ln = $input.get;
    } # while !$input.eof #
    if $ln {
        if $ln ~~ rx/ ^ '#' ** {2 .. ∞} / {
            $output.say: $ln
        } elsif $ln ~~ rx/^ \h* $<key> = [ \w+ [ <-[\h]>+ \w+ ]* ] \h* $<type> = [ '-->' || ' =>' ] \h* $<path> = [ <-[ : # ]>+ ] \h* [ '#' \h* $<comment> = [ .* ] ]?  $/ {
            my Str:D $path = ~$<path>;
            $path         .=trim;
            my Str $line = sprintf "%-*s %-3s %-*s", $key-width, ~$<key>, ~$<type>, $path-width, $path;
            with $<comment> {
                $line ~= " # $<comment>";
            }
            $output.say: $line;
        } elsif $ln ~~ rx/^ \h* '#' \h* $<key> = [ \w+ [ <-[\h]>+ \w+ ]* ] \h* $<type> = [ '-->' || ' =>' || 'sep' ] \h* $<path> = [ <-[ : # ]>+ ] \h* [ '#' \h* $<comment> = [ .* ] ]?  $/ {
            my Str:D $path = ~$<path>;
            $path         .=trim;
            my Str $line;
            if $key-to-find.trim eq (~$<key>).trim {
                $line = sprintf "%-*s %-3s %-*s", $key-width, ~$<key>, ~$<type>, $path-width, $path;
            } else {
                $line = sprintf "#%-*s %-3s %-*s", $key-width - 1, ~$<key>, ~$<type>, $path-width, $path;
            }
            with $<comment> {
                $line ~= " # $<comment>";
            }
            $output.say: $line;
        } else {
            $output.say: $ln
        }
    } # $ln #
    $input.close;
    $output.close;
    if "$config/pack.p_ck.new".IO.move: "$config/pack.p_ck" {
        return True;
    } else {
        die "move failed";
    }
} # sub undelete(Str:D $key-to-find --> Bool) is export #

sub stats(Str:D $prefix, Bool:D $colour, Bool:D $syntax, Regex:D $pattern --> Bool:D) is export {
    my Str:D @quanties = 'lines-total', 'header-lines', 'rows-of-hashes',
                          'empty-strs', 'comment-lines', 'commented',
                          'commented-dirs', 'lines', 'dirs';
    my @rows;
    for @quanties -> $quantity {
        my %row = quantity => $quantity, value => %stats{$quantity};
        @rows.push: %row;
    }
    my Str:D @fields     = 'quantity', 'value';
    my Str:D %fancynames = quantity => 'Quantity', value => 'Number';
    my Str:D %prompts    = lines-total => 'number of lines in file:',
                           header-lines => 'number of header lines in file:',
                           rows-of-hashes => 'rows of hashes in file:',
                           empty-strs => 'empty lines in file:',
                           comment-lines => 'comment lines:',
                           commented => 'trashed lines:',
                           commented-dirs => 'trashed dirs in db:',
                           lines => 'number of elts in db:',
                           dirs => 'number of dirs in db:';
    my %defaults;
    my $page-length = 30; # basically $page-length is redundant here. #
    sub include-row(Str:D $prefix, Regex:D $pattern, Int:D $idx, Str:D @fields, %row --> Bool:D) {
        my Str:D $value = ~(%prompts{%row«quantity»} // '');
        return True if $value.starts-with($prefix, :ignorecase) && $value ~~ $pattern;
        return False;
    } # sub include-row(Str:D $prefix, Regex:D $pattern, Int:D $idx, Str:D @fields, %row --> Bool:D) #
    sub head-value(Int:D $indx, Str:D $field, Bool:D $colour, Bool:D $syntax, Str:D @fields --> Str:D) {
        #dd $indx, $field, $colour, $syntax, @fields;
        if $colour {
            if $syntax { 
                return t.color(0, 255, 255) ~ %fancynames{$field};
            } else {
                return t.color(0, 255, 255) ~ %fancynames{$field};
            }
        } else {
            return %fancynames{$field};
        }
    } # sub head-value(Int:D $indx, Str:D $field, Bool:D $colour, Bool:D $syntax, Str:D @fields --> Str:D) #
    sub head-between(Int:D $indx, Str:D $field, Bool:D $colour, Bool:D $syntax, Str:D @fields --> Str:D) {
        return ' ' x 5;
    } # sub head-between(Int:D $indx, Str:D $field, Bool:D $colour, Bool:D $syntax, Str:D @fields --> Str:D) #
    sub field-value(Int:D $idx, Str:D $field, $value, Bool:D $colour, Bool:D $syntax, Str:D @fields, %row --> Str:D) {
        my Str:D $val = ~($value // ''); #`««« assumming $value is a Str:D »»»
        #dd $val, $value, $field;
        if $syntax {
            given $field {
                when 'quantity' { return t.color(255, 0, 0)   ~ %prompts{$val}; }
                when 'value'    { return t.color(255, 0, 255) ~ $val;           }
                default         { return t.color(255, 0, 0)   ~ $val;           }
            } # given $field #
        } elsif $colour {
            given $field {
                when 'quantity' { return t.color(0, 0, 255) ~ %prompts{$val}; }
                when 'value'    { return t.color(0, 0, 255) ~ $val;           }
                default         { return t.color(255, 0, 0) ~ $val;           }
            } # given $field #
        } else {
            given $field {
                when 'quantity' { return %prompts{$val}; }
                when 'value'    { return $val;           }
                default         { return $val;           }
            } # given $field #
        }
    } # sub field-value(Int:D $idx, Str:D $field, $value, Bool:D $colour, Bool:D $syntax, Str:D @fields, %row --> Str:D) #
    sub between(Int:D $idx, Str:D $field, Bool:D $colour, Bool:D $syntax, Str:D @fields, %row --> Str:D) {
        return ' ' x 5;
    } # sub between(Int:D $idx, Str:D $field, Bool:D $colour, Bool:D $syntax, Str:D @fields, %row --> Str:D) #
    sub row-formatting(Int:D $cnt, Bool:D $colour, Bool:D $syntax --> Str:D) {
        if $colour {
            if $syntax { 
                return t.bg-color(255, 0, 255) ~ t.bold ~ t.bright-blue if $cnt == -3; # three heading lines. #
                return t.bg-color(0, 0, 127) ~ t.bold ~ t.bright-blue if $cnt == -2;
                return t.bg-color(255, 0, 255) ~ t.bold ~ t.bright-blue if $cnt == -1;
                return (($cnt % 2 == 0) ?? t.bg-yellow !! t.bg-color(0,195,0)) ~ t.bold ~ t.bright-blue;
            } else {
                return t.bg-color(255, 0, 255) ~ t.bold ~ t.bright-blue if $cnt == -3;
                return t.bg-color(0, 0, 127) ~ t.bold ~ t.bright-blue if $cnt == -2;
                return t.bg-color(255, 0, 255) ~ t.bold ~ t.bright-blue if $cnt == -1;
                return (($cnt % 2 == 0) ?? t.bg-yellow !! t.bg-color(0,195,0)) ~ t.bold ~ t.bright-blue;
            }
        } else {
            return '';
        }
    } # sub row-formatting(Int:D $cnt, Bool:D $colour, Bool:D $syntax --> Str:D) #
    return list-by($prefix, $colour, $syntax, $page-length,
                  $pattern, @fields, %defaults, @rows,
                  :!sort,
                  :&include-row, 
                  :&head-value, 
                  :&head-between,
                  :&field-value, 
                  :&between,
                  :&row-formatting);
} # sub stats(Str:D $prefix, Bool:D $colour, Bool:D $syntax, Regex:D $pattern --> Bool:D) is export #

sub backup-db-file(Bool:D $use-windows-formating --> Bool) is export {
    my DateTime $now = DateTime.now;
    my Str:D $time-stamp = $now.Str;
    if $*DISTRO.is-win || $use-windows-formating {
        $time-stamp ~~ tr/./·/;
        $time-stamp ~~ tr/:/./;
    }
    return "$config/pack.p_ck".IO.copy("$config/pack.p_ck.$time-stamp".IO);
} # sub backup-db-file(Bool:D $use-windows-formating --> Bool) is export #

sub restore-db-file(IO::Path $restore-from --> Bool) is export {
    with $restore-from {
        my $actions = PathFileActions;
        if $restore-from ~~ :f {
            my @db-file = $restore-from.slurp.split("\n");
            return $restore-from.copy("$config/pack.p_ck".IO) if PathsFile.parse(@db-file.join("\x0A"), :enc('UTF-8'), :$actions).made;
        }
        return False;
    } else {
        return False;
    }
}

sub backups-menu-restore-db(Bool:D $colour, Bool:D $syntax, Str:D $message = "" --> Bool:D) is export {
    my IO::Path @backups = $config.IO.dir(:test(rx/ ^ 
                                                           'pack.p_ck.' \d ** 4 '-' \d ** 2 '-' \d ** 2
                                                               [ 'T' \d **2 [ [ '.' || ':' ] \d ** 2 ] ** {0..2} [ [ '.' || '·' ] \d+ 
                                                                   [ [ '+' || '-' ] \d ** 2 [ '.' || ':' ] \d ** 2 || 'z' ]?  ]?
                                                               ]?
                                                           $
                                                         /
                                                       )
                                                );
    #dd @backups;
    my $actions = PathFileActions;
    @backups .=grep: -> IO::Path $fl { 
                                my @file = $fl.slurp.split("\n");
                                PathsFile.parse(@file.join("\x0A"), :enc('UTF-8'), :$actions).made;
                            };
    #dd @backups;
    my $highlight-bg-colour = t.bg-color(0, 0, 107) ~ t.bold;
    my $highlight-fg-colour = t.color(255, 255, 0);
    my @Backups = @backups.map: -> IO::Path $f {
          my %elt = value => $f.Str, backup => $f.basename,
                      perms => symbolic-perms($f, :$colour, :$syntax, :highlight-fg-colour(''),
                                              :fg-colour0(''), :fg-colour1('')),
                      user => uid2username($f.user), group => gid2groupname($f.group),
                      size => format-bytes($f.s), modified => $f.modified.DateTime.local.Str;
          %elt;
    };
    @Backups .=sort( -> %lhs, %rhs { %lhs«value».IO.basename cmp %rhs«value».IO.basename });
    sub row(Int:D $cnt, Int:D $pos, @array,
                                     Bool:D :$colour = False, Bool:D :$syntax = False,
                                     Str:D :$highlight-bg-colour = '',
                                     Str:D :$highlight-fg-colour = '',
                                     Str:D :$bg-colour0 = '',
                                     Str:D :$fg-colour0 = '', 
                                     Str:D :$bg-colour1 = '',
                                     Str:D :$fg-colour1 = ''  --> Str:D) {
        my %r = @array[$cnt];
        if $syntax {
            if %r«value» eq 'cancel' {
                return %r«name» if %r«name»:exists;
                return %r«value»;
            } 
            my Str:D $name = %r«perms» ~ ' ';
            if $cnt == $pos {
                $name ~= $highlight-bg-colour ~ t.color(255, 0, 0)   ~ %r«size»     ~ ' ';
                $name ~= $highlight-bg-colour ~ t.color(255, 255, 0) ~ %r«user»     ~ ' ';
                $name ~= $highlight-bg-colour ~ t.color(255, 255, 0) ~ %r«group»    ~ ' ';
                $name ~= $highlight-bg-colour ~ t.color(0, 0, 255)   ~ %r«modified» ~ ' ';
                $name ~= $highlight-bg-colour ~ t.color(255, 0, 255) ~ %r«backup»   ~ ' ';
            } elsif $cnt %% 2 {
                $name ~= $bg-colour0 ~ t.color(255, 0, 0)   ~ %r«size»     ~ ' ';
                $name ~= $bg-colour0 ~ t.color(255, 255, 0) ~ %r«user»     ~ ' ';
                $name ~= $bg-colour0 ~ t.color(255, 255, 0) ~ %r«group»    ~ ' ';
                $name ~= $bg-colour0 ~ t.color(0, 0, 255)   ~ %r«modified» ~ ' ';
                $name ~= $bg-colour0 ~ t.color(255, 0, 255) ~ %r«backup»   ~ ' ';
            } else {
                $name ~= $bg-colour1 ~ t.color(255, 0, 0)   ~ %r«size»     ~ ' ';
                $name ~= $bg-colour1 ~ t.color(255, 255, 0) ~ %r«user»     ~ ' ';
                $name ~= $bg-colour1 ~ t.color(255, 255, 0) ~ %r«group»    ~ ' ';
                $name ~= $bg-colour1 ~ t.color(0, 0, 255)   ~ %r«modified» ~ ' ';
                $name ~= $bg-colour1 ~ t.color(255, 0, 255) ~ %r«backup»   ~ ' ';
            }
        } elsif $colour {
            if %r«value» eq 'cancel' {
                return %r«name» if %r«name»:exists;
                return %r«value»;
            } 
            my Str:D $name = %r«size» ~ ' ' ~ %r«user» ~ ' ' ~ %r«group» ~ ' ' ~ %r«modified» ~ ' ' ~ %r«backup»;
            if $cnt == $pos {
                return $highlight-bg-col