}
+=head2 progress_bar
+
+Draw progress bar on STDERR.
+
+ $webpac->progress_bar($current, $max);
+
+=cut
+
+sub progress_bar {
+ my $self = shift;
+
+ my ($curr,$max) = @_;
+
+ my $log = $self->_get_logger();
+
+ $log->logconfess("no current value!") if (! $curr);
+ $log->logconfess("no maximum value!") if (! $max);
+
+ if ($curr > $max) {
+ $max = $curr;
+ $log->debug("overflow to $curr");
+ }
+
+ $self->{'last_pcnt'} ||= 1;
+ $self->{'start_t'} ||= time();
+
+ my $p = int($curr * 100 / $max) || 1;
+
+ # reset on re-run
+ if ($p < $self->{'last_pcnt'}) {
+ $self->{'last_pcnt'} = $p;
+ $self->{'start_t'} = time();
+ }
+
+ if ($p != $self->{'last_pcnt'}) {
+
+ my $t = time();
+ my $rate = ($curr / ($t - $self->{'start_t'} || 1));
+ my $eta = ($max-$curr) / ($rate || 1);
+ printf STDERR ("%5d [%-38s] %-5d %0.1f/s %s\r",$curr,"=" x ($p/3)."$p%>", $max, $rate, $self->fmt_time($eta));
+ $self->{'last_pcnt'} = $p;
+ $self->{'last_curr'} = $curr;
+ }
+ print STDERR "\n" if ($p == 100);
+}
+
+=head2 fmt_time
+
+Format time (in seconds) for display.
+
+ print $webpac->fmt_time(time());
+
+This method is called by L<progress_bar> to display remaining time.
+
+=cut
+
+sub fmt_time {
+ my $self = shift;
+
+ my $t = shift || 0;
+ my $out = "";
+
+ my ($ss,$mm,$hh) = gmtime($t);
+ $out .= "${hh}h" if ($hh);
+ $out .= sprintf("%02d:%02d", $mm,$ss);
+ $out .= " " if ($hh == 0);
+ return $out;
+}
+
+#
+#
+#
+
=head1 INTERNAL METHODS
Here is a quick list of internal methods, mostly useful to turn debugging