#!/usr/bin/env perl

# This chunk of stuff was generated by App::FatPacker. To find the original
# file's code, look for the end of this BEGIN block or the string 'FATPACK'
BEGIN {
my %fatpacked;

$fatpacked{"App/FatPacker.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'APP_FATPACKER';
  package App::FatPacker;
  
  use strict;
  use warnings FATAL => 'all';
  use 5.008001;
  use Getopt::Long;
  use Cwd qw(cwd);
  use File::Find qw(find);
  use File::Spec::Functions qw(
    catdir splitpath splitdir catpath rel2abs abs2rel
  );
  use File::Spec::Unix;
  use File::Copy qw(copy);
  use File::Path qw(mkpath rmtree);
  use B qw(perlstring);
  
  our $VERSION = '0.010002'; # 0.10.2
  
  $VERSION = eval $VERSION;
  
  sub call_parser {
    my $self = shift;
    my ($args, $options) = @_;
  
    local *ARGV = [ @{$args} ];
    $self->{option_parser}->getoptions(@$options);
  
    return [ @ARGV ];
  }
  
  sub lines_of {
    map +(chomp,$_)[1], do { local @ARGV = ($_[0]); <> };
  }
  
  sub stripspace {
    my ($text) = @_;
    $text =~ /^(\s+)/ && $text =~ s/^$1//mg;
    $text;
  }
  
  sub import {
    $_[1] && $_[1] eq '-run_script'
      and return shift->new->run_script;
  }
  
  sub new {
    bless {
      option_parser => Getopt::Long::Parser->new(
        config => [ qw(require_order pass_through bundling no_auto_abbrev) ]
      ),
    }, $_[0];
  }
  
  sub run_script {
    my ($self, $args) = @_;
    my @args = $args ? @$args : @ARGV;
    (my $cmd = shift @args || 'help') =~ s/-/_/g;
  
    if (my $meth = $self->can("script_command_${cmd}")) {
      $self->$meth(\@args);
    } else {
      die "No such command ${cmd}";
    }
  }
  
  sub script_command_help {
    print "Try `perldoc fatpack` for how to use me\n";
  }
  
  sub script_command_pack {
    my ($self, $args) = @_;
  
    my @modules = split /\r?\n/, $self->trace(args => $args);
    my @packlists = $self->packlists_containing(\@modules);
  
    my $base = catdir(cwd, 'fatlib');
    $self->packlists_to_tree($base, \@packlists);
  
    my $file = shift @$args;
    print $self->fatpack_file($file);
  }
  
  sub script_command_trace {
    my ($self, $args) = @_;
  
    $args = $self->call_parser($args => [
      'to=s' => \my $file,
      'to-stderr' => \my $to_stderr,
      'use=s' => \my @additional_use
    ]);
  
    die "Can't use to and to-stderr on same call" if $file && $to_stderr;
  
    $file ||= 'fatpacker.trace';
  
    if (!$to_stderr and -e $file) {
      unlink $file or die "Couldn't remove old trace file: $!";
    }
    my $arg = do {
      if ($to_stderr) {
        ">&STDERR"
      } elsif ($file) {
        ">>${file}"
      }
    };
  
    $self->trace(
      use => \@additional_use,
      args => $args,
      output => $arg,
    );
  }
  
  sub trace {
    my ($self, %opts) = @_;
  
    my $output = $opts{output};
    my $trace_opts = join ',', $output||'>&STDOUT', @{$opts{use}||[]};
  
    local $ENV{PERL5OPT} = join ' ',
      ($ENV{PERL5OPT}||()), '-MApp::FatPacker::Trace='.$trace_opts;
  
    my @args = @{$opts{args}||[]};
  
    if ($output) {
      # user specified output target, JFDI
      system $^X, @args;
      return;
    } else {
      # no output target specified, slurp
      open my $out_fh, "$^X @args |";
      return do { local $/; <$out_fh> };
    }
  }
  
  sub script_command_packlists_for {
    my ($self, $args) = @_;
    foreach my $pl ($self->packlists_containing($args)) {
      print "${pl}\n";
    }
  }
  
  sub packlists_containing {
    my ($self, $targets) = @_;
    my @targets = @$targets;
    {
      local @INC = ('lib', @INC);
      foreach my $t (@targets) {
        require $t;
      }
    }
    my @search = grep -d $_, map catdir($_, 'auto'), @INC;
    my %pack_rev;
    find({
      no_chdir => 1,
      wanted => sub {
        return unless /[\\\/]\.packlist$/ && -f $_;
        $pack_rev{$_} = $File::Find::name for lines_of $File::Find::name;
      },
    }, @search);
    my %found; @found{map +($pack_rev{Cwd::abs_path($INC{$_})}||()), @targets} = ();
    sort keys %found;
  }
  
  sub script_command_tree {
    my ($self, $args) = @_;
    my $base = catdir(cwd,'fatlib');
    $self->packlists_to_tree($base, $args);
  }
  
  sub packlists_to_tree {
    my ($self, $where, $packlists) = @_;
    rmtree $where;
    mkpath $where;
    foreach my $pl (@$packlists) {
      my ($vol, $dirs, $file) = splitpath $pl;
      my @dir_parts = splitdir $dirs;
      my $pack_base;
      PART: foreach my $p (0 .. $#dir_parts) {
        if ($dir_parts[$p] eq 'auto') {
          # $p-2 since it's <wanted path>/$Config{archname}/auto
          $pack_base = catpath $vol, catdir @dir_parts[0..$p-2];
          last PART;
        }
      }
      die "Couldn't figure out base path of packlist ${pl}" unless $pack_base;
      foreach my $source (lines_of $pl) {
        # there is presumably a better way to do "is this under this base?"
        # but if so, it's not obvious to me in File::Spec
        next unless substr($source,0,length $pack_base) eq $pack_base;
        my $target = rel2abs( abs2rel($source, $pack_base), $where );
        my $target_dir = catpath((splitpath $target)[0,1]);
        mkpath $target_dir;
        copy $source => $target;
      }
    }
  }
  
  sub script_command_file {
    my ($self, $args) = @_;
    my $file = shift @$args;
    print $self->fatpack_file($file);
  }
  
  sub fatpack_file {
    my ($self, $file) = @_;
  
    my $shebang = "";
    my $script = "";
    if ( defined $file and -r $file ) {
      ($shebang, $script) = $self->load_main_script($file);
    }
  
    my @dirs = $self->collect_dirs();
    my %files;
    $self->collect_files($_, \%files) for @dirs;
  
    return join "\n", $shebang, $self->fatpack_code(\%files), $script;
  }
  
  # This method can be overload in sub classes
  # For example to skip POD
  sub load_file {
    my ($self, $file) = @_;
    my $content = do {
      local (@ARGV, $/) = ($file);
      <>
    };
    close ARGV;
    return $content;
  }
  
  sub collect_dirs {
    my ($self) = @_;
    my $cwd = cwd;
    return grep -d, map rel2abs($_, $cwd), ('lib','fatlib');
  }
  
  sub collect_files {
    my ($self, $dir, $files) = @_;
    find(sub {
      return unless -f $_;
      !/\.pm$/ and warn "File ${File::Find::name} isn't a .pm file - can't pack this -- if you hoped we were going to, things may not be what you expected later\n" and return;
      $files->{File::Spec::Unix->abs2rel($File::Find::name,$dir)} =
        $self->load_file($File::Find::name);
    }, $dir);
  }
  
  sub load_main_script {
    my ($self, $file) = @_;
    open my $fh, "<", $file or die("Can't read $file: $!");
    my $shebang = <$fh>;
    my $script = join "", <$fh>;
    close $fh;
    unless ( index($shebang, '#!') == 0 ) {
      $script = $shebang . $script;
      $shebang = "";
    }
    return ($shebang, $script);
  }
  
  sub fatpack_start {
    return stripspace <<'  END_START';
      # This chunk of stuff was generated by App::FatPacker. To find the original
      # file's code, look for the end of this BEGIN block or the string 'FATPACK'
      BEGIN {
      my %fatpacked;
    END_START
  }
  
  sub fatpack_end {
    return stripspace <<'  END_END';
      s/^  //mg for values %fatpacked;
  
      my $class = 'FatPacked::'.(0+\%fatpacked);
      no strict 'refs';
      *{"${class}::files"} = sub { keys %{$_[0]} };
  
      if ($] < 5.008) {
        *{"${class}::INC"} = sub {
           if (my $fat = $_[0]{$_[1]}) {
             return sub {
               return 0 unless length $fat;
               $fat =~ s/^([^\n]*\n?)//;
               $_ = $1;
               return 1;
             };
           }
           return;
        };
      }
  
      else {
        *{"${class}::INC"} = sub {
          if (my $fat = $_[0]{$_[1]}) {
            open my $fh, '<', \$fat
              or die "FatPacker error loading $_[1] (could be a perl installation issue?)";
            return $fh;
          }
          return;
        };
      }
  
      unshift @INC, bless \%fatpacked, $class;
    } # END OF FATPACK CODE
    END_END
  }
  
  sub fatpack_code {
    my ($self, $files) = @_;
    my @segments = map {
      (my $stub = $_) =~ s/\.pm$//;
      my $name = uc join '_', split '/', $stub;
      my $data = $files->{$_}; $data =~ s/^/  /mg; $data =~ s/(?<!\n)\z/\n/;
      '$fatpacked{'.perlstring($_).qq!} = '#line '.(1+__LINE__).' "'.__FILE__."\\"\\n".<<'${name}';\n!
      .qq!${data}${name}\n!;
    } sort keys %$files;
  
    return join "\n", $self->fatpack_start, @segments, $self->fatpack_end;
  }
  
  =encoding UTF-8
  
  =head1 NAME
  
  App::FatPacker - pack your dependencies onto your script file
  
  =head1 SYNOPSIS
  
    $ fatpack pack myscript.pl >myscript.packed.pl
  
  Or, with more step-by-step control:
  
    $ fatpack trace myscript.pl
    $ fatpack packlists-for `cat fatpacker.trace` >packlists
    $ fatpack tree `cat packlists`
    $ fatpack file myscript.pl >myscript.packed.pl
  
  See the documentation for the L<fatpack> script itself for more information.
  
  The programmatic API for this code is not yet fully decided, hence the 0.x
  release version. Expect that to be cleaned up for 1.0.
  
  =head1 SEE ALSO
  
  L<article for Perl Advent 2012|http://www.perladvent.org/2012/2012-12-14.html>
  
  =head1 SUPPORT
  
  Your current best avenue is to come annoy mst on #toolchain on
  irc.perl.org. There should be a non-IRC means of support by 1.0.
  
  =head1 AUTHOR
  
  Matt S. Trout (mst) <mst@shadowcat.co.uk>
  
  =head2 CONTRIBUTORS
  
  miyagawa - Tatsuhiko Miyagawa (cpan:MIYAGAWA) <miyagawa@bulknews.net>
  
  tokuhirom - MATSUNO★Tokuhiro (cpan:TOKUHIROM) <tokuhirom@gmail.com>
  
  dg - David Leadbeater (cpan:DGL) <dgl@dgl.cx>
  
  gugod - 劉康民 (cpan:GUGOD) <gugod@cpan.org>
  
  t0m - Tomas Doran (cpan:BOBTFISH) <bobtfish@bobtfish.net>
  
  sawyer - Sawyer X (cpan:XSAWYERX) <xsawyerx@cpan.org>
  
  ether - Karen Etheridge (cpan:ETHER) <ether@cpan.org>
  
  Mithaldu - Christian Walde (cpan:MITHALDU) <walde.christian@googlemail.com>
  
  dolmen - Olivier Mengué (cpan:DOLMEN) <dolmen@cpan.org>
  
  djerius - Diab Jerius (cpan:DJERIUS) <djerius@cpan.org>
  
  haarg - Graham Knop (cpan:HAARG> <haarg@haarg.org>
  
  Many more people are probably owed thanks for ideas. Yet
  another doc nit to fix.
  
  =head1 COPYRIGHT
  
  Copyright (c) 2010 the App::FatPacker L</AUTHOR> and L</CONTRIBUTORS>
  as listed above.
  
  =head1 LICENSE
  
  This library is free software and may be distributed under the same terms
  as perl itself.
  
  =cut
  
  1;
  
APP_FATPACKER

$fatpacked{"App/FatPacker/Trace.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'APP_FATPACKER_TRACE';
  package App::FatPacker::Trace;
  
  use strict;
  use warnings FATAL => 'all';
  use B ();
  
  my $trace_file;
  my %initial_inc;
  
  sub import {
    my (undef, $file, @extras) = @_;
  
    $trace_file = $file || '>>fatpacker.trace';
    # For filtering out our own deps later.
    # (Not strictly required as these are core only and won't have packlists, but 
    # looks neater.)
    %initial_inc = %INC;
  
    # Use any extra modules specified
    eval "use $_" for @extras;
  
    B::minus_c;
  }
  
  CHECK {
    return unless $trace_file; # not imported
  
    open my $trace, $trace_file
        or die "Couldn't open $trace_file to trace to: $!";
  
    for my $inc (keys %INC) {
      next if exists $initial_inc{$inc};
      print $trace "$inc\n";
    }
  }
  
  1;
  
  __END__
  
  =head1 NAME
  
  App::FatPacker::Trace - Tracing module usage using compilation checking
  
  =head1 SYNOPSIS
  
      # open STDERR for writing
      # will be like: open my $fh, '>', '&STDERR'...
      perl -MApp::FatPacker::Trace=>&STDERR myscript.pl
  
      # open a file for writing
      # will be like: open my $fh, '>>', 'fatpacker.trace'
      perl -MApp::FatPacker::Trace=>>fatpacker.trace myscript.pl
  
  =head1 DESCRIPTION
  
  This module allows tracing the modules being used by your code. It does that
  using clever trickery using the C<import> method, the C<CHECK> block and
  L<B>'s C<minus_c> function.
  
  When App::FatPacker::Trace is being used, the import() method will call
  C<B::minus_c> in order to set up the global compilation-only flag perl
  (the interpreter) has. This will prevent any other code from being run.
  
  Then in the C<CHECK> block which is reached at the end of the compilation
  phase (see L<perlmod>), it will gather all modules that have been loaded,
  using C<%INC>, and will write it to a file or to STDERR, determined by
  parameters sent to the C<import> method.
  
  =head1 METHODS
  
  =head2 import
  
  This method gets run when you just load L<App::FatPacker::Trace>. It will
  note the current C<%INC> and will set up the output to be written to, and
  raise the compilation-only flag, which will prevent anything from being
  run past that point. This flag cannot be unset, so this is most easily run
  from the command line as such:
  
      perl -MApp::FatPacker::Trace [...]
  
  You can control the parameters to the import using an equal sign, as such:
  
      # send the parameter "hello"
      perl -MApp::FatPacker::Trace=hello [...]
  
      # send the parameter ">&STDERR"
      perl -MApp::FatPacker::Trace=>&STDERR [...]
  
  The import method accepts a first parameter telling it which output to open
  and how. These are both sent in a single parameter.
  
      # append to mytrace.txt
      perl -MApp::FatPacker::Trace=>>mytrace.txt myscript.pl
  
      # write to STDERR
      perl -MApp::FatPacker::Trace=>&STDERR myscript.pl
  
  The import method accepts additional parameters of extra modules to load.
  It will then add these modules to the trace. This is helpful if you want
  to explicitly indicate additional modules to trace, even if they aren't
  used in your script. Perhaps you're conditionally using them, perhaps
  they're for additional features, perhaps they're loaded lazily, whatever
  the reason.
  
      # Add Moo to the trace, even if you don't trace it in myscript.pl
      perl -MApp::FatPacker::Trace=>&STDERR,Moo myscript.pl
  
APP_FATPACKER_TRACE

$fatpacked{"App/cpanminus.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'APP_CPANMINUS';
  package App::cpanminus;
  our $VERSION = "1.7025";
  
  =encoding utf8
  
  =head1 NAME
  
  App::cpanminus - get, unpack, build and install modules from CPAN
  
  =head1 SYNOPSIS
  
      cpanm Module
  
  Run C<cpanm -h> or C<perldoc cpanm> for more options.
  
  =head1 DESCRIPTION
  
  cpanminus is a script to get, unpack, build and install modules from
  CPAN and does nothing else.
  
  It's dependency free (can bootstrap itself), requires zero
  configuration, and stands alone. When running, it requires only 10MB
  of RAM.
  
  =head1 INSTALLATION
  
  There are several ways to install cpanminus to your system.
  
  =head2 Package management system
  
  There are Debian packages, RPMs, FreeBSD ports, and packages for other
  operation systems available. If you want to use the package management system,
  search for cpanminus and use the appropriate command to install. This makes it
  easy to install C<cpanm> to your system without thinking about where to
  install, and later upgrade.
  
  =head2 Installing to system perl
  
  You can also use the latest cpanminus to install cpanminus itself:
  
      curl -L https://cpanmin.us | perl - --sudo App::cpanminus
  
  This will install C<cpanm> to your bin directory like
  C</usr/local/bin> and you'll need the C<--sudo> option to write to
  the directory, unless you configured C<INSTALL_BASE> with L<local::lib>.
  
  =head2 Installing to local perl (perlbrew)
  
  If you have perl in your home directory, which is the case if you use
  tools like L<perlbrew>, you don't need the C<--sudo> option, since
  you're most likely to have a write permission to the perl's library
  path. You can just do:
  
      curl -L https://cpanmin.us | perl - App::cpanminus
  
  to install the C<cpanm> executable to the perl's bin path, like
  C<~/perl5/perlbrew/bin/cpanm>.
  
  =head2 Downloading the standalone executable
  
  You can also copy the standalone executable to whatever location you'd like.
  
      cd ~/bin
      curl -LO http://xrl.us/cpanm
      chmod +x cpanm
      # edit shebang if you don't have /usr/bin/env
  
  This just works, but be sure to grab the new version manually when you
  upgrade because C<--self-upgrade> might not work for this.
  
  =head1 DEPENDENCIES
  
  perl 5.8 or later.
  
  =over 4
  
  =item *
  
  'tar' executable (bsdtar or GNU tar version 1.22 are recommended) or Archive::Tar to unpack files.
  
  =item *
  
  C compiler, if you want to build XS modules.
  
  =item *
  
  make
  
  =item *
  
  Module::Build (core in 5.10)
  
  =back
  
  =head1 QUESTIONS
  
  =head2 Another CPAN installer?
  
  OK, the first motivation was this: the CPAN shell runs out of memory (or swaps
  heavily and gets really slow) on Slicehost/linode's most affordable plan with
  only 256MB RAM. Should I pay more to install perl modules from CPAN? I don't
  think so.
  
  =head2 But why a new client?
  
  First of all, let me be clear that CPAN and CPANPLUS are great tools
  I've used for I<literally> years (you know how many modules I have on
  CPAN, right?). I really respect their efforts of maintaining the most
  important tools in the CPAN toolchain ecosystem.
  
  However, for less experienced users (mostly from outside the Perl community),
  or even really experienced Perl developers who know how to shoot themselves in
  their feet, setting up the CPAN toolchain often feels like yak shaving,
  especially when all they want to do is just install some modules and start
  writing code.
  
  =head2 Zero-conf? How does this module get/parse/update the CPAN index?
  
  It queries the CPAN Meta DB site at L<http://cpanmetadb.plackperl.org/>.
  The site is updated at least every hour to reflect the latest changes
  from fast syncing mirrors. The script then also falls back to query the
  module at L<http://metacpan.org/> using its wonderful API.
  
  Upon calling these API hosts, cpanm (1.6004 or later) will send the
  local perl versions to the server in User-Agent string by default. You
  can turn it off with C<--no-report-perl-version> option. Read more
  about the option with L<cpanm>, and read more about the privacy policy
  about this data collection at L<http://cpanmetadb.plackperl.org/#privacy>
  
  Fetched files are unpacked in C<~/.cpanm> and automatically cleaned up
  periodically.  You can configure the location of this with the
  C<PERL_CPANM_HOME> environment variable.
  
  =head2 Where does this install modules to? Do I need root access?
  
  It installs to wherever ExtUtils::MakeMaker and Module::Build are
  configured to (via C<PERL_MM_OPT> and C<PERL_MB_OPT>). So if you're
  using local::lib, then it installs to your local perl5
  directory. Otherwise it installs to the site_perl directory that
  belongs to your perl.
  
  cpanminus at a boot time checks whether you have configured
  local::lib, or have the permission to install modules to the site_perl
  directory.  If neither, it automatically sets up local::lib compatible
  installation path in a C<perl5> directory under your home
  directory. To avoid this, run the script as the root user, with
  C<--sudo> option or with C<--local-lib> option.
  
  =head2 cpanminus can't install the module XYZ. Is it a bug?
  
  It is more likely a problem with the distribution itself. cpanminus
  doesn't support or is known to have issues with distributions like as
  follows:
  
  =over 4
  
  =item *
  
  Tests that require input from STDIN.
  
  =item *
  
  Build.PL or Makefile.PL that prompts for input when C<PERL_MM_USE_DEFAULT> is enabled.
  
  =item *
  
  Modules that have invalid numeric values as VERSION (such as C<1.1a>)
  
  =back
  
  These failures can be reported back to the author of the module so
  that they can fix it accordingly, rather than me.
  
  =head2 Does cpanm support the feature XYZ of L<CPAN> and L<CPANPLUS>?
  
  Most likely not. Here are the things that cpanm doesn't do by
  itself. And it's a feature - you got that from the name I<minus>,
  right?
  
  If you need these features, use L<CPAN>, L<CPANPLUS> or the standalone
  tools that are mentioned.
  
  =over 4
  
  =item *
  
  CPAN testers reporting. See L<App::cpanminus::reporter>
  
  =item *
  
  Building RPM packages from CPAN modules
  
  =item *
  
  Listing the outdated modules that needs upgrading. See L<App::cpanoutdated>
  
  =item *
  
  Showing the changes of the modules you're about to upgrade. See L<cpan-listchanges>
  
  =item *
  
  Patching CPAN modules with distroprefs.
  
  =back
  
  See L<cpanm> or C<cpanm -h> to see what cpanminus I<can> do :)
  
  =head1 COPYRIGHT
  
  Copyright 2010- Tatsuhiko Miyagawa
  
  The standalone executable contains the following modules embedded.
  
  =over 4
  
  =item L<CPAN::DistnameInfo> Copyright 2003 Graham Barr
  
  =item L<local::lib> Copyright 2007-2009 Matt S Trout
  
  =item L<HTTP::Tiny> Copyright 2011 Christian Hansen
  
  =item L<Module::Metadata> Copyright 2001-2006 Ken Williams. 2010 Matt S Trout
  
  =item L<version> Copyright 2004-2010 John Peacock
  
  =item L<JSON::PP> Copyright 2007-2011 by Makamaka Hannyaharamitu
  
  =item L<CPAN::Meta>, L<CPAN::Meta::Requirements> Copyright (c) 2010 by David Golden and Ricardo Signes
  
  =item L<CPAN::Meta::YAML> Copyright 2010 Adam Kennedy
  
  =item L<File::pushd> Copyright 2012 David Golden
  
  =back
  
  =head1 LICENSE
  
  This software is licensed under the same terms as Perl.
  
  =head1 CREDITS
  
  =head2 CONTRIBUTORS
  
  Patches and code improvements were contributed by:
  
  Goro Fuji, Kazuhiro Osawa, Tokuhiro Matsuno, Kenichi Ishigaki, Ian
  Wells, Pedro Melo, Masayoshi Sekimura, Matt S Trout (mst), squeeky,
  horus and Ingy dot Net.
  
  =head2 ACKNOWLEDGEMENTS
  
  Bug reports, suggestions and feedbacks were sent by, or general
  acknowledgement goes to:
  
  Jesse Vincent, David Golden, Andreas Koenig, Jos Boumans, Chris
  Williams, Adam Kennedy, Audrey Tang, J. Shirley, Chris Prather, Jesse
  Luehrs, Marcus Ramberg, Shawn M Moore, chocolateboy, Chirs Nehren,
  Jonathan Rockway, Leon Brocard, Simon Elliott, Ricardo Signes, AEvar
  Arnfjord Bjarmason, Eric Wilhelm, Florian Ragwitz and xaicron.
  
  =head1 COMMUNITY
  
  =over 4
  
  =item L<http://github.com/miyagawa/cpanminus> - source code repository, issue tracker
  
  =item L<irc://irc.perl.org/#toolchain> - discussions about Perl toolchain. I'm there.
  
  =back
  
  =head1 NO WARRANTY
  
  This software is provided "as-is," without any express or implied
  warranty. In no event shall the author be held liable for any damages
  arising from the use of the software.
  
  =head1 SEE ALSO
  
  L<CPAN> L<CPANPLUS> L<pip>
  
  =cut
  
  1;
APP_CPANMINUS

$fatpacked{"App/cpanminus/fatscript.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'APP_CPANMINUS_FATSCRIPT';
  package App::cpanminus::fatscript;
  #
  # This is a pre-compiled source code for the cpanm (cpanminus) program.
  # For more details about how to install cpanm, go to the following URL:
  #
  #   https://github.com/miyagawa/cpanminus
  #
  # Quickstart: Run the following command and it will install itself for
  # you. You might want to run it as a root with sudo if you want to install
  # to places like /usr/local/bin.
  #
  #   % curl -L https://cpanmin.us | perl - App::cpanminus
  #
  # If you don't have curl but wget, replace `curl -L` with `wget -O -`.
  
  # DO NOT EDIT -- this is an auto generated file
  
  # This chunk of stuff was generated by App::FatPacker. To find the original
  # file's code, look for the end of this BEGIN block or the string 'FATPACK'
  BEGIN {
  my %fatpacked;
  
  $fatpacked{"App/cpanminus.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'APP_CPANMINUS';
    package App::cpanminus;
    our $VERSION = "1.7025";
    
    =encoding utf8
    
    =head1 NAME
    
    App::cpanminus - get, unpack, build and install modules from CPAN
    
    =head1 SYNOPSIS
    
        cpanm Module
    
    Run C<cpanm -h> or C<perldoc cpanm> for more options.
    
    =head1 DESCRIPTION
    
    cpanminus is a script to get, unpack, build and install modules from
    CPAN and does nothing else.
    
    It's dependency free (can bootstrap itself), requires zero
    configuration, and stands alone. When running, it requires only 10MB
    of RAM.
    
    =head1 INSTALLATION
    
    There are several ways to install cpanminus to your system.
    
    =head2 Package management system
    
    There are Debian packages, RPMs, FreeBSD ports, and packages for other
    operation systems available. If you want to use the package management system,
    search for cpanminus and use the appropriate command to install. This makes it
    easy to install C<cpanm> to your system without thinking about where to
    install, and later upgrade.
    
    =head2 Installing to system perl
    
    You can also use the latest cpanminus to install cpanminus itself:
    
        curl -L https://cpanmin.us | perl - --sudo App::cpanminus
    
    This will install C<cpanm> to your bin directory like
    C</usr/local/bin> and you'll need the C<--sudo> option to write to
    the directory, unless you configured C<INSTALL_BASE> with L<local::lib>.
    
    =head2 Installing to local perl (perlbrew)
    
    If you have perl in your home directory, which is the case if you use
    tools like L<perlbrew>, you don't need the C<--sudo> option, since
    you're most likely to have a write permission to the perl's library
    path. You can just do:
    
        curl -L https://cpanmin.us | perl - App::cpanminus
    
    to install the C<cpanm> executable to the perl's bin path, like
    C<~/perl5/perlbrew/bin/cpanm>.
    
    =head2 Downloading the standalone executable
    
    You can also copy the standalone executable to whatever location you'd like.
    
        cd ~/bin
        curl -LO http://xrl.us/cpanm
        chmod +x cpanm
        # edit shebang if you don't have /usr/bin/env
    
    This just works, but be sure to grab the new version manually when you
    upgrade because C<--self-upgrade> might not work for this.
    
    =head1 DEPENDENCIES
    
    perl 5.8 or later.
    
    =over 4
    
    =item *
    
    'tar' executable (bsdtar or GNU tar version 1.22 are recommended) or Archive::Tar to unpack files.
    
    =item *
    
    C compiler, if you want to build XS modules.
    
    =item *
    
    make
    
    =item *
    
    Module::Build (core in 5.10)
    
    =back
    
    =head1 QUESTIONS
    
    =head2 Another CPAN installer?
    
    OK, the first motivation was this: the CPAN shell runs out of memory (or swaps
    heavily and gets really slow) on Slicehost/linode's most affordable plan with
    only 256MB RAM. Should I pay more to install perl modules from CPAN? I don't
    think so.
    
    =head2 But why a new client?
    
    First of all, let me be clear that CPAN and CPANPLUS are great tools
    I've used for I<literally> years (you know how many modules I have on
    CPAN, right?). I really respect their efforts of maintaining the most
    important tools in the CPAN toolchain ecosystem.
    
    However, for less experienced users (mostly from outside the Perl community),
    or even really experienced Perl developers who know how to shoot themselves in
    their feet, setting up the CPAN toolchain often feels like yak shaving,
    especially when all they want to do is just install some modules and start
    writing code.
    
    =head2 Zero-conf? How does this module get/parse/update the CPAN index?
    
    It queries the CPAN Meta DB site at L<http://cpanmetadb.plackperl.org/>.
    The site is updated at least every hour to reflect the latest changes
    from fast syncing mirrors. The script then also falls back to query the
    module at L<http://metacpan.org/> using its wonderful API.
    
    Upon calling these API hosts, cpanm (1.6004 or later) will send the
    local perl versions to the server in User-Agent string by default. You
    can turn it off with C<--no-report-perl-version> option. Read more
    about the option with L<cpanm>, and read more about the privacy policy
    about this data collection at L<http://cpanmetadb.plackperl.org/#privacy>
    
    Fetched files are unpacked in C<~/.cpanm> and automatically cleaned up
    periodically.  You can configure the location of this with the
    C<PERL_CPANM_HOME> environment variable.
    
    =head2 Where does this install modules to? Do I need root access?
    
    It installs to wherever ExtUtils::MakeMaker and Module::Build are
    configured to (via C<PERL_MM_OPT> and C<PERL_MB_OPT>). So if you're
    using local::lib, then it installs to your local perl5
    directory. Otherwise it installs to the site_perl directory that
    belongs to your perl.
    
    cpanminus at a boot time checks whether you have configured
    local::lib, or have the permission to install modules to the site_perl
    directory.  If neither, it automatically sets up local::lib compatible
    installation path in a C<perl5> directory under your home
    directory. To avoid this, run the script as the root user, with
    C<--sudo> option or with C<--local-lib> option.
    
    =head2 cpanminus can't install the module XYZ. Is it a bug?
    
    It is more likely a problem with the distribution itself. cpanminus
    doesn't support or is known to have issues with distributions like as
    follows:
    
    =over 4
    
    =item *
    
    Tests that require input from STDIN.
    
    =item *
    
    Build.PL or Makefile.PL that prompts for input when C<PERL_MM_USE_DEFAULT> is enabled.
    
    =item *
    
    Modules that have invalid numeric values as VERSION (such as C<1.1a>)
    
    =back
    
    These failures can be reported back to the author of the module so
    that they can fix it accordingly, rather than me.
    
    =head2 Does cpanm support the feature XYZ of L<CPAN> and L<CPANPLUS>?
    
    Most likely not. Here are the things that cpanm doesn't do by
    itself. And it's a feature - you got that from the name I<minus>,
    right?
    
    If you need these features, use L<CPAN>, L<CPANPLUS> or the standalone
    tools that are mentioned.
    
    =over 4
    
    =item *
    
    CPAN testers reporting. See L<App::cpanminus::reporter>
    
    =item *
    
    Building RPM packages from CPAN modules
    
    =item *
    
    Listing the outdated modules that needs upgrading. See L<App::cpanoutdated>
    
    =item *
    
    Showing the changes of the modules you're about to upgrade. See L<cpan-listchanges>
    
    =item *
    
    Patching CPAN modules with distroprefs.
    
    =back
    
    See L<cpanm> or C<cpanm -h> to see what cpanminus I<can> do :)
    
    =head1 COPYRIGHT
    
    Copyright 2010- Tatsuhiko Miyagawa
    
    The standalone executable contains the following modules embedded.
    
    =over 4
    
    =item L<CPAN::DistnameInfo> Copyright 2003 Graham Barr
    
    =item L<local::lib> Copyright 2007-2009 Matt S Trout
    
    =item L<HTTP::Tiny> Copyright 2011 Christian Hansen
    
    =item L<Module::Metadata> Copyright 2001-2006 Ken Williams. 2010 Matt S Trout
    
    =item L<version> Copyright 2004-2010 John Peacock
    
    =item L<JSON::PP> Copyright 2007-2011 by Makamaka Hannyaharamitu
    
    =item L<CPAN::Meta>, L<CPAN::Meta::Requirements> Copyright (c) 2010 by David Golden and Ricardo Signes
    
    =item L<CPAN::Meta::YAML> Copyright 2010 Adam Kennedy
    
    =item L<File::pushd> Copyright 2012 David Golden
    
    =back
    
    =head1 LICENSE
    
    This software is licensed under the same terms as Perl.
    
    =head1 CREDITS
    
    =head2 CONTRIBUTORS
    
    Patches and code improvements were contributed by:
    
    Goro Fuji, Kazuhiro Osawa, Tokuhiro Matsuno, Kenichi Ishigaki, Ian
    Wells, Pedro Melo, Masayoshi Sekimura, Matt S Trout (mst), squeeky,
    horus and Ingy dot Net.
    
    =head2 ACKNOWLEDGEMENTS
    
    Bug reports, suggestions and feedbacks were sent by, or general
    acknowledgement goes to:
    
    Jesse Vincent, David Golden, Andreas Koenig, Jos Boumans, Chris
    Williams, Adam Kennedy, Audrey Tang, J. Shirley, Chris Prather, Jesse
    Luehrs, Marcus Ramberg, Shawn M Moore, chocolateboy, Chirs Nehren,
    Jonathan Rockway, Leon Brocard, Simon Elliott, Ricardo Signes, AEvar
    Arnfjord Bjarmason, Eric Wilhelm, Florian Ragwitz and xaicron.
    
    =head1 COMMUNITY
    
    =over 4
    
    =item L<http://github.com/miyagawa/cpanminus> - source code repository, issue tracker
    
    =item L<irc://irc.perl.org/#toolchain> - discussions about Perl toolchain. I'm there.
    
    =back
    
    =head1 NO WARRANTY
    
    This software is provided "as-is," without any express or implied
    warranty. In no event shall the author be held liable for any damages
    arising from the use of the software.
    
    =head1 SEE ALSO
    
    L<CPAN> L<CPANPLUS> L<pip>
    
    =cut
    
    1;
  APP_CPANMINUS
  
  $fatpacked{"App/cpanminus/CPANVersion.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'APP_CPANMINUS_CPANVERSION';
    package App::cpanminus::CPANVersion;
    # copy of CPAN::Version since it's not core on older 5.8
    
    use strict;
    #use vars qw($VERSION);
    #$VERSION = "5.5001";
    
    # CPAN::Version::vcmp courtesy Jost Krieger
    sub vcmp {
        my($self,$l,$r) = @_;
        local($^W) = 0;
        #CPAN->debug("l[$l] r[$r]") if $CPAN::DEBUG;
    
        return 0 if $l eq $r; # short circuit for quicker success
    
        for ($l,$r) {
            s/_//g;
        }
        #CPAN->debug("l[$l] r[$r]") if $CPAN::DEBUG;
        for ($l,$r) {
            next unless tr/.// > 1 || /^v/;
            s/^v?/v/;
            1 while s/\.0+(\d)/.$1/; # remove leading zeroes per group
        }
        #CPAN->debug("l[$l] r[$r]") if $CPAN::DEBUG;
        if ($l=~/^v/ <=> $r=~/^v/) {
            for ($l,$r) {
                next if /^v/;
                $_ = $self->float2vv($_);
            }
        }
        #CPAN->debug("l[$l] r[$r]") if $CPAN::DEBUG;
        my $lvstring = "v0";
        my $rvstring = "v0";
        if ($] >= 5.006
         && $l =~ /^v/
         && $r =~ /^v/) {
            $lvstring = $self->vstring($l);
            $rvstring = $self->vstring($r);
            #CPAN->debug(sprintf "lv[%vd] rv[%vd]", $lvstring, $rvstring) if $CPAN::DEBUG;
        }
    
        return (
                ($l ne "undef") <=> ($r ne "undef")
                ||
                $lvstring cmp $rvstring
                ||
                $l <=> $r
                ||
                $l cmp $r
        );
    }
    
    sub vgt {
        my($self,$l,$r) = @_;
        $self->vcmp($l,$r) > 0;
    }
    
    sub vlt {
        my($self,$l,$r) = @_;
        $self->vcmp($l,$r) < 0;
    }
    
    sub vge {
        my($self,$l,$r) = @_;
        $self->vcmp($l,$r) >= 0;
    }
    
    sub vle {
        my($self,$l,$r) = @_;
        $self->vcmp($l,$r) <= 0;
    }
    
    sub vstring {
        my($self,$n) = @_;
        $n =~ s/^v// or die "CPAN::Version::vstring() called with invalid arg [$n]";
        pack "U*", split /\./, $n;
    }
    
    # vv => visible vstring
    sub float2vv {
        my($self,$n) = @_;
        my($rev) = int($n);
        $rev ||= 0;
        my($mantissa) = $n =~ /\.(\d{1,12})/; # limit to 12 digits to limit
                                              # architecture influence
        $mantissa ||= 0;
        $mantissa .= "0" while length($mantissa)%3;
        my $ret = "v" . $rev;
        while ($mantissa) {
            $mantissa =~ s/(\d{1,3})// or
                die "Panic: length>0 but not a digit? mantissa[$mantissa]";
            $ret .= ".".int($1);
        }
        # warn "n[$n]ret[$ret]";
        $ret =~ s/(\.0)+/.0/; # v1.0.0 => v1.0
        $ret;
    }
    
    sub readable {
        my($self,$n) = @_;
        $n =~ /^([\w\-\+\.]+)/;
    
        return $1 if defined $1 && length($1)>0;
        # if the first user reaches version v43, he will be treated as "+".
        # We'll have to decide about a new rule here then, depending on what
        # will be the prevailing versioning behavior then.
    
        if ($] < 5.006) { # or whenever v-strings were introduced
            # we get them wrong anyway, whatever we do, because 5.005 will
            # have already interpreted 0.2.4 to be "0.24". So even if he
            # indexer sends us something like "v0.2.4" we compare wrongly.
    
            # And if they say v1.2, then the old perl takes it as "v12"
    
    #        if (defined $CPAN::Frontend) {
    #            $CPAN::Frontend->mywarn("Suspicious version string seen [$n]\n");
    #        } else {
                warn("Suspicious version string seen [$n]\n");
    #        }
            return $n;
        }
        my $better = sprintf "v%vd", $n;
        #CPAN->debug("n[$n] better[$better]") if $CPAN::DEBUG;
        return $better;
    }
    
    1;
    
    __END__
  APP_CPANMINUS_CPANVERSION
  
  $fatpacked{"App/cpanminus/Dependency.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'APP_CPANMINUS_DEPENDENCY';
    package App::cpanminus::Dependency;
    use strict;
    use CPAN::Meta::Requirements;
    
    sub from_prereqs {
        my($class, $prereq, $phases, $types) = @_;
    
        my @deps;
    
        for my $type (@$types) {
            my $req = CPAN::Meta::Requirements->new;
            $req->add_requirements($prereq->requirements_for($_, $type))
              for @$phases;
    
            push @deps, $class->from_versions($req->as_string_hash, $type);
        }
    
        return @deps;
    }
    
    sub from_versions {
        my($class, $versions, $type) = @_;
    
        my @deps;
        while (my($module, $version) = each %$versions) {
            push @deps, $class->new($module, $version, $type)
        }
    
        @deps;
    }
    
    sub new {
        my($class, $module, $version, $type) = @_;
    
        bless {
            module => $module,
            version => $version,
            type => $type || 'requires',
        }, $class;
    }
    
    sub module  { $_[0]->{module} }
    sub version { $_[0]->{version} }
    sub type    { $_[0]->{type} }
    
    sub is_requirement {
        $_[0]->{type} eq 'requires';
    }
    
    1;
  APP_CPANMINUS_DEPENDENCY
  
  $fatpacked{"App/cpanminus/script.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'APP_CPANMINUS_SCRIPT';
    package App::cpanminus::script;
    use strict;
    use Config;
    use Cwd ();
    use App::cpanminus;
    use App::cpanminus::Dependency;
    use File::Basename ();
    use File::Find ();
    use File::Path ();
    use File::Spec ();
    use File::Copy ();
    use File::Temp ();
    use Getopt::Long ();
    use Symbol ();
    use String::ShellQuote ();
    use version ();
    
    use constant WIN32 => $^O eq 'MSWin32';
    use constant BAD_TAR => ($^O eq 'solaris' || $^O eq 'hpux');
    use constant CAN_SYMLINK => eval { symlink("", ""); 1 };
    
    our $VERSION = $App::cpanminus::VERSION;
    
    if ($INC{"App/FatPacker/Trace.pm"}) {
        require JSON::PP;
        require CPAN::Meta::YAML;
        require CPAN::Meta::Prereqs;
        require version::vpp;
        require File::pushd;
        require Parse::PMFile;
    }
    
    my $quote = WIN32 ? q/"/ : q/'/;
    
    sub agent {
        my $self = shift;
        my $agent = "cpanminus/$VERSION";
        $agent .= " perl/$]" if $self->{report_perl_version};
        $agent;
    }
    
    sub determine_home {
        my $class = shift;
    
        my $homedir = $ENV{HOME}
          || eval { require File::HomeDir; File::HomeDir->my_home }
          || join('', @ENV{qw(HOMEDRIVE HOMEPATH)}); # Win32
    
        if (WIN32) {
            require Win32; # no fatpack
            $homedir = Win32::GetShortPathName($homedir);
        }
    
        return "$homedir/.cpanm";
    }
    
    sub new {
        my $class = shift;
    
        bless {
            home => $class->determine_home,
            cmd  => 'install',
            seen => {},
            notest => undef,
            test_only => undef,
            installdeps => undef,
            force => undef,
            sudo => undef,
            make  => undef,
            verbose => undef,
            quiet => undef,
            interactive => undef,
            log => undef,
            mirrors => [],
            mirror_only => undef,
            mirror_index => undef,
            cpanmetadb => "http://cpanmetadb.plackperl.org/v1.0/",
            perl => $^X,
            argv => [],
            local_lib => undef,
            self_contained => undef,
            exclude_vendor => undef,
            prompt_timeout => 0,
            prompt => undef,
            configure_timeout => 60,
            build_timeout => 3600,
            test_timeout => 1800,
            try_lwp => 0,
            try_wget => 0,
            try_curl => 0,
            uninstall_shadows => ($] < 5.012),
            skip_installed => 1,
            skip_satisfied => 0,
            auto_cleanup => 7, # days
            pod2man => 1,
            installed_dists => 0,
            install_types => ['requires'],
            with_develop => 0,
            showdeps => 0,
            scandeps => 0,
            scandeps_tree => [],
            format   => 'tree',
            save_dists => undef,
            skip_configure => 0,
            verify => 0,
            report_perl_version => 1,
            build_args => {},
            features => {},
            pure_perl => 0,
            cpanfile_path => 'cpanfile',
            @_,
        }, $class;
    }
    
    sub env {
        my($self, $key) = @_;
        $ENV{"PERL_CPANM_" . $key};
    }
    
    sub install_type_handlers {
        my $self = shift;
    
        my @handlers;
        for my $type (qw( recommends suggests )) {
            push @handlers, "with-$type" => sub {
                my %uniq;
                $self->{install_types} = [ grep !$uniq{$_}++, @{$self->{install_types}}, $type ];
            };
            push @handlers, "without-$type" => sub {
                $self->{install_types} = [ grep $_ ne $type, @{$self->{install_types}} ];
            };
        }
    
        @handlers;
    }
    
    sub build_args_handlers {
        my $self = shift;
    
        my @handlers;
        for my $phase (qw( configure build test install )) {
            push @handlers, "$phase-args=s" => \($self->{build_args}{$phase});
        }
    
        @handlers;
    }
    
    sub parse_options {
        my $self = shift;
    
        local @ARGV = @{$self->{argv}};
        push @ARGV, grep length, split /\s+/, $self->env('OPT');
        push @ARGV, @_;
    
        Getopt::Long::Configure("bundling");
        Getopt::Long::GetOptions(
            'f|force'   => sub { $self->{skip_installed} = 0; $self->{force} = 1 },
            'n|notest!' => \$self->{notest},
            'test-only' => sub { $self->{notest} = 0; $self->{skip_installed} = 0; $self->{test_only} = 1 },
            'S|sudo!'   => \$self->{sudo},
            'v|verbose' => \$self->{verbose},
            'verify!'   => \$self->{verify},
            'q|quiet!'  => \$self->{quiet},
            'h|help'    => sub { $self->{action} = 'show_help' },
            'V|version' => sub { $self->{action} = 'show_version' },
            'perl=s'    => sub {
                $self->diag("--perl is deprecated since it's known to be fragile in figuring out dependencies. Run `$_[1] -S cpanm` instead.\n", 1);
                $self->{perl} = $_[1];
            },
            'l|local-lib=s' => sub { $self->{local_lib} = $self->maybe_abs($_[1]) },
            'L|local-lib-contained=s' => sub {
                $self->{local_lib} = $self->maybe_abs($_[1]);
                $self->{self_contained} = 1;
                $self->{pod2man} = undef;
            },
            'self-contained!' => \$self->{self_contained},
            'exclude-vendor!' => \$self->{exclude_vendor},
            'mirror=s@' => $self->{mirrors},
            'mirror-only!' => \$self->{mirror_only},
            'mirror-index=s' => \$self->{mirror_index},
            'M|from=s' => sub {
                $self->{mirrors}     = [$_[1]];
                $self->{mirror_only} = 1;
            },
            'cpanmetadb=s'    => \$self->{cpanmetadb},
            'cascade-search!' => \$self->{cascade_search},
            'prompt!'   => \$self->{prompt},
            'installdeps' => \$self->{installdeps},
            'skip-installed!' => \$self->{skip_installed},
            'skip-satisfied!' => \$self->{skip_satisfied},
            'reinstall'    => sub { $self->{skip_installed} = 0 },
            'interactive!' => \$self->{interactive},
            'i|install'    => sub { $self->{cmd} = 'install' },
            'info'         => sub { $self->{cmd} = 'info' },
            'look'         => sub { $self->{cmd} = 'look'; $self->{skip_installed} = 0 },
            'U|uninstall'  => sub { $self->{cmd} = 'uninstall' },
            'self-upgrade' => sub { $self->{action} = 'self_upgrade' },
            'uninst-shadows!'  => \$self->{uninstall_shadows},
            'lwp!'    => \$self->{try_lwp},
            'wget!'   => \$self->{try_wget},
            'curl!'   => \$self->{try_curl},
            'auto-cleanup=s' => \$self->{auto_cleanup},
            'man-pages!' => \$self->{pod2man},
            'scandeps'   => \$self->{scandeps},
            'showdeps'   => sub { $self->{showdeps} = 1; $self->{skip_installed} = 0 },
            'format=s'   => \$self->{format},
            'save-dists=s' => sub {
                $self->{save_dists} = $self->maybe_abs($_[1]);
            },
            'skip-configure!' => \$self->{skip_configure},
            'dev!'       => \$self->{dev_release},
            'report-perl-version!' => \$self->{report_perl_version},
            'configure-timeout=i' => \$self->{configure_timeout},
            'build-timeout=i' => \$self->{build_timeout},
            'test-timeout=i' => \$self->{test_timeout},
            'with-develop' => \$self->{with_develop},
            'without-develop' => sub { $self->{with_develop} = 0 },
            'with-feature=s' => sub { $self->{features}{$_[1]} = 1 },
            'without-feature=s' => sub { $self->{features}{$_[1]} = 0 },
            'with-all-features' => sub { $self->{features}{__all} = 1 },
            'pp|pureperl!' => \$self->{pure_perl},
            "cpanfile=s" => \$self->{cpanfile_path},
            $self->install_type_handlers,
            $self->build_args_handlers,
        );
    
        if (!@ARGV && $0 ne '-' && !-t STDIN){ # e.g. # cpanm < author/requires.cpanm
            push @ARGV, $self->load_argv_from_fh(\*STDIN);
            $self->{load_from_stdin} = 1;
        }
    
        $self->{argv} = \@ARGV;
    }
    
    sub check_upgrade {
        my $self = shift;
        my $install_base = $ENV{PERL_LOCAL_LIB_ROOT} ? $self->local_lib_target($ENV{PERL_LOCAL_LIB_ROOT}) : $Config{installsitebin};
        if ($0 eq '-') {
            # run from curl, that's fine
            return;
        } elsif ($0 !~ /^$install_base/) {
            if ($0 =~ m!perlbrew/bin!) {
                die <<DIE;
    It appears your cpanm executable was installed via `perlbrew install-cpanm`.
    cpanm --self-upgrade won't upgrade the version of cpanm you're running.
    
    Run the following command to get it upgraded.
    
      perlbrew install-cpanm
    
    DIE
            } else {
                die <<DIE;
    You are running cpanm from the path where your current perl won't install executables to.
    Because of that, cpanm --self-upgrade won't upgrade the version of cpanm you're running.
    
      cpanm path   : $0
      Install path : $Config{installsitebin}
    
    It means you either installed cpanm globally with system perl, or use distro packages such
    as rpm or apt-get, and you have to use them again to upgrade cpanm.
    DIE
            }
        }
    }
    
    sub check_libs {
        my $self = shift;
        return if $self->{_checked}++;
    
        $self->bootstrap_local_lib;
        if (@{$self->{bootstrap_deps} || []}) {
            local $self->{notest} = 1; # test failure in bootstrap should be tolerated
            local $self->{scandeps} = 0;
            $self->install_deps(Cwd::cwd, 0, @{$self->{bootstrap_deps}});
        }
    }
    
    sub setup_verify {
        my $self = shift;
    
        my $has_modules = eval { require Module::Signature; require Digest::SHA; 1 };
        $self->{cpansign} = $self->which('cpansign');
    
        unless ($has_modules && $self->{cpansign}) {
            warn "WARNING: Module::Signature and Digest::SHA is required for distribution verifications.\n";
            $self->{verify} = 0;
        }
    }
    
    sub parse_module_args {
        my($self, $module) = @_;
    
        # Plack@1.2 -> Plack~"==1.2"
        # BUT don't expand @ in git URLs
        $module =~ s/^([A-Za-z0-9_:]+)@([v\d\._]+)$/$1~== $2/;
    
        # Plack~1.20, DBI~"> 1.0, <= 2.0"
        if ($module =~ /\~[v\d\._,\!<>= ]+$/) {
            return split /\~/, $module, 2;
        } else {
            return $module, undef;
        }
    }
    
    sub doit {
        my $self = shift;
    
        my $code;
        eval {
            $code = ($self->_doit == 0);
        }; if (my $e = $@) {
            warn $e;
            $code = 1;
        }
    
        return $code;
    }
    
    sub _doit {
        my $self = shift;
    
        $self->setup_home;
        $self->init_tools;
        $self->setup_verify if $self->{verify};
    
        if (my $action = $self->{action}) {
            $self->$action() and return 1;
        }
    
        return $self->show_help(1)
            unless @{$self->{argv}} or $self->{load_from_stdin};
    
        $self->configure_mirrors;
    
        my $cwd = Cwd::cwd;
    
        my @fail;
        for my $module (@{$self->{argv}}) {
            if ($module =~ s/\.pm$//i) {
                my ($volume, $dirs, $file) = File::Spec->splitpath($module);
                $module = join '::', grep { $_ } File::Spec->splitdir($dirs), $file;
            }
            ($module, my $version) = $self->parse_module_args($module);
    
            $self->chdir($cwd);
            if ($self->{cmd} eq 'uninstall') {
                $self->uninstall_module($module)
                  or push @fail, $module;
            } else {
                $self->install_module($module, 0, $version)
                    or push @fail, $module;
            }
        }
    
        if ($self->{base} && $self->{auto_cleanup}) {
            $self->cleanup_workdirs;
        }
    
        if ($self->{installed_dists}) {
            my $dists = $self->{installed_dists} > 1 ? "distributions" : "distribution";
            $self->diag("$self->{installed_dists} $dists installed\n", 1);
        }
    
        if ($self->{scandeps}) {
            $self->dump_scandeps();
        }
        # Workaround for older File::Temp's
        # where creating a tempdir with an implicit $PWD
        # causes tempdir non-cleanup if $PWD changes
        # as paths are stored internally without being resolved
        # absolutely.
        # https://rt.cpan.org/Public/Bug/Display.html?id=44924
        $self->chdir($cwd);
    
        return !@fail;
    }
    
    sub setup_home {
        my $self = shift;
    
        $self->{home} = $self->env('HOME') if $self->env('HOME');
    
        unless (_writable($self->{home})) {
            die "Can't write to cpanm home '$self->{home}': You should fix it with chown/chmod first.\n";
        }
    
        $self->{base} = "$self->{home}/work/" . time . ".$$";
        File::Path::mkpath([ $self->{base} ], 0, 0777);
    
        # native path because we use shell redirect
        $self->{log} = File::Spec->catfile($self->{base}, "build.log");
        my $final_log = "$self->{home}/build.log";
    
        { open my $out, ">$self->{log}" or die "$self->{log}: $!" }
    
        if (CAN_SYMLINK) {
            my $build_link = "$self->{home}/latest-build";
            unlink $build_link;
            symlink $self->{base}, $build_link;
    
            unlink $final_log;
            symlink $self->{log}, $final_log;
        } else {
            my $log = $self->{log}; my $home = $self->{home};
            $self->{at_exit} = sub {
                my $self = shift;
                my $temp_log = "$home/build.log." . time . ".$$";
                File::Copy::copy($log, $temp_log)
                    && unlink($final_log);
                rename($temp_log, $final_log);
            }
        }
    
        $self->chat("cpanm (App::cpanminus) $VERSION on perl $] built for $Config{archname}\n" .
                    "Work directory is $self->{base}\n");
    }
    
    sub package_index_for {
        my ($self, $mirror) = @_;
        return $self->source_for($mirror) . "/02packages.details.txt";
    }
    
    sub generate_mirror_index {
        my ($self, $mirror) = @_;
        my $file = $self->package_index_for($mirror);
        my $gz_file = $file . '.gz';
        my $index_mtime = (stat $gz_file)[9];
    
        unless (-e $file && (stat $file)[9] >= $index_mtime) {
            $self->chat("Uncompressing index file...\n");
            if (eval {require Compress::Zlib}) {
                my $gz = Compress::Zlib::gzopen($gz_file, "rb")
                    or do { $self->diag_fail("$Compress::Zlib::gzerrno opening compressed index"); return};
                open my $fh, '>', $file
                    or do { $self->diag_fail("$! opening uncompressed index for write"); return };
                my $buffer;
                while (my $status = $gz->gzread($buffer)) {
                    if ($status < 0) {
                        $self->diag_fail($gz->gzerror . " reading compressed index");
                        return;
                    }
                    print $fh $buffer;
                }
            } else {
                if (system("gunzip -c $gz_file > $file")) {
                    $self->diag_fail("Cannot uncompress -- please install gunzip or Compress::Zlib");
                    return;
                }
            }
            utime $index_mtime, $index_mtime, $file;
        }
        return 1;
    }
    
    sub search_mirror_index {
        my ($self, $mirror, $module, $version) = @_;
        $self->search_mirror_index_file($self->package_index_for($mirror), $module, $version);
    }
    
    sub search_mirror_index_file {
        my($self, $file, $module, $version) = @_;
    
        open my $fh, '<', $file or return;
        my $found;
        while (<$fh>) {
            if (m!^\Q$module\E\s+([\w\.]+)\s+(\S*)!m) {
                $found = $self->cpan_module($module, $2, $1);
                last;
            }
        }
    
        return $found unless $self->{cascade_search};
    
        if ($found) {
            if ($self->satisfy_version($module, $found->{module_version}, $version)) {
                return $found;
            } else {
                $self->chat("Found $module $found->{module_version} which doesn't satisfy $version.\n");
            }
        }
    
        return;
    }
    
    sub with_version_range {
        my($self, $version) = @_;
        defined($version) && $version =~ /[<>=]/;
    }
    
    sub encode_json {
        my($self, $data) = @_;
        require JSON::PP;
    
        my $json = JSON::PP::encode_json($data);
        $json =~ s/([^a-zA-Z0-9_\-.])/uc sprintf("%%%02x",ord($1))/eg;
        $json;
    }
    
    # TODO extract this as a module?
    sub version_to_query {
        my($self, $module, $version) = @_;
    
        require CPAN::Meta::Requirements;
    
        my $requirements = CPAN::Meta::Requirements->new;
        $requirements->add_string_requirement($module, $version || '0');
    
        my $req = $requirements->requirements_for_module($module);
    
        if ($req =~ s/^==\s*//) {
            return {
                term => { 'module.version' => $req },
            };
        } elsif ($req !~ /\s/) {
            return {
                range => { 'module.version_numified' => { 'gte' => $self->numify_ver_metacpan($req) } },
            };
        } else {
            my %ops = qw(< lt <= lte > gt >= gte);
            my(%range, @exclusion);
            my @requirements = split /,\s*/, $req;
            for my $r (@requirements) {
                if ($r =~ s/^([<>]=?)\s*//) {
                    $range{$ops{$1}} = $self->numify_ver_metacpan($r);
                } elsif ($r =~ s/\!=\s*//) {
                    push @exclusion, $self->numify_ver_metacpan($r);
                }
            }
    
            my @filters= (
                { range => { 'module.version_numified' => \%range } },
            );
    
            if (@exclusion) {
                push @filters, {
                    not => { or => [ map { +{ term => { 'module.version_numified' => $self->numify_ver_metacpan($_) } } } @exclusion ] },
                };
            }
    
            return @filters;
        }
    }
    
    # Apparently MetaCPAN numifies devel releases by stripping _ first
    sub numify_ver_metacpan {
        my($self, $ver) = @_;
        $ver =~ s/_//g;
        version->new($ver)->numify;
    }
    
    # version->new("1.00_00")->numify => "1.00_00" :/
    sub numify_ver {
        my($self, $ver) = @_;
        eval version->new($ver)->numify;
    }
    
    sub maturity_filter {
        my($self, $module, $version) = @_;
    
        my @filters;
    
        # TODO: dev release should be enabled per dist
        if (!$self->with_version_range($version) or $self->{dev_release}) {
            # backpan'ed dev release are considered "cancelled"
            push @filters, { not => { term => { status => 'backpan' } } };
        }
    
        unless ($self->{dev_release} or $version =~ /==/) {
            push @filters, { term => { maturity => 'released' } };
        }
    
        return @filters;
    }
    
    sub by_version {
        my %s = qw( latest 3  cpan 2  backpan 1 );
        $b->{_score} <=> $a->{_score} ||                             # version: higher version that satisfies the query
        $s{ $b->{fields}{status} } <=> $s{ $a->{fields}{status} };   # prefer non-BackPAN dist
    }
    
    sub by_first_come {
        $a->{fields}{date} cmp $b->{fields}{date};                   # first one wins, if all are in BackPAN/CPAN
    }
    
    sub by_date {
        $b->{fields}{date} cmp $a->{fields}{date};                   # prefer new uploads, when searching for dev
    }
    
    sub find_best_match {
        my($self, $match, $version) = @_;
        return unless $match && @{$match->{hits}{hits} || []};
        my @hits = $self->{dev_release}
            ? sort { by_version || by_date } @{$match->{hits}{hits}}
            : sort { by_version || by_first_come } @{$match->{hits}{hits}};
        $hits[0]->{fields};
    }
    
    sub search_metacpan {
        my($self, $module, $version) = @_;
    
        require JSON::PP;
    
        $self->chat("Searching $module ($version) on metacpan ...\n");
    
        my $metacpan_uri = 'http://api.metacpan.org/v0';
    
        my @filter = $self->maturity_filter($module, $version);
    
        my $query = { filtered => {
            (@filter ? (filter => { and => \@filter }) : ()),
            query => { nested => {
                score_mode => 'max',
                path => 'module',
                query => { custom_score => {
                    metacpan_script => "score_version_numified",
                    query => { constant_score => {
                        filter => { and => [
                            { term => { 'module.authorized' => JSON::PP::true() } },
                            { term => { 'module.indexed' => JSON::PP::true() } },
                            { term => { 'module.name' => $module } },
                            $self->version_to_query($module, $version),
                        ] }
                    } },
                } },
            } },
        } };
    
        my $module_uri = "$metacpan_uri/file/_search?source=";
        $module_uri .= $self->encode_json({
            query => $query,
            fields => [ 'date', 'release', 'author', 'module', 'status' ],
        });
    
        my($release, $author, $module_version);
    
        my $module_json = $self->get($module_uri);
        my $module_meta = eval { JSON::PP::decode_json($module_json) };
        my $match = $self->find_best_match($module_meta);
        if ($match) {
            $release = $match->{release};
            $author = $match->{author};
            my $module_matched = (grep { $_->{name} eq $module } @{$match->{module}})[0];
            $module_version = $module_matched->{version};
        }
    
        unless ($release) {
            $self->chat("! Could not find a release matching $module ($version) on MetaCPAN.\n");
            return;
        }
    
        my $dist_uri = "$metacpan_uri/release/_search?source=";
        $dist_uri .= $self->encode_json({
            filter => { and => [
                { term => { 'release.name' => $release } },
                { term => { 'release.author' => $author } },
            ]},
            fields => [ 'download_url', 'stat', 'status' ],
        });
    
        my $dist_json = $self->get($dist_uri);
        my $dist_meta = eval { JSON::PP::decode_json($dist_json) };
    
        if ($dist_meta) {
            $dist_meta = $dist_meta->{hits}{hits}[0]{fields};
        }
        if ($dist_meta && $dist_meta->{download_url}) {
            (my $distfile = $dist_meta->{download_url}) =~ s!.+/authors/id/!!;
            local $self->{mirrors} = $self->{mirrors};
            if ($dist_meta->{status} eq 'backpan') {
                $self->{mirrors} = [ 'http://backpan.perl.org' ];
            } elsif ($dist_meta->{stat}{mtime} > time()-24*60*60) {
                $self->{mirrors} = [ 'http://cpan.metacpan.org' ];
            }
            return $self->cpan_module($module, $distfile, $module_version);
        }
    
        $self->diag_fail("Finding $module on metacpan failed.");
        return;
    }
    
    sub search_database {
        my($self, $module, $version) = @_;
    
        my $found;
        my $range = ($self->with_version_range($version) || $self->{dev_release});
    
        if ($range) {
            $found = $self->search_metacpan($module, $version)   and return $found;
            $found = $self->search_cpanmetadb($module, $version) and return $found;
        } else {
            $found = $self->search_cpanmetadb($module, $version) and return $found;
            $found = $self->search_metacpan($module, $version)   and return $found;
        }
    }
    
    sub search_cpanmetadb {
        my($self, $module, $version) = @_;
    
        require CPAN::Meta::YAML;
    
        $self->chat("Searching $module on cpanmetadb ...\n");
    
        (my $uri = $self->{cpanmetadb}) =~ s{/?$}{/package/$module};
        my $yaml = $self->get($uri);
        my $meta = eval { CPAN::Meta::YAML::Load($yaml) };
        if ($meta && $meta->{distfile}) {
            return $self->cpan_module($module, $meta->{distfile}, $meta->{version});
        }
    
        $self->diag_fail("Finding $module on cpanmetadb failed.");
        return;
    }
    
    sub search_module {
        my($self, $module, $version) = @_;
    
        if ($self->{mirror_index}) {
            $self->mask_output( chat => "Searching $module on mirror index $self->{mirror_index} ...\n" );
            my $pkg = $self->search_mirror_index_file($self->{mirror_index}, $module, $version);
            return $pkg if $pkg;
    
            unless ($self->{cascade_search}) {
               $self->mask_output( diag_fail => "Finding $module ($version) on mirror index $self->{mirror_index} failed." );
               return;
            }
        }
    
        unless ($self->{mirror_only}) {
            my $found = $self->search_database($module, $version);
            return $found if $found;
        }
    
        MIRROR: for my $mirror (@{ $self->{mirrors} }) {
            $self->mask_output( chat => "Searching $module on mirror $mirror ...\n" );
            my $name = '02packages.details.txt.gz';
            my $uri  = "$mirror/modules/$name";
            my $gz_file = $self->package_index_for($mirror) . '.gz';
    
            unless ($self->{pkgs}{$uri}) {
                $self->mask_output( chat => "Downloading index file $uri ...\n" );
                $self->mirror($uri, $gz_file);
                $self->generate_mirror_index($mirror) or next MIRROR;
                $self->{pkgs}{$uri} = "!!retrieved!!";
            }
    
            my $pkg = $self->search_mirror_index($mirror, $module, $version);
            return $pkg if $pkg;
    
            $self->mask_output( diag_fail => "Finding $module ($version) on mirror $mirror failed." );
        }
    
        return;
    }
    
    sub source_for {
        my($self, $mirror) = @_;
        $mirror =~ s/[^\w\.\-]+/%/g;
    
        my $dir = "$self->{home}/sources/$mirror";
        File::Path::mkpath([ $dir ], 0, 0777);
    
        return $dir;
    }
    
    sub load_argv_from_fh {
        my($self, $fh) = @_;
    
        my @argv;
        while(defined(my $line = <$fh>)){
            chomp $line;
            $line =~ s/#.+$//; # comment
            $line =~ s/^\s+//; # trim spaces
            $line =~ s/\s+$//; # trim spaces
    
            push @argv, split ' ', $line if $line;
        }
        return @argv;
    }
    
    sub show_version {
        my $self = shift;
    
        print "cpanm (App::cpanminus) version $VERSION ($0)\n";
        print "perl version $] ($^X)\n\n";
    
        print "  \%Config:\n";
        for my $key (qw( archname installsitelib installsitebin installman1dir installman3dir
                         sitearchexp sitelibexp vendorarch vendorlibexp archlibexp privlibexp )) {
            print "    $key=$Config{$key}\n" if $Config{$key};
        }
    
        print "  \%ENV:\n";
        for my $key (grep /^PERL/, sort keys %ENV) {
            print "    $key=$ENV{$key}\n";
        }
    
        print "  \@INC:\n";
        for my $inc (@INC) {
            print "    $inc\n" unless ref($inc) eq 'CODE';
        }
    
        return 1;
    }
    
    sub show_help {
        my $self = shift;
    
        if ($_[0]) {
            print <<USAGE;
    Usage: cpanm [options] Module [...]
    
    Try `cpanm --help` or `man cpanm` for more options.
    USAGE
            return;
        }
    
        print <<HELP;
    Usage: cpanm [options] Module [...]
    
    Options:
      -v,--verbose              Turns on chatty output
      -q,--quiet                Turns off the most output
      --interactive             Turns on interactive configure (required for Task:: modules)
      -f,--force                force install
      -n,--notest               Do not run unit tests
      --test-only               Run tests only, do not install
      -S,--sudo                 sudo to run install commands
      --installdeps             Only install dependencies
      --showdeps                Only display direct dependencies
      --reinstall               Reinstall the distribution even if you already have the latest version installed
      --mirror                  Specify the base URL for the mirror (e.g. http://cpan.cpantesters.org/)
      --mirror-only             Use the mirror's index file instead of the CPAN Meta DB
      -M,--from                 Use only this mirror base URL and its index file
      --prompt                  Prompt when configure/build/test fails
      -l,--local-lib            Specify the install base to install modules
      -L,--local-lib-contained  Specify the install base to install all non-core modules
      --self-contained          Install all non-core modules, even if they're already installed.
      --auto-cleanup            Number of days that cpanm's work directories expire in. Defaults to 7
    
    Commands:
      --self-upgrade            upgrades itself
      --info                    Displays distribution info on CPAN
      --look                    Opens the distribution with your SHELL
      -U,--uninstall            Uninstalls the modules (EXPERIMENTAL)
      -V,--version              Displays software version
    
    Examples:
    
      cpanm Test::More                                          # install Test::More
      cpanm MIYAGAWA/Plack-0.99_05.tar.gz                       # full distribution path
      cpanm http://example.org/LDS/CGI.pm-3.20.tar.gz           # install from URL
      cpanm ~/dists/MyCompany-Enterprise-1.00.tar.gz            # install from a local file
      cpanm --interactive Task::Kensho                          # Configure interactively
      cpanm .                                                   # install from local directory
      cpanm --installdeps .                                     # install all the deps for the current directory
      cpanm -L extlib Plack                                     # install Plack and all non-core deps into extlib
      cpanm --mirror http://cpan.cpantesters.org/ DBI           # use the fast-syncing mirror
      cpanm -M https://cpan.metacpan.org App::perlbrew          # use only this secure mirror and its index
    
    You can also specify the default options in PERL_CPANM_OPT environment variable in the shell rc:
    
      export PERL_CPANM_OPT="--prompt --reinstall -l ~/perl --mirror http://cpan.cpantesters.org"
    
    Type `man cpanm` or `perldoc cpanm` for the more detailed explanation of the options.
    
    HELP
    
        return 1;
    }
    
    sub _writable {
        my $dir = shift;
        my @dir = File::Spec->splitdir($dir);
        while (@dir) {
            $dir = File::Spec->catdir(@dir);
            if (-e $dir) {
                return -w _;
            }
            pop @dir;
        }
    
        return;
    }
    
    sub maybe_abs {
        my($self, $lib) = @_;
        if ($lib eq '_' or $lib =~ /^~/ or File::Spec->file_name_is_absolute($lib)) {
            return $lib;
        } else {
            return File::Spec->canonpath(File::Spec->catdir(Cwd::cwd(), $lib));
        }
    }
    
    sub local_lib_target {
        my($self, $root) = @_;
        # local::lib 1.008025 changed the order of PERL_LOCAL_LIB_ROOT
        (grep { $_ ne '' } split /\Q$Config{path_sep}/, $root)[0];
    }
    
    sub bootstrap_local_lib {
        my $self = shift;
    
        # If -l is specified, use that.
        if ($self->{local_lib}) {
            return $self->setup_local_lib($self->{local_lib});
        }
    
        # PERL_LOCAL_LIB_ROOT is defined. Run as local::lib mode without overwriting ENV
        if ($ENV{PERL_LOCAL_LIB_ROOT} && $ENV{PERL_MM_OPT}) {
            return $self->setup_local_lib($self->local_lib_target($ENV{PERL_LOCAL_LIB_ROOT}), 1);
        }
    
        # root, locally-installed perl or --sudo: don't care about install_base
        return if $self->{sudo} or (_writable($Config{installsitelib}) and _writable($Config{installsitebin}));
    
        # local::lib is configured in the shell -- yay
        if ($ENV{PERL_MM_OPT} and ($ENV{MODULEBUILDRC} or $ENV{PERL_MB_OPT})) {
            $self->bootstrap_local_lib_deps;
            return;
        }
    
        $self->setup_local_lib;
    
        $self->diag(<<DIAG, 1);
    !
    ! Can't write to $Config{installsitelib} and $Config{installsitebin}: Installing modules to $ENV{HOME}/perl5
    ! To turn off this warning, you have to do one of the following:
    !   - run me as a root or with --sudo option (to install to $Config{installsitelib} and $Config{installsitebin})
    !   - Configure local::lib your existing local::lib in this shell to set PERL_MM_OPT etc.
    !   - Install local::lib by running the following commands
    !
    !         cpanm --local-lib=~/perl5 local::lib && eval \$(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)
    !
    DIAG
        sleep 2;
    }
    
    sub _core_only_inc {
        my($self, $base) = @_;
        require local::lib;
        (
            local::lib->resolve_path(local::lib->install_base_arch_path($base)),
            local::lib->resolve_path(local::lib->install_base_perl_path($base)),
            (!$self->{exclude_vendor} ? grep {$_} @Config{qw(vendorarch vendorlibexp)} : ()),
            @Config{qw(archlibexp privlibexp)},
        );
    }
    
    sub _diff {
        my($self, $old, $new) = @_;
    
        my @diff;
        my %old = map { $_ => 1 } @$old;
        for my $n (@$new) {
            push @diff, $n unless exists $old{$n};
        }
    
        @diff;
    }
    
    sub _setup_local_lib_env {
        my($self, $base) = @_;
    
        $self->diag(<<WARN, 1) if $base =~ /\s/;
    WARNING: Your lib directory name ($base) contains a space in it. It's known to cause issues with perl builder tools such as local::lib and MakeMaker. You're recommended to rename your directory.
    WARN
    
        local $SIG{__WARN__} = sub { }; # catch 'Attempting to write ...'
        local::lib->setup_env_hash_for($base, 0);
    }
    
    sub setup_local_lib {
        my($self, $base, $no_env) = @_;
        $base = undef if $base eq '_';
    
        require local::lib;
        {
            local $0 = 'cpanm'; # so curl/wget | perl works
            $base ||= "~/perl5";
            $base = local::lib->resolve_path($base);
            if ($self->{self_contained}) {
                my @inc = $self->_core_only_inc($base);
                $self->{search_inc} = [ @inc ];
            } else {
                $self->{search_inc} = [
                    local::lib->install_base_arch_path($base),
                    local::lib->install_base_perl_path($base),
                    @INC,
                ];
            }
            $self->_setup_local_lib_env($base) unless $no_env;
            $self->{local_lib} = $base;
        }
    
        $self->bootstrap_local_lib_deps;
    }
    
    sub bootstrap_local_lib_deps {
        my $self = shift;
        push @{$self->{bootstrap_deps}},
            App::cpanminus::Dependency->new('ExtUtils::MakeMaker' => 6.58),
            App::cpanminus::Dependency->new('ExtUtils::Install'   => 1.46);
    }
    
    sub prompt_bool {
        my($self, $mess, $def) = @_;
    
        my $val = $self->prompt($mess, $def);
        return lc $val eq 'y';
    }
    
    sub prompt {
        my($self, $mess, $def) = @_;
    
        my $isa_tty = -t STDIN && (-t STDOUT || !(-f STDOUT || -c STDOUT)) ;
        my $dispdef = defined $def ? "[$def] " : " ";
        $def = defined $def ? $def : "";
    
        if (!$self->{prompt} || (!$isa_tty && eof STDIN)) {
            return $def;
        }
    
        local $|=1;
        local $\;
        my $ans;
        eval {
            local $SIG{ALRM} = sub { undef $ans; die "alarm\n" };
            print STDOUT "$mess $dispdef";
            alarm $self->{prompt_timeout} if $self->{prompt_timeout};
            $ans = <STDIN>;
            alarm 0;
        };
        if ( defined $ans ) {
            chomp $ans;
        } else { # user hit ctrl-D or alarm timeout
            print STDOUT "\n";
        }
    
        return (!defined $ans || $ans eq '') ? $def : $ans;
    }
    
    sub diag_ok {
        my($self, $msg) = @_;
        chomp $msg;
        $msg ||= "OK";
        if ($self->{in_progress}) {
            $self->_diag("$msg\n");
            $self->{in_progress} = 0;
        }
        $self->log("-> $msg\n");
    }
    
    sub diag_fail {
        my($self, $msg, $always) = @_;
        chomp $msg;
        if ($self->{in_progress}) {
            $self->_diag("FAIL\n");
            $self->{in_progress} = 0;
        }
    
        if ($msg) {
            $self->_diag("! $msg\n", $always, 1);
            $self->log("-> FAIL $msg\n");
        }
    }
    
    sub diag_progress {
        my($self, $msg) = @_;
        chomp $msg;
        $self->{in_progress} = 1;
        $self->_diag("$msg ... ");
        $self->log("$msg\n");
    }
    
    sub _diag {
        my($self, $msg, $always, $error) = @_;
        my $fh = $error ? *STDERR : *STDOUT;
        print {$fh} $msg if $always or $self->{verbose} or !$self->{quiet};
    }
    
    sub diag {
        my($self, $msg, $always) = @_;
        $self->_diag($msg, $always);
        $self->log($msg);
    }
    
    sub chat {
        my $self = shift;
        print STDERR @_ if $self->{verbose};
        $self->log(@_);
    }
    
    sub mask_output {
        my $self = shift;
        my $method = shift;
        $self->$method( $self->mask_uri_passwords(@_) );
    }
    
    sub log {
        my $self = shift;
        open my $out, ">>$self->{log}";
        print $out @_;
    }
    
    sub run {
        my($self, $cmd) = @_;
    
        if (WIN32) {
            $cmd = $self->shell_quote(@$cmd) if ref $cmd eq 'ARRAY';
            unless ($self->{verbose}) {
                $cmd .= " >> " . $self->shell_quote($self->{log}) . " 2>&1";
            }
            !system $cmd;
        } else {
            my $pid = fork;
            if ($pid) {
                waitpid $pid, 0;
                return !$?;
            } else {
                $self->run_exec($cmd);
            }
        }
    }
    
    sub run_exec {
        my($self, $cmd) = @_;
    
        if (ref $cmd eq 'ARRAY') {
            unless ($self->{verbose}) {
                open my $logfh, ">>", $self->{log};
                open STDERR, '>&', $logfh;
                open STDOUT, '>&', $logfh;
                close $logfh;
            }
            exec @$cmd;
        } else {
            unless ($self->{verbose}) {
                $cmd .= " >> " . $self->shell_quote($self->{log}) . " 2>&1";
            }
            exec $cmd;
        }
    }
    
    sub run_timeout {
        my($self, $cmd, $timeout) = @_;
        return $self->run($cmd) if WIN32 || $self->{verbose} || !$timeout;
    
        my $pid = fork;
        if ($pid) {
            eval {
                local $SIG{ALRM} = sub { die "alarm\n" };
                alarm $timeout;
                waitpid $pid, 0;
                alarm 0;
            };
            if ($@ && $@ eq "alarm\n") {
                $self->diag_fail("Timed out (> ${timeout}s). Use --verbose to retry.");
                local $SIG{TERM} = 'IGNORE';
                kill TERM => 0;
                waitpid $pid, 0;
                return;
            }
            return !$?;
        } elsif ($pid == 0) {
            $self->run_exec($cmd);
        } else {
            $self->chat("! fork failed: falling back to system()\n");
            $self->run($cmd);
        }
    }
    
    sub append_args {
        my($self, $cmd, $phase) = @_;
    
        if (my $args = $self->{build_args}{$phase}) {
            $cmd = join ' ', $self->shell_quote(@$cmd), $args;
        }
    
        $cmd;
    }
    
    sub configure {
        my($self, $cmd, $depth) = @_;
    
        # trick AutoInstall
        local $ENV{PERL5_CPAN_IS_RUNNING} = local $ENV{PERL5_CPANPLUS_IS_RUNNING} = $$;
    
        # e.g. skip CPAN configuration on local::lib
        local $ENV{PERL5_CPANM_IS_RUNNING} = $$;
    
        my $use_default = !$self->{interactive};
        local $ENV{PERL_MM_USE_DEFAULT} = $use_default;
    
        local $ENV{PERL_MM_OPT} = $ENV{PERL_MM_OPT};
        local $ENV{PERL_MB_OPT} = $ENV{PERL_MB_OPT};
    
        # skip man page generation
        unless ($self->{pod2man}) {
            $ENV{PERL_MM_OPT} .= " INSTALLMAN1DIR=none INSTALLMAN3DIR=none";
            $ENV{PERL_MB_OPT} .= " --config installman1dir= --config installsiteman1dir= --config installman3dir= --config installsiteman3dir=";
        }
    
        # Lancaster Consensus
        if ($self->{pure_perl}) {
            $ENV{PERL_MM_OPT} .= " PUREPERL_ONLY=1";
            $ENV{PERL_MB_OPT} .= " --pureperl-only";
        }
    
        $cmd = $self->append_args($cmd, 'configure') if $depth == 0;
    
        local $self->{verbose} = $self->{verbose} || $self->{interactive};
        $self->run_timeout($cmd, $self->{configure_timeout});
    }
    
    sub build {
        my($self, $cmd, $distname, $depth) = @_;
    
        local $ENV{PERL_MM_USE_DEFAULT} = !$self->{interactive};
    
        $cmd = $self->append_args($cmd, 'build') if $depth == 0;
    
        return 1 if $self->run_timeout($cmd, $self->{build_timeout});
        while (1) {
            my $ans = lc $self->prompt("Building $distname failed.\nYou can s)kip, r)etry, e)xamine build log, or l)ook ?", "s");
            return                                       if $ans eq 's';
            return $self->build($cmd, $distname, $depth) if $ans eq 'r';
            $self->show_build_log                        if $ans eq 'e';
            $self->look                                  if $ans eq 'l';
        }
    }
    
    sub test {
        my($self, $cmd, $distname, $depth) = @_;
        return 1 if $self->{notest};
    
        # https://rt.cpan.org/Ticket/Display.html?id=48965#txn-1013385
        local $ENV{PERL_MM_USE_DEFAULT} = !$self->{interactive};
    
        # https://github.com/Perl-Toolchain-Gang/toolchain-site/blob/master/lancaster-consensus.md
        local $ENV{NONINTERACTIVE_TESTING} = !$self->{interactive};
    
        $cmd = $self->append_args($cmd, 'test') if $depth == 0;
    
        return 1 if $self->run_timeout($cmd, $self->{test_timeout});
        if ($self->{force}) {
            $self->diag_fail("Testing $distname failed but installing it anyway.");
            return 1;
        } else {
            $self->diag_fail;
            while (1) {
                my $ans = lc $self->prompt("Testing $distname failed.\nYou can s)kip, r)etry, f)orce install, e)xamine build log, or l)ook ?", "s");
                return                                      if $ans eq 's';
                return $self->test($cmd, $distname, $depth) if $ans eq 'r';
                return 1                                    if $ans eq 'f';
                $self->show_build_log                       if $ans eq 'e';
                $self->look                                 if $ans eq 'l';
            }
        }
    }
    
    sub install {
        my($self, $cmd, $uninst_opts, $depth) = @_;
    
        if ($depth == 0 && $self->{test_only}) {
            return 1;
        }
    
        if ($self->{sudo}) {
            unshift @$cmd, "sudo";
        }
    
        if ($self->{uninstall_shadows} && !$ENV{PERL_MM_OPT}) {
            push @$cmd, @$uninst_opts;
        }
    
        $cmd = $self->append_args($cmd, 'install') if $depth == 0;
    
        $self->run($cmd);
    }
    
    sub look {
        my $self = shift;
    
        my $shell = $ENV{SHELL};
        $shell  ||= $ENV{COMSPEC} if WIN32;
        if ($shell) {
            my $cwd = Cwd::cwd;
            $self->diag("Entering $cwd with $shell\n");
            system $shell;
        } else {
            $self->diag_fail("You don't seem to have a SHELL :/");
        }
    }
    
    sub show_build_log {
        my $self = shift;
    
        my @pagers = (
            $ENV{PAGER},
            (WIN32 ? () : ('less')),
            'more'
        );
        my $pager;
        while (@pagers) {
            $pager = shift @pagers;
            next unless $pager;
            $pager = $self->which($pager);
            next unless $pager;
            last;
        }
    
        if ($pager) {
            # win32 'more' doesn't allow "more build.log", the < is required
            system("$pager < $self->{log}");
        }
        else {
            $self->diag_fail("You don't seem to have a PAGER :/");
        }
    }
    
    sub chdir {
        my $self = shift;
        Cwd::chdir(File::Spec->canonpath($_[0])) or die "$_[0]: $!";
    }
    
    sub configure_mirrors {
        my $self = shift;
        unless (@{$self->{mirrors}}) {
            $self->{mirrors} = [ 'http://www.cpan.org' ];
        }
        for (@{$self->{mirrors}}) {
            s!^/!file:///!;
            s!/$!!;
        }
    }
    
    sub self_upgrade {
        my $self = shift;
        $self->check_upgrade;
        $self->{argv} = [ 'App::cpanminus' ];
        return; # continue
    }
    
    sub install_module {
        my($self, $module, $depth, $version) = @_;
    
        $self->check_libs;
    
        if ($self->{seen}{$module}++) {
            # TODO: circular dependencies
            $self->chat("Already tried $module. Skipping.\n");
            return 1;
        }
    
        if ($self->{skip_satisfied}) {
            my($ok, $local) = $self->check_module($module, $version || 0);
            if ($ok) {
                $self->diag("You have $module ($local)\n", 1);
                return 1;
            }
        }
    
        my $dist = $self->resolve_name($module, $version);
        unless ($dist) {
            my $what = $module . ($version ? " ($version)" : "");
            $self->diag_fail("Couldn't find module or a distribution $what", 1);
            return;
        }
    
        if ($dist->{distvname} && $self->{seen}{$dist->{distvname}}++) {
            $self->chat("Already tried $dist->{distvname}. Skipping.\n");
            return 1;
        }
    
        if ($self->{cmd} eq 'info') {
            print $self->format_dist($dist), "\n";
            return 1;
        }
    
        $dist->{depth} = $depth; # ugly hack
    
        if ($dist->{module}) {
            unless ($self->satisfy_version($dist->{module}, $dist->{module_version}, $version)) {
                $self->diag("Found $dist->{module} $dist->{module_version} which doesn't satisfy $version.\n", 1);
                return;
            }
    
            # If a version is requested, it has to be the exact same version, otherwise, check as if
            # it is the minimum version you need.
            my $cmp = $version ? "==" : "";
            my $requirement = $dist->{module_version} ? "$cmp$dist->{module_version}" : 0;
            my($ok, $local) = $self->check_module($dist->{module}, $requirement);
            if ($self->{skip_installed} && $ok) {
                $self->diag("$dist->{module} is up to date. ($local)\n", 1);
                return 1;
            }
        }
    
        if ($dist->{dist} eq 'perl'){
            $self->diag("skipping $dist->{pathname}\n");
            return 1;
        }
    
        $self->diag("--> Working on $module\n");
    
        $dist->{dir} ||= $self->fetch_module($dist);
    
        unless ($dist->{dir}) {
            $self->diag_fail("Failed to fetch distribution $dist->{distvname}", 1);
            return;
        }
    
        $self->chat("Entering $dist->{dir}\n");
        $self->chdir($self->{base});
        $self->chdir($dist->{dir});
    
        if ($self->{cmd} eq 'look') {
            $self->look;
            return 1;
        }
    
        return $self->build_stuff($module, $dist, $depth);
    }
    
    sub uninstall_search_path {
        my $self = shift;
    
        $self->{local_lib}
            ? (local::lib->install_base_arch_path($self->{local_lib}),
               local::lib->install_base_perl_path($self->{local_lib}))
            : @Config{qw(installsitearch installsitelib)};
    }
    
    sub uninstall_module {
        my ($self, $module) = @_;
    
        $self->check_libs;
    
        my @inc = $self->uninstall_search_path;
    
        my($metadata, $packlist) = $self->packlists_containing($module, \@inc);
        unless ($packlist) {
            $self->diag_fail(<<DIAG, 1);
    $module is not found in the following directories and can't be uninstalled.
    
    @{[ join("  \n", map "  $_", @inc) ]}
    
    DIAG
            return;
        }
    
        my @uninst_files = $self->uninstall_target($metadata, $packlist);
    
        $self->ask_permission($module, \@uninst_files) or return;
        $self->uninstall_files(@uninst_files, $packlist);
    
        $self->diag("Successfully uninstalled $module\n", 1);
    
        return 1;
    }
    
    sub packlists_containing {
        my($self, $module, $inc) = @_;
    
        require Module::Metadata;
        my $metadata = Module::Metadata->new_from_module($module, inc => $inc)
            or return;
    
        my $packlist;
        my $wanted = sub {
            return unless $_ eq '.packlist' && -f $_;
            for my $file ($self->unpack_packlist($File::Find::name)) {
                $packlist ||= $File::Find::name if $file eq $metadata->filename;
            }
        };
    
        {
            require File::pushd;
            my $pushd = File::pushd::pushd();
            my @search = grep -d $_, map File::Spec->catdir($_, 'auto'), @$inc;
            File::Find::find($wanted, @search);
        }
    
        return $metadata, $packlist;
    }
    
    sub uninstall_target {
        my($self, $metadata, $packlist) = @_;
    
        # If the module has a shadow install, or uses local::lib, then you can't just remove
        # all files in .packlist since it might have shadows in there
        if ($self->has_shadow_install($metadata) or $self->{local_lib}) {
            grep $self->should_unlink($_), $self->unpack_packlist($packlist);
        } else {
            $self->unpack_packlist($packlist);
        }
    }
    
    sub has_shadow_install {
        my($self, $metadata) = @_;
    
        # check if you have the module in site_perl *and* perl
        my @shadow = grep defined, map Module::Metadata->new_from_module($metadata->name, inc => [$_]), @INC;
        @shadow >= 2;
    }
    
    sub should_unlink {
        my($self, $file) = @_;
    
        # If local::lib is used, everything under the directory can be safely removed
        # Otherwise, bin and man files might be shared with the shadows i.e. site_perl vs perl
        # This is not 100% safe to keep the script there hoping to work with older version of .pm
        # files in the shadow, but there's nothing you can do about it.
        if ($self->{local_lib}) {
            $file =~ /^\Q$self->{local_lib}\E/;
        } else {
            !(grep $file =~ /^\Q$_\E/, @Config{qw(installbin installscript installman1dir installman3dir)});
        }
    }
    
    sub ask_permission {
        my ($self, $module, $files) = @_;
    
        $self->diag("$module contains the following files:\n\n");
        for my $file (@$files) {
            $self->diag("  $file\n");
        }
        $self->diag("\n");
    
        return 'force uninstall' if $self->{force};
        local $self->{prompt} = 1;
        return $self->prompt_bool("Are you sure you want to uninstall $module?", 'y');
    }
    
    sub unpack_packlist {
        my ($self, $packlist) = @_;
        open my $fh, '<', $packlist or die "$packlist: $!";
        map { chomp; $_ } <$fh>;
    }
    
    sub uninstall_files {
        my ($self, @files) = @_;
    
        $self->diag("\n");
    
        for my $file (@files) {
            $self->diag("Unlink: $file\n");
            unlink $file or $self->diag_fail("$!: $file");
        }
    
        $self->diag("\n");
    
        return 1;
    }
    
    sub format_dist {
        my($self, $dist) = @_;
    
        # TODO support --dist-format?
        return "$dist->{cpanid}/$dist->{filename}";
    }
    
    sub trim {
        local $_ = shift;
        tr/\n/ /d;
        s/^\s*|\s*$//g;
        $_;
    }
    
    sub fetch_module {
        my($self, $dist) = @_;
    
        $self->chdir($self->{base});
    
        for my $uri (@{$dist->{uris}}) {
            $self->mask_output( diag_progress => "Fetching $uri" );
    
            # Ugh, $dist->{filename} can contain sub directory
            my $filename = $dist->{filename} || $uri;
            my $name = File::Basename::basename($filename);
    
            my $cancelled;
            my $fetch = sub {
                my $file;
                eval {
                    local $SIG{INT} = sub { $cancelled = 1; die "SIGINT\n" };
                    $self->mirror($uri, $name);
                    $file = $name if -e $name;
                };
                $self->diag("ERROR: " . trim("$@") . "\n", 1) if $@ && $@ ne "SIGINT\n";
                return $file;
            };
    
            my($try, $file);
            while ($try++ < 3) {
                $file = $fetch->();
                last if $cancelled or $file;
                $self->mask_output( diag_fail => "Download $uri failed. Retrying ... ");
            }
    
            if ($cancelled) {
                $self->diag_fail("Download cancelled.");
                return;
            }
    
            unless ($file) {
                $self->mask_output( diag_fail => "Failed to download $uri");
                next;
            }
    
            $self->diag_ok;
            $dist->{local_path} = File::Spec->rel2abs($name);
    
            my $dir = $self->unpack($file, $uri, $dist);
            next unless $dir; # unpack failed
    
            if (my $save = $self->{save_dists}) {
                # Only distros retrieved from CPAN have a pathname set
                my $path = $dist->{pathname} ? "$save/authors/id/$dist->{pathname}"
                                             : "$save/vendor/$file";
                $self->chat("Copying $name to $path\n");
                File::Path::mkpath([ File::Basename::dirname($path) ], 0, 0777);
                File::Copy::copy($file, $path) or warn $!;
            }
    
            return $dist, $dir;
        }
    }
    
    sub unpack {
        my($self, $file, $uri, $dist) = @_;
    
        if ($self->{verify}) {
            $self->verify_archive($file, $uri, $dist) or return;
        }
    
        $self->chat("Unpacking $file\n");
        my $dir = $file =~ /\.zip/i ? $self->unzip($file) : $self->untar($file);
        unless ($dir) {
            $self->diag_fail("Failed to unpack $file: no directory");
        }
        return $dir;
    }
    
    sub verify_checksums_signature {
        my($self, $chk_file) = @_;
    
        require Module::Signature; # no fatpack
    
        $self->chat("Verifying the signature of CHECKSUMS\n");
    
        my $rv = eval {
            local $SIG{__WARN__} = sub {}; # suppress warnings
            my $v = Module::Signature::_verify($chk_file);
            $v == Module::Signature::SIGNATURE_OK();
        };
        if ($rv) {
            $self->chat("Verified OK!\n");
        } else {
            $self->diag_fail("Verifying CHECKSUMS signature failed: $rv\n");
            return;
        }
    
        return 1;
    }
    
    sub verify_archive {
        my($self, $file, $uri, $dist) = @_;
    
        unless ($dist->{cpanid}) {
            $self->chat("Archive '$file' does not seem to be from PAUSE. Skip verification.\n");
            return 1;
        }
    
        (my $mirror = $uri) =~ s!/authors/id.*$!!;
    
        (my $chksum_uri = $uri) =~ s!/[^/]*$!/CHECKSUMS!;
        my $chk_file = $self->source_for($mirror) . "/$dist->{cpanid}.CHECKSUMS";
        $self->mask_output( diag_progress => "Fetching $chksum_uri" );
        $self->mirror($chksum_uri, $chk_file);
    
        unless (-e $chk_file) {
            $self->diag_fail("Fetching $chksum_uri failed.\n");
            return;
        }
    
        $self->diag_ok;
        $self->verify_checksums_signature($chk_file) or return;
        $self->verify_checksum($file, $chk_file);
    }
    
    sub verify_checksum {
        my($self, $file, $chk_file) = @_;
    
        $self->chat("Verifying the SHA1 for $file\n");
    
        open my $fh, "<$chk_file" or die "$chk_file: $!";
        my $data = join '', <$fh>;
        $data =~ s/\015?\012/\n/g;
    
        require Safe; # no fatpack
        my $chksum = Safe->new->reval($data);
    
        if (!ref $chksum or ref $chksum ne 'HASH') {
            $self->diag_fail("! Checksum file downloaded from $chk_file is broken.\n");
            return;
        }
    
        if (my $sha = $chksum->{$file}{sha256}) {
            my $hex = $self->sha1_for($file);
            if ($hex eq $sha) {
                $self->chat("Checksum for $file: Verified!\n");
            } else {
                $self->diag_fail("Checksum mismatch for $file\n");
                return;
            }
        } else {
            $self->chat("Checksum for $file not found in CHECKSUMS.\n");
            return;
        }
    }
    
    sub sha1_for {
        my($self, $file) = @_;
    
        require Digest::SHA; # no fatpack
    
        open my $fh, "<", $file or die "$file: $!";
        my $dg = Digest::SHA->new(256);
        my($data);
        while (read($fh, $data, 4096)) {
            $dg->add($data);
        }
    
        return $dg->hexdigest;
    }
    
    sub verify_signature {
        my($self, $dist) = @_;
    
        $self->diag_progress("Verifying the SIGNATURE file");
        my $out = `$self->{cpansign} -v --skip 2>&1`;
        $self->log($out);
    
        if ($out =~ /Signature verified OK/) {
            $self->diag_ok("Verified OK");
            return 1;
        } else {
            $self->diag_fail("SIGNATURE verificaion for $dist->{filename} failed\n");
            return;
        }
    }
    
    sub resolve_name {
        my($self, $module, $version) = @_;
    
        # URL
        if ($module =~ /^(ftp|https?|file):/) {
            if ($module =~ m!authors/id/(.*)!) {
                return $self->cpan_dist($1, $module);
            } else {
                return { uris => [ $module ] };
            }
        }
    
        # Directory
        if ($module =~ m!^[\./]! && -d $module) {
            return {
                source => 'local',
                dir => Cwd::abs_path($module),
            };
        }
    
        # File
        if (-f $module) {
            return {
                source => 'local',
                uris => [ "file://" . Cwd::abs_path($module) ],
            };
        }
    
        # Git
        if ($module =~ /(?:^git:|\.git(?:@.+)?$)/) {
            return $self->git_uri($module);
        }
    
        # cpan URI
        if ($module =~ s!^cpan:///distfile/!!) {
            return $self->cpan_dist($module);
        }
    
        # PAUSEID/foo
        # P/PA/PAUSEID/foo
        if ($module =~ m!^(?:[A-Z]/[A-Z]{2}/)?([A-Z]{2}[\-A-Z0-9]*/.*)$!) {
            return $self->cpan_dist($1);
        }
    
        # Module name
        return $self->search_module($module, $version);
    }
    
    sub cpan_module {
        my($self, $module, $dist, $version) = @_;
    
        my $dist = $self->cpan_dist($dist);
        $dist->{module} = $module;
        $dist->{module_version} = $version if $version && $version ne 'undef';
    
        return $dist;
    }
    
    sub cpan_dist {
        my($self, $dist, $url) = @_;
    
        $dist =~ s!^([A-Z]{2})!substr($1,0,1)."/".substr($1,0,2)."/".$1!e;
    
        require CPAN::DistnameInfo;
        my $d = CPAN::DistnameInfo->new($dist);
    
        if ($url) {
            $url = [ $url ] unless ref $url eq 'ARRAY';
        } else {
            my $id = $d->cpanid;
            my $fn = substr($id, 0, 1) . "/" . substr($id, 0, 2) . "/" . $id . "/" . $d->filename;
    
            my @mirrors = @{$self->{mirrors}};
            my @urls    = map "$_/authors/id/$fn", @mirrors;
    
            $url = \@urls,
        }
    
        return {
            $d->properties,
            source  => 'cpan',
            uris    => $url,
        };
    }
    
    sub git_uri {
        my ($self, $uri) = @_;
    
        # similar to http://www.pip-installer.org/en/latest/logic.html#vcs-support
        # git URL has to end with .git when you need to use pin @ commit/tag/branch
    
        ($uri, my $commitish) = split /(?<=\.git)@/i, $uri, 2;
    
        my $dir = File::Temp::tempdir(CLEANUP => 1);
    
        $self->mask_output( diag_progress => "Cloning $uri" );
        $self->run([ 'git', 'clone', $uri, $dir ]);
    
        unless (-e "$dir/.git") {
            $self->diag_fail("Failed cloning git repository $uri", 1);
            return;
        }
    
        if ($commitish) {
            require File::pushd;
            my $dir = File::pushd::pushd($dir);
    
            unless ($self->run([ 'git', 'checkout', $commitish ])) {
                $self->diag_fail("Failed to checkout '$commitish' in git repository $uri\n");
                return;
            }
        }
    
        $self->diag_ok;
    
        return {
            source => 'local',
            dir    => $dir,
        };
    }
    
    sub setup_module_build_patch {
        my $self = shift;
    
        open my $out, ">$self->{base}/ModuleBuildSkipMan.pm" or die $!;
        print $out <<EOF;
    package ModuleBuildSkipMan;
    CHECK {
      if (%Module::Build::) {
        no warnings 'redefine';
        *Module::Build::Base::ACTION_manpages = sub {};
        *Module::Build::Base::ACTION_docs     = sub {};
      }
    }
    1;
    EOF
    }
    
    sub core_version_for {
        my($self, $module) = @_;
    
        require Module::CoreList; # no fatpack
        unless (exists $Module::CoreList::version{$]+0}) {
            die sprintf("Module::CoreList %s (loaded from %s) doesn't seem to have entries for perl $]. " .
                        "You're strongly recommended to upgrade Module::CoreList from CPAN.\n",
                        $Module::CoreList::VERSION, $INC{"Module/CoreList.pm"});
        }
    
        unless (exists $Module::CoreList::version{$]+0}{$module}) {
            return -1;
        }
    
        return $Module::CoreList::version{$]+0}{$module};
    }
    
    sub search_inc {
        my $self = shift;
        $self->{search_inc} ||= do {
            # strip lib/ and fatlib/ from search path when booted from dev
            if (defined $::Bin) {
                [grep !/^\Q$::Bin\E\/..\/(?:fat)?lib$/, @INC]
            } else {
                [@INC]
            }
        };
    }
    
    sub check_module {
        my($self, $mod, $want_ver) = @_;
    
        require Module::Metadata;
        my $meta = Module::Metadata->new_from_module($mod, inc => $self->search_inc)
            or return 0, undef;
    
        my $version = $meta->version;
    
        # When -L is in use, the version loaded from 'perl' library path
        # might be newer than (or actually wasn't core at) the version
        # that is shipped with the current perl
        if ($self->{self_contained} && $self->loaded_from_perl_lib($meta)) {
            $version = $self->core_version_for($mod);
            return 0, undef if $version && $version == -1;
        }
    
        $self->{local_versions}{$mod} = $version;
    
        if ($self->is_deprecated($meta)){
            return 0, $version;
        } elsif ($self->satisfy_version($mod, $version, $want_ver)) {
            return 1, ($version || 'undef');
        } else {
            return 0, $version;
        }
    }
    
    sub satisfy_version {
        my($self, $mod, $version, $want_ver) = @_;
    
        $want_ver = '0' unless defined($want_ver) && length($want_ver);
    
        require CPAN::Meta::Requirements;
        my $requirements = CPAN::Meta::Requirements->new;
        $requirements->add_string_requirement($mod, $want_ver);
        $requirements->accepts_module($mod, $version);
    }
    
    sub unsatisfy_how {
        my($self, $ver, $want_ver) = @_;
    
        if ($want_ver =~ /^[v0-9\.\_]+$/) {
            return "$ver < $want_ver";
        } else {
            return "$ver doesn't satisfy $want_ver";
        }
    }
    
    sub is_deprecated {
        my($self, $meta) = @_;
    
        my $deprecated = eval {
            require Module::CoreList; # no fatpack
            Module::CoreList::is_deprecated($meta->{module});
        };
    
        return $deprecated && $self->loaded_from_perl_lib($meta);
    }
    
    sub loaded_from_perl_lib {
        my($self, $meta) = @_;
    
        require Config;
        my @dirs = qw(archlibexp privlibexp);
        if ($self->{self_contained} && ! $self->{exclude_vendor} && $Config{vendorarch}) {
            unshift @dirs, qw(vendorarch vendorlibexp);
        }
        for my $dir (@dirs) {
            my $confdir = $Config{$dir};
            if ($confdir eq substr($meta->filename, 0, length($confdir))) {
                return 1;
            }
        }
    
        return;
    }
    
    sub should_install {
        my($self, $mod, $ver) = @_;
    
        $self->chat("Checking if you have $mod $ver ... ");
        my($ok, $local) = $self->check_module($mod, $ver);
    
        if ($ok)       { $self->chat("Yes ($local)\n") }
        elsif ($local) { $self->chat("No (" . $self->unsatisfy_how($local, $ver) . ")\n") }
        else           { $self->chat("No\n") }
    
        return $mod unless $ok;
        return;
    }
    
    sub check_perl_version {
        my($self, $version) = @_;
        require CPAN::Meta::Requirements;
        my $req = CPAN::Meta::Requirements->from_string_hash({ perl => $version });
        $req->accepts_module(perl => $]);
    }
    
    sub install_deps {
        my($self, $dir, $depth, @deps) = @_;
    
        my(@install, %seen, @fail);
        for my $dep (@deps) {
            next if $seen{$dep->module};
            if ($dep->module eq 'perl') {
                if ($dep->is_requirement && !$self->check_perl_version($dep->version)) {
                    $self->diag("Needs perl @{[$dep->version]}, you have $]\n");
                    push @fail, 'perl';
                }
            } elsif ($self->should_install($dep->module, $dep->version)) {
                push @install, $dep;
                $seen{$dep->module} = 1;
            }
        }
    
        if (@install) {
            $self->diag("==> Found dependencies: " . join(", ",  map $_->module, @install) . "\n");
        }
    
        for my $dep (@install) {
            $self->install_module($dep->module, $depth + 1, $dep->version);
        }
    
        $self->chdir($self->{base});
        $self->chdir($dir) if $dir;
    
        if ($self->{scandeps}) {
            return 1; # Don't check if dependencies are installed, since with --scandeps they aren't
        }
        my @not_ok = $self->unsatisfied_deps(@deps);
        if (@not_ok) {
            return 0, \@not_ok;
        } else {
            return 1;
        }
    }
    
    sub unsatisfied_deps {
        my($self, @deps) = @_;
    
        require CPAN::Meta::Check;
        require CPAN::Meta::Requirements;
    
        my $reqs = CPAN::Meta::Requirements->new;
        for my $dep (grep $_->is_requirement, @deps) {
            $reqs->add_string_requirement($dep->module => $dep->version || '0');
        }
    
        my $ret = CPAN::Meta::Check::check_requirements($reqs, 'requires', $self->{search_inc});
        grep defined, values %$ret;
    }
    
    sub install_deps_bailout {
        my($self, $target, $dir, $depth, @deps) = @_;
    
        my($ok, $fail) = $self->install_deps($dir, $depth, @deps);
        if (!$ok) {
            $self->diag_fail("Installing the dependencies failed: " . join(", ", @$fail), 1);
            unless ($self->prompt_bool("Do you want to continue building $target anyway?", "n")) {
                $self->diag_fail("Bailing out the installation for $target.", 1);
                return;
            }
        }
    
        return 1;
    }
    
    sub build_stuff {
        my($self, $stuff, $dist, $depth) = @_;
    
        if ($self->{verify} && -e 'SIGNATURE') {
            $self->verify_signature($dist) or return;
        }
    
        require CPAN::Meta;
    
        my($meta_file) = grep -f, qw(META.json META.yml);
        if ($meta_file) {
            $self->chat("Checking configure dependencies from $meta_file\n");
            $dist->{cpanmeta} = eval { CPAN::Meta->load_file($meta_file) };
        } elsif ($dist->{dist} && $dist->{version}) {
            $self->chat("META.yml/json not found. Creating skeleton for it.\n");
            $dist->{cpanmeta} = CPAN::Meta->new({ name => $dist->{dist}, version => $dist->{version} });
        }
    
        $dist->{meta} = $dist->{cpanmeta} ? $dist->{cpanmeta}->as_struct : {};
    
        my @config_deps;
        if ($dist->{cpanmeta}) {
            push @config_deps, App::cpanminus::Dependency->from_prereqs(
                $dist->{cpanmeta}->effective_prereqs, ['configure'], $self->{install_types},
            );
        }
    
        # workaround for bad M::B based dists with no configure_requires
        # https://github.com/miyagawa/cpanminus/issues/273
        if (-e 'Build.PL' && !$self->should_use_mm($dist->{dist}) && !@config_deps) {
            push @config_deps, App::cpanminus::Dependency->from_versions(
                { 'Module::Build' => '0.36' }, 'configure',
            );
        }
    
        my $target = $dist->{meta}{name} ? "$dist->{meta}{name}-$dist->{meta}{version}" : $dist->{dir};
    
        $self->install_deps_bailout($target, $dist->{dir}, $depth, @config_deps)
            or return;
    
        $self->diag_progress("Configuring $target");
    
        my $configure_state = $self->configure_this($dist, $depth);
        $self->diag_ok($configure_state->{configured_ok} ? "OK" : "N/A");
    
        $dist->{provides} = $self->extract_packages($dist->{cpanmeta}, ".")
            if $dist->{cpanmeta} && $dist->{source} eq 'cpan';
    
        # install direct 'test' dependencies for --installdeps, even with --notest
        my $root_target = (($self->{installdeps} or $self->{showdeps}) and $depth == 0);
        $dist->{want_phases} = $self->{notest} && !$root_target
                             ? [qw( build runtime )] : [qw( build test runtime )];
    
        push @{$dist->{want_phases}}, 'develop' if $self->{with_develop} && $depth == 0;
    
        my @deps = $self->find_prereqs($dist);
        my $module_name = $self->find_module_name($configure_state) || $dist->{meta}{name};
        $module_name =~ s/-/::/g;
    
        if ($self->{showdeps}) {
            for my $dep (@config_deps, @deps) {
                print $dep->module, ($dep->version ? ("~".$dep->version) : ""), "\n";
            }
            return 1;
        }
    
        my $distname = $dist->{meta}{name} ? "$dist->{meta}{name}-$dist->{meta}{version}" : $stuff;
    
        my $walkup;
        if ($self->{scandeps}) {
            $walkup = $self->scandeps_append_child($dist);
        }
    
        $self->install_deps_bailout($distname, $dist->{dir}, $depth, @deps)
            or return;
    
        if ($self->{scandeps}) {
            unless ($configure_state->{configured_ok}) {
                my $diag = <<DIAG;
    ! Configuring $distname failed. See $self->{log} for details.
    ! You might have to install the following modules first to get --scandeps working correctly.
    DIAG
                if (@config_deps) {
                    my @tree = @{$self->{scandeps_tree}};
                    $diag .= "!\n" . join("", map "! * $_->[0]{module}\n", @tree[0..$#tree-1]) if @tree;
                }
                $self->diag("!\n$diag!\n", 1);
            }
            $walkup->();
            return 1;
        }
    
        if ($self->{installdeps} && $depth == 0) {
            if ($configure_state->{configured_ok}) {
                $self->diag("<== Installed dependencies for $stuff. Finishing.\n");
                return 1;
            } else {
                $self->diag("! Configuring $distname failed. See $self->{log} for details.\n", 1);
                return;
            }
        }
    
        my $installed;
        if ($configure_state->{use_module_build} && -e 'Build' && -f _) {
            $self->diag_progress("Building " . ($self->{notest} ? "" : "and testing ") . $distname);
            $self->build([ $self->{perl}, "./Build" ], $distname, $depth) &&
            $self->test([ $self->{perl}, "./Build", "test" ], $distname, $depth) &&
            $self->install([ $self->{perl}, "./Build", "install" ], [ "--uninst", 1 ], $depth) &&
            $installed++;
        } elsif ($self->{make} && -e 'Makefile') {
            $self->diag_progress("Building " . ($self->{notest} ? "" : "and testing ") . $distname);
            $self->build([ $self->{make} ], $distname, $depth) &&
            $self->test([ $self->{make}, "test" ], $distname, $depth) &&
            $self->install([ $self->{make}, "install" ], [ "UNINST=1" ], $depth) &&
            $installed++;
        } else {
            my $why;
            my $configure_failed = $configure_state->{configured} && !$configure_state->{configured_ok};
            if ($configure_failed) { $why = "Configure failed for $distname." }
            elsif ($self->{make})  { $why = "The distribution doesn't have a proper Makefile.PL/Build.PL" }
            else                   { $why = "Can't configure the distribution. You probably need to have 'make'." }
    
            $self->diag_fail("$why See $self->{log} for details.", 1);
            return;
        }
    
        if ($installed && $self->{test_only}) {
            $self->diag_ok;
            $self->diag("Successfully tested $distname\n", 1);
        } elsif ($installed) {
            my $local   = $self->{local_versions}{$dist->{module} || ''};
            my $version = $dist->{module_version} || $dist->{meta}{version} || $dist->{version};
            my $reinstall = $local && ($local eq $version);
            my $action  = $local && !$reinstall
                        ? $self->numify_ver($version) < $self->numify_ver($local)
                            ? "downgraded"
                            : "upgraded"
                        : undef;
    
            my $how = $reinstall ? "reinstalled $distname"
                    : $local     ? "installed $distname ($action from $local)"
                                 : "installed $distname" ;
            my $msg = "Successfully $how";
            $self->diag_ok;
            $self->diag("$msg\n", 1);
            $self->{installed_dists}++;
            $self->save_meta($stuff, $dist, $module_name, \@config_deps, \@deps);
            return 1;
        } else {
            my $what = $self->{test_only} ? "Testing" : "Installing";
            $self->diag_fail("$what $stuff failed. See $self->{log} for details. Retry with --force to force install it.", 1);
            return;
        }
    }
    
    sub perl_requirements {
        my($self, @requires) = @_;
    
        my @perl;
        for my $requires (grep defined, @requires) {
            if (exists $requires->{perl}) {
                push @perl, App::cpanminus::Dependency->new(perl => $requires->{perl});
            }
        }
    
        return @perl;
    }
    
    sub should_use_mm {
        my($self, $dist) = @_;
    
        # Module::Build deps should use MakeMaker because that causes circular deps and fail
        # Otherwise we should prefer Build.PL
        my %should_use_mm = map { $_ => 1 } qw( version ExtUtils-ParseXS ExtUtils-Install ExtUtils-Manifest );
    
        $should_use_mm{$dist};
    }
    
    sub configure_this {
        my($self, $dist, $depth) = @_;
    
        if (-e $self->{cpanfile_path} && $self->{installdeps} && $depth == 0) {
            require Module::CPANfile;
            $dist->{cpanfile} = eval { Module::CPANfile->load($self->{cpanfile_path}) };
            $self->diag_fail($@, 1) if $@;
            return {
                configured       => 1,
                configured_ok    => !!$dist->{cpanfile},
                use_module_build => 0,
            };
        }
    
        if ($self->{skip_configure}) {
            my $eumm = -e 'Makefile';
            my $mb   = -e 'Build' && -f _;
            return {
                configured => 1,
                configured_ok => $eumm || $mb,
                use_module_build => $mb,
            };
        }
    
        my $state = {};
    
        my $try_eumm = sub {
            if (-e 'Makefile.PL') {
                $self->chat("Running Makefile.PL\n");
    
                # NOTE: according to Devel::CheckLib, most XS modules exit
                # with 0 even if header files are missing, to avoid receiving
                # tons of FAIL reports in such cases. So exit code can't be
                # trusted if it went well.
                if ($self->configure([ $self->{perl}, "Makefile.PL" ], $depth)) {
                    $state->{configured_ok} = -e 'Makefile';
                }
                $state->{configured}++;
            }
        };
    
        my $try_mb = sub {
            if (-e 'Build.PL') {
                $self->chat("Running Build.PL\n");
                if ($self->configure([ $self->{perl}, "Build.PL" ], $depth)) {
                    $state->{configured_ok} = -e 'Build' && -f _;
                }
                $state->{use_module_build}++;
                $state->{configured}++;
            }
        };
    
        my @try;
        if ($dist->{dist} && $self->should_use_mm($dist->{dist})) {
            @try = ($try_eumm, $try_mb);
        } else {
            @try = ($try_mb, $try_eumm);
        }
    
        for my $try (@try) {
            $try->();
            last if $state->{configured_ok};
        }
    
        unless ($state->{configured_ok}) {
            while (1) {
                my $ans = lc $self->prompt("Configuring $dist->{dist} failed.\nYou can s)kip, r)etry, e)xamine build log, or l)ook ?", "s");
                last                                        if $ans eq 's';
                return $self->configure_this($dist, $depth) if $ans eq 'r';
                $self->show_build_log                       if $ans eq 'e';
                $self->look                                 if $ans eq 'l';
            }
        }
    
        return $state;
    }
    
    sub find_module_name {
        my($self, $state) = @_;
    
        return unless $state->{configured_ok};
    
        if ($state->{use_module_build} &&
            -e "_build/build_params") {
            my $params = do { open my $in, "_build/build_params"; $self->safe_eval(join "", <$in>) };
            return eval { $params->[2]{module_name} } || undef;
        } elsif (-e "Makefile") {
            open my $mf, "Makefile";
            while (<$mf>) {
                if (/^\#\s+NAME\s+=>\s+(.*)/) {
                    return $self->safe_eval($1);
                }
            }
        }
    
        return;
    }
    
    sub list_files {
        my $self = shift;
    
        if (-e 'MANIFEST') {
            require ExtUtils::Manifest;
            my $manifest = eval { ExtUtils::Manifest::manifind() } || {};
            return sort { lc $a cmp lc $b } keys %$manifest;
        } else {
            require File::Find;
            my @files;
            my $finder = sub {
                my $name = $File::Find::name;
                $name =~ s!\.[/\\]!!;
                push @files, $name;
            };
            File::Find::find($finder, ".");
            return sort { lc $a cmp lc $b } @files;
        }
    }
    
    sub extract_packages {
        my($self, $meta, $dir) = @_;
    
        my $try = sub {
            my $file = shift;
            return 0 if $file =~ m!^(?:x?t|inc|local|perl5|fatlib|_build)/!;
            return 1 unless $meta->{no_index};
            return 0 if grep { $file =~ m!^$_/! } @{$meta->{no_index}{directory} || []};
            return 0 if grep { $file eq $_ } @{$meta->{no_index}{file} || []};
            return 1;
        };
    
        require Parse::PMFile;
    
        my @files = grep { /\.pm(?:\.PL)?$/ && $try->($_) } $self->list_files;
    
        my $provides = {};
    
        for my $file (@files) {
            my $parser = Parse::PMFile->new($meta, { UNSAFE => 1, ALLOW_DEV_VERSION => 1 });
            my $packages = $parser->parse($file);
    
            while (my($package, $meta) = each %$packages) {
                $provides->{$package} ||= {
                    file => $meta->{infile},
                    ($meta->{version} eq 'undef') ? () : (version => $meta->{version}),
                };
            }
        }
    
        return $provides;
    }
    
    sub save_meta {
        my($self, $module, $dist, $module_name, $config_deps, $build_deps) = @_;
    
        return unless $dist->{distvname} && $dist->{source} eq 'cpan';
    
        my $base = ($ENV{PERL_MM_OPT} || '') =~ /INSTALL_BASE=/
            ? ($self->install_base($ENV{PERL_MM_OPT}) . "/lib/perl5") : $Config{sitelibexp};
    
        my $provides = $dist->{provides};
    
        File::Path::mkpath("blib/meta", 0, 0777);
    
        my $local = {
            name => $module_name,
            target => $module,
            version => exists $provides->{$module_name}
                ? ($provides->{$module_name}{version} || $dist->{version}) : $dist->{version},
            dist => $dist->{distvname},
            pathname => $dist->{pathname},
            provides => $provides,
        };
    
        require JSON::PP;
        open my $fh, ">", "blib/meta/install.json" or die $!;
        print $fh JSON::PP::encode_json($local);
    
        # Existence of MYMETA.* Depends on EUMM/M::B versions and CPAN::Meta
        if (-e "MYMETA.json") {
            File::Copy::copy("MYMETA.json", "blib/meta/MYMETA.json");
        }
    
        my @cmd = (
            ($self->{sudo} ? 'sudo' : ()),
            $^X,
            '-MExtUtils::Install=install',
            '-e',
            qq[install({ 'blib/meta' => '$base/$Config{archname}/.meta/$dist->{distvname}' })],
        );
        $self->run(\@cmd);
    }
    
    sub _merge_hashref {
        my($self, @hashrefs) = @_;
    
        my %hash;
        for my $h (@hashrefs) {
            %hash = (%hash, %$h);
        }
    
        return \%hash;
    }
    
    sub install_base {
        my($self, $mm_opt) = @_;
        $mm_opt =~ /INSTALL_BASE=(\S+)/ and return $1;
        die "Your PERL_MM_OPT doesn't contain INSTALL_BASE";
    }
    
    sub safe_eval {
        my($self, $code) = @_;
        eval $code;
    }
    
    sub configure_features {
        my($self, $dist, @features) = @_;
        map $_->identifier, grep { $self->effective_feature($dist, $_) } @features;
    }
    
    sub effective_feature {
        my($self, $dist, $feature) = @_;
    
        if ($dist->{depth} == 0) {
            my $value = $self->{features}{$feature->identifier};
            return $value if defined $value;
            return 1 if $self->{features}{__all};
        }
    
        if ($self->{interactive}) {
            require CPAN::Meta::Requirements;
    
            $self->diag("[@{[ $feature->description ]}]\n", 1);
    
            my $req = CPAN::Meta::Requirements->new;
            for my $phase (@{$dist->{want_phases}}) {
                for my $type (@{$self->{install_types}}) {
                    $req->add_requirements($feature->prereqs->requirements_for($phase, $type));
                }
            }
    
            my $reqs = $req->as_string_hash;
            my @missing;
            for my $module (keys %$reqs) {
                if ($self->should_install($module, $req->{$module})) {
                    push @missing, $module;
                }
            }
    
            if (@missing) {
                my $howmany = @missing;
                $self->diag("==> Found missing dependencies: " . join(", ", @missing) . "\n", 1);
                local $self->{prompt} = 1;
                return $self->prompt_bool("Install the $howmany optional module(s)?", "y");
            }
        }
    
        return;
    }
    
    sub find_prereqs {
        my($self, $dist) = @_;
    
        my @deps = $self->extract_meta_prereqs($dist);
    
        if ($dist->{module} =~ /^Bundle::/i) {
            push @deps, $self->bundle_deps($dist);
        }
    
        return @deps;
    }
    
    sub extract_meta_prereqs {
        my($self, $dist) = @_;
    
        if ($dist->{cpanfile}) {
            my @features = $self->configure_features($dist, $dist->{cpanfile}->features);
            my $prereqs = $dist->{cpanfile}->prereqs_with(@features);
            return App::cpanminus::Dependency->from_prereqs($prereqs, $dist->{want_phases}, $self->{install_types});
        }
    
        require CPAN::Meta;
    
        my @deps;
        my($meta_file) = grep -f, qw(MYMETA.json MYMETA.yml);
        if ($meta_file) {
            $self->chat("Checking dependencies from $meta_file ...\n");
            my $mymeta = eval { CPAN::Meta->load_file($meta_file, { lazy_validation => 1 }) };
            if ($mymeta) {
                $dist->{meta}{name}    = $mymeta->name;
                $dist->{meta}{version} = $mymeta->version;
                return $self->extract_prereqs($mymeta, $dist);
            }
        }
    
        if (-e '_build/prereqs') {
            $self->chat("Checking dependencies from _build/prereqs ...\n");
            my $prereqs = do { open my $in, "_build/prereqs"; $self->safe_eval(join "", <$in>) };
            my $meta = CPAN::Meta->new(
                { name => $dist->{meta}{name}, version => $dist->{meta}{version}, %$prereqs },
                { lazy_validation => 1 },
            );
            @deps = $self->extract_prereqs($meta, $dist);
        } elsif (-e 'Makefile') {
            $self->chat("Finding PREREQ from Makefile ...\n");
            open my $mf, "Makefile";
            while (<$mf>) {
                if (/^\#\s+PREREQ_PM => \{\s*(.*?)\s*\}/) {
                    my @all;
                    my @pairs = split ', ', $1;
                    for (@pairs) {
                        my ($pkg, $v) = split '=>', $_;
                        push @all, [ $pkg, $v ];
                    }
                    my $list = join ", ", map { "'$_->[0]' => $_->[1]" } @all;
                    my $prereq = $self->safe_eval("no strict; +{ $list }");
                    push @deps, App::cpanminus::Dependency->from_versions($prereq) if $prereq;
                    last;
                }
            }
        }
    
        return @deps;
    }
    
    sub bundle_deps {
        my($self, $dist) = @_;
    
        my @files;
        File::Find::find({
            wanted => sub { push @files, File::Spec->rel2abs($_) if /\.pm/i },
            no_chdir => 1,
        }, '.');
    
        my @deps;
    
        for my $file (@files) {
            open my $pod, "<", $file or next;
            my $in_contents;
            while (<$pod>) {
                if (/^=head\d\s+CONTENTS/) {
                    $in_contents = 1;
                } elsif (/^=/) {
                    $in_contents = 0;
                } elsif ($in_contents) {
                    /^(\S+)\s*(\S+)?/
                        and push @deps, App::cpanminus::Dependency->new($1, $self->maybe_version($2));
                }
            }
        }
    
        return @deps;
    }
    
    sub maybe_version {
        my($self, $string) = @_;
        return $string && $string =~ /^\.?\d/ ? $string : undef;
    }
    
    sub extract_prereqs {
        my($self, $meta, $dist) = @_;
    
        my @features = $self->configure_features($dist, $meta->features);
        return App::cpanminus::Dependency->from_prereqs($meta->effective_prereqs(\@features), $dist->{want_phases}, $self->{install_types});
    }
    
    sub cleanup_workdirs {
        my $self = shift;
    
        my $expire = time - 24 * 60 * 60 * $self->{auto_cleanup};
        my @targets;
    
        opendir my $dh, "$self->{home}/work";
        while (my $e = readdir $dh) {
            next if $e !~ /^(\d+)\.\d+$/; # {UNIX time}.{PID}
            my $time = $1;
            if ($time < $expire) {
                push @targets, "$self->{home}/work/$e";
            }
        }
    
        if (@targets) {
            if (@targets >= 64) {
                $self->diag("Expiring " . scalar(@targets) . " work directories. This might take a while...\n");
            } else {
                $self->chat("Expiring " . scalar(@targets) . " work directories.\n");
            }
            File::Path::rmtree(\@targets, 0, 0); # safe = 0, since blib usually doesn't have write bits
        }
    }
    
    sub scandeps_append_child {
        my($self, $dist) = @_;
    
        my $new_node = [ $dist, [] ];
    
        my $curr_node = $self->{scandeps_current} || [ undef, $self->{scandeps_tree} ];
        push @{$curr_node->[1]}, $new_node;
    
        $self->{scandeps_current} = $new_node;
    
        return sub { $self->{scandeps_current} = $curr_node };
    }
    
    sub dump_scandeps {
        my $self = shift;
    
        if ($self->{format} eq 'tree') {
            $self->walk_down(sub {
                my($dist, $depth) = @_;
                if ($depth == 0) {
                    print "$dist->{distvname}\n";
                } else {
                    print " " x ($depth - 1);
                    print "\\_ $dist->{distvname}\n";
                }
            }, 1);
        } elsif ($self->{format} =~ /^dists?$/) {
            $self->walk_down(sub {
                my($dist, $depth) = @_;
                print $self->format_dist($dist), "\n";
            }, 0);
        } elsif ($self->{format} eq 'json') {
            require JSON::PP;
            print JSON::PP::encode_json($self->{scandeps_tree});
        } elsif ($self->{format} eq 'yaml') {
            require YAML; # no fatpack
            print YAML::Dump($self->{scandeps_tree});
        } else {
            $self->diag("Unknown format: $self->{format}\n");
        }
    }
    
    sub walk_down {
        my($self, $cb, $pre) = @_;
        $self->_do_walk_down($self->{scandeps_tree}, $cb, 0, $pre);
    }
    
    sub _do_walk_down {
        my($self, $children, $cb, $depth, $pre) = @_;
    
        # DFS - $pre determines when we call the callback
        for my $node (@$children) {
            $cb->($node->[0], $depth) if $pre;
            $self->_do_walk_down($node->[1], $cb, $depth + 1, $pre);
            $cb->($node->[0], $depth) unless $pre;
        }
    }
    
    sub DESTROY {
        my $self = shift;
        $self->{at_exit}->($self) if $self->{at_exit};
    }
    
    # Utils
    
    sub shell_quote {
        my($self, @stuff) = @_;
        if (WIN32) {
            join ' ', map { /^${quote}.+${quote}$/ ? $_ : ($quote . $_ . $quote) } @stuff;
        } else {
            String::ShellQuote::shell_quote_best_effort(@stuff);
        }
    }
    
    sub which {
        my($self, $name) = @_;
        if (File::Spec->file_name_is_absolute($name)) {
            if (-x $name && !-d _) {
                return $name;
            }
        }
        my $exe_ext = $Config{_exe};
        for my $dir (File::Spec->path) {
            my $fullpath = File::Spec->catfile($dir, $name);
            if ((-x $fullpath || -x ($fullpath .= $exe_ext)) && !-d _) {
                if ($fullpath =~ /\s/) {
                    $fullpath = $self->shell_quote($fullpath);
                }
                return $fullpath;
            }
        }
        return;
    }
    
    sub get {
        my($self, $uri) = @_;
        if ($uri =~ /^file:/) {
            $self->file_get($uri);
        } else {
            $self->{_backends}{get}->(@_);
        }
    }
    
    sub mirror {
        my($self, $uri, $local) = @_;
        if ($uri =~ /^file:/) {
            $self->file_mirror($uri, $local);
        } else {
            $self->{_backends}{mirror}->(@_);
        }
    }
    
    sub untar    { $_[0]->{_backends}{untar}->(@_) };
    sub unzip    { $_[0]->{_backends}{unzip}->(@_) };
    
    sub uri_to_file {
        my($self, $uri) = @_;
    
        # file:///path/to/file -> /path/to/file
        # file://C:/path       -> C:/path
        if ($uri =~ s!file:/+!!) {
            $uri = "/$uri" unless $uri =~ m![a-zA-Z]:!;
        }
    
        return $uri;
    }
    
    sub file_get {
        my($self, $uri) = @_;
        my $file = $self->uri_to_file($uri);
        open my $fh, "<$file" or return;
        join '', <$fh>;
    }
    
    sub file_mirror {
        my($self, $uri, $path) = @_;
        my $file = $self->uri_to_file($uri);
        File::Copy::copy($file, $path);
    }
    
    sub has_working_lwp {
        my($self, $mirrors) = @_;
        my $https = grep /^https:/, @$mirrors;
        eval {
            require LWP::UserAgent; # no fatpack
            LWP::UserAgent->VERSION(5.802);
            require LWP::Protocol::https if $https; # no fatpack
            1;
        };
    }
    
    sub init_tools {
        my $self = shift;
    
        return if $self->{initialized}++;
    
        if ($self->{make} = $self->which($Config{make})) {
            $self->chat("You have make $self->{make}\n");
        }
    
        # use --no-lwp if they have a broken LWP, to upgrade LWP
        if ($self->{try_lwp} && $self->has_working_lwp($self->{mirrors})) {
            $self->chat("You have LWP $LWP::VERSION\n");
            my $ua = sub {
                LWP::UserAgent->new(
                    parse_head => 0,
                    env_proxy => 1,
                    agent => $self->agent,
                    timeout => 30,
                    @_,
                );
            };
            $self->{_backends}{get} = sub {
                my $self = shift;
                my $res = $ua->()->request(HTTP::Request->new(GET => $_[0]));
                return unless $res->is_success;
                return $res->decoded_content;
            };
            $self->{_backends}{mirror} = sub {
                my $self = shift;
                my $res = $ua->()->mirror(@_);
                die $res->content if $res->code == 501;
                $res->code;
            };
        } elsif ($self->{try_wget} and my $wget = $self->which('wget')) {
            $self->chat("You have $wget\n");
            my @common = (
                '--user-agent', $self->agent,
                '--retry-connrefused',
                ($self->{verbose} ? () : ('-q')),
            );
            $self->{_backends}{get} = sub {
                my($self, $uri) = @_;
                $self->safeexec( my $fh, $wget, $uri, @common, '-O', '-' ) or die "wget $uri: $!";
                local $/;
                <$fh>;
            };
            $self->{_backends}{mirror} = sub {
                my($self, $uri, $path) = @_;
                $self->safeexec( my $fh, $wget, $uri, @common, '-O', $path ) or die "wget $uri: $!";
                local $/;
                <$fh>;
            };
        } elsif ($self->{try_curl} and my $curl = $self->which('curl')) {
            $self->chat("You have $curl\n");
            my @common = (
                '--location',
                '--user-agent', $self->agent,
                ($self->{verbose} ? () : '-s'),
            );
            $self->{_backends}{get} = sub {
                my($self, $uri) = @_;
                $self->safeexec( my $fh, $curl, @common, $uri ) or die "curl $uri: $!";
                local $/;
                <$fh>;
            };
            $self->{_backends}{mirror} = sub {
                my($self, $uri, $path) = @_;
                $self->safeexec( my $fh, $curl, @common, $uri, '-#', '-o', $path ) or die "curl $uri: $!";
                local $/;
                <$fh>;
            };
        } else {
            require HTTP::Tiny;
            $self->chat("Falling back to HTTP::Tiny $HTTP::Tiny::VERSION\n");
            my %common = (
                agent => $self->agent,
            );
            $self->{_backends}{get} = sub {
                my $self = shift;
                my $res = HTTP::Tiny->new(%common)->get($_[0]);
                return unless $res->{success};
                return $res->{content};
            };
            $self->{_backends}{mirror} = sub {
                my $self = shift;
                my $res = HTTP::Tiny->new(%common)->mirror(@_);
                return $res->{status};
            };
        }
    
        my $tar = $self->which('tar');
        my $tar_ver;
        my $maybe_bad_tar = sub { WIN32 || BAD_TAR || (($tar_ver = `$tar --version 2>/dev/null`) =~ /GNU.*1\.13/i) };
    
        if ($tar && !$maybe_bad_tar->()) {
            chomp $tar_ver;
            $self->chat("You have $tar: $tar_ver\n");
            $self->{_backends}{untar} = sub {
                my($self, $tarfile) = @_;
    
                my $xf = ($self->{verbose} ? 'v' : '')."xf";
                my $ar = $tarfile =~ /bz2$/ ? 'j' : 'z';
    
                my($root, @others) = `$tar ${ar}tf $tarfile`
                    or return undef;
    
                FILE: {
                    chomp $root;
                    $root =~ s!^\./!!;
                    $root =~ s{^(.+?)/.*$}{$1};
    
                    if (!length($root)) {
                        # archive had ./ as the first entry, so try again
                        $root = shift(@others);
                        redo FILE if $root;
                    }
                }
    
                system "$tar $ar$xf $tarfile";
                return $root if -d $root;
    
                $self->diag_fail("Bad archive: $tarfile");
                return undef;
            }
        } elsif (    $tar
                 and my $gzip = $self->which('gzip')
                 and my $bzip2 = $self->which('bzip2')) {
            $self->chat("You have $tar, $gzip and $bzip2\n");
            $self->{_backends}{untar} = sub {
                my($self, $tarfile) = @_;
    
                my $x  = "x" . ($self->{verbose} ? 'v' : '') . "f -";
                my $ar = $tarfile =~ /bz2$/ ? $bzip2 : $gzip;
    
                my($root, @others) = `$ar -dc $tarfile | $tar tf -`
                    or return undef;
    
                FILE: {
                    chomp $root;
                    $root =~ s!^\./!!;
                    $root =~ s{^(.+?)/.*$}{$1};
    
                    if (!length($root)) {
                        # archive had ./ as the first entry, so try again
                        $root = shift(@others);
                        redo FILE if $root;
                    }
                }
    
                system "$ar -dc $tarfile | $tar $x";
                return $root if -d $root;
    
                $self->diag_fail("Bad archive: $tarfile");
                return undef;
            }
        } elsif (eval { require Archive::Tar }) { # uses too much memory!
            $self->chat("Falling back to Archive::Tar $Archive::Tar::VERSION\n");
            $self->{_backends}{untar} = sub {
                my $self = shift;
                my $t = Archive::Tar->new($_[0]);
                my($root, @others) = $t->list_files;
                FILE: {
                    $root =~ s!^\./!!;
                    $root =~ s{^(.+?)/.*$}{$1};
    
                    if (!length($root)) {
                        # archive had ./ as the first entry, so try again
                        $root = shift(@others);
                        redo FILE if $root;
                    }
                }
                $t->extract;
                return -d $root ? $root : undef;
            };
        } else {
            $self->{_backends}{untar} = sub {
                die "Failed to extract $_[1] - You need to have tar or Archive::Tar installed.\n";
            };
        }
    
        if (my $unzip = $self->which('unzip')) {
            $self->chat("You have $unzip\n");
            $self->{_backends}{unzip} = sub {
                my($self, $zipfile) = @_;
    
                my $opt = $self->{verbose} ? '' : '-q';
                my(undef, $root, @others) = `$unzip -t $zipfile`
                    or return undef;
    
                chomp $root;
                $root =~ s{^\s+testing:\s+([^/]+)/.*?\s+OK$}{$1};
    
                system "$unzip $opt $zipfile";
                return $root if -d $root;
    
                $self->diag_fail("Bad archive: [$root] $zipfile");
                return undef;
            }
        } else {
            $self->{_backends}{unzip} = sub {
                eval { require Archive::Zip }
                    or  die "Failed to extract $_[1] - You need to have unzip or Archive::Zip installed.\n";
                my($self, $file) = @_;
                my $zip = Archive::Zip->new();
                my $status;
                $status = $zip->read($file);
                $self->diag_fail("Read of file[$file] failed")
                    if $status != Archive::Zip::AZ_OK();
                my @members = $zip->members();
                for my $member ( @members ) {
                    my $af = $member->fileName();
                    next if ($af =~ m!^(/|\.\./)!);
                    $status = $member->extractToFileNamed( $af );
                    $self->diag_fail("Extracting of file[$af] from zipfile[$file failed")
                        if $status != Archive::Zip::AZ_OK();
                }
    
                my ($root) = $zip->membersMatching( qr<^[^/]+/$> );
                $root &&= $root->fileName;
                return -d $root ? $root : undef;
            };
        }
    }
    
    sub safeexec {
        my $self = shift;
        my $rdr = $_[0] ||= Symbol::gensym();
    
        if (WIN32) {
            my $cmd = $self->shell_quote(@_[1..$#_]);
            return open( $rdr, "$cmd |" );
        }
    
        if ( my $pid = open( $rdr, '-|' ) ) {
            return $pid;
        }
        elsif ( defined $pid ) {
            exec( @_[ 1 .. $#_ ] );
            exit 1;
        }
        else {
            return;
        }
    }
    
    sub mask_uri_passwords {
        my($self, @strings) = @_;
        s{ (https?://) ([^:/]+) : [^@/]+ @ }{$1$2:********@}gx for @strings;
        return @strings;
    }
    
    1;
  APP_CPANMINUS_SCRIPT
  
  $fatpacked{"CPAN/DistnameInfo.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CPAN_DISTNAMEINFO';
    
    package CPAN::DistnameInfo;
    
    $VERSION = "0.12";
    use strict;
    
    sub distname_info {
      my $file = shift or return;
    
      my ($dist, $version) = $file =~ /^
        ((?:[-+.]*(?:[A-Za-z0-9]+|(?<=\D)_|_(?=\D))*
         (?:
    	[A-Za-z](?=[^A-Za-z]|$)
    	|
    	\d(?=-)
         )(?<![._-][vV])
        )+)(.*)
      $/xs or return ($file,undef,undef);
    
      if ($dist =~ /-undef\z/ and ! length $version) {
        $dist =~ s/-undef\z//;
      }
    
      # Remove potential -withoutworldwriteables suffix
      $version =~ s/-withoutworldwriteables$//;
    
      if ($version =~ /^(-[Vv].*)-(\d.*)/) {
       
        # Catch names like Unicode-Collate-Standard-V3_1_1-0.1
        # where the V3_1_1 is part of the distname
        $dist .= $1;
        $version = $2;
      }
    
      if ($version =~ /(.+_.*)-(\d.*)/) {
          # Catch names like Task-Deprecations5_14-1.00.tar.gz where the 5_14 is
          # part of the distname. However, names like libao-perl_0.03-1.tar.gz
          # should still have 0.03-1 as their version.
          $dist .= $1;
          $version = $2;
      }
    
      # Normalize the Dist.pm-1.23 convention which CGI.pm and
      # a few others use.
      $dist =~ s{\.pm$}{};
    
      $version = $1
        if !length $version and $dist =~ s/-(\d+\w)$//;
    
      $version = $1 . $version
        if $version =~ /^\d+$/ and $dist =~ s/-(\w+)$//;
    
      if ($version =~ /\d\.\d/) {
        $version =~ s/^[-_.]+//;
      }
      else {
        $version =~ s/^[-_]+//;
      }
    
      my $dev;
      if (length $version) {
        if ($file =~ /^perl-?\d+\.(\d+)(?:\D(\d+))?(-(?:TRIAL|RC)\d+)?$/) {
          $dev = 1 if (($1 > 6 and $1 & 1) or ($2 and $2 >= 50)) or $3;
        }
        elsif ($version =~ /\d\D\d+_\d/ or $version =~ /-TRIAL/) {
          $dev = 1;
        }
      }
      else {
        $version = undef;
      }
    
      ($dist, $version, $dev);
    }
    
    sub new {
      my $class = shift;
      my $distfile = shift;
    
      $distfile =~ s,//+,/,g;
    
      my %info = ( pathname => $distfile );
    
      ($info{filename} = $distfile) =~ s,^(((.*?/)?authors/)?id/)?([A-Z])/(\4[A-Z])/(\5[-A-Z0-9]*)/,,
        and $info{cpanid} = $6;
    
      if ($distfile =~ m,([^/]+)\.(tar\.(?:g?z|bz2)|zip|tgz)$,i) { # support more ?
        $info{distvname} = $1;
        $info{extension} = $2;
      }
    
      @info{qw(dist version beta)} = distname_info($info{distvname});
      $info{maturity} = delete $info{beta} ? 'developer' : 'released';
    
      return bless \%info, $class;
    }
    
    sub dist      { shift->{dist} }
    sub version   { shift->{version} }
    sub maturity  { shift->{maturity} }
    sub filename  { shift->{filename} }
    sub cpanid    { shift->{cpanid} }
    sub distvname { shift->{distvname} }
    sub extension { shift->{extension} }
    sub pathname  { shift->{pathname} }
    
    sub properties { %{ $_[0] } }
    
    1;
    
    __END__
    
    =head1 NAME
    
    CPAN::DistnameInfo - Extract distribution name and version from a distribution filename
    
    =head1 SYNOPSIS
    
      my $pathname = "authors/id/G/GB/GBARR/CPAN-DistnameInfo-0.02.tar.gz";
    
      my $d = CPAN::DistnameInfo->new($pathname);
    
      my $dist      = $d->dist;      # "CPAN-DistnameInfo"
      my $version   = $d->version;   # "0.02"
      my $maturity  = $d->maturity;  # "released"
      my $filename  = $d->filename;  # "CPAN-DistnameInfo-0.02.tar.gz"
      my $cpanid    = $d->cpanid;    # "GBARR"
      my $distvname = $d->distvname; # "CPAN-DistnameInfo-0.02"
      my $extension = $d->extension; # "tar.gz"
      my $pathname  = $d->pathname;  # "authors/id/G/GB/GBARR/..."
    
      my %prop = $d->properties;
    
    =head1 DESCRIPTION
    
    Many online services that are centered around CPAN attempt to
    associate multiple uploads by extracting a distribution name from
    the filename of the upload. For most distributions this is easy as
    they have used ExtUtils::MakeMaker or Module::Build to create the
    distribution, which results in a uniform name. But sadly not all
    uploads are created in this way.
    
    C<CPAN::DistnameInfo> uses heuristics that have been learnt by
    L<http://search.cpan.org/> to extract the distribution name and
    version from filenames and also report if the version is to be
    treated as a developer release
    
    The constructor takes a single pathname, returning an object with the following methods
    
    =over
    
    =item cpanid
    
    If the path given looked like a CPAN authors directory path, then this will be the
    the CPAN id of the author.
    
    =item dist
    
    The name of the distribution
    
    =item distvname
    
    The file name with any suffix and leading directory names removed
    
    =item filename
    
    If the path given looked like a CPAN authors directory path, then this will be the
    path to the file relative to the detected CPAN author directory. Otherwise it is the path
    that was passed in.
    
    =item maturity
    
    The maturity of the distribution. This will be either C<released> or C<developer>
    
    =item extension
    
    The extension of the distribution, often used to denote the archive type (e.g. 'tar.gz')
    
    =item pathname
    
    The pathname that was passed to the constructor when creating the object.
    
    =item properties
    
    This will return a list of key-value pairs, suitable for assigning to a hash,
    for the known properties.
    
    =item version
    
    The extracted version
    
    =back
    
    =head1 AUTHOR
    
    Graham Barr <gbarr@pobox.com>
    
    =head1 COPYRIGHT 
    
    Copyright (c) 2003 Graham Barr. All rights reserved. This program is
    free software; you can redistribute it and/or modify it under the same
    terms as Perl itself.
    
    =cut
    
  CPAN_DISTNAMEINFO
  
  $fatpacked{"CPAN/Meta.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CPAN_META';
    use 5.006;
    use strict;
    use warnings;
    package CPAN::Meta;
    # VERSION
    $CPAN::Meta::VERSION = '2.143240';
    #pod =head1 SYNOPSIS
    #pod
    #pod     use v5.10;
    #pod     use strict;
    #pod     use warnings;
    #pod     use CPAN::Meta;
    #pod     use Module::Load;
    #pod
    #pod     my $meta = CPAN::Meta->load_file('META.json');
    #pod
    #pod     printf "testing requirements for %s version %s\n",
    #pod     $meta->name,
    #pod     $meta->version;
    #pod
    #pod     my $prereqs = $meta->effective_prereqs;
    #pod
    #pod     for my $phase ( qw/configure runtime build test/ ) {
    #pod         say "Requirements for $phase:";
    #pod         my $reqs = $prereqs->requirements_for($phase, "requires");
    #pod         for my $module ( sort $reqs->required_modules ) {
    #pod             my $status;
    #pod             if ( eval { load $module unless $module eq 'perl'; 1 } ) {
    #pod                 my $version = $module eq 'perl' ? $] : $module->VERSION;
    #pod                 $status = $reqs->accepts_module($module, $version)
    #pod                         ? "$version ok" : "$version not ok";
    #pod             } else {
    #pod                 $status = "missing"
    #pod             };
    #pod             say "  $module ($status)";
    #pod         }
    #pod     }
    #pod
    #pod =head1 DESCRIPTION
    #pod
    #pod Software distributions released to the CPAN include a F<META.json> or, for
    #pod older distributions, F<META.yml>, which describes the distribution, its
    #pod contents, and the requirements for building and installing the distribution.
    #pod The data structure stored in the F<META.json> file is described in
    #pod L<CPAN::Meta::Spec>.
    #pod
    #pod CPAN::Meta provides a simple class to represent this distribution metadata (or
    #pod I<distmeta>), along with some helpful methods for interrogating that data.
    #pod
    #pod The documentation below is only for the methods of the CPAN::Meta object.  For
    #pod information on the meaning of individual fields, consult the spec.
    #pod
    #pod =cut
    
    use Carp qw(carp croak);
    use CPAN::Meta::Feature;
    use CPAN::Meta::Prereqs;
    use CPAN::Meta::Converter;
    use CPAN::Meta::Validator;
    use Parse::CPAN::Meta 1.4414 ();
    
    BEGIN { *_dclone = \&CPAN::Meta::Converter::_dclone }
    
    #pod =head1 STRING DATA
    #pod
    #pod The following methods return a single value, which is the value for the
    #pod corresponding entry in the distmeta structure.  Values should be either undef
    #pod or strings.
    #pod
    #pod =for :list
    #pod * abstract
    #pod * description
    #pod * dynamic_config
    #pod * generated_by
    #pod * name
    #pod * release_status
    #pod * version
    #pod
    #pod =cut
    
    BEGIN {
      my @STRING_READERS = qw(
        abstract
        description
        dynamic_config
        generated_by
        name
        release_status
        version
      );
    
      no strict 'refs';
      for my $attr (@STRING_READERS) {
        *$attr = sub { $_[0]{ $attr } };
      }
    }
    
    #pod =head1 LIST DATA
    #pod
    #pod These methods return lists of string values, which might be represented in the
    #pod distmeta structure as arrayrefs or scalars:
    #pod
    #pod =for :list
    #pod * authors
    #pod * keywords
    #pod * licenses
    #pod
    #pod The C<authors> and C<licenses> methods may also be called as C<author> and
    #pod C<license>, respectively, to match the field name in the distmeta structure.
    #pod
    #pod =cut
    
    BEGIN {
      my @LIST_READERS = qw(
        author
        keywords
        license
      );
    
      no strict 'refs';
      for my $attr (@LIST_READERS) {
        *$attr = sub {
          my $value = $_[0]{ $attr };
          croak "$attr must be called in list context"
            unless wantarray;
          return @{ _dclone($value) } if ref $value;
          return $value;
        };
      }
    }
    
    sub authors  { $_[0]->author }
    sub licenses { $_[0]->license }
    
    #pod =head1 MAP DATA
    #pod
    #pod These readers return hashrefs of arbitrary unblessed data structures, each
    #pod described more fully in the specification:
    #pod
    #pod =for :list
    #pod * meta_spec
    #pod * resources
    #pod * provides
    #pod * no_index
    #pod * prereqs
    #pod * optional_features
    #pod
    #pod =cut
    
    BEGIN {
      my @MAP_READERS = qw(
        meta-spec
        resources
        provides
        no_index
    
        prereqs
        optional_features
      );
    
      no strict 'refs';
      for my $attr (@MAP_READERS) {
        (my $subname = $attr) =~ s/-/_/;
        *$subname = sub {
          my $value = $_[0]{ $attr };
          return _dclone($value) if $value;
          return {};
        };
      }
    }
    
    #pod =head1 CUSTOM DATA
    #pod
    #pod A list of custom keys are available from the C<custom_keys> method and
    #pod particular keys may be retrieved with the C<custom> method.
    #pod
    #pod   say $meta->custom($_) for $meta->custom_keys;
    #pod
    #pod If a custom key refers to a data structure, a deep clone is returned.
    #pod
    #pod =cut
    
    sub custom_keys {
      return grep { /^x_/i } keys %{$_[0]};
    }
    
    sub custom {
      my ($self, $attr) = @_;
      my $value = $self->{$attr};
      return _dclone($value) if ref $value;
      return $value;
    }
    
    #pod =method new
    #pod
    #pod   my $meta = CPAN::Meta->new($distmeta_struct, \%options);
    #pod
    #pod Returns a valid CPAN::Meta object or dies if the supplied metadata hash
    #pod reference fails to validate.  Older-format metadata will be up-converted to
    #pod version 2 if they validate against the original stated specification.
    #pod
    #pod It takes an optional hashref of options. Valid options include:
    #pod
    #pod =over
    #pod
    #pod =item *
    #pod
    #pod lazy_validation -- if true, new will attempt to convert the given metadata
    #pod to version 2 before attempting to validate it.  This means than any
    #pod fixable errors will be handled by CPAN::Meta::Converter before validation.
    #pod (Note that this might result in invalid optional data being silently
    #pod dropped.)  The default is false.
    #pod
    #pod =back
    #pod
    #pod =cut
    
    sub _new {
      my ($class, $struct, $options) = @_;
      my $self;
    
      if ( $options->{lazy_validation} ) {
        # try to convert to a valid structure; if succeeds, then return it
        my $cmc = CPAN::Meta::Converter->new( $struct );
        $self = $cmc->convert( version => 2 ); # valid or dies
        return bless $self, $class;
      }
      else {
        # validate original struct
        my $cmv = CPAN::Meta::Validator->new( $struct );
        unless ( $cmv->is_valid) {
          die "Invalid metadata structure. Errors: "
            . join(", ", $cmv->errors) . "\n";
        }
      }
    
      # up-convert older spec versions
      my $version = $struct->{'meta-spec'}{version} || '1.0';
      if ( $version == 2 ) {
        $self = $struct;
      }
      else {
        my $cmc = CPAN::Meta::Converter->new( $struct );
        $self = $cmc->convert( version => 2 );
      }
    
      return bless $self, $class;
    }
    
    sub new {
      my ($class, $struct, $options) = @_;
      my $self = eval { $class->_new($struct, $options) };
      croak($@) if $@;
      return $self;
    }
    
    #pod =method create
    #pod
    #pod   my $meta = CPAN::Meta->create($distmeta_struct, \%options);
    #pod
    #pod This is same as C<new()>, except that C<generated_by> and C<meta-spec> fields
    #pod will be generated if not provided.  This means the metadata structure is
    #pod assumed to otherwise follow the latest L<CPAN::Meta::Spec>.
    #pod
    #pod =cut
    
    sub create {
      my ($class, $struct, $options) = @_;
      my $version = __PACKAGE__->VERSION || 2;
      $struct->{generated_by} ||= __PACKAGE__ . " version $version" ;
      $struct->{'meta-spec'}{version} ||= int($version);
      my $self = eval { $class->_new($struct, $options) };
      croak ($@) if $@;
      return $self;
    }
    
    #pod =method load_file
    #pod
    #pod   my $meta = CPAN::Meta->load_file($distmeta_file, \%options);
    #pod
    #pod Given a pathname to a file containing metadata, this deserializes the file
    #pod according to its file suffix and constructs a new C<CPAN::Meta> object, just
    #pod like C<new()>.  It will die if the deserialized version fails to validate
    #pod against its stated specification version.
    #pod
    #pod It takes the same options as C<new()> but C<lazy_validation> defaults to
    #pod true.
    #pod
    #pod =cut
    
    sub load_file {
      my ($class, $file, $options) = @_;
      $options->{lazy_validation} = 1 unless exists $options->{lazy_validation};
    
      croak "load_file() requires a valid, readable filename"
        unless -r $file;
    
      my $self;
      eval {
        my $struct = Parse::CPAN::Meta->load_file( $file );
        $self = $class->_new($struct, $options);
      };
      croak($@) if $@;
      return $self;
    }
    
    #pod =method load_yaml_string
    #pod
    #pod   my $meta = CPAN::Meta->load_yaml_string($yaml, \%options);
    #pod
    #pod This method returns a new CPAN::Meta object using the first document in the
    #pod given YAML string.  In other respects it is identical to C<load_file()>.
    #pod
    #pod =cut
    
    sub load_yaml_string {
      my ($class, $yaml, $options) = @_;
      $options->{lazy_validation} = 1 unless exists $options->{lazy_validation};
    
      my $self;
      eval {
        my ($struct) = Parse::CPAN::Meta->load_yaml_string( $yaml );
        $self = $class->_new($struct, $options);
      };
      croak($@) if $@;
      return $self;
    }
    
    #pod =method load_json_string
    #pod
    #pod   my $meta = CPAN::Meta->load_json_string($json, \%options);
    #pod
    #pod This method returns a new CPAN::Meta object using the structure represented by
    #pod the given JSON string.  In other respects it is identical to C<load_file()>.
    #pod
    #pod =cut
    
    sub load_json_string {
      my ($class, $json, $options) = @_;
      $options->{lazy_validation} = 1 unless exists $options->{lazy_validation};
    
      my $self;
      eval {
        my $struct = Parse::CPAN::Meta->load_json_string( $json );
        $self = $class->_new($struct, $options);
      };
      croak($@) if $@;
      return $self;
    }
    
    #pod =method load_string
    #pod
    #pod   my $meta = CPAN::Meta->load_string($string, \%options);
    #pod
    #pod If you don't know if a string contains YAML or JSON, this method will use
    #pod L<Parse::CPAN::Meta> to guess.  In other respects it is identical to
    #pod C<load_file()>.
    #pod
    #pod =cut
    
    sub load_string {
      my ($class, $string, $options) = @_;
      $options->{lazy_validation} = 1 unless exists $options->{lazy_validation};
    
      my $self;
      eval {
        my $struct = Parse::CPAN::Meta->load_string( $string );
        $self = $class->_new($struct, $options);
      };
      croak($@) if $@;
      return $self;
    }
    
    #pod =method save
    #pod
    #pod   $meta->save($distmeta_file, \%options);
    #pod
    #pod Serializes the object as JSON and writes it to the given file.  The only valid
    #pod option is C<version>, which defaults to '2'. On Perl 5.8.1 or later, the file
    #pod is saved with UTF-8 encoding.
    #pod
    #pod For C<version> 2 (or higher), the filename should end in '.json'.  L<JSON::PP>
    #pod is the default JSON backend. Using another JSON backend requires L<JSON> 2.5 or
    #pod later and you must set the C<$ENV{PERL_JSON_BACKEND}> to a supported alternate
    #pod backend like L<JSON::XS>.
    #pod
    #pod For C<version> less than 2, the filename should end in '.yml'.
    #pod L<CPAN::Meta::Converter> is used to generate an older metadata structure, which
    #pod is serialized to YAML.  CPAN::Meta::YAML is the default YAML backend.  You may
    #pod set the C<$ENV{PERL_YAML_BACKEND}> to a supported alternative backend, though
    #pod this is not recommended due to subtle incompatibilities between YAML parsers on
    #pod CPAN.
    #pod
    #pod =cut
    
    sub save {
      my ($self, $file, $options) = @_;
    
      my $version = $options->{version} || '2';
      my $layer = $] ge '5.008001' ? ':utf8' : '';
    
      if ( $version ge '2' ) {
        carp "'$file' should end in '.json'"
          unless $file =~ m{\.json$};
      }
      else {
        carp "'$file' should end in '.yml'"
          unless $file =~ m{\.yml$};
      }
    
      my $data = $self->as_string( $options );
      open my $fh, ">$layer", $file
        or die "Error opening '$file' for writing: $!\n";
    
      print {$fh} $data;
      close $fh
        or die "Error closing '$file': $!\n";
    
      return 1;
    }
    
    #pod =method meta_spec_version
    #pod
    #pod This method returns the version part of the C<meta_spec> entry in the distmeta
    #pod structure.  It is equivalent to:
    #pod
    #pod   $meta->meta_spec->{version};
    #pod
    #pod =cut
    
    sub meta_spec_version {
      my ($self) = @_;
      return $self->meta_spec->{version};
    }
    
    #pod =method effective_prereqs
    #pod
    #pod   my $prereqs = $meta->effective_prereqs;
    #pod
    #pod   my $prereqs = $meta->effective_prereqs( \@feature_identifiers );
    #pod
    #pod This method returns a L<CPAN::Meta::Prereqs> object describing all the
    #pod prereqs for the distribution.  If an arrayref of feature identifiers is given,
    #pod the prereqs for the identified features are merged together with the
    #pod distribution's core prereqs before the CPAN::Meta::Prereqs object is returned.
    #pod
    #pod =cut
    
    sub effective_prereqs {
      my ($self, $features) = @_;
      $features ||= [];
    
      my $prereq = CPAN::Meta::Prereqs->new($self->prereqs);
    
      return $prereq unless @$features;
    
      my @other = map {; $self->feature($_)->prereqs } @$features;
    
      return $prereq->with_merged_prereqs(\@other);
    }
    
    #pod =method should_index_file
    #pod
    #pod   ... if $meta->should_index_file( $filename );
    #pod
    #pod This method returns true if the given file should be indexed.  It decides this
    #pod by checking the C<file> and C<directory> keys in the C<no_index> property of
    #pod the distmeta structure. Note that neither the version format nor
    #pod C<release_status> are considered.
    #pod
    #pod C<$filename> should be given in unix format.
    #pod
    #pod =cut
    
    sub should_index_file {
      my ($self, $filename) = @_;
    
      for my $no_index_file (@{ $self->no_index->{file} || [] }) {
        return if $filename eq $no_index_file;
      }
    
      for my $no_index_dir (@{ $self->no_index->{directory} }) {
        $no_index_dir =~ s{$}{/} unless $no_index_dir =~ m{/\z};
        return if index($filename, $no_index_dir) == 0;
      }
    
      return 1;
    }
    
    #pod =method should_index_package
    #pod
    #pod   ... if $meta->should_index_package( $package );
    #pod
    #pod This method returns true if the given package should be indexed.  It decides
    #pod this by checking the C<package> and C<namespace> keys in the C<no_index>
    #pod property of the distmeta structure. Note that neither the version format nor
    #pod C<release_status> are considered.
    #pod
    #pod =cut
    
    sub should_index_package {
      my ($self, $package) = @_;
    
      for my $no_index_pkg (@{ $self->no_index->{package} || [] }) {
        return if $package eq $no_index_pkg;
      }
    
      for my $no_index_ns (@{ $self->no_index->{namespace} }) {
        return if index($package, "${no_index_ns}::") == 0;
      }
    
      return 1;
    }
    
    #pod =method features
    #pod
    #pod   my @feature_objects = $meta->features;
    #pod
    #pod This method returns a list of L<CPAN::Meta::Feature> objects, one for each
    #pod optional feature described by the distribution's metadata.
    #pod
    #pod =cut
    
    sub features {
      my ($self) = @_;
    
      my $opt_f = $self->optional_features;
      my @features = map {; CPAN::Meta::Feature->new($_ => $opt_f->{ $_ }) }
                     keys %$opt_f;
    
      return @features;
    }
    
    #pod =method feature
    #pod
    #pod   my $feature_object = $meta->feature( $identifier );
    #pod
    #pod This method returns a L<CPAN::Meta::Feature> object for the optional feature
    #pod with the given identifier.  If no feature with that identifier exists, an
    #pod exception will be raised.
    #pod
    #pod =cut
    
    sub feature {
      my ($self, $ident) = @_;
    
      croak "no feature named $ident"
        unless my $f = $self->optional_features->{ $ident };
    
      return CPAN::Meta::Feature->new($ident, $f);
    }
    
    #pod =method as_struct
    #pod
    #pod   my $copy = $meta->as_struct( \%options );
    #pod
    #pod This method returns a deep copy of the object's metadata as an unblessed hash
    #pod reference.  It takes an optional hashref of options.  If the hashref contains
    #pod a C<version> argument, the copied metadata will be converted to the version
    #pod of the specification and returned.  For example:
    #pod
    #pod   my $old_spec = $meta->as_struct( {version => "1.4"} );
    #pod
    #pod =cut
    
    sub as_struct {
      my ($self, $options) = @_;
      my $struct = _dclone($self);
      if ( $options->{version} ) {
        my $cmc = CPAN::Meta::Converter->new( $struct );
        $struct = $cmc->convert( version => $options->{version} );
      }
      return $struct;
    }
    
    #pod =method as_string
    #pod
    #pod   my $string = $meta->as_string( \%options );
    #pod
    #pod This method returns a serialized copy of the object's metadata as a character
    #pod string.  (The strings are B<not> UTF-8 encoded.)  It takes an optional hashref
    #pod of options.  If the hashref contains a C<version> argument, the copied metadata
    #pod will be converted to the version of the specification and returned.  For
    #pod example:
    #pod
    #pod   my $string = $meta->as_string( {version => "1.4"} );
    #pod
    #pod For C<version> greater than or equal to 2, the string will be serialized as
    #pod JSON.  For C<version> less than 2, the string will be serialized as YAML.  In
    #pod both cases, the same rules are followed as in the C<save()> method for choosing
    #pod a serialization backend.
    #pod
    #pod =cut
    
    sub as_string {
      my ($self, $options) = @_;
    
      my $version = $options->{version} || '2';
    
      my $struct;
      if ( $self->meta_spec_version ne $version ) {
        my $cmc = CPAN::Meta::Converter->new( $self->as_struct );
        $struct = $cmc->convert( version => $version );
      }
      else {
        $struct = $self->as_struct;
      }
    
      my ($data, $backend);
      if ( $version ge '2' ) {
        $backend = Parse::CPAN::Meta->json_backend();
        $data = $backend->new->pretty->canonical->encode($struct);
      }
      else {
        $backend = Parse::CPAN::Meta->yaml_backend();
        $data = eval { no strict 'refs'; &{"$backend\::Dump"}($struct) };
        if ( $@ ) {
          croak $backend->can('errstr') ? $backend->errstr : $@
        }
      }
    
      return $data;
    }
    
    # Used by JSON::PP, etc. for "convert_blessed"
    sub TO_JSON {
      return { %{ $_[0] } };
    }
    
    1;
    
    # ABSTRACT: the distribution metadata for a CPAN dist
    
    __END__
    
    =pod
    
    =encoding UTF-8
    
    =head1 NAME
    
    CPAN::Meta - the distribution metadata for a CPAN dist
    
    =head1 VERSION
    
    version 2.143240
    
    =head1 SYNOPSIS
    
        use v5.10;
        use strict;
        use warnings;
        use CPAN::Meta;
        use Module::Load;
    
        my $meta = CPAN::Meta->load_file('META.json');
    
        printf "testing requirements for %s version %s\n",
        $meta->name,
        $meta->version;
    
        my $prereqs = $meta->effective_prereqs;
    
        for my $phase ( qw/configure runtime build test/ ) {
            say "Requirements for $phase:";
            my $reqs = $prereqs->requirements_for($phase, "requires");
            for my $module ( sort $reqs->required_modules ) {
                my $status;
                if ( eval { load $module unless $module eq 'perl'; 1 } ) {
                    my $version = $module eq 'perl' ? $] : $module->VERSION;
                    $status = $reqs->accepts_module($module, $version)
                            ? "$version ok" : "$version not ok";
                } else {
                    $status = "missing"
                };
                say "  $module ($status)";
            }
        }
    
    =head1 DESCRIPTION
    
    Software distributions released to the CPAN include a F<META.json> or, for
    older distributions, F<META.yml>, which describes the distribution, its
    contents, and the requirements for building and installing the distribution.
    The data structure stored in the F<META.json> file is described in
    L<CPAN::Meta::Spec>.
    
    CPAN::Meta provides a simple class to represent this distribution metadata (or
    I<distmeta>), along with some helpful methods for interrogating that data.
    
    The documentation below is only for the methods of the CPAN::Meta object.  For
    information on the meaning of individual fields, consult the spec.
    
    =head1 METHODS
    
    =head2 new
    
      my $meta = CPAN::Meta->new($distmeta_struct, \%options);
    
    Returns a valid CPAN::Meta object or dies if the supplied metadata hash
    reference fails to validate.  Older-format metadata will be up-converted to
    version 2 if they validate against the original stated specification.
    
    It takes an optional hashref of options. Valid options include:
    
    =over
    
    =item *
    
    lazy_validation -- if true, new will attempt to convert the given metadata
    to version 2 before attempting to validate it.  This means than any
    fixable errors will be handled by CPAN::Meta::Converter before validation.
    (Note that this might result in invalid optional data being silently
    dropped.)  The default is false.
    
    =back
    
    =head2 create
    
      my $meta = CPAN::Meta->create($distmeta_struct, \%options);
    
    This is same as C<new()>, except that C<generated_by> and C<meta-spec> fields
    will be generated if not provided.  This means the metadata structure is
    assumed to otherwise follow the latest L<CPAN::Meta::Spec>.
    
    =head2 load_file
    
      my $meta = CPAN::Meta->load_file($distmeta_file, \%options);
    
    Given a pathname to a file containing metadata, this deserializes the file
    according to its file suffix and constructs a new C<CPAN::Meta> object, just
    like C<new()>.  It will die if the deserialized version fails to validate
    against its stated specification version.
    
    It takes the same options as C<new()> but C<lazy_validation> defaults to
    true.
    
    =head2 load_yaml_string
    
      my $meta = CPAN::Meta->load_yaml_string($yaml, \%options);
    
    This method returns a new CPAN::Meta object using the first document in the
    given YAML string.  In other respects it is identical to C<load_file()>.
    
    =head2 load_json_string
    
      my $meta = CPAN::Meta->load_json_string($json, \%options);
    
    This method returns a new CPAN::Meta object using the structure represented by
    the given JSON string.  In other respects it is identical to C<load_file()>.
    
    =head2 load_string
    
      my $meta = CPAN::Meta->load_string($string, \%options);
    
    If you don't know if a string contains YAML or JSON, this method will use
    L<Parse::CPAN::Meta> to guess.  In other respects it is identical to
    C<load_file()>.
    
    =head2 save
    
      $meta->save($distmeta_file, \%options);
    
    Serializes the object as JSON and writes it to the given file.  The only valid
    option is C<version>, which defaults to '2'. On Perl 5.8.1 or later, the file
    is saved with UTF-8 encoding.
    
    For C<version> 2 (or higher), the filename should end in '.json'.  L<JSON::PP>
    is the default JSON backend. Using another JSON backend requires L<JSON> 2.5 or
    later and you must set the C<$ENV{PERL_JSON_BACKEND}> to a supported alternate
    backend like L<JSON::XS>.
    
    For C<version> less than 2, the filename should end in '.yml'.
    L<CPAN::Meta::Converter> is used to generate an older metadata structure, which
    is serialized to YAML.  CPAN::Meta::YAML is the default YAML backend.  You may
    set the C<$ENV{PERL_YAML_BACKEND}> to a supported alternative backend, though
    this is not recommended due to subtle incompatibilities between YAML parsers on
    CPAN.
    
    =head2 meta_spec_version
    
    This method returns the version part of the C<meta_spec> entry in the distmeta
    structure.  It is equivalent to:
    
      $meta->meta_spec->{version};
    
    =head2 effective_prereqs
    
      my $prereqs = $meta->effective_prereqs;
    
      my $prereqs = $meta->effective_prereqs( \@feature_identifiers );
    
    This method returns a L<CPAN::Meta::Prereqs> object describing all the
    prereqs for the distribution.  If an arrayref of feature identifiers is given,
    the prereqs for the identified features are merged together with the
    distribution's core prereqs before the CPAN::Meta::Prereqs object is returned.
    
    =head2 should_index_file
    
      ... if $meta->should_index_file( $filename );
    
    This method returns true if the given file should be indexed.  It decides this
    by checking the C<file> and C<directory> keys in the C<no_index> property of
    the distmeta structure. Note that neither the version format nor
    C<release_status> are considered.
    
    C<$filename> should be given in unix format.
    
    =head2 should_index_package
    
      ... if $meta->should_index_package( $package );
    
    This method returns true if the given package should be indexed.  It decides
    this by checking the C<package> and C<namespace> keys in the C<no_index>
    property of the distmeta structure. Note that neither the version format nor
    C<release_status> are considered.
    
    =head2 features
    
      my @feature_objects = $meta->features;
    
    This method returns a list of L<CPAN::Meta::Feature> objects, one for each
    optional feature described by the distribution's metadata.
    
    =head2 feature
    
      my $feature_object = $meta->feature( $identifier );
    
    This method returns a L<CPAN::Meta::Feature> object for the optional feature
    with the given identifier.  If no feature with that identifier exists, an
    exception will be raised.
    
    =head2 as_struct
    
      my $copy = $meta->as_struct( \%options );
    
    This method returns a deep copy of the object's metadata as an unblessed hash
    reference.  It takes an optional hashref of options.  If the hashref contains
    a C<version> argument, the copied metadata will be converted to the version
    of the specification and returned.  For example:
    
      my $old_spec = $meta->as_struct( {version => "1.4"} );
    
    =head2 as_string
    
      my $string = $meta->as_string( \%options );
    
    This method returns a serialized copy of the object's metadata as a character
    string.  (The strings are B<not> UTF-8 encoded.)  It takes an optional hashref
    of options.  If the hashref contains a C<version> argument, the copied metadata
    will be converted to the version of the specification and returned.  For
    example:
    
      my $string = $meta->as_string( {version => "1.4"} );
    
    For C<version> greater than or equal to 2, the string will be serialized as
    JSON.  For C<version> less than 2, the string will be serialized as YAML.  In
    both cases, the same rules are followed as in the C<save()> method for choosing
    a serialization backend.
    
    =head1 STRING DATA
    
    The following methods return a single value, which is the value for the
    corresponding entry in the distmeta structure.  Values should be either undef
    or strings.
    
    =over 4
    
    =item *
    
    abstract
    
    =item *
    
    description
    
    =item *
    
    dynamic_config
    
    =item *
    
    generated_by
    
    =item *
    
    name
    
    =item *
    
    release_status
    
    =item *
    
    version
    
    =back
    
    =head1 LIST DATA
    
    These methods return lists of string values, which might be represented in the
    distmeta structure as arrayrefs or scalars:
    
    =over 4
    
    =item *
    
    authors
    
    =item *
    
    keywords
    
    =item *
    
    licenses
    
    =back
    
    The C<authors> and C<licenses> methods may also be called as C<author> and
    C<license>, respectively, to match the field name in the distmeta structure.
    
    =head1 MAP DATA
    
    These readers return hashrefs of arbitrary unblessed data structures, each
    described more fully in the specification:
    
    =over 4
    
    =item *
    
    meta_spec
    
    =item *
    
    resources
    
    =item *
    
    provides
    
    =item *
    
    no_index
    
    =item *
    
    prereqs
    
    =item *
    
    optional_features
    
    =back
    
    =head1 CUSTOM DATA
    
    A list of custom keys are available from the C<custom_keys> method and
    particular keys may be retrieved with the C<custom> method.
    
      say $meta->custom($_) for $meta->custom_keys;
    
    If a custom key refers to a data structure, a deep clone is returned.
    
    =for Pod::Coverage TO_JSON abstract author authors custom custom_keys description dynamic_config
    generated_by keywords license licenses meta_spec name no_index
    optional_features prereqs provides release_status resources version
    
    =head1 BUGS
    
    Please report any bugs or feature using the CPAN Request Tracker.
    Bugs can be submitted through the web interface at
    L<http://rt.cpan.org/Dist/Display.html?Queue=CPAN-Meta>
    
    When submitting a bug or request, please include a test-file or a patch to an
    existing test-file that illustrates the bug or desired feature.
    
    =head1 SEE ALSO
    
    =over 4
    
    =item *
    
    L<CPAN::Meta::Converter>
    
    =item *
    
    L<CPAN::Meta::Validator>
    
    =back
    
    =for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan
    
    =head1 SUPPORT
    
    =head2 Bugs / Feature Requests
    
    Please report any bugs or feature requests through the issue tracker
    at L<https://github.com/Perl-Toolchain-Gang/CPAN-Meta/issues>.
    You will be notified automatically of any progress on your issue.
    
    =head2 Source Code
    
    This is open source software.  The code repository is available for
    public review and contribution under the terms of the license.
    
    L<https://github.com/Perl-Toolchain-Gang/CPAN-Meta>
    
      git clone https://github.com/Perl-Toolchain-Gang/CPAN-Meta.git
    
    =head1 AUTHORS
    
    =over 4
    
    =item *
    
    David Golden <dagolden@cpan.org>
    
    =item *
    
    Ricardo Signes <rjbs@cpan.org>
    
    =back
    
    =head1 CONTRIBUTORS
    
    =for stopwords Ansgar Burchardt Avar Arnfjord Bjarmason Christopher J. Madsen Chuck Adams Cory G Watson Damyan Ivanov Eric Wilhelm Graham Knop Gregor Hermann Karen Etheridge Kenichi Ishigaki Ken Williams Lars Dieckow Leon Timmermans majensen Mark Fowler Matt S Trout Michael G. Schwern moznion Olaf Alders Olivier Mengue Randy Sims
    
    =over 4
    
    =item *
    
    Ansgar Burchardt <ansgar@cpan.org>
    
    =item *
    
    Avar Arnfjord Bjarmason <avar@cpan.org>
    
    =item *
    
    Christopher J. Madsen <cjm@cpan.org>
    
    =item *
    
    Chuck Adams <cja987@gmail.com>
    
    =item *
    
    Cory G Watson <gphat@cpan.org>
    
    =item *
    
    Damyan Ivanov <dam@cpan.org>
    
    =item *
    
    Eric Wilhelm <ewilhelm@cpan.org>
    
    =item *
    
    Graham Knop <haarg@haarg.org>
    
    =item *
    
    Gregor Hermann <gregoa@debian.org>
    
    =item *
    
    Karen Etheridge <ether@cpan.org>
    
    =item *
    
    Kenichi Ishigaki <ishigaki@cpan.org>
    
    =item *
    
    Ken Williams <kwilliams@cpan.org>
    
    =item *
    
    Lars Dieckow <daxim@cpan.org>
    
    =item *
    
    Leon Timmermans <leont@cpan.org>
    
    =item *
    
    majensen <maj@fortinbras.us>
    
    =item *
    
    Mark Fowler <markf@cpan.org>
    
    =item *
    
    Matt S Trout <mst@shadowcat.co.uk>
    
    =item *
    
    Michael G. Schwern <mschwern@cpan.org>
    
    =item *
    
    moznion <moznion@gmail.com>
    
    =item *
    
    Olaf Alders <olaf@wundersolutions.com>
    
    =item *
    
    Olivier Mengue <dolmen@cpan.org>
    
    =item *
    
    Randy Sims <randys@thepierianspring.org>
    
    =back
    
    =head1 COPYRIGHT AND LICENSE
    
    This software is copyright (c) 2010 by David Golden and Ricardo Signes.
    
    This is free software; you can redistribute it and/or modify it under
    the same terms as the Perl 5 programming language system itself.
    
    =cut
  CPAN_META
  
  $fatpacked{"CPAN/Meta/Check.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CPAN_META_CHECK';
    package CPAN::Meta::Check;
    $CPAN::Meta::Check::VERSION = '0.010';
    use strict;
    use warnings;
    
    use Exporter 5.57 'import';
    our @EXPORT = qw//;
    our @EXPORT_OK = qw/check_requirements requirements_for verify_dependencies/;
    our %EXPORT_TAGS = (all => [ @EXPORT, @EXPORT_OK ] );
    
    use CPAN::Meta::Requirements 2.121;
    use Module::Metadata 1.000023;
    
    sub _check_dep {
    	my ($reqs, $module, $dirs) = @_;
    
    	$module eq 'perl' and return ($reqs->accepts_module($module, $]) ? () : sprintf "Your Perl (%s) is not in the range '%s'", $], $reqs->requirements_for_module($module));
    
    	my $metadata = Module::Metadata->new_from_module($module, inc => $dirs);
    	return "Module '$module' is not installed" if not defined $metadata;
    	my $version = eval { $metadata->version };
    	return "Missing version info for module '$module'" if $reqs->requirements_for_module($module) and not $version;
    	return sprintf 'Installed version (%s) of %s is not in range \'%s\'', $version, $module, $reqs->requirements_for_module($module) if not $reqs->accepts_module($module, $version || 0);
    	return;
    }
    
    sub _check_conflict {
    	my ($reqs, $module, $dirs) = @_;
    	my $metadata = Module::Metadata->new_from_module($module, inc => $dirs);
    	return if not defined $metadata;
    	my $version = eval { $metadata->version };
    	return "Missing version info for module '$module'" if not $version;
    	return sprintf 'Installed version (%s) of %s is in range \'%s\'', $version, $module, $reqs->requirements_for_module($module) if $reqs->accepts_module($module, $version);
    	return;
    }
    
    sub requirements_for {
    	my ($meta, $phases, $type) = @_;
    	my $prereqs = ref($meta) eq 'CPAN::Meta' ? $meta->effective_prereqs : $meta;
    	return $prereqs->merged_requirements(ref($phases) ? $phases : [ $phases ], [ $type ]);
    }
    
    sub check_requirements {
    	my ($reqs, $type, $dirs) = @_;
    
    	return +{
    		map {
    			$_ => $type ne 'conflicts'
    				? scalar _check_dep($reqs, $_, $dirs)
    				: scalar _check_conflict($reqs, $_, $dirs)
    		} $reqs->required_modules
    	};
    }
    
    sub verify_dependencies {
    	my ($meta, $phases, $type, $dirs) = @_;
    	my $reqs = requirements_for($meta, $phases, $type);
    	my $issues = check_requirements($reqs, $type, $dirs);
    	return grep { defined } values %{ $issues };
    }
    
    1;
    
    #ABSTRACT: Verify requirements in a CPAN::Meta object
    
    __END__
    
    =pod
    
    =encoding UTF-8
    
    =head1 NAME
    
    CPAN::Meta::Check - Verify requirements in a CPAN::Meta object
    
    =head1 VERSION
    
    version 0.010
    
    =head1 SYNOPSIS
    
     warn "$_\n" for verify_dependencies($meta, [qw/runtime build test/], 'requires');
    
    =head1 DESCRIPTION
    
    This module verifies if requirements described in a CPAN::Meta object are present.
    
    =head1 FUNCTIONS
    
    =head2 check_requirements($reqs, $type, $incdirs)
    
    This function checks if all dependencies in C<$reqs> (a L<CPAN::Meta::Requirements|CPAN::Meta::Requirements> object) are met, taking into account that 'conflicts' dependencies have to be checked in reverse. It returns a hash with the modules as keys and any problems as values; the value for a successfully found module will be undef. Modules are searched for in C<@$incdirs>, defaulting to C<@INC>.
    
    =head2 verify_dependencies($meta, $phases, $types, $incdirs)
    
    Check all requirements in C<$meta> for phases C<$phases> and type C<$type>. Modules are searched for in C<@$incdirs>, defaulting to C<@INC>. C<$meta> should be a L<CPAN::Meta::Prereqs> or L<CPAN::Meta> object.
    
    =head2 requirements_for($meta, $phases, $types)
    
    B<< This function is deprecated and may be removed at some point in the future, please use CPAN::Meta::Prereqs->merged_requirements instead. >>
    
    This function returns a unified L<CPAN::Meta::Requirements|CPAN::Meta::Requirements> object for all C<$type> requirements for C<$phases>. C<$phases> may be either one (scalar) value or an arrayref of valid values as defined by the L<CPAN::Meta spec|CPAN::Meta::Spec>. C<$type> must be a relationship as defined by the same spec. C<$meta> should be a L<CPAN::Meta::Prereqs> or L<CPAN::Meta> object.
    
    =head1 SEE ALSO
    
    =over 4
    
    =item * L<Test::CheckDeps|Test::CheckDeps>
    
    =item * L<CPAN::Meta|CPAN::Meta>
    
    =for comment # vi:noet:sts=2:sw=2:ts=2
    
    =back
    
    =head1 AUTHOR
    
    Leon Timmermans <leont@cpan.org>
    
    =head1 COPYRIGHT AND LICENSE
    
    This software is copyright (c) 2012 by Leon Timmermans.
    
    This is free software; you can redistribute it and/or modify it under
    the same terms as the Perl 5 programming language system itself.
    
    =cut
  CPAN_META_CHECK
  
  $fatpacked{"CPAN/Meta/Converter.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CPAN_META_CONVERTER';
    use 5.006;
    use strict;
    use warnings;
    package CPAN::Meta::Converter;
    # VERSION
    $CPAN::Meta::Converter::VERSION = '2.143240';
    #pod =head1 SYNOPSIS
    #pod
    #pod   my $struct = decode_json_file('META.json');
    #pod
    #pod   my $cmc = CPAN::Meta::Converter->new( $struct );
    #pod
    #pod   my $new_struct = $cmc->convert( version => "2" );
    #pod
    #pod =head1 DESCRIPTION
    #pod
    #pod This module converts CPAN Meta structures from one form to another.  The
    #pod primary use is to convert older structures to the most modern version of
    #pod the specification, but other transformations may be implemented in the
    #pod future as needed.  (E.g. stripping all custom fields or stripping all
    #pod optional fields.)
    #pod
    #pod =cut
    
    use CPAN::Meta::Validator;
    use CPAN::Meta::Requirements;
    use Parse::CPAN::Meta 1.4400 ();
    
    # To help ExtUtils::MakeMaker bootstrap CPAN::Meta::Requirements on perls
    # before 5.10, we fall back to the EUMM bundled compatibility version module if
    # that's the only thing available.  This shouldn't ever happen in a normal CPAN
    # install of CPAN::Meta::Requirements, as version.pm will be picked up from
    # prereqs and be available at runtime.
    
    BEGIN {
      eval "use version ()"; ## no critic
      if ( my $err = $@ ) {
        eval "use ExtUtils::MakeMaker::version" or die $err; ## no critic
      }
    }
    
    # Perl 5.10.0 didn't have "is_qv" in version.pm
    *_is_qv = version->can('is_qv') ? sub { $_[0]->is_qv } : sub { exists $_[0]->{qv} };
    
    sub _dclone {
      my $ref = shift;
    
      # if an object is in the data structure and doesn't specify how to
      # turn itself into JSON, we just stringify the object.  That does the
      # right thing for typical things that might be there, like version objects,
      # Path::Class objects, etc.
      no warnings 'once';
      no warnings 'redefine';
      local *UNIVERSAL::TO_JSON = sub { "$_[0]" };
    
      my $json = Parse::CPAN::Meta->json_backend()->new
          ->utf8
          ->allow_blessed
          ->convert_blessed;
      $json->decode($json->encode($ref))
    }
    
    my %known_specs = (
        '2'   => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec',
        '1.4' => 'http://module-build.sourceforge.net/META-spec-v1.4.html',
        '1.3' => 'http://module-build.sourceforge.net/META-spec-v1.3.html',
        '1.2' => 'http://module-build.sourceforge.net/META-spec-v1.2.html',
        '1.1' => 'http://module-build.sourceforge.net/META-spec-v1.1.html',
        '1.0' => 'http://module-build.sourceforge.net/META-spec-v1.0.html'
    );
    
    my @spec_list = sort { $a <=> $b } keys %known_specs;
    my ($LOWEST, $HIGHEST) = @spec_list[0,-1];
    
    #--------------------------------------------------------------------------#
    # converters
    #
    # called as $converter->($element, $field_name, $full_meta, $to_version)
    #
    # defined return value used for field
    # undef return value means field is skipped
    #--------------------------------------------------------------------------#
    
    sub _keep { $_[0] }
    
    sub _keep_or_one { defined($_[0]) ? $_[0] : 1 }
    
    sub _keep_or_zero { defined($_[0]) ? $_[0] : 0 }
    
    sub _keep_or_unknown { defined($_[0]) && length($_[0]) ? $_[0] : "unknown" }
    
    sub _generated_by {
      my $gen = shift;
      my $sig = __PACKAGE__ . " version " . (__PACKAGE__->VERSION || "<dev>");
    
      return $sig unless defined $gen and length $gen;
      return $gen if $gen =~ /\Q$sig/;
      return "$gen, $sig";
    }
    
    sub _listify { ! defined $_[0] ? undef : ref $_[0] eq 'ARRAY' ? $_[0] : [$_[0]] }
    
    sub _prefix_custom {
      my $key = shift;
      $key =~ s/^(?!x_)   # Unless it already starts with x_
                 (?:x-?)? # Remove leading x- or x (if present)
               /x_/ix;    # and prepend x_
      return $key;
    }
    
    sub _ucfirst_custom {
      my $key = shift;
      $key = ucfirst $key unless $key =~ /[A-Z]/;
      return $key;
    }
    
    sub _no_prefix_ucfirst_custom {
      my $key = shift;
      $key =~ s/^x_//;
      return _ucfirst_custom($key);
    }
    
    sub _change_meta_spec {
      my ($element, undef, undef, $version) = @_;
      return {
        version => $version,
        url => $known_specs{$version},
      };
    }
    
    my @open_source = (
      'perl',
      'gpl',
      'apache',
      'artistic',
      'artistic_2',
      'lgpl',
      'bsd',
      'gpl',
      'mit',
      'mozilla',
      'open_source',
    );
    
    my %is_open_source = map {; $_ => 1 } @open_source;
    
    my @valid_licenses_1 = (
      @open_source,
      'unrestricted',
      'restrictive',
      'unknown',
    );
    
    my %license_map_1 = (
      ( map { $_ => $_ } @valid_licenses_1 ),
      artistic2 => 'artistic_2',
    );
    
    sub _license_1 {
      my ($element) = @_;
      return 'unknown' unless defined $element;
      if ( $license_map_1{lc $element} ) {
        return $license_map_1{lc $element};
      }
      else {
        return 'unknown';
      }
    }
    
    my @valid_licenses_2 = qw(
      agpl_3
      apache_1_1
      apache_2_0
      artistic_1
      artistic_2
      bsd
      freebsd
      gfdl_1_2
      gfdl_1_3
      gpl_1
      gpl_2
      gpl_3
      lgpl_2_1
      lgpl_3_0
      mit
      mozilla_1_0
      mozilla_1_1
      openssl
      perl_5
      qpl_1_0
      ssleay
      sun
      zlib
      open_source
      restricted
      unrestricted
      unknown
    );
    
    # The "old" values were defined by Module::Build, and were often vague.  I have
    # made the decisions below based on reading Module::Build::API and how clearly
    # it specifies the version of the license.
    my %license_map_2 = (
      (map { $_ => $_ } @valid_licenses_2),
      apache      => 'apache_2_0',  # clearly stated as 2.0
      artistic    => 'artistic_1',  # clearly stated as 1
      artistic2   => 'artistic_2',  # clearly stated as 2
      gpl         => 'open_source', # we don't know which GPL; punt
      lgpl        => 'open_source', # we don't know which LGPL; punt
      mozilla     => 'open_source', # we don't know which MPL; punt
      perl        => 'perl_5',      # clearly Perl 5
      restrictive => 'restricted',
    );
    
    sub _license_2 {
      my ($element) = @_;
      return [ 'unknown' ] unless defined $element;
      $element = [ $element ] unless ref $element eq 'ARRAY';
      my @new_list;
      for my $lic ( @$element ) {
        next unless defined $lic;
        if ( my $new = $license_map_2{lc $lic} ) {
          push @new_list, $new;
        }
      }
      return @new_list ? \@new_list : [ 'unknown' ];
    }
    
    my %license_downgrade_map = qw(
      agpl_3            open_source
      apache_1_1        apache
      apache_2_0        apache
      artistic_1        artistic
      artistic_2        artistic_2
      bsd               bsd
      freebsd           open_source
      gfdl_1_2          open_source
      gfdl_1_3          open_source
      gpl_1             gpl
      gpl_2             gpl
      gpl_3             gpl
      lgpl_2_1          lgpl
      lgpl_3_0          lgpl
      mit               mit
      mozilla_1_0       mozilla
      mozilla_1_1       mozilla
      openssl           open_source
      perl_5            perl
      qpl_1_0           open_source
      ssleay            open_source
      sun               open_source
      zlib              open_source
      open_source       open_source
      restricted        restrictive
      unrestricted      unrestricted
      unknown           unknown
    );
    
    sub _downgrade_license {
      my ($element) = @_;
      if ( ! defined $element ) {
        return "unknown";
      }
      elsif( ref $element eq 'ARRAY' ) {
        if ( @$element > 1) {
          if (grep { !$is_open_source{ $license_downgrade_map{lc $_} || 'unknown' } } @$element) {
            return 'unknown';
          }
          else {
            return 'open_source';
          }
        }
        elsif ( @$element == 1 ) {
          return $license_downgrade_map{lc $element->[0]} || "unknown";
        }
      }
      elsif ( ! ref $element ) {
        return $license_downgrade_map{lc $element} || "unknown";
      }
      return "unknown";
    }
    
    my $no_index_spec_1_2 = {
      'file' => \&_listify,
      'dir' => \&_listify,
      'package' => \&_listify,
      'namespace' => \&_listify,
    };
    
    my $no_index_spec_1_3 = {
      'file' => \&_listify,
      'directory' => \&_listify,
      'package' => \&_listify,
      'namespace' => \&_listify,
    };
    
    my $no_index_spec_2 = {
      'file' => \&_listify,
      'directory' => \&_listify,
      'package' => \&_listify,
      'namespace' => \&_listify,
      ':custom'  => \&_prefix_custom,
    };
    
    sub _no_index_1_2 {
      my (undef, undef, $meta) = @_;
      my $no_index = $meta->{no_index} || $meta->{private};
      return unless $no_index;
    
      # cleanup wrong format
      if ( ! ref $no_index ) {
        my $item = $no_index;
        $no_index = { dir => [ $item ], file => [ $item ] };
      }
      elsif ( ref $no_index eq 'ARRAY' ) {
        my $list = $no_index;
        $no_index = { dir => [ @$list ], file => [ @$list ] };
      }
    
      # common mistake: files -> file
      if ( exists $no_index->{files} ) {
        $no_index->{file} = delete $no_index->{file};
      }
      # common mistake: modules -> module
      if ( exists $no_index->{modules} ) {
        $no_index->{module} = delete $no_index->{module};
      }
      return _convert($no_index, $no_index_spec_1_2);
    }
    
    sub _no_index_directory {
      my ($element, $key, $meta, $version) = @_;
      return unless $element;
    
      # cleanup wrong format
      if ( ! ref $element ) {
        my $item = $element;
        $element = { directory => [ $item ], file => [ $item ] };
      }
      elsif ( ref $element eq 'ARRAY' ) {
        my $list = $element;
        $element = { directory => [ @$list ], file => [ @$list ] };
      }
    
      if ( exists $element->{dir} ) {
        $element->{directory} = delete $element->{dir};
      }
      # common mistake: files -> file
      if ( exists $element->{files} ) {
        $element->{file} = delete $element->{file};
      }
      # common mistake: modules -> module
      if ( exists $element->{modules} ) {
        $element->{module} = delete $element->{module};
      }
      my $spec = $version == 2 ? $no_index_spec_2 : $no_index_spec_1_3;
      return _convert($element, $spec);
    }
    
    sub _is_module_name {
      my $mod = shift;
      return unless defined $mod && length $mod;
      return $mod =~ m{^[A-Za-z][A-Za-z0-9_]*(?:::[A-Za-z0-9_]+)*$};
    }
    
    sub _clean_version {
      my ($element) = @_;
      return 0 if ! defined $element;
    
      $element =~ s{^\s*}{};
      $element =~ s{\s*$}{};
      $element =~ s{^\.}{0.};
    
      return 0 if ! length $element;
      return 0 if ( $element eq 'undef' || $element eq '<undef>' );
    
      my $v = eval { version->new($element) };
      # XXX check defined $v and not just $v because version objects leak memory
      # in boolean context -- dagolden, 2012-02-03
      if ( defined $v ) {
        return _is_qv($v) ? $v->normal : $element;
      }
      else {
        return 0;
      }
    }
    
    sub _bad_version_hook {
      my ($v) = @_;
      $v =~ s{[a-z]+$}{}; # strip trailing alphabetics
      my $vobj = eval { version->new($v) };
      return defined($vobj) ? $vobj : version->new(0); # or give up
    }
    
    sub _version_map {
      my ($element) = @_;
      return unless defined $element;
      if ( ref $element eq 'HASH' ) {
        # XXX turn this into CPAN::Meta::Requirements with bad version hook
        # and then turn it back into a hash
        my $new_map = CPAN::Meta::Requirements->new(
          { bad_version_hook => \&_bad_version_hook } # punt
        );
        while ( my ($k,$v) = each %$element ) {
          next unless _is_module_name($k);
          if ( !defined($v) || !length($v) || $v eq 'undef' || $v eq '<undef>'  ) {
            $v = 0;
          }
          # some weird, old META have bad yml with module => module
          # so check if value is like a module name and not like a version
          if ( _is_module_name($v) && ! version::is_lax($v) ) {
            $new_map->add_minimum($k => 0);
            $new_map->add_minimum($v => 0);
          }
          $new_map->add_string_requirement($k => $v);
        }
        return $new_map->as_string_hash;
      }
      elsif ( ref $element eq 'ARRAY' ) {
        my $hashref = { map { $_ => 0 } @$element };
        return _version_map($hashref); # cleanup any weird stuff
      }
      elsif ( ref $element eq '' && length $element ) {
        return { $element => 0 }
      }
      return;
    }
    
    sub _prereqs_from_1 {
      my (undef, undef, $meta) = @_;
      my $prereqs = {};
      for my $phase ( qw/build configure/ ) {
        my $key = "${phase}_requires";
        $prereqs->{$phase}{requires} = _version_map($meta->{$key})
          if $meta->{$key};
      }
      for my $rel ( qw/requires recommends conflicts/ ) {
        $prereqs->{runtime}{$rel} = _version_map($meta->{$rel})
          if $meta->{$rel};
      }
      return $prereqs;
    }
    
    my $prereqs_spec = {
      configure => \&_prereqs_rel,
      build     => \&_prereqs_rel,
      test      => \&_prereqs_rel,
      runtime   => \&_prereqs_rel,
      develop   => \&_prereqs_rel,
      ':custom'  => \&_prefix_custom,
    };
    
    my $relation_spec = {
      requires   => \&_version_map,
      recommends => \&_version_map,
      suggests   => \&_version_map,
      conflicts  => \&_version_map,
      ':custom'  => \&_prefix_custom,
    };
    
    sub _cleanup_prereqs {
      my ($prereqs, $key, $meta, $to_version) = @_;
      return unless $prereqs && ref $prereqs eq 'HASH';
      return _convert( $prereqs, $prereqs_spec, $to_version );
    }
    
    sub _prereqs_rel {
      my ($relation, $key, $meta, $to_version) = @_;
      return unless $relation && ref $relation eq 'HASH';
      return _convert( $relation, $relation_spec, $to_version );
    }
    
    
    BEGIN {
      my @old_prereqs = qw(
        requires
        configure_requires
        recommends
        conflicts
      );
    
      for ( @old_prereqs ) {
        my $sub = "_get_$_";
        my ($phase,$type) = split qr/_/, $_;
        if ( ! defined $type ) {
          $type = $phase;
          $phase = 'runtime';
        }
        no strict 'refs';
        *{$sub} = sub { _extract_prereqs($_[2]->{prereqs},$phase,$type) };
      }
    }
    
    sub _get_build_requires {
      my ($data, $key, $meta) = @_;
    
      my $test_h  = _extract_prereqs($_[2]->{prereqs}, qw(test  requires)) || {};
      my $build_h = _extract_prereqs($_[2]->{prereqs}, qw(build requires)) || {};
    
      my $test_req  = CPAN::Meta::Requirements->from_string_hash($test_h);
      my $build_req = CPAN::Meta::Requirements->from_string_hash($build_h);
    
      $test_req->add_requirements($build_req)->as_string_hash;
    }
    
    sub _extract_prereqs {
      my ($prereqs, $phase, $type) = @_;
      return unless ref $prereqs eq 'HASH';
      return scalar _version_map($prereqs->{$phase}{$type});
    }
    
    sub _downgrade_optional_features {
      my (undef, undef, $meta) = @_;
      return unless exists $meta->{optional_features};
      my $origin = $meta->{optional_features};
      my $features = {};
      for my $name ( keys %$origin ) {
        $features->{$name} = {
          description => $origin->{$name}{description},
          requires => _extract_prereqs($origin->{$name}{prereqs},'runtime','requires'),
          configure_requires => _extract_prereqs($origin->{$name}{prereqs},'runtime','configure_requires'),
          build_requires => _extract_prereqs($origin->{$name}{prereqs},'runtime','build_requires'),
          recommends => _extract_prereqs($origin->{$name}{prereqs},'runtime','recommends'),
          conflicts => _extract_prereqs($origin->{$name}{prereqs},'runtime','conflicts'),
        };
        for my $k (keys %{$features->{$name}} ) {
          delete $features->{$name}{$k} unless defined $features->{$name}{$k};
        }
      }
      return $features;
    }
    
    sub _upgrade_optional_features {
      my (undef, undef, $meta) = @_;
      return unless exists $meta->{optional_features};
      my $origin = $meta->{optional_features};
      my $features = {};
      for my $name ( keys %$origin ) {
        $features->{$name} = {
          description => $origin->{$name}{description},
          prereqs => _prereqs_from_1(undef, undef, $origin->{$name}),
        };
        delete $features->{$name}{prereqs}{configure};
      }
      return $features;
    }
    
    my $optional_features_2_spec = {
      description => \&_keep,
      prereqs => \&_cleanup_prereqs,
      ':custom'  => \&_prefix_custom,
    };
    
    sub _feature_2 {
      my ($element, $key, $meta, $to_version) = @_;
      return unless $element && ref $element eq 'HASH';
      _convert( $element, $optional_features_2_spec, $to_version );
    }
    
    sub _cleanup_optional_features_2 {
      my ($element, $key, $meta, $to_version) = @_;
      return unless $element && ref $element eq 'HASH';
      my $new_data = {};
      for my $k ( keys %$element ) {
        $new_data->{$k} = _feature_2( $element->{$k}, $k, $meta, $to_version );
      }
      return unless keys %$new_data;
      return $new_data;
    }
    
    sub _optional_features_1_4 {
      my ($element) = @_;
      return unless $element;
      $element = _optional_features_as_map($element);
      for my $name ( keys %$element ) {
        for my $drop ( qw/requires_packages requires_os excluded_os/ ) {
          delete $element->{$name}{$drop};
        }
      }
      return $element;
    }
    
    sub _optional_features_as_map {
      my ($element) = @_;
      return unless $element;
      if ( ref $element eq 'ARRAY' ) {
        my %map;
        for my $feature ( @$element ) {
          my (@parts) = %$feature;
          $map{$parts[0]} = $parts[1];
        }
        $element = \%map;
      }
      return $element;
    }
    
    sub _is_urlish { defined $_[0] && $_[0] =~ m{\A[-+.a-z0-9]+:.+}i }
    
    sub _url_or_drop {
      my ($element) = @_;
      return $element if _is_urlish($element);
      return;
    }
    
    sub _url_list {
      my ($element) = @_;
      return unless $element;
      $element = _listify( $element );
      $element = [ grep { _is_urlish($_) } @$element ];
      return unless @$element;
      return $element;
    }
    
    sub _author_list {
      my ($element) = @_;
      return [ 'unknown' ] unless $element;
      $element = _listify( $element );
      $element = [ map { defined $_ && length $_ ? $_ : 'unknown' } @$element ];
      return [ 'unknown' ] unless @$element;
      return $element;
    }
    
    my $resource2_upgrade = {
      license    => sub { return _is_urlish($_[0]) ? _listify( $_[0] ) : undef },
      homepage   => \&_url_or_drop,
      bugtracker => sub {
        my ($item) = @_;
        return unless $item;
        if ( $item =~ m{^mailto:(.*)$} ) { return { mailto => $1 } }
        elsif( _is_urlish($item) ) { return { web => $item } }
        else { return }
      },
      repository => sub { return _is_urlish($_[0]) ? { url => $_[0] } : undef },
      ':custom'  => \&_prefix_custom,
    };
    
    sub _upgrade_resources_2 {
      my (undef, undef, $meta, $version) = @_;
      return unless exists $meta->{resources};
      return _convert($meta->{resources}, $resource2_upgrade);
    }
    
    my $bugtracker2_spec = {
      web => \&_url_or_drop,
      mailto => \&_keep,
      ':custom'  => \&_prefix_custom,
    };
    
    sub _repo_type {
      my ($element, $key, $meta, $to_version) = @_;
      return $element if defined $element;
      return unless exists $meta->{url};
      my $repo_url = $meta->{url};
      for my $type ( qw/git svn/ ) {
        return $type if $repo_url =~ m{\A$type};
      }
      return;
    }
    
    my $repository2_spec = {
      web => \&_url_or_drop,
      url => \&_url_or_drop,
      type => \&_repo_type,
      ':custom'  => \&_prefix_custom,
    };
    
    my $resources2_cleanup = {
      license    => \&_url_list,
      homepage   => \&_url_or_drop,
      bugtracker => sub { ref $_[0] ? _convert( $_[0], $bugtracker2_spec ) : undef },
      repository => sub { my $data = shift; ref $data ? _convert( $data, $repository2_spec ) : undef },
      ':custom'  => \&_prefix_custom,
    };
    
    sub _cleanup_resources_2 {
      my ($resources, $key, $meta, $to_version) = @_;
      return unless $resources && ref $resources eq 'HASH';
      return _convert($resources, $resources2_cleanup, $to_version);
    }
    
    my $resource1_spec = {
      license    => \&_url_or_drop,
      homepage   => \&_url_or_drop,
      bugtracker => \&_url_or_drop,
      repository => \&_url_or_drop,
      ':custom'  => \&_keep,
    };
    
    sub _resources_1_3 {
      my (undef, undef, $meta, $version) = @_;
      return unless exists $meta->{resources};
      return _convert($meta->{resources}, $resource1_spec);
    }
    
    *_resources_1_4 = *_resources_1_3;
    
    sub _resources_1_2 {
      my (undef, undef, $meta) = @_;
      my $resources = $meta->{resources} || {};
      if ( $meta->{license_url} && ! $resources->{license} ) {
        $resources->{license} = $meta->{license_url}
          if _is_urlish($meta->{license_url});
      }
      return unless keys %$resources;
      return _convert($resources, $resource1_spec);
    }
    
    my $resource_downgrade_spec = {
      license    => sub { return ref $_[0] ? $_[0]->[0] : $_[0] },
      homepage   => \&_url_or_drop,
      bugtracker => sub { return $_[0]->{web} },
      repository => sub { return $_[0]->{url} || $_[0]->{web} },
      ':custom'  => \&_no_prefix_ucfirst_custom,
    };
    
    sub _downgrade_resources {
      my (undef, undef, $meta, $version) = @_;
      return unless exists $meta->{resources};
      return _convert($meta->{resources}, $resource_downgrade_spec);
    }
    
    sub _release_status {
      my ($element, undef, $meta) = @_;
      return $element if $element && $element =~ m{\A(?:stable|testing|unstable)\z};
      return _release_status_from_version(undef, undef, $meta);
    }
    
    sub _release_status_from_version {
      my (undef, undef, $meta) = @_;
      my $version = $meta->{version} || '';
      return ( $version =~ /_/ ) ? 'testing' : 'stable';
    }
    
    my $provides_spec = {
      file => \&_keep,
      version => \&_keep,
    };
    
    my $provides_spec_2 = {
      file => \&_keep,
      version => \&_keep,
      ':custom'  => \&_prefix_custom,
    };
    
    sub _provides {
      my ($element, $key, $meta, $to_version) = @_;
      return unless defined $element && ref $element eq 'HASH';
      my $spec = $to_version == 2 ? $provides_spec_2 : $provides_spec;
      my $new_data = {};
      for my $k ( keys %$element ) {
        $new_data->{$k} = _convert($element->{$k}, $spec, $to_version);
        $new_data->{$k}{version} = _clean_version($element->{$k}{version})
          if exists $element->{$k}{version};
      }
      return $new_data;
    }
    
    sub _convert {
      my ($data, $spec, $to_version, $is_fragment) = @_;
    
      my $new_data = {};
      for my $key ( keys %$spec ) {
        next if $key eq ':custom' || $key eq ':drop';
        next unless my $fcn = $spec->{$key};
        if ( $is_fragment && $key eq 'generated_by' ) {
          $fcn = \&_keep;
        }
        die "spec for '$key' is not a coderef"
          unless ref $fcn && ref $fcn eq 'CODE';
        my $new_value = $fcn->($data->{$key}, $key, $data, $to_version);
        $new_data->{$key} = $new_value if defined $new_value;
      }
    
      my $drop_list   = $spec->{':drop'};
      my $customizer  = $spec->{':custom'} || \&_keep;
    
      for my $key ( keys %$data ) {
        next if $drop_list && grep { $key eq $_ } @$drop_list;
        next if exists $spec->{$key}; # we handled it
        $new_data->{ $customizer->($key) } = $data->{$key};
      }
    
      return $new_data;
    }
    
    #--------------------------------------------------------------------------#
    # define converters for each conversion
    #--------------------------------------------------------------------------#
    
    # each converts from prior version
    # special ":custom" field is used for keys not recognized in spec
    my %up_convert = (
      '2-from-1.4' => {
        # PRIOR MANDATORY
        'abstract'            => \&_keep_or_unknown,
        'author'              => \&_author_list,
        'generated_by'        => \&_generated_by,
        'license'             => \&_license_2,
        'meta-spec'           => \&_change_meta_spec,
        'name'                => \&_keep,
        'version'             => \&_keep,
        # CHANGED TO MANDATORY
        'dynamic_config'      => \&_keep_or_one,
        # ADDED MANDATORY
        'release_status'      => \&_release_status_from_version,
        # PRIOR OPTIONAL
        'keywords'            => \&_keep,
        'no_index'            => \&_no_index_directory,
        'optional_features'   => \&_upgrade_optional_features,
        'provides'            => \&_provides,
        'resources'           => \&_upgrade_resources_2,
        # ADDED OPTIONAL
        'description'         => \&_keep,
        'prereqs'             => \&_prereqs_from_1,
    
        # drop these deprecated fields, but only after we convert
        ':drop' => [ qw(
            build_requires
            configure_requires
            conflicts
            distribution_type
            license_url
            private
            recommends
            requires
        ) ],
    
        # other random keys need x_ prefixing
        ':custom'              => \&_prefix_custom,
      },
      '1.4-from-1.3' => {
        # PRIOR MANDATORY
        'abstract'            => \&_keep_or_unknown,
        'author'              => \&_author_list,
        'generated_by'        => \&_generated_by,
        'license'             => \&_license_1,
        'meta-spec'           => \&_change_meta_spec,
        'name'                => \&_keep,
        'version'             => \&_keep,
        # PRIOR OPTIONAL
        'build_requires'      => \&_version_map,
        'conflicts'           => \&_version_map,
        'distribution_type'   => \&_keep,
        'dynamic_config'      => \&_keep_or_one,
        'keywords'            => \&_keep,
        'no_index'            => \&_no_index_directory,
        'optional_features'   => \&_optional_features_1_4,
        'provides'            => \&_provides,
        'recommends'          => \&_version_map,
        'requires'            => \&_version_map,
        'resources'           => \&_resources_1_4,
        # ADDED OPTIONAL
        'configure_requires'  => \&_keep,
    
        # drop these deprecated fields, but only after we convert
        ':drop' => [ qw(
          license_url
          private
        )],
    
        # other random keys are OK if already valid
        ':custom'              => \&_keep
      },
      '1.3-from-1.2' => {
        # PRIOR MANDATORY
        'abstract'            => \&_keep_or_unknown,
        'author'              => \&_author_list,
        'generated_by'        => \&_generated_by,
        'license'             => \&_license_1,
        'meta-spec'           => \&_change_meta_spec,
        'name'                => \&_keep,
        'version'             => \&_keep,
        # PRIOR OPTIONAL
        'build_requires'      => \&_version_map,
        'conflicts'           => \&_version_map,
        'distribution_type'   => \&_keep,
        'dynamic_config'      => \&_keep_or_one,
        'keywords'            => \&_keep,
        'no_index'            => \&_no_index_directory,
        'optional_features'   => \&_optional_features_as_map,
        'provides'            => \&_provides,
        'recommends'          => \&_version_map,
        'requires'            => \&_version_map,
        'resources'           => \&_resources_1_3,
    
        # drop these deprecated fields, but only after we convert
        ':drop' => [ qw(
          license_url
          private
        )],
    
        # other random keys are OK if already valid
        ':custom'              => \&_keep
      },
      '1.2-from-1.1' => {
        # PRIOR MANDATORY
        'version'             => \&_keep,
        # CHANGED TO MANDATORY
        'license'             => \&_license_1,
        'name'                => \&_keep,
        'generated_by'        => \&_generated_by,
        # ADDED MANDATORY
        'abstract'            => \&_keep_or_unknown,
        'author'              => \&_author_list,
        'meta-spec'           => \&_change_meta_spec,
        # PRIOR OPTIONAL
        'build_requires'      => \&_version_map,
        'conflicts'           => \&_version_map,
        'distribution_type'   => \&_keep,
        'dynamic_config'      => \&_keep_or_one,
        'recommends'          => \&_version_map,
        'requires'            => \&_version_map,
        # ADDED OPTIONAL
        'keywords'            => \&_keep,
        'no_index'            => \&_no_index_1_2,
        'optional_features'   => \&_optional_features_as_map,
        'provides'            => \&_provides,
        'resources'           => \&_resources_1_2,
    
        # drop these deprecated fields, but only after we convert
        ':drop' => [ qw(
          license_url
          private
        )],
    
        # other random keys are OK if already valid
        ':custom'              => \&_keep
      },
      '1.1-from-1.0' => {
        # CHANGED TO MANDATORY
        'version'             => \&_keep,
        # IMPLIED MANDATORY
        'name'                => \&_keep,
        # PRIOR OPTIONAL
        'build_requires'      => \&_version_map,
        'conflicts'           => \&_version_map,
        'distribution_type'   => \&_keep,
        'dynamic_config'      => \&_keep_or_one,
        'generated_by'        => \&_generated_by,
        'license'             => \&_license_1,
        'recommends'          => \&_version_map,
        'requires'            => \&_version_map,
        # ADDED OPTIONAL
        'license_url'         => \&_url_or_drop,
        'private'             => \&_keep,
    
        # other random keys are OK if already valid
        ':custom'              => \&_keep
      },
    );
    
    my %down_convert = (
      '1.4-from-2' => {
        # MANDATORY
        'abstract'            => \&_keep_or_unknown,
        'author'              => \&_author_list,
        'generated_by'        => \&_generated_by,
        'license'             => \&_downgrade_license,
        'meta-spec'           => \&_change_meta_spec,
        'name'                => \&_keep,
        'version'             => \&_keep,
        # OPTIONAL
        'build_requires'      => \&_get_build_requires,
        'configure_requires'  => \&_get_configure_requires,
        'conflicts'           => \&_get_conflicts,
        'distribution_type'   => \&_keep,
        'dynamic_config'      => \&_keep_or_one,
        'keywords'            => \&_keep,
        'no_index'            => \&_no_index_directory,
        'optional_features'   => \&_downgrade_optional_features,
        'provides'            => \&_provides,
        'recommends'          => \&_get_recommends,
        'requires'            => \&_get_requires,
        'resources'           => \&_downgrade_resources,
    
        # drop these unsupported fields (after conversion)
        ':drop' => [ qw(
          description
          prereqs
          release_status
        )],
    
        # custom keys will be left unchanged
        ':custom'              => \&_keep
      },
      '1.3-from-1.4' => {
        # MANDATORY
        'abstract'            => \&_keep_or_unknown,
        'author'              => \&_author_list,
        'generated_by'        => \&_generated_by,
        'license'             => \&_license_1,
        'meta-spec'           => \&_change_meta_spec,
        'name'                => \&_keep,
        'version'             => \&_keep,
        # OPTIONAL
        'build_requires'      => \&_version_map,
        'conflicts'           => \&_version_map,
        'distribution_type'   => \&_keep,
        'dynamic_config'      => \&_keep_or_one,
        'keywords'            => \&_keep,
        'no_index'            => \&_no_index_directory,
        'optional_features'   => \&_optional_features_as_map,
        'provides'            => \&_provides,
        'recommends'          => \&_version_map,
        'requires'            => \&_version_map,
        'resources'           => \&_resources_1_3,
    
        # drop these unsupported fields, but only after we convert
        ':drop' => [ qw(
          configure_requires
        )],
    
        # other random keys are OK if already valid
        ':custom'              => \&_keep,
      },
      '1.2-from-1.3' => {
        # MANDATORY
        'abstract'            => \&_keep_or_unknown,
        'author'              => \&_author_list,
        'generated_by'        => \&_generated_by,
        'license'             => \&_license_1,
        'meta-spec'           => \&_change_meta_spec,
        'name'                => \&_keep,
        'version'             => \&_keep,
        # OPTIONAL
        'build_requires'      => \&_version_map,
        'conflicts'           => \&_version_map,
        'distribution_type'   => \&_keep,
        'dynamic_config'      => \&_keep_or_one,
        'keywords'            => \&_keep,
        'no_index'            => \&_no_index_1_2,
        'optional_features'   => \&_optional_features_as_map,
        'provides'            => \&_provides,
        'recommends'          => \&_version_map,
        'requires'            => \&_version_map,
        'resources'           => \&_resources_1_3,
    
        # other random keys are OK if already valid
        ':custom'              => \&_keep,
      },
      '1.1-from-1.2' => {
        # MANDATORY
        'version'             => \&_keep,
        # IMPLIED MANDATORY
        'name'                => \&_keep,
        'meta-spec'           => \&_change_meta_spec,
        # OPTIONAL
        'build_requires'      => \&_version_map,
        'conflicts'           => \&_version_map,
        'distribution_type'   => \&_keep,
        'dynamic_config'      => \&_keep_or_one,
        'generated_by'        => \&_generated_by,
        'license'             => \&_license_1,
        'private'             => \&_keep,
        'recommends'          => \&_version_map,
        'requires'            => \&_version_map,
    
        # drop unsupported fields
        ':drop' => [ qw(
          abstract
          author
          provides
          no_index
          keywords
          resources
        )],
    
        # other random keys are OK if already valid
        ':custom'              => \&_keep,
      },
      '1.0-from-1.1' => {
        # IMPLIED MANDATORY
        'name'                => \&_keep,
        'meta-spec'           => \&_change_meta_spec,
        'version'             => \&_keep,
        # PRIOR OPTIONAL
        'build_requires'      => \&_version_map,
        'conflicts'           => \&_version_map,
        'distribution_type'   => \&_keep,
        'dynamic_config'      => \&_keep_or_one,
        'generated_by'        => \&_generated_by,
        'license'             => \&_license_1,
        'recommends'          => \&_version_map,
        'requires'            => \&_version_map,
    
        # other random keys are OK if already valid
        ':custom'              => \&_keep,
      },
    );
    
    my %cleanup = (
      '2' => {
        # PRIOR MANDATORY
        'abstract'            => \&_keep_or_unknown,
        'author'              => \&_author_list,
        'generated_by'        => \&_generated_by,
        'license'             => \&_license_2,
        'meta-spec'           => \&_change_meta_spec,
        'name'                => \&_keep,
        'version'             => \&_keep,
        # CHANGED TO MANDATORY
        'dynamic_config'      => \&_keep_or_one,
        # ADDED MANDATORY
        'release_status'      => \&_release_status,
        # PRIOR OPTIONAL
        'keywords'            => \&_keep,
        'no_index'            => \&_no_index_directory,
        'optional_features'   => \&_cleanup_optional_features_2,
        'provides'            => \&_provides,
        'resources'           => \&_cleanup_resources_2,
        # ADDED OPTIONAL
        'description'         => \&_keep,
        'prereqs'             => \&_cleanup_prereqs,
    
        # drop these deprecated fields, but only after we convert
        ':drop' => [ qw(
            build_requires
            configure_requires
            conflicts
            distribution_type
            license_url
            private
            recommends
            requires
        ) ],
    
        # other random keys need x_ prefixing
        ':custom'              => \&_prefix_custom,
      },
      '1.4' => {
        # PRIOR MANDATORY
        'abstract'            => \&_keep_or_unknown,
        'author'              => \&_author_list,
        'generated_by'        => \&_generated_by,
        'license'             => \&_license_1,
        'meta-spec'           => \&_change_meta_spec,
        'name'                => \&_keep,
        'version'             => \&_keep,
        # PRIOR OPTIONAL
        'build_requires'      => \&_version_map,
        'conflicts'           => \&_version_map,
        'distribution_type'   => \&_keep,
        'dynamic_config'      => \&_keep_or_one,
        'keywords'            => \&_keep,
        'no_index'            => \&_no_index_directory,
        'optional_features'   => \&_optional_features_1_4,
        'provides'            => \&_provides,
        'recommends'          => \&_version_map,
        'requires'            => \&_version_map,
        'resources'           => \&_resources_1_4,
        # ADDED OPTIONAL
        'configure_requires'  => \&_keep,
    
        # other random keys are OK if already valid
        ':custom'             => \&_keep
      },
      '1.3' => {
        # PRIOR MANDATORY
        'abstract'            => \&_keep_or_unknown,
        'author'              => \&_author_list,
        'generated_by'        => \&_generated_by,
        'license'             => \&_license_1,
        'meta-spec'           => \&_change_meta_spec,
        'name'                => \&_keep,
        'version'             => \&_keep,
        # PRIOR OPTIONAL
        'build_requires'      => \&_version_map,
        'conflicts'           => \&_version_map,
        'distribution_type'   => \&_keep,
        'dynamic_config'      => \&_keep_or_one,
        'keywords'            => \&_keep,
        'no_index'            => \&_no_index_directory,
        'optional_features'   => \&_optional_features_as_map,
        'provides'            => \&_provides,
        'recommends'          => \&_version_map,
        'requires'            => \&_version_map,
        'resources'           => \&_resources_1_3,
    
        # other random keys are OK if already valid
        ':custom'             => \&_keep
      },
      '1.2' => {
        # PRIOR MANDATORY
        'version'             => \&_keep,
        # CHANGED TO MANDATORY
        'license'             => \&_license_1,
        'name'                => \&_keep,
        'generated_by'        => \&_generated_by,
        # ADDED MANDATORY
        'abstract'            => \&_keep_or_unknown,
        'author'              => \&_author_list,
        'meta-spec'           => \&_change_meta_spec,
        # PRIOR OPTIONAL
        'build_requires'      => \&_version_map,
        'conflicts'           => \&_version_map,
        'distribution_type'   => \&_keep,
        'dynamic_config'      => \&_keep_or_one,
        'recommends'          => \&_version_map,
        'requires'            => \&_version_map,
        # ADDED OPTIONAL
        'keywords'            => \&_keep,
        'no_index'            => \&_no_index_1_2,
        'optional_features'   => \&_optional_features_as_map,
        'provides'            => \&_provides,
        'resources'           => \&_resources_1_2,
    
        # other random keys are OK if already valid
        ':custom'             => \&_keep
      },
      '1.1' => {
        # CHANGED TO MANDATORY
        'version'             => \&_keep,
        # IMPLIED MANDATORY
        'name'                => \&_keep,
        'meta-spec'           => \&_change_meta_spec,
        # PRIOR OPTIONAL
        'build_requires'      => \&_version_map,
        'conflicts'           => \&_version_map,
        'distribution_type'   => \&_keep,
        'dynamic_config'      => \&_keep_or_one,
        'generated_by'        => \&_generated_by,
        'license'             => \&_license_1,
        'recommends'          => \&_version_map,
        'requires'            => \&_version_map,
        # ADDED OPTIONAL
        'license_url'         => \&_url_or_drop,
        'private'             => \&_keep,
    
        # other random keys are OK if already valid
        ':custom'             => \&_keep
      },
      '1.0' => {
        # IMPLIED MANDATORY
        'name'                => \&_keep,
        'meta-spec'           => \&_change_meta_spec,
        'version'             => \&_keep,
        # IMPLIED OPTIONAL
        'build_requires'      => \&_version_map,
        'conflicts'           => \&_version_map,
        'distribution_type'   => \&_keep,
        'dynamic_config'      => \&_keep_or_one,
        'generated_by'        => \&_generated_by,
        'license'             => \&_license_1,
        'recommends'          => \&_version_map,
        'requires'            => \&_version_map,
    
        # other random keys are OK if already valid
        ':custom'             => \&_keep,
      },
    );
    
    # for a given field in a spec version, what fields will it feed
    # into in the *latest* spec (i.e. v2); meta-spec omitted because
    # we always expect a meta-spec to be generated
    my %fragments_generate = (
      '2' => {
        'abstract'            =>   'abstract',
        'author'              =>   'author',
        'generated_by'        =>   'generated_by',
        'license'             =>   'license',
        'name'                =>   'name',
        'version'             =>   'version',
        'dynamic_config'      =>   'dynamic_config',
        'release_status'      =>   'release_status',
        'keywords'            =>   'keywords',
        'no_index'            =>   'no_index',
        'optional_features'   =>   'optional_features',
        'provides'            =>   'provides',
        'resources'           =>   'resources',
        'description'         =>   'description',
        'prereqs'             =>   'prereqs',
      },
      '1.4' => {
        'abstract'            => 'abstract',
        'author'              => 'author',
        'generated_by'        => 'generated_by',
        'license'             => 'license',
        'name'                => 'name',
        'version'             => 'version',
        'build_requires'      => 'prereqs',
        'conflicts'           => 'prereqs',
        'distribution_type'   => 'distribution_type',
        'dynamic_config'      => 'dynamic_config',
        'keywords'            => 'keywords',
        'no_index'            => 'no_index',
        'optional_features'   => 'optional_features',
        'provides'            => 'provides',
        'recommends'          => 'prereqs',
        'requires'            => 'prereqs',
        'resources'           => 'resources',
        'configure_requires'  => 'prereqs',
      },
    );
    # this is not quite true but will work well enough
    # as 1.4 is a superset of earlier ones
    $fragments_generate{$_} = $fragments_generate{'1.4'} for qw/1.3 1.2 1.1 1.0/;
    
    #--------------------------------------------------------------------------#
    # Code
    #--------------------------------------------------------------------------#
    
    #pod =method new
    #pod
    #pod   my $cmc = CPAN::Meta::Converter->new( $struct );
    #pod
    #pod The constructor should be passed a valid metadata structure but invalid
    #pod structures are accepted.  If no meta-spec version is provided, version 1.0 will
    #pod be assumed.
    #pod
    #pod Optionally, you can provide a C<default_version> argument after C<$struct>:
    #pod
    #pod   my $cmc = CPAN::Meta::Converter->new( $struct, default_version => "1.4" );
    #pod
    #pod This is only needed when converting a metadata fragment that does not include a
    #pod C<meta-spec> field.
    #pod
    #pod =cut
    
    sub new {
      my ($class,$data,%args) = @_;
    
      # create an attributes hash
      my $self = {
        'data'    => $data,
        'spec'    => _extract_spec_version($data, $args{default_version}),
      };
    
      # create the object
      return bless $self, $class;
    }
    
    sub _extract_spec_version {
        my ($data, $default) = @_;
        my $spec = $data->{'meta-spec'};
    
        # is meta-spec there and valid?
        return( $default || "1.0" ) unless defined $spec && ref $spec eq 'HASH'; # before meta-spec?
    
        # does the version key look like a valid version?
        my $v = $spec->{version};
        if ( defined $v && $v =~ /^\d+(?:\.\d+)?$/ ) {
            return $v if defined $v && grep { $v eq $_ } keys %known_specs; # known spec
            return $v+0 if defined $v && grep { $v == $_ } keys %known_specs; # 2.0 => 2
        }
    
        # otherwise, use heuristics: look for 1.x vs 2.0 fields
        return "2" if exists $data->{prereqs};
        return "1.4" if exists $data->{configure_requires};
        return( $default || "1.2" ); # when meta-spec was first defined
    }
    
    #pod =method convert
    #pod
    #pod   my $new_struct = $cmc->convert( version => "2" );
    #pod
    #pod Returns a new hash reference with the metadata converted to a different form.
    #pod C<convert> will die if any conversion/standardization still results in an
    #pod invalid structure.
    #pod
    #pod Valid parameters include:
    #pod
    #pod =over
    #pod
    #pod =item *
    #pod
    #pod C<version> -- Indicates the desired specification version (e.g. "1.0", "1.1" ... "1.4", "2").
    #pod Defaults to the latest version of the CPAN Meta Spec.
    #pod
    #pod =back
    #pod
    #pod Conversion proceeds through each version in turn.  For example, a version 1.2
    #pod structure might be converted to 1.3 then 1.4 then finally to version 2. The
    #pod conversion process attempts to clean-up simple errors and standardize data.
    #pod For example, if C<author> is given as a scalar, it will converted to an array
    #pod reference containing the item. (Converting a structure to its own version will
    #pod also clean-up and standardize.)
    #pod
    #pod When data are cleaned and standardized, missing or invalid fields will be
    #pod replaced with sensible defaults when possible.  This may be lossy or imprecise.
    #pod For example, some badly structured META.yml files on CPAN have prerequisite
    #pod modules listed as both keys and values:
    #pod
    #pod   requires => { 'Foo::Bar' => 'Bam::Baz' }
    #pod
    #pod These would be split and each converted to a prerequisite with a minimum
    #pod version of zero.
    #pod
    #pod When some mandatory fields are missing or invalid, the conversion will attempt
    #pod to provide a sensible default or will fill them with a value of 'unknown'.  For
    #pod example a missing or unrecognized C<license> field will result in a C<license>
    #pod field of 'unknown'.  Fields that may get an 'unknown' include:
    #pod
    #pod =for :list
    #pod * abstract
    #pod * author
    #pod * license
    #pod
    #pod =cut
    
    sub convert {
      my ($self, %args) = @_;
      my $args = { %args };
    
      my $new_version = $args->{version} || $HIGHEST;
      my $is_fragment = $args->{is_fragment};
    
      my ($old_version) = $self->{spec};
      my $converted = _dclone($self->{data});
    
      if ( $old_version == $new_version ) {
        $converted = _convert( $converted, $cleanup{$old_version}, $old_version, $is_fragment );
        unless ( $args->{is_fragment} ) {
          my $cmv = CPAN::Meta::Validator->new( $converted );
          unless ( $cmv->is_valid ) {
            my $errs = join("\n", $cmv->errors);
            die "Failed to clean-up $old_version metadata. Errors:\n$errs\n";
          }
        }
        return $converted;
      }
      elsif ( $old_version > $new_version )  {
        my @vers = sort { $b <=> $a } keys %known_specs;
        for my $i ( 0 .. $#vers-1 ) {
          next if $vers[$i] > $old_version;
          last if $vers[$i+1] < $new_version;
          my $spec_string = "$vers[$i+1]-from-$vers[$i]";
          $converted = _convert( $converted, $down_convert{$spec_string}, $vers[$i+1], $is_fragment );
          unless ( $args->{is_fragment} ) {
            my $cmv = CPAN::Meta::Validator->new( $converted );
            unless ( $cmv->is_valid ) {
              my $errs = join("\n", $cmv->errors);
              die "Failed to downconvert metadata to $vers[$i+1]. Errors:\n$errs\n";
            }
          }
        }
        return $converted;
      }
      else {
        my @vers = sort { $a <=> $b } keys %known_specs;
        for my $i ( 0 .. $#vers-1 ) {
          next if $vers[$i] < $old_version;
          last if $vers[$i+1] > $new_version;
          my $spec_string = "$vers[$i+1]-from-$vers[$i]";
          $converted = _convert( $converted, $up_convert{$spec_string}, $vers[$i+1], $is_fragment );
          unless ( $args->{is_fragment} ) {
            my $cmv = CPAN::Meta::Validator->new( $converted );
            unless ( $cmv->is_valid ) {
              my $errs = join("\n", $cmv->errors);
              die "Failed to upconvert metadata to $vers[$i+1]. Errors:\n$errs\n";
            }
          }
        }
        return $converted;
      }
    }
    
    #pod =method upgrade_fragment
    #pod
    #pod   my $new_struct = $cmc->upgrade_fragment;
    #pod
    #pod Returns a new hash reference with the metadata converted to the latest version
    #pod of the CPAN Meta Spec.  No validation is done on the result -- you must
    #pod validate after merging fragments into a complete metadata document.
    #pod
    #pod =cut
    
    sub upgrade_fragment {
      my ($self) = @_;
      my ($old_version) = $self->{spec};
      my %expected =
        map {; $_ => 1 }
        grep { defined }
        map { $fragments_generate{$old_version}{$_} }
        keys %{ $self->{data} };
      my $converted = $self->convert( version => $HIGHEST, is_fragment => 1 );
      for my $key ( keys %$converted ) {
        next if $key =~ /^x_/i || $key eq 'meta-spec';
        delete $converted->{$key} unless $expected{$key};
      }
      return $converted;
    }
    
    1;
    
    # ABSTRACT: Convert CPAN distribution metadata structures
    
    =pod
    
    =encoding UTF-8
    
    =head1 NAME
    
    CPAN::Meta::Converter - Convert CPAN distribution metadata structures
    
    =head1 VERSION
    
    version 2.143240
    
    =head1 SYNOPSIS
    
      my $struct = decode_json_file('META.json');
    
      my $cmc = CPAN::Meta::Converter->new( $struct );
    
      my $new_struct = $cmc->convert( version => "2" );
    
    =head1 DESCRIPTION
    
    This module converts CPAN Meta structures from one form to another.  The
    primary use is to convert older structures to the most modern version of
    the specification, but other transformations may be implemented in the
    future as needed.  (E.g. stripping all custom fields or stripping all
    optional fields.)
    
    =head1 METHODS
    
    =head2 new
    
      my $cmc = CPAN::Meta::Converter->new( $struct );
    
    The constructor should be passed a valid metadata structure but invalid
    structures are accepted.  If no meta-spec version is provided, version 1.0 will
    be assumed.
    
    Optionally, you can provide a C<default_version> argument after C<$struct>:
    
      my $cmc = CPAN::Meta::Converter->new( $struct, default_version => "1.4" );
    
    This is only needed when converting a metadata fragment that does not include a
    C<meta-spec> field.
    
    =head2 convert
    
      my $new_struct = $cmc->convert( version => "2" );
    
    Returns a new hash reference with the metadata converted to a different form.
    C<convert> will die if any conversion/standardization still results in an
    invalid structure.
    
    Valid parameters include:
    
    =over
    
    =item *
    
    C<version> -- Indicates the desired specification version (e.g. "1.0", "1.1" ... "1.4", "2").
    Defaults to the latest version of the CPAN Meta Spec.
    
    =back
    
    Conversion proceeds through each version in turn.  For example, a version 1.2
    structure might be converted to 1.3 then 1.4 then finally to version 2. The
    conversion process attempts to clean-up simple errors and standardize data.
    For example, if C<author> is given as a scalar, it will converted to an array
    reference containing the item. (Converting a structure to its own version will
    also clean-up and standardize.)
    
    When data are cleaned and standardized, missing or invalid fields will be
    replaced with sensible defaults when possible.  This may be lossy or imprecise.
    For example, some badly structured META.yml files on CPAN have prerequisite
    modules listed as both keys and values:
    
      requires => { 'Foo::Bar' => 'Bam::Baz' }
    
    These would be split and each converted to a prerequisite with a minimum
    version of zero.
    
    When some mandatory fields are missing or invalid, the conversion will attempt
    to provide a sensible default or will fill them with a value of 'unknown'.  For
    example a missing or unrecognized C<license> field will result in a C<license>
    field of 'unknown'.  Fields that may get an 'unknown' include:
    
    =over 4
    
    =item *
    
    abstract
    
    =item *
    
    author
    
    =item *
    
    license
    
    =back
    
    =head2 upgrade_fragment
    
      my $new_struct = $cmc->upgrade_fragment;
    
    Returns a new hash reference with the metadata converted to the latest version
    of the CPAN Meta Spec.  No validation is done on the result -- you must
    validate after merging fragments into a complete metadata document.
    
    =head1 BUGS
    
    Please report any bugs or feature using the CPAN Request Tracker.
    Bugs can be submitted through the web interface at
    L<http://rt.cpan.org/Dist/Display.html?Queue=CPAN-Meta>
    
    When submitting a bug or request, please include a test-file or a patch to an
    existing test-file that illustrates the bug or desired feature.
    
    =head1 AUTHORS
    
    =over 4
    
    =item *
    
    David Golden <dagolden@cpan.org>
    
    =item *
    
    Ricardo Signes <rjbs@cpan.org>
    
    =back
    
    =head1 COPYRIGHT AND LICENSE
    
    This software is copyright (c) 2010 by David Golden and Ricardo Signes.
    
    This is free software; you can redistribute it and/or modify it under
    the same terms as the Perl 5 programming language system itself.
    
    =cut
    
    __END__
    
    
    # vim: ts=2 sts=2 sw=2 et:
  CPAN_META_CONVERTER
  
  $fatpacked{"CPAN/Meta/Feature.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CPAN_META_FEATURE';
    use 5.006;
    use strict;
    use warnings;
    package CPAN::Meta::Feature;
    # VERSION
    $CPAN::Meta::Feature::VERSION = '2.143240';
    use CPAN::Meta::Prereqs;
    
    #pod =head1 DESCRIPTION
    #pod
    #pod A CPAN::Meta::Feature object describes an optional feature offered by a CPAN
    #pod distribution and specified in the distribution's F<META.json> (or F<META.yml>)
    #pod file.
    #pod
    #pod For the most part, this class will only be used when operating on the result of
    #pod the C<feature> or C<features> methods on a L<CPAN::Meta> object.
    #pod
    #pod =method new
    #pod
    #pod   my $feature = CPAN::Meta::Feature->new( $identifier => \%spec );
    #pod
    #pod This returns a new Feature object.  The C<%spec> argument to the constructor
    #pod should be the same as the value of the C<optional_feature> entry in the
    #pod distmeta.  It must contain entries for C<description> and C<prereqs>.
    #pod
    #pod =cut
    
    sub new {
      my ($class, $identifier, $spec) = @_;
    
      my %guts = (
        identifier  => $identifier,
        description => $spec->{description},
        prereqs     => CPAN::Meta::Prereqs->new($spec->{prereqs}),
      );
    
      bless \%guts => $class;
    }
    
    #pod =method identifier
    #pod
    #pod This method returns the feature's identifier.
    #pod
    #pod =cut
    
    sub identifier  { $_[0]{identifier}  }
    
    #pod =method description
    #pod
    #pod This method returns the feature's long description.
    #pod
    #pod =cut
    
    sub description { $_[0]{description} }
    
    #pod =method prereqs
    #pod
    #pod This method returns the feature's prerequisites as a L<CPAN::Meta::Prereqs>
    #pod object.
    #pod
    #pod =cut
    
    sub prereqs     { $_[0]{prereqs} }
    
    1;
    
    # ABSTRACT: an optional feature provided by a CPAN distribution
    
    __END__
    
    =pod
    
    =encoding UTF-8
    
    =head1 NAME
    
    CPAN::Meta::Feature - an optional feature provided by a CPAN distribution
    
    =head1 VERSION
    
    version 2.143240
    
    =head1 DESCRIPTION
    
    A CPAN::Meta::Feature object describes an optional feature offered by a CPAN
    distribution and specified in the distribution's F<META.json> (or F<META.yml>)
    file.
    
    For the most part, this class will only be used when operating on the result of
    the C<feature> or C<features> methods on a L<CPAN::Meta> object.
    
    =head1 METHODS
    
    =head2 new
    
      my $feature = CPAN::Meta::Feature->new( $identifier => \%spec );
    
    This returns a new Feature object.  The C<%spec> argument to the constructor
    should be the same as the value of the C<optional_feature> entry in the
    distmeta.  It must contain entries for C<description> and C<prereqs>.
    
    =head2 identifier
    
    This method returns the feature's identifier.
    
    =head2 description
    
    This method returns the feature's long description.
    
    =head2 prereqs
    
    This method returns the feature's prerequisites as a L<CPAN::Meta::Prereqs>
    object.
    
    =head1 BUGS
    
    Please report any bugs or feature using the CPAN Request Tracker.
    Bugs can be submitted through the web interface at
    L<http://rt.cpan.org/Dist/Display.html?Queue=CPAN-Meta>
    
    When submitting a bug or request, please include a test-file or a patch to an
    existing test-file that illustrates the bug or desired feature.
    
    =head1 AUTHORS
    
    =over 4
    
    =item *
    
    David Golden <dagolden@cpan.org>
    
    =item *
    
    Ricardo Signes <rjbs@cpan.org>
    
    =back
    
    =head1 COPYRIGHT AND LICENSE
    
    This software is copyright (c) 2010 by David Golden and Ricardo Signes.
    
    This is free software; you can redistribute it and/or modify it under
    the same terms as the Perl 5 programming language system itself.
    
    =cut
  CPAN_META_FEATURE
  
  $fatpacked{"CPAN/Meta/History.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CPAN_META_HISTORY';
    # vi:tw=72
    use 5.006;
    use strict;
    use warnings;
    package CPAN::Meta::History;
    # VERSION
    $CPAN::Meta::History::VERSION = '2.143240';
    1;
    
    # ABSTRACT: history of CPAN Meta Spec changes
    
    __END__
    
    =pod
    
    =encoding UTF-8
    
    =head1 NAME
    
    CPAN::Meta::History - history of CPAN Meta Spec changes
    
    =head1 VERSION
    
    version 2.143240
    
    =head1 DESCRIPTION
    
    The CPAN Meta Spec has gone through several iterations.  It was
    originally written in HTML and later revised into POD (though published
    in HTML generated from the POD).  Fields were added, removed or changed,
    sometimes by design and sometimes to reflect real-world usage after the
    fact.
    
    This document reconstructs the history of the CPAN Meta Spec based on
    change logs, repository commit messages and the published HTML files.
    In some cases, particularly prior to version 1.2, the exact version
    when certain fields were introduced or changed is inconsistent between
    sources.  When in doubt, the published HTML files for versions 1.0 to
    1.4 as they existed when version 2 was developed are used as the
    definitive source.
    
    Starting with version 2, the specification document is part of the
    CPAN-Meta distribution and will be published on CPAN as
    L<CPAN::Meta::Spec>.
    
    Going forward, specification version numbers will be integers and
    decimal portions will correspond to a release date for the CPAN::Meta
    library.
    
    =head1 HISTORY
    
    =head2 Version 2
    
    April 2010
    
    =over
    
    =item *
    
    Revised spec examples as perl data structures rather than YAML
    
    =item *
    
    Switched to JSON serialization from YAML
    
    =item *
    
    Specified allowed version number formats
    
    =item *
    
    Replaced 'requires', 'build_requires', 'configure_requires',
    'recommends' and 'conflicts' with new 'prereqs' data structure divided
    by I<phase> (configure, build, test, runtime, etc.) and I<relationship>
    (requires, recommends, suggests, conflicts)
    
    =item *
    
    Added support for 'develop' phase for requirements for maintaining
    a list of authoring tools
    
    =item *
    
    Changed 'license' to a list and revised the set of valid licenses
    
    =item *
    
    Made 'dynamic_config' mandatory to reduce confusion
    
    =item *
    
    Changed 'resources' subkey 'repository' to a hash that clarifies
    repository type, url for browsing and url for checkout
    
    =item *
    
    Changed 'resources' subkey 'bugtracker' to a hash for either web
    or mailto resource
    
    =item *
    
    Changed specification of 'optional_features':
    
    =over
    
    =item *
    
    Added formal specification and usage guide instead of just example
    
    =item *
    
    Changed to use new prereqs data structure instead of individual keys
    
    =back
    
    =item *
    
    Clarified intended use of 'author' as generalized contact list
    
    =item *
    
    Added 'release_status' field to indicate stable, testing or unstable
    status to provide hints to indexers
    
    =item *
    
    Added 'description' field for a longer description of the distribution
    
    =item *
    
    Formalized use of "x_" or "X_" for all custom keys not listed in the
    official spec
    
    =back
    
    =head2 Version 1.4
    
    June 2008
    
    =over
    
    =item *
    
    Noted explicit support for 'perl' in prerequisites
    
    =item *
    
    Added 'configure_requires' prerequisite type
    
    =item *
    
    Changed 'optional_features'
    
    =over
    
    =item *
    
    Example corrected to show map of maps instead of list of maps
    (though descriptive text said 'map' even in v1.3)
    
    =item *
    
    Removed 'requires_packages', 'requires_os' and 'excluded_os'
    as valid subkeys
    
    =back
    
    =back
    
    =head2 Version 1.3
    
    November 2006
    
    =over
    
    =item *
    
    Added 'no_index' subkey 'directory' and removed 'dir' to match actual
    usage in the wild
    
    =item *
    
    Added a 'repository' subkey to 'resources'
    
    =back
    
    =head2 Version 1.2
    
    August 2005
    
    =over
    
    =item *
    
    Re-wrote and restructured spec in POD syntax
    
    =item *
    
    Changed 'name' to be mandatory
    
    =item *
    
    Changed 'generated_by' to be mandatory
    
    =item *
    
    Changed 'license' to be mandatory
    
    =item *
    
    Added version range specifications for prerequisites
    
    =item *
    
    Added required 'abstract' field
    
    =item *
    
    Added required 'author' field
    
    =item *
    
    Added required 'meta-spec' field to define 'version' (and 'url') of the
    CPAN Meta Spec used for metadata
    
    =item *
    
    Added 'provides' field
    
    =item *
    
    Added 'no_index' field and deprecated 'private' field.  'no_index'
    subkeys include 'file', 'dir', 'package' and 'namespace'
    
    =item *
    
    Added 'keywords' field
    
    =item *
    
    Added 'resources' field with subkeys 'homepage', 'license', and
    'bugtracker'
    
    =item *
    
    Added 'optional_features' field as an alternate under 'recommends'.
    Includes 'description', 'requires', 'build_requires', 'conflicts',
    'requires_packages', 'requires_os' and 'excluded_os' as valid subkeys
    
    =item *
    
    Removed 'license_uri' field
    
    =back
    
    =head2 Version 1.1
    
    May 2003
    
    =over
    
    =item *
    
    Changed 'version' to be mandatory
    
    =item *
    
    Added 'private' field
    
    =item *
    
    Added 'license_uri' field
    
    =back
    
    =head2 Version 1.0
    
    March 2003
    
    =over
    
    =item *
    
    Original release (in HTML format only)
    
    =item *
    
    Included 'name', 'version', 'license', 'distribution_type', 'requires',
    'recommends', 'build_requires', 'conflicts', 'dynamic_config',
    'generated_by'
    
    =back
    
    =head1 AUTHORS
    
    =over 4
    
    =item *
    
    David Golden <dagolden@cpan.org>
    
    =item *
    
    Ricardo Signes <rjbs@cpan.org>
    
    =back
    
    =head1 COPYRIGHT AND LICENSE
    
    This software is copyright (c) 2010 by David Golden and Ricardo Signes.
    
    This is free software; you can redistribute it and/or modify it under
    the same terms as the Perl 5 programming language system itself.
    
    =cut
  CPAN_META_HISTORY
  
  $fatpacked{"CPAN/Meta/Merge.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CPAN_META_MERGE';
    use strict;
    use warnings;
    
    package CPAN::Meta::Merge;
    # VERSION
    $CPAN::Meta::Merge::VERSION = '2.143240';
    use Carp qw/croak/;
    use Scalar::Util qw/blessed/;
    use CPAN::Meta::Converter;
    
    sub _identical {
      my ($left, $right, $path) = @_;
      croak sprintf "Can't merge attribute %s: '%s' does not equal '%s'", join('.', @{$path}), $left, $right unless $left eq $right;
      return $left;
    }
    
    sub _merge {
      my ($current, $next, $mergers, $path) = @_;
      for my $key (keys %{$next}) {
        if (not exists $current->{$key}) {
          $current->{$key} = $next->{$key};
        }
        elsif (my $merger = $mergers->{$key}) {
          $current->{$key} = $merger->($current->{$key}, $next->{$key}, [ @{$path}, $key ]);
        }
        elsif ($merger = $mergers->{':default'}) {
          $current->{$key} = $merger->($current->{$key}, $next->{$key}, [ @{$path}, $key ]);
        }
        else {
          croak sprintf "Can't merge unknown attribute '%s'", join '.', @{$path}, $key;
        }
      }
      return $current;
    }
    
    sub _uniq {
      my %seen = ();
      return grep { not $seen{$_}++ } @_;
    }
    
    sub _set_addition {
      my ($left, $right) = @_;
      return [ +_uniq(@{$left}, @{$right}) ];
    }
    
    sub _uniq_map {
      my ($left, $right, $path) = @_;
      for my $key (keys %{$right}) {
        if (not exists $left->{$key}) {
          $left->{$key} = $right->{$key};
        }
        else {
          croak 'Duplication of element ' . join '.', @{$path}, $key;
        }
      }
      return $left;
    }
    
    sub _improvize {
      my ($left, $right, $path) = @_;
      my ($name) = reverse @{$path};
      if ($name =~ /^x_/) {
        if (ref($left) eq 'ARRAY') {
          return _set_addition($left, $right, $path);
        }
        elsif (ref($left) eq 'HASH') {
          return _uniq_map($left, $right, $path);
        }
        else {
          return _identical($left, $right, $path);
        }
      }
      croak sprintf "Can't merge '%s'", join '.', @{$path};
    }
    
    sub _optional_features {
      my ($left, $right, $path) = @_;
    
      for my $key (keys %{$right}) {
        if (not exists $left->{$key}) {
          $left->{$key} = $right->{$key};
        }
        else {
          for my $subkey (keys %{ $right->{$key} }) {
            next if $subkey eq 'prereqs';
            if (not exists $left->{$key}{$subkey}) {
              $left->{$key}{$subkey} = $right->{$key}{$subkey};
            }
            else {
              Carp::croak "Cannot merge two optional_features named '$key' with different '$subkey' values"
                if do { no warnings 'uninitialized'; $left->{$key}{$subkey} ne $right->{$key}{$subkey} };
            }
          }
    
          require CPAN::Meta::Prereqs;
          $left->{$key}{prereqs} =
            CPAN::Meta::Prereqs->new($left->{$key}{prereqs})
              ->with_merged_prereqs(CPAN::Meta::Prereqs->new($right->{$key}{prereqs}))
              ->as_string_hash;
        }
      }
      return $left;
    }
    
    
    my %default = (
      abstract       => \&_identical,
      author         => \&_set_addition,
      dynamic_config => sub {
        my ($left, $right) = @_;
        return $left || $right;
      },
      generated_by => sub {
        my ($left, $right) = @_;
        return join ', ', _uniq(split(/, /, $left), split(/, /, $right));
      },
      license     => \&_set_addition,
      'meta-spec' => {
        version => \&_identical,
        url     => \&_identical
      },
      name              => \&_identical,
      release_status    => \&_identical,
      version           => \&_identical,
      description       => \&_identical,
      keywords          => \&_set_addition,
      no_index          => { map { ($_ => \&_set_addition) } qw/file directory package namespace/ },
      optional_features => \&_optional_features,
      prereqs           => sub {
        require CPAN::Meta::Prereqs;
        my ($left, $right) = map { CPAN::Meta::Prereqs->new($_) } @_[0,1];
        return $left->with_merged_prereqs($right)->as_string_hash;
      },
      provides  => \&_uniq_map,
      resources => {
        license    => \&_set_addition,
        homepage   => \&_identical,
        bugtracker => \&_uniq_map,
        repository => \&_uniq_map,
        ':default' => \&_improvize,
      },
      ':default' => \&_improvize,
    );
    
    sub new {
      my ($class, %arguments) = @_;
      croak 'default version required' if not exists $arguments{default_version};
      my %mapping = %default;
      my %extra = %{ $arguments{extra_mappings} || {} };
      for my $key (keys %extra) {
        if (ref($mapping{$key}) eq 'HASH') {
          $mapping{$key} = { %{ $mapping{$key} }, %{ $extra{$key} } };
        }
        else {
          $mapping{$key} = $extra{$key};
        }
      }
      return bless {
        default_version => $arguments{default_version},
        mapping => _coerce_mapping(\%mapping, []),
      }, $class;
    }
    
    my %coderef_for = (
      set_addition => \&_set_addition,
      uniq_map     => \&_uniq_map,
      identical    => \&_identical,
      improvize    => \&_improvize,
    );
    
    sub _coerce_mapping {
      my ($orig, $map_path) = @_;
      my %ret;
      for my $key (keys %{$orig}) {
        my $value = $orig->{$key};
        if (ref($orig->{$key}) eq 'CODE') {
          $ret{$key} = $value;
        }
        elsif (ref($value) eq 'HASH') {
          my $mapping = _coerce_mapping($value, [ @{$map_path}, $key ]);
          $ret{$key} = sub {
            my ($left, $right, $path) = @_;
            return _merge($left, $right, $mapping, [ @{$path} ]);
          };
        }
        elsif ($coderef_for{$value}) {
          $ret{$key} = $coderef_for{$value};
        }
        else {
          croak "Don't know what to do with " . join '.', @{$map_path}, $key;
        }
      }
      return \%ret;
    }
    
    sub merge {
      my ($self, @items) = @_;
      my $current = {};
      for my $next (@items) {
        if ( blessed($next) && $next->isa('CPAN::Meta') ) {
          $next = $next->as_struct;
        }
        elsif ( ref($next) eq 'HASH' ) {
          my $cmc = CPAN::Meta::Converter->new(
            $next, default_version => $self->{default_version}
          );
          $next = $cmc->upgrade_fragment;
        }
        else {
          croak "Don't know how to merge '$next'";
        }
        $current = _merge($current, $next, $self->{mapping}, []);
      }
      return $current;
    }
    
    1;
    
    # ABSTRACT: Merging CPAN Meta fragments
    
    __END__
    
    =pod
    
    =encoding UTF-8
    
    =head1 NAME
    
    CPAN::Meta::Merge - Merging CPAN Meta fragments
    
    =head1 VERSION
    
    version 2.143240
    
    =head1 SYNOPSIS
    
     my $merger = CPAN::Meta::Merge->new(default_version => "2");
     my $meta = $merger->merge($base, @additional);
    
    =head1 DESCRIPTION
    
    =head1 METHODS
    
    =head2 new
    
    This creates a CPAN::Meta::Merge object. It takes one mandatory named
    argument, C<version>, declaring the version of the meta-spec that must be
    used for the merge. It can optionally take an C<extra_mappings> argument
    that allows one to add additional merging functions for specific elements.
    
    =head2 merge(@fragments)
    
    Merge all C<@fragments> together. It will accept both CPAN::Meta objects and
    (possibly incomplete) hashrefs of metadata.
    
    =head1 AUTHORS
    
    =over 4
    
    =item *
    
    David Golden <dagolden@cpan.org>
    
    =item *
    
    Ricardo Signes <rjbs@cpan.org>
    
    =back
    
    =head1 COPYRIGHT AND LICENSE
    
    This software is copyright (c) 2010 by David Golden and Ricardo Signes.
    
    This is free software; you can redistribute it and/or modify it under
    the same terms as the Perl 5 programming language system itself.
    
    =cut
  CPAN_META_MERGE
  
  $fatpacked{"CPAN/Meta/Prereqs.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CPAN_META_PREREQS';
    use 5.006;
    use strict;
    use warnings;
    package CPAN::Meta::Prereqs;
    # VERSION
    $CPAN::Meta::Prereqs::VERSION = '2.143240';
    #pod =head1 DESCRIPTION
    #pod
    #pod A CPAN::Meta::Prereqs object represents the prerequisites for a CPAN
    #pod distribution or one of its optional features.  Each set of prereqs is
    #pod organized by phase and type, as described in L<CPAN::Meta::Prereqs>.
    #pod
    #pod =cut
    
    use Carp qw(confess);
    use Scalar::Util qw(blessed);
    use CPAN::Meta::Requirements 2.121;
    
    #pod =method new
    #pod
    #pod   my $prereq = CPAN::Meta::Prereqs->new( \%prereq_spec );
    #pod
    #pod This method returns a new set of Prereqs.  The input should look like the
    #pod contents of the C<prereqs> field described in L<CPAN::Meta::Spec>, meaning
    #pod something more or less like this:
    #pod
    #pod   my $prereq = CPAN::Meta::Prereqs->new({
    #pod     runtime => {
    #pod       requires => {
    #pod         'Some::Module' => '1.234',
    #pod         ...,
    #pod       },
    #pod       ...,
    #pod     },
    #pod     ...,
    #pod   });
    #pod
    #pod You can also construct an empty set of prereqs with:
    #pod
    #pod   my $prereqs = CPAN::Meta::Prereqs->new;
    #pod
    #pod This empty set of prereqs is useful for accumulating new prereqs before finally
    #pod dumping the whole set into a structure or string.
    #pod
    #pod =cut
    
    sub __legal_phases { qw(configure build test runtime develop)   }
    sub __legal_types  { qw(requires recommends suggests conflicts) }
    
    # expect a prereq spec from META.json -- rjbs, 2010-04-11
    sub new {
      my ($class, $prereq_spec) = @_;
      $prereq_spec ||= {};
    
      my %is_legal_phase = map {; $_ => 1 } $class->__legal_phases;
      my %is_legal_type  = map {; $_ => 1 } $class->__legal_types;
    
      my %guts;
      PHASE: for my $phase (keys %$prereq_spec) {
        next PHASE unless $phase =~ /\Ax_/i or $is_legal_phase{$phase};
    
        my $phase_spec = $prereq_spec->{ $phase };
        next PHASE unless keys %$phase_spec;
    
        TYPE: for my $type (keys %$phase_spec) {
          next TYPE unless $type =~ /\Ax_/i or $is_legal_type{$type};
    
          my $spec = $phase_spec->{ $type };
    
          next TYPE unless keys %$spec;
    
          $guts{prereqs}{$phase}{$type} = CPAN::Meta::Requirements->from_string_hash(
            $spec
          );
        }
      }
    
      return bless \%guts => $class;
    }
    
    #pod =method requirements_for
    #pod
    #pod   my $requirements = $prereqs->requirements_for( $phase, $type );
    #pod
    #pod This method returns a L<CPAN::Meta::Requirements> object for the given
    #pod phase/type combination.  If no prerequisites are registered for that
    #pod combination, a new CPAN::Meta::Requirements object will be returned, and it may
    #pod be added to as needed.
    #pod
    #pod If C<$phase> or C<$type> are undefined or otherwise invalid, an exception will
    #pod be raised.
    #pod
    #pod =cut
    
    sub requirements_for {
      my ($self, $phase, $type) = @_;
    
      confess "requirements_for called without phase" unless defined $phase;
      confess "requirements_for called without type"  unless defined $type;
    
      unless ($phase =~ /\Ax_/i or grep { $phase eq $_ } $self->__legal_phases) {
        confess "requested requirements for unknown phase: $phase";
      }
    
      unless ($type =~ /\Ax_/i or grep { $type eq $_ } $self->__legal_types) {
        confess "requested requirements for unknown type: $type";
      }
    
      my $req = ($self->{prereqs}{$phase}{$type} ||= CPAN::Meta::Requirements->new);
    
      $req->finalize if $self->is_finalized;
    
      return $req;
    }
    
    #pod =method with_merged_prereqs
    #pod
    #pod   my $new_prereqs = $prereqs->with_merged_prereqs( $other_prereqs );
    #pod
    #pod   my $new_prereqs = $prereqs->with_merged_prereqs( \@other_prereqs );
    #pod
    #pod This method returns a new CPAN::Meta::Prereqs objects in which all the
    #pod other prerequisites given are merged into the current set.  This is primarily
    #pod provided for combining a distribution's core prereqs with the prereqs of one of
    #pod its optional features.
    #pod
    #pod The new prereqs object has no ties to the originals, and altering it further
    #pod will not alter them.
    #pod
    #pod =cut
    
    sub with_merged_prereqs {
      my ($self, $other) = @_;
    
      my @other = blessed($other) ? $other : @$other;
    
      my @prereq_objs = ($self, @other);
    
      my %new_arg;
    
      for my $phase ($self->__legal_phases) {
        for my $type ($self->__legal_types) {
          my $req = CPAN::Meta::Requirements->new;
    
          for my $prereq (@prereq_objs) {
            my $this_req = $prereq->requirements_for($phase, $type);
            next unless $this_req->required_modules;
    
            $req->add_requirements($this_req);
          }
    
          next unless $req->required_modules;
    
          $new_arg{ $phase }{ $type } = $req->as_string_hash;
        }
      }
    
      return (ref $self)->new(\%new_arg);
    }
    
    #pod =method merged_requirements
    #pod
    #pod     my $new_reqs = $prereqs->merged_requirements( \@phases, \@types );
    #pod     my $new_reqs = $prereqs->merged_requirements( \@phases );
    #pod     my $new_reqs = $preerqs->merged_requirements();
    #pod
    #pod This method joins together all requirements across a number of phases
    #pod and types into a new L<CPAN::Meta::Requirements> object.  If arguments
    #pod are omitted, it defaults to "runtime", "build" and "test" for phases
    #pod and "requires" and "recommends" for types.
    #pod
    #pod =cut
    
    sub merged_requirements {
      my ($self, $phases, $types) = @_;
      $phases = [qw/runtime build test/] unless defined $phases;
      $types = [qw/requires recommends/] unless defined $types;
    
      confess "merged_requirements phases argument must be an arrayref"
        unless ref $phases eq 'ARRAY';
      confess "merged_requirements types argument must be an arrayref"
        unless ref $types eq 'ARRAY';
    
      my $req = CPAN::Meta::Requirements->new;
    
      for my $phase ( @$phases ) {
        unless ($phase =~ /\Ax_/i or grep { $phase eq $_ } $self->__legal_phases) {
            confess "requested requirements for unknown phase: $phase";
        }
        for my $type ( @$types ) {
          unless ($type =~ /\Ax_/i or grep { $type eq $_ } $self->__legal_types) {
              confess "requested requirements for unknown type: $type";
          }
          $req->add_requirements( $self->requirements_for($phase, $type) );
        }
      }
    
      $req->finalize if $self->is_finalized;
    
      return $req;
    }
    
    
    #pod =method as_string_hash
    #pod
    #pod This method returns a hashref containing structures suitable for dumping into a
    #pod distmeta data structure.  It is made up of hashes and strings, only; there will
    #pod be no Prereqs, CPAN::Meta::Requirements, or C<version> objects inside it.
    #pod
    #pod =cut
    
    sub as_string_hash {
      my ($self) = @_;
    
      my %hash;
    
      for my $phase ($self->__legal_phases) {
        for my $type ($self->__legal_types) {
          my $req = $self->requirements_for($phase, $type);
          next unless $req->required_modules;
    
          $hash{ $phase }{ $type } = $req->as_string_hash;
        }
      }
    
      return \%hash;
    }
    
    #pod =method is_finalized
    #pod
    #pod This method returns true if the set of prereqs has been marked "finalized," and
    #pod cannot be altered.
    #pod
    #pod =cut
    
    sub is_finalized { $_[0]{finalized} }
    
    #pod =method finalize
    #pod
    #pod Calling C<finalize> on a Prereqs object will close it for further modification.
    #pod Attempting to make any changes that would actually alter the prereqs will
    #pod result in an exception being thrown.
    #pod
    #pod =cut
    
    sub finalize {
      my ($self) = @_;
    
      $self->{finalized} = 1;
    
      for my $phase (keys %{ $self->{prereqs} }) {
        $_->finalize for values %{ $self->{prereqs}{$phase} };
      }
    }
    
    #pod =method clone
    #pod
    #pod   my $cloned_prereqs = $prereqs->clone;
    #pod
    #pod This method returns a Prereqs object that is identical to the original object,
    #pod but can be altered without affecting the original object.  Finalization does
    #pod not survive cloning, meaning that you may clone a finalized set of prereqs and
    #pod then modify the clone.
    #pod
    #pod =cut
    
    sub clone {
      my ($self) = @_;
    
      my $clone = (ref $self)->new( $self->as_string_hash );
    }
    
    1;
    
    # ABSTRACT: a set of distribution prerequisites by phase and type
    
    __END__
    
    =pod
    
    =encoding UTF-8
    
    =head1 NAME
    
    CPAN::Meta::Prereqs - a set of distribution prerequisites by phase and type
    
    =head1 VERSION
    
    version 2.143240
    
    =head1 DESCRIPTION
    
    A CPAN::Meta::Prereqs object represents the prerequisites for a CPAN
    distribution or one of its optional features.  Each set of prereqs is
    organized by phase and type, as described in L<CPAN::Meta::Prereqs>.
    
    =head1 METHODS
    
    =head2 new
    
      my $prereq = CPAN::Meta::Prereqs->new( \%prereq_spec );
    
    This method returns a new set of Prereqs.  The input should look like the
    contents of the C<prereqs> field described in L<CPAN::Meta::Spec>, meaning
    something more or less like this:
    
      my $prereq = CPAN::Meta::Prereqs->new({
        runtime => {
          requires => {
            'Some::Module' => '1.234',
            ...,
          },
          ...,
        },
        ...,
      });
    
    You can also construct an empty set of prereqs with:
    
      my $prereqs = CPAN::Meta::Prereqs->new;
    
    This empty set of prereqs is useful for accumulating new prereqs before finally
    dumping the whole set into a structure or string.
    
    =head2 requirements_for
    
      my $requirements = $prereqs->requirements_for( $phase, $type );
    
    This method returns a L<CPAN::Meta::Requirements> object for the given
    phase/type combination.  If no prerequisites are registered for that
    combination, a new CPAN::Meta::Requirements object will be returned, and it may
    be added to as needed.
    
    If C<$phase> or C<$type> are undefined or otherwise invalid, an exception will
    be raised.
    
    =head2 with_merged_prereqs
    
      my $new_prereqs = $prereqs->with_merged_prereqs( $other_prereqs );
    
      my $new_prereqs = $prereqs->with_merged_prereqs( \@other_prereqs );
    
    This method returns a new CPAN::Meta::Prereqs objects in which all the
    other prerequisites given are merged into the current set.  This is primarily
    provided for combining a distribution's core prereqs with the prereqs of one of
    its optional features.
    
    The new prereqs object has no ties to the originals, and altering it further
    will not alter them.
    
    =head2 merged_requirements
    
        my $new_reqs = $prereqs->merged_requirements( \@phases, \@types );
        my $new_reqs = $prereqs->merged_requirements( \@phases );
        my $new_reqs = $preerqs->merged_requirements();
    
    This method joins together all requirements across a number of phases
    and types into a new L<CPAN::Meta::Requirements> object.  If arguments
    are omitted, it defaults to "runtime", "build" and "test" for phases
    and "requires" and "recommends" for types.
    
    =head2 as_string_hash
    
    This method returns a hashref containing structures suitable for dumping into a
    distmeta data structure.  It is made up of hashes and strings, only; there will
    be no Prereqs, CPAN::Meta::Requirements, or C<version> objects inside it.
    
    =head2 is_finalized
    
    This method returns true if the set of prereqs has been marked "finalized," and
    cannot be altered.
    
    =head2 finalize
    
    Calling C<finalize> on a Prereqs object will close it for further modification.
    Attempting to make any changes that would actually alter the prereqs will
    result in an exception being thrown.
    
    =head2 clone
    
      my $cloned_prereqs = $prereqs->clone;
    
    This method returns a Prereqs object that is identical to the original object,
    but can be altered without affecting the original object.  Finalization does
    not survive cloning, meaning that you may clone a finalized set of prereqs and
    then modify the clone.
    
    =head1 BUGS
    
    Please report any bugs or feature using the CPAN Request Tracker.
    Bugs can be submitted through the web interface at
    L<http://rt.cpan.org/Dist/Display.html?Queue=CPAN-Meta>
    
    When submitting a bug or request, please include a test-file or a patch to an
    existing test-file that illustrates the bug or desired feature.
    
    =head1 AUTHORS
    
    =over 4
    
    =item *
    
    David Golden <dagolden@cpan.org>
    
    =item *
    
    Ricardo Signes <rjbs@cpan.org>
    
    =back
    
    =head1 COPYRIGHT AND LICENSE
    
    This software is copyright (c) 2010 by David Golden and Ricardo Signes.
    
    This is free software; you can redistribute it and/or modify it under
    the same terms as the Perl 5 programming language system itself.
    
    =cut
  CPAN_META_PREREQS
  
  $fatpacked{"CPAN/Meta/Requirements.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CPAN_META_REQUIREMENTS';
    use strict;
    use warnings;
    package CPAN::Meta::Requirements;
    # ABSTRACT: a set of version requirements for a CPAN dist
    
    our $VERSION = '2.132';
    
    #pod =head1 SYNOPSIS
    #pod
    #pod   use CPAN::Meta::Requirements;
    #pod
    #pod   my $build_requires = CPAN::Meta::Requirements->new;
    #pod
    #pod   $build_requires->add_minimum('Library::Foo' => 1.208);
    #pod
    #pod   $build_requires->add_minimum('Library::Foo' => 2.602);
    #pod
    #pod   $build_requires->add_minimum('Module::Bar'  => 'v1.2.3');
    #pod
    #pod   $METAyml->{build_requires} = $build_requires->as_string_hash;
    #pod
    #pod =head1 DESCRIPTION
    #pod
    #pod A CPAN::Meta::Requirements object models a set of version constraints like
    #pod those specified in the F<META.yml> or F<META.json> files in CPAN distributions,
    #pod and as defined by L<CPAN::Meta::Spec>;
    #pod It can be built up by adding more and more constraints, and it will reduce them
    #pod to the simplest representation.
    #pod
    #pod Logically impossible constraints will be identified immediately by thrown
    #pod exceptions.
    #pod
    #pod =cut
    
    use Carp ();
    
    # To help ExtUtils::MakeMaker bootstrap CPAN::Meta::Requirements on perls
    # before 5.10, we fall back to the EUMM bundled compatibility version module if
    # that's the only thing available.  This shouldn't ever happen in a normal CPAN
    # install of CPAN::Meta::Requirements, as version.pm will be picked up from
    # prereqs and be available at runtime.
    
    BEGIN {
      eval "use version ()"; ## no critic
      if ( my $err = $@ ) {
        eval "use ExtUtils::MakeMaker::version" or die $err; ## no critic
      }
    }
    
    # Perl 5.10.0 didn't have "is_qv" in version.pm
    *_is_qv = version->can('is_qv') ? sub { $_[0]->is_qv } : sub { exists $_[0]->{qv} };
    
    # construct once, reuse many times
    my $V0 = version->new(0);
    
    #pod =method new
    #pod
    #pod   my $req = CPAN::Meta::Requirements->new;
    #pod
    #pod This returns a new CPAN::Meta::Requirements object.  It takes an optional
    #pod hash reference argument.  Currently, only one key is supported:
    #pod
    #pod =for :list
    #pod * C<bad_version_hook> -- if provided, when a version cannot be parsed into
    #pod   a version object, this code reference will be called with the invalid
    #pod   version string as first argument, and the module name as second
    #pod   argument.  It must return a valid version object.
    #pod
    #pod All other keys are ignored.
    #pod
    #pod =cut
    
    my @valid_options = qw( bad_version_hook );
    
    sub new {
      my ($class, $options) = @_;
      $options ||= {};
      Carp::croak "Argument to $class\->new() must be a hash reference"
        unless ref $options eq 'HASH';
      my %self = map {; $_ => $options->{$_}} @valid_options;
    
      return bless \%self => $class;
    }
    
    # from version::vpp
    sub _find_magic_vstring {
      my $value = shift;
      my $tvalue = '';
      require B;
      my $sv = B::svref_2object(\$value);
      my $magic = ref($sv) eq 'B::PVMG' ? $sv->MAGIC : undef;
      while ( $magic ) {
        if ( $magic->TYPE eq 'V' ) {
          $tvalue = $magic->PTR;
          $tvalue =~ s/^v?(.+)$/v$1/;
          last;
        }
        else {
          $magic = $magic->MOREMAGIC;
        }
      }
      return $tvalue;
    }
    
    # safe if given an unblessed reference
    sub _isa_version {
      UNIVERSAL::isa( $_[0], 'UNIVERSAL' ) && $_[0]->isa('version')
    }
    
    sub _version_object {
      my ($self, $module, $version) = @_;
    
      my $vobj;
    
      # hack around version::vpp not handling <3 character vstring literals
      if ( $INC{'version/vpp.pm'} || $INC{'ExtUtils/MakeMaker/version/vpp.pm'} ) {
        my $magic = _find_magic_vstring( $version );
        $version = $magic if length $magic;
      }
    
      eval {
        if (not defined $version or (!ref($version) && $version eq '0')) {
          $vobj = $V0;
        }
        elsif ( ref($version) eq 'version' || _isa_version($version) ) {
          $vobj = $version;
        }
        else {
          local $SIG{__WARN__} = sub { die "Invalid version: $_[0]" };
          $vobj = version->new($version);
        }
      };
    
      if ( my $err = $@ ) {
        my $hook = $self->{bad_version_hook};
        $vobj = eval { $hook->($version, $module) }
          if ref $hook eq 'CODE';
        unless (eval { $vobj->isa("version") }) {
          $err =~ s{ at .* line \d+.*$}{};
          die "Can't convert '$version': $err";
        }
      }
    
      # ensure no leading '.'
      if ( $vobj =~ m{\A\.} ) {
        $vobj = version->new("0$vobj");
      }
    
      # ensure normal v-string form
      if ( _is_qv($vobj) ) {
        $vobj = version->new($vobj->normal);
      }
    
      return $vobj;
    }
    
    #pod =method add_minimum
    #pod
    #pod   $req->add_minimum( $module => $version );
    #pod
    #pod This adds a new minimum version requirement.  If the new requirement is
    #pod redundant to the existing specification, this has no effect.
    #pod
    #pod Minimum requirements are inclusive.  C<$version> is required, along with any
    #pod greater version number.
    #pod
    #pod This method returns the requirements object.
    #pod
    #pod =method add_maximum
    #pod
    #pod   $req->add_maximum( $module => $version );
    #pod
    #pod This adds a new maximum version requirement.  If the new requirement is
    #pod redundant to the existing specification, this has no effect.
    #pod
    #pod Maximum requirements are inclusive.  No version strictly greater than the given
    #pod version is allowed.
    #pod
    #pod This method returns the requirements object.
    #pod
    #pod =method add_exclusion
    #pod
    #pod   $req->add_exclusion( $module => $version );
    #pod
    #pod This adds a new excluded version.  For example, you might use these three
    #pod method calls:
    #pod
    #pod   $req->add_minimum( $module => '1.00' );
    #pod   $req->add_maximum( $module => '1.82' );
    #pod
    #pod   $req->add_exclusion( $module => '1.75' );
    #pod
    #pod Any version between 1.00 and 1.82 inclusive would be acceptable, except for
    #pod 1.75.
    #pod
    #pod This method returns the requirements object.
    #pod
    #pod =method exact_version
    #pod
    #pod   $req->exact_version( $module => $version );
    #pod
    #pod This sets the version required for the given module to I<exactly> the given
    #pod version.  No other version would be considered acceptable.
    #pod
    #pod This method returns the requirements object.
    #pod
    #pod =cut
    
    BEGIN {
      for my $type (qw(maximum exclusion exact_version)) {
        my $method = "with_$type";
        my $to_add = $type eq 'exact_version' ? $type : "add_$type";
    
        my $code = sub {
          my ($self, $name, $version) = @_;
    
          $version = $self->_version_object( $name, $version );
    
          $self->__modify_entry_for($name, $method, $version);
    
          return $self;
        };
        
        no strict 'refs';
        *$to_add = $code;
      }
    }
    
    sub add_minimum {
      my ($self, $name, $version) = @_;
    
      if (not defined $version or (!ref($version) && $version eq '0')) {
        return $self if $self->__entry_for($name);
        Carp::confess("can't add new requirements to finalized requirements")
          if $self->is_finalized;
    
        $self->{requirements}{ $name } =
          CPAN::Meta::Requirements::_Range::Range->with_minimum($V0);
      }
      else {
        $version = $self->_version_object( $name, $version );
    
        $self->__modify_entry_for($name, 'with_minimum', $version);
      }
      return $self;
    }
    
    #pod =method add_requirements
    #pod
    #pod   $req->add_requirements( $another_req_object );
    #pod
    #pod This method adds all the requirements in the given CPAN::Meta::Requirements object
    #pod to the requirements object on which it was called.  If there are any conflicts,
    #pod an exception is thrown.
    #pod
    #pod This method returns the requirements object.
    #pod
    #pod =cut
    
    sub add_requirements {
      my ($self, $req) = @_;
    
      for my $module ($req->required_modules) {
        my $modifiers = $req->__entry_for($module)->as_modifiers;
        for my $modifier (@$modifiers) {
          my ($method, @args) = @$modifier;
          $self->$method($module => @args);
        };
      }
    
      return $self;
    }
    
    #pod =method accepts_module
    #pod
    #pod   my $bool = $req->accepts_module($module => $version);
    #pod
    #pod Given an module and version, this method returns true if the version
    #pod specification for the module accepts the provided version.  In other words,
    #pod given:
    #pod
    #pod   Module => '>= 1.00, < 2.00'
    #pod
    #pod We will accept 1.00 and 1.75 but not 0.50 or 2.00.
    #pod
    #pod For modules that do not appear in the requirements, this method will return
    #pod true.
    #pod
    #pod =cut
    
    sub accepts_module {
      my ($self, $module, $version) = @_;
    
      $version = $self->_version_object( $module, $version );
    
      return 1 unless my $range = $self->__entry_for($module);
      return $range->_accepts($version);
    }
    
    #pod =method clear_requirement
    #pod
    #pod   $req->clear_requirement( $module );
    #pod
    #pod This removes the requirement for a given module from the object.
    #pod
    #pod This method returns the requirements object.
    #pod
    #pod =cut
    
    sub clear_requirement {
      my ($self, $module) = @_;
    
      return $self unless $self->__entry_for($module);
    
      Carp::confess("can't clear requirements on finalized requirements")
        if $self->is_finalized;
    
      delete $self->{requirements}{ $module };
    
      return $self;
    }
    
    #pod =method requirements_for_module
    #pod
    #pod   $req->requirements_for_module( $module );
    #pod
    #pod This returns a string containing the version requirements for a given module in
    #pod the format described in L<CPAN::Meta::Spec> or undef if the given module has no
    #pod requirements. This should only be used for informational purposes such as error
    #pod messages and should not be interpreted or used for comparison (see
    #pod L</accepts_module> instead.)
    #pod
    #pod =cut
    
    sub requirements_for_module {
      my ($self, $module) = @_;
      my $entry = $self->__entry_for($module);
      return unless $entry;
      return $entry->as_string;
    }
    
    #pod =method required_modules
    #pod
    #pod This method returns a list of all the modules for which requirements have been
    #pod specified.
    #pod
    #pod =cut
    
    sub required_modules { keys %{ $_[0]{requirements} } }
    
    #pod =method clone
    #pod
    #pod   $req->clone;
    #pod
    #pod This method returns a clone of the invocant.  The clone and the original object
    #pod can then be changed independent of one another.
    #pod
    #pod =cut
    
    sub clone {
      my ($self) = @_;
      my $new = (ref $self)->new;
    
      return $new->add_requirements($self);
    }
    
    sub __entry_for     { $_[0]{requirements}{ $_[1] } }
    
    sub __modify_entry_for {
      my ($self, $name, $method, $version) = @_;
    
      my $fin = $self->is_finalized;
      my $old = $self->__entry_for($name);
    
      Carp::confess("can't add new requirements to finalized requirements")
        if $fin and not $old;
    
      my $new = ($old || 'CPAN::Meta::Requirements::_Range::Range')
              ->$method($version);
    
      Carp::confess("can't modify finalized requirements")
        if $fin and $old->as_string ne $new->as_string;
    
      $self->{requirements}{ $name } = $new;
    }
    
    #pod =method is_simple
    #pod
    #pod This method returns true if and only if all requirements are inclusive minimums
    #pod -- that is, if their string expression is just the version number.
    #pod
    #pod =cut
    
    sub is_simple {
      my ($self) = @_;
      for my $module ($self->required_modules) {
        # XXX: This is a complete hack, but also entirely correct.
        return if $self->__entry_for($module)->as_string =~ /\s/;
      }
    
      return 1;
    }
    
    #pod =method is_finalized
    #pod
    #pod This method returns true if the requirements have been finalized by having the
    #pod C<finalize> method called on them.
    #pod
    #pod =cut
    
    sub is_finalized { $_[0]{finalized} }
    
    #pod =method finalize
    #pod
    #pod This method marks the requirements finalized.  Subsequent attempts to change
    #pod the requirements will be fatal, I<if> they would result in a change.  If they
    #pod would not alter the requirements, they have no effect.
    #pod
    #pod If a finalized set of requirements is cloned, the cloned requirements are not
    #pod also finalized.
    #pod
    #pod =cut
    
    sub finalize { $_[0]{finalized} = 1 }
    
    #pod =method as_string_hash
    #pod
    #pod This returns a reference to a hash describing the requirements using the
    #pod strings in the L<CPAN::Meta::Spec> specification.
    #pod
    #pod For example after the following program:
    #pod
    #pod   my $req = CPAN::Meta::Requirements->new;
    #pod
    #pod   $req->add_minimum('CPAN::Meta::Requirements' => 0.102);
    #pod
    #pod   $req->add_minimum('Library::Foo' => 1.208);
    #pod
    #pod   $req->add_maximum('Library::Foo' => 2.602);
    #pod
    #pod   $req->add_minimum('Module::Bar'  => 'v1.2.3');
    #pod
    #pod   $req->add_exclusion('Module::Bar'  => 'v1.2.8');
    #pod
    #pod   $req->exact_version('Xyzzy'  => '6.01');
    #pod
    #pod   my $hashref = $req->as_string_hash;
    #pod
    #pod C<$hashref> would contain:
    #pod
    #pod   {
    #pod     'CPAN::Meta::Requirements' => '0.102',
    #pod     'Library::Foo' => '>= 1.208, <= 2.206',
    #pod     'Module::Bar'  => '>= v1.2.3, != v1.2.8',
    #pod     'Xyzzy'        => '== 6.01',
    #pod   }
    #pod
    #pod =cut
    
    sub as_string_hash {
      my ($self) = @_;
    
      my %hash = map {; $_ => $self->{requirements}{$_}->as_string }
                 $self->required_modules;
    
      return \%hash;
    }
    
    #pod =method add_string_requirement
    #pod
    #pod   $req->add_string_requirement('Library::Foo' => '>= 1.208, <= 2.206');
    #pod   $req->add_string_requirement('Library::Foo' => v1.208);
    #pod
    #pod This method parses the passed in string and adds the appropriate requirement
    #pod for the given module.  A version can be a Perl "v-string".  It understands
    #pod version ranges as described in the L<CPAN::Meta::Spec/Version Ranges>. For
    #pod example:
    #pod
    #pod =over 4
    #pod
    #pod =item 1.3
    #pod
    #pod =item >= 1.3
    #pod
    #pod =item <= 1.3
    #pod
    #pod =item == 1.3
    #pod
    #pod =item != 1.3
    #pod
    #pod =item > 1.3
    #pod
    #pod =item < 1.3
    #pod
    #pod =item >= 1.3, != 1.5, <= 2.0
    #pod
    #pod A version number without an operator is equivalent to specifying a minimum
    #pod (C<E<gt>=>).  Extra whitespace is allowed.
    #pod
    #pod =back
    #pod
    #pod =cut
    
    my %methods_for_op = (
      '==' => [ qw(exact_version) ],
      '!=' => [ qw(add_exclusion) ],
      '>=' => [ qw(add_minimum)   ],
      '<=' => [ qw(add_maximum)   ],
      '>'  => [ qw(add_minimum add_exclusion) ],
      '<'  => [ qw(add_maximum add_exclusion) ],
    );
    
    sub add_string_requirement {
      my ($self, $module, $req) = @_;
    
      unless ( defined $req && length $req ) {
        $req = 0;
        $self->_blank_carp($module);
      }
    
      my $magic = _find_magic_vstring( $req );
      if (length $magic) {
        $self->add_minimum($module => $magic);
        return;
      }
    
      my @parts = split qr{\s*,\s*}, $req;
    
      for my $part (@parts) {
        my ($op, $ver) = $part =~ m{\A\s*(==|>=|>|<=|<|!=)\s*(.*)\z};
    
        if (! defined $op) {
          $self->add_minimum($module => $part);
        } else {
          Carp::confess("illegal requirement string: $req")
            unless my $methods = $methods_for_op{ $op };
    
          $self->$_($module => $ver) for @$methods;
        }
      }
    }
    
    #pod =method from_string_hash
    #pod
    #pod   my $req = CPAN::Meta::Requirements->from_string_hash( \%hash );
    #pod   my $req = CPAN::Meta::Requirements->from_string_hash( \%hash, \%opts );
    #pod
    #pod This is an alternate constructor for a CPAN::Meta::Requirements
    #pod object. It takes a hash of module names and version requirement
    #pod strings and returns a new CPAN::Meta::Requirements object. As with
    #pod add_string_requirement, a version can be a Perl "v-string". Optionally,
    #pod you can supply a hash-reference of options, exactly as with the L</new>
    #pod method.
    #pod
    #pod =cut
    
    sub _blank_carp {
      my ($self, $module) = @_;
      Carp::carp("Undefined requirement for $module treated as '0'");
    }
    
    sub from_string_hash {
      my ($class, $hash, $options) = @_;
    
      my $self = $class->new($options);
    
      for my $module (keys %$hash) {
        my $req = $hash->{$module};
        unless ( defined $req && length $req ) {
          $req = 0;
          $class->_blank_carp($module);
        }
        $self->add_string_requirement($module, $req);
      }
    
      return $self;
    }
    
    ##############################################################
    
    {
      package
        CPAN::Meta::Requirements::_Range::Exact;
      sub _new     { bless { version => $_[1] } => $_[0] }
    
      sub _accepts { return $_[0]{version} == $_[1] }
    
      sub as_string { return "== $_[0]{version}" }
    
      sub as_modifiers { return [ [ exact_version => $_[0]{version} ] ] }
    
      sub _clone {
        (ref $_[0])->_new( version->new( $_[0]{version} ) )
      }
    
      sub with_exact_version {
        my ($self, $version) = @_;
    
        return $self->_clone if $self->_accepts($version);
    
        Carp::confess("illegal requirements: unequal exact version specified");
      }
    
      sub with_minimum {
        my ($self, $minimum) = @_;
        return $self->_clone if $self->{version} >= $minimum;
        Carp::confess("illegal requirements: minimum above exact specification");
      }
    
      sub with_maximum {
        my ($self, $maximum) = @_;
        return $self->_clone if $self->{version} <= $maximum;
        Carp::confess("illegal requirements: maximum below exact specification");
      }
    
      sub with_exclusion {
        my ($self, $exclusion) = @_;
        return $self->_clone unless $exclusion == $self->{version};
        Carp::confess("illegal requirements: excluded exact specification");
      }
    }
    
    ##############################################################
    
    {
      package
        CPAN::Meta::Requirements::_Range::Range;
    
      sub _self { ref($_[0]) ? $_[0] : (bless { } => $_[0]) }
    
      sub _clone {
        return (bless { } => $_[0]) unless ref $_[0];
    
        my ($s) = @_;
        my %guts = (
          (exists $s->{minimum} ? (minimum => version->new($s->{minimum})) : ()),
          (exists $s->{maximum} ? (maximum => version->new($s->{maximum})) : ()),
    
          (exists $s->{exclusions}
            ? (exclusions => [ map { version->new($_) } @{ $s->{exclusions} } ])
            : ()),
        );
    
        bless \%guts => ref($s);
      }
    
      sub as_modifiers {
        my ($self) = @_;
        my @mods;
        push @mods, [ add_minimum => $self->{minimum} ] if exists $self->{minimum};
        push @mods, [ add_maximum => $self->{maximum} ] if exists $self->{maximum};
        push @mods, map {; [ add_exclusion => $_ ] } @{$self->{exclusions} || []};
        return \@mods;
      }
    
      sub as_string {
        my ($self) = @_;
    
        return 0 if ! keys %$self;
    
        return "$self->{minimum}" if (keys %$self) == 1 and exists $self->{minimum};
    
        my @exclusions = @{ $self->{exclusions} || [] };
    
        my @parts;
    
        for my $pair (
          [ qw( >= > minimum ) ],
          [ qw( <= < maximum ) ],
        ) {
          my ($op, $e_op, $k) = @$pair;
          if (exists $self->{$k}) {
            my @new_exclusions = grep { $_ != $self->{ $k } } @exclusions;
            if (@new_exclusions == @exclusions) {
              push @parts, "$op $self->{ $k }";
            } else {
              push @parts, "$e_op $self->{ $k }";
              @exclusions = @new_exclusions;
            }
          }
        }
    
        push @parts, map {; "!= $_" } @exclusions;
    
        return join q{, }, @parts;
      }
    
      sub with_exact_version {
        my ($self, $version) = @_;
        $self = $self->_clone;
    
        Carp::confess("illegal requirements: exact specification outside of range")
          unless $self->_accepts($version);
    
        return CPAN::Meta::Requirements::_Range::Exact->_new($version);
      }
    
      sub _simplify {
        my ($self) = @_;
    
        if (defined $self->{minimum} and defined $self->{maximum}) {
          if ($self->{minimum} == $self->{maximum}) {
            Carp::confess("illegal requirements: excluded all values")
              if grep { $_ == $self->{minimum} } @{ $self->{exclusions} || [] };
    
            return CPAN::Meta::Requirements::_Range::Exact->_new($self->{minimum})
          }
    
          Carp::confess("illegal requirements: minimum exceeds maximum")
            if $self->{minimum} > $self->{maximum};
        }
    
        # eliminate irrelevant exclusions
        if ($self->{exclusions}) {
          my %seen;
          @{ $self->{exclusions} } = grep {
            (! defined $self->{minimum} or $_ >= $self->{minimum})
            and
            (! defined $self->{maximum} or $_ <= $self->{maximum})
            and
            ! $seen{$_}++
          } @{ $self->{exclusions} };
        }
    
        return $self;
      }
    
      sub with_minimum {
        my ($self, $minimum) = @_;
        $self = $self->_clone;
    
        if (defined (my $old_min = $self->{minimum})) {
          $self->{minimum} = (sort { $b cmp $a } ($minimum, $old_min))[0];
        } else {
          $self->{minimum} = $minimum;
        }
    
        return $self->_simplify;
      }
    
      sub with_maximum {
        my ($self, $maximum) = @_;
        $self = $self->_clone;
    
        if (defined (my $old_max = $self->{maximum})) {
          $self->{maximum} = (sort { $a cmp $b } ($maximum, $old_max))[0];
        } else {
          $self->{maximum} = $maximum;
        }
    
        return $self->_simplify;
      }
    
      sub with_exclusion {
        my ($self, $exclusion) = @_;
        $self = $self->_clone;
    
        push @{ $self->{exclusions} ||= [] }, $exclusion;
    
        return $self->_simplify;
      }
    
      sub _accepts {
        my ($self, $version) = @_;
    
        return if defined $self->{minimum} and $version < $self->{minimum};
        return if defined $self->{maximum} and $version > $self->{maximum};
        return if defined $self->{exclusions}
              and grep { $version == $_ } @{ $self->{exclusions} };
    
        return 1;
      }
    }
    
    1;
    # vim: ts=2 sts=2 sw=2 et:
    
    __END__
    
    =pod
    
    =encoding UTF-8
    
    =head1 NAME
    
    CPAN::Meta::Requirements - a set of version requirements for a CPAN dist
    
    =head1 VERSION
    
    version 2.132
    
    =head1 SYNOPSIS
    
      use CPAN::Meta::Requirements;
    
      my $build_requires = CPAN::Meta::Requirements->new;
    
      $build_requires->add_minimum('Library::Foo' => 1.208);
    
      $build_requires->add_minimum('Library::Foo' => 2.602);
    
      $build_requires->add_minimum('Module::Bar'  => 'v1.2.3');
    
      $METAyml->{build_requires} = $build_requires->as_string_hash;
    
    =head1 DESCRIPTION
    
    A CPAN::Meta::Requirements object models a set of version constraints like
    those specified in the F<META.yml> or F<META.json> files in CPAN distributions,
    and as defined by L<CPAN::Meta::Spec>;
    It can be built up by adding more and more constraints, and it will reduce them
    to the simplest representation.
    
    Logically impossible constraints will be identified immediately by thrown
    exceptions.
    
    =head1 METHODS
    
    =head2 new
    
      my $req = CPAN::Meta::Requirements->new;
    
    This returns a new CPAN::Meta::Requirements object.  It takes an optional
    hash reference argument.  Currently, only one key is supported:
    
    =over 4
    
    =item *
    
    C<bad_version_hook> -- if provided, when a version cannot be parsed into a version object, this code reference will be called with the invalid version string as first argument, and the module name as second argument.  It must return a valid version object.
    
    =back
    
    All other keys are ignored.
    
    =head2 add_minimum
    
      $req->add_minimum( $module => $version );
    
    This adds a new minimum version requirement.  If the new requirement is
    redundant to the existing specification, this has no effect.
    
    Minimum requirements are inclusive.  C<$version> is required, along with any
    greater version number.
    
    This method returns the requirements object.
    
    =head2 add_maximum
    
      $req->add_maximum( $module => $version );
    
    This adds a new maximum version requirement.  If the new requirement is
    redundant to the existing specification, this has no effect.
    
    Maximum requirements are inclusive.  No version strictly greater than the given
    version is allowed.
    
    This method returns the requirements object.
    
    =head2 add_exclusion
    
      $req->add_exclusion( $module => $version );
    
    This adds a new excluded version.  For example, you might use these three
    method calls:
    
      $req->add_minimum( $module => '1.00' );
      $req->add_maximum( $module => '1.82' );
    
      $req->add_exclusion( $module => '1.75' );
    
    Any version between 1.00 and 1.82 inclusive would be acceptable, except for
    1.75.
    
    This method returns the requirements object.
    
    =head2 exact_version
    
      $req->exact_version( $module => $version );
    
    This sets the version required for the given module to I<exactly> the given
    version.  No other version would be considered acceptable.
    
    This method returns the requirements object.
    
    =head2 add_requirements
    
      $req->add_requirements( $another_req_object );
    
    This method adds all the requirements in the given CPAN::Meta::Requirements object
    to the requirements object on which it was called.  If there are any conflicts,
    an exception is thrown.
    
    This method returns the requirements object.
    
    =head2 accepts_module
    
      my $bool = $req->accepts_module($module => $version);
    
    Given an module and version, this method returns true if the version
    specification for the module accepts the provided version.  In other words,
    given:
    
      Module => '>= 1.00, < 2.00'
    
    We will accept 1.00 and 1.75 but not 0.50 or 2.00.
    
    For modules that do not appear in the requirements, this method will return
    true.
    
    =head2 clear_requirement
    
      $req->clear_requirement( $module );
    
    This removes the requirement for a given module from the object.
    
    This method returns the requirements object.
    
    =head2 requirements_for_module
    
      $req->requirements_for_module( $module );
    
    This returns a string containing the version requirements for a given module in
    the format described in L<CPAN::Meta::Spec> or undef if the given module has no
    requirements. This should only be used for informational purposes such as error
    messages and should not be interpreted or used for comparison (see
    L</accepts_module> instead.)
    
    =head2 required_modules
    
    This method returns a list of all the modules for which requirements have been
    specified.
    
    =head2 clone
    
      $req->clone;
    
    This method returns a clone of the invocant.  The clone and the original object
    can then be changed independent of one another.
    
    =head2 is_simple
    
    This method returns true if and only if all requirements are inclusive minimums
    -- that is, if their string expression is just the version number.
    
    =head2 is_finalized
    
    This method returns true if the requirements have been finalized by having the
    C<finalize> method called on them.
    
    =head2 finalize
    
    This method marks the requirements finalized.  Subsequent attempts to change
    the requirements will be fatal, I<if> they would result in a change.  If they
    would not alter the requirements, they have no effect.
    
    If a finalized set of requirements is cloned, the cloned requirements are not
    also finalized.
    
    =head2 as_string_hash
    
    This returns a reference to a hash describing the requirements using the
    strings in the L<CPAN::Meta::Spec> specification.
    
    For example after the following program:
    
      my $req = CPAN::Meta::Requirements->new;
    
      $req->add_minimum('CPAN::Meta::Requirements' => 0.102);
    
      $req->add_minimum('Library::Foo' => 1.208);
    
      $req->add_maximum('Library::Foo' => 2.602);
    
      $req->add_minimum('Module::Bar'  => 'v1.2.3');
    
      $req->add_exclusion('Module::Bar'  => 'v1.2.8');
    
      $req->exact_version('Xyzzy'  => '6.01');
    
      my $hashref = $req->as_string_hash;
    
    C<$hashref> would contain:
    
      {
        'CPAN::Meta::Requirements' => '0.102',
        'Library::Foo' => '>= 1.208, <= 2.206',
        'Module::Bar'  => '>= v1.2.3, != v1.2.8',
        'Xyzzy'        => '== 6.01',
      }
    
    =head2 add_string_requirement
    
      $req->add_string_requirement('Library::Foo' => '>= 1.208, <= 2.206');
      $req->add_string_requirement('Library::Foo' => v1.208);
    
    This method parses the passed in string and adds the appropriate requirement
    for the given module.  A version can be a Perl "v-string".  It understands
    version ranges as described in the L<CPAN::Meta::Spec/Version Ranges>. For
    example:
    
    =over 4
    
    =item 1.3
    
    =item >= 1.3
    
    =item <= 1.3
    
    =item == 1.3
    
    =item != 1.3
    
    =item > 1.3
    
    =item < 1.3
    
    =item >= 1.3, != 1.5, <= 2.0
    
    A version number without an operator is equivalent to specifying a minimum
    (C<E<gt>=>).  Extra whitespace is allowed.
    
    =back
    
    =head2 from_string_hash
    
      my $req = CPAN::Meta::Requirements->from_string_hash( \%hash );
      my $req = CPAN::Meta::Requirements->from_string_hash( \%hash, \%opts );
    
    This is an alternate constructor for a CPAN::Meta::Requirements
    object. It takes a hash of module names and version requirement
    strings and returns a new CPAN::Meta::Requirements object. As with
    add_string_requirement, a version can be a Perl "v-string". Optionally,
    you can supply a hash-reference of options, exactly as with the L</new>
    method.
    
    =for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan
    
    =head1 SUPPORT
    
    =head2 Bugs / Feature Requests
    
    Please report any bugs or feature requests through the issue tracker
    at L<https://github.com/dagolden/CPAN-Meta-Requirements/issues>.
    You will be notified automatically of any progress on your issue.
    
    =head2 Source Code
    
    This is open source software.  The code repository is available for
    public review and contribution under the terms of the license.
    
    L<https://github.com/dagolden/CPAN-Meta-Requirements>
    
      git clone https://github.com/dagolden/CPAN-Meta-Requirements.git
    
    =head1 AUTHORS
    
    =over 4
    
    =item *
    
    David Golden <dagolden@cpan.org>
    
    =item *
    
    Ricardo Signes <rjbs@cpan.org>
    
    =back
    
    =head1 CONTRIBUTORS
    
    =for stopwords Ed J Karen Etheridge Leon Timmermans robario
    
    =over 4
    
    =item *
    
    Ed J <mohawk2@users.noreply.github.com>
    
    =item *
    
    Karen Etheridge <ether@cpan.org>
    
    =item *
    
    Leon Timmermans <fawaka@gmail.com>
    
    =item *
    
    robario <webmaster@robario.com>
    
    =back
    
    =head1 COPYRIGHT AND LICENSE
    
    This software is copyright (c) 2010 by David Golden and Ricardo Signes.
    
    This is free software; you can redistribute it and/or modify it under
    the same terms as the Perl 5 programming language system itself.
    
    =cut
  CPAN_META_REQUIREMENTS
  
  $fatpacked{"CPAN/Meta/Spec.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CPAN_META_SPEC';
    # XXX RULES FOR PATCHING THIS FILE XXX
    # Patches that fix typos or formatting are acceptable.  Patches
    # that change semantics are not acceptable without prior approval
    # by David Golden or Ricardo Signes.
    
    use 5.006;
    use strict;
    use warnings;
    package CPAN::Meta::Spec;
    # VERSION
    $CPAN::Meta::Spec::VERSION = '2.143240';
    1;
    
    # ABSTRACT: specification for CPAN distribution metadata
    
    
    # vi:tw=72
    
    __END__
    
    =pod
    
    =encoding UTF-8
    
    =head1 NAME
    
    CPAN::Meta::Spec - specification for CPAN distribution metadata
    
    =head1 VERSION
    
    version 2.143240
    
    =head1 SYNOPSIS
    
      my $distmeta = {
        name => 'Module-Build',
        abstract => 'Build and install Perl modules',
        description =>  "Module::Build is a system for "
          . "building, testing, and installing Perl modules. "
          . "It is meant to ... blah blah blah ...",
        version  => '0.36',
        release_status => 'stable',
        author   => [
          'Ken Williams <kwilliams@cpan.org>',
          'Module-Build List <module-build@perl.org>', # additional contact
        ],
        license  => [ 'perl_5' ],
        prereqs => {
          runtime => {
            requires => {
              'perl'   => '5.006',
              'ExtUtils::Install' => '0',
              'File::Basename' => '0',
              'File::Compare'  => '0',
              'IO::File'   => '0',
            },
            recommends => {
              'Archive::Tar' => '1.00',
              'ExtUtils::Install' => '0.3',
              'ExtUtils::ParseXS' => '2.02',
            },
          },
          build => {
            requires => {
              'Test::More' => '0',
            },
          }
        },
        resources => {
          license => ['http://dev.perl.org/licenses/'],
        },
        optional_features => {
          domination => {
            description => 'Take over the world',
            prereqs     => {
              develop => { requires => { 'Genius::Evil'     => '1.234' } },
              runtime => { requires => { 'Machine::Weather' => '2.0'   } },
            },
          },
        },
        dynamic_config => 1,
        keywords => [ qw/ toolchain cpan dual-life / ],
        'meta-spec' => {
          version => '2',
          url     => 'https://metacpan.org/pod/CPAN::Meta::Spec',
        },
        generated_by => 'Module::Build version 0.36',
      };
    
    =head1 DESCRIPTION
    
    This document describes version 2 of the CPAN distribution metadata
    specification, also known as the "CPAN Meta Spec".
    
    Revisions of this specification for typo corrections and prose
    clarifications may be issued as CPAN::Meta::Spec 2.I<x>.  These
    revisions will never change semantics or add or remove specified
    behavior.
    
    Distribution metadata describe important properties of Perl
    distributions. Distribution building tools like Module::Build,
    Module::Install, ExtUtils::MakeMaker or Dist::Zilla should create a
    metadata file in accordance with this specification and include it with
    the distribution for use by automated tools that index, examine, package
    or install Perl distributions.
    
    =head1 TERMINOLOGY
    
    =over 4
    
    =item distribution
    
    This is the primary object described by the metadata. In the context of
    this document it usually refers to a collection of modules, scripts,
    and/or documents that are distributed together for other developers to
    use.  Examples of distributions are C<Class-Container>, C<libwww-perl>,
    or C<DBI>.
    
    =item module
    
    This refers to a reusable library of code contained in a single file.
    Modules usually contain one or more packages and are often referred
    to by the name of a primary package that can be mapped to the file
    name. For example, one might refer to C<File::Spec> instead of
    F<File/Spec.pm>
    
    =item package
    
    This refers to a namespace declared with the Perl C<package> statement.
    In Perl, packages often have a version number property given by the
    C<$VERSION> variable in the namespace.
    
    =item consumer
    
    This refers to code that reads a metadata file, deserializes it into a
    data structure in memory, or interprets a data structure of metadata
    elements.
    
    =item producer
    
    This refers to code that constructs a metadata data structure,
    serializes into a bytestream and/or writes it to disk.
    
    =item must, should, may, etc.
    
    These terms are interpreted as described in IETF RFC 2119.
    
    =back
    
    =head1 DATA TYPES
    
    Fields in the L</STRUCTURE> section describe data elements, each of
    which has an associated data type as described herein.  There are four
    primitive types: Boolean, String, List and Map.  Other types are
    subtypes of primitives and define compound data structures or define
    constraints on the values of a data element.
    
    =head2 Boolean
    
    A I<Boolean> is used to provide a true or false value.  It B<must> be
    represented as a defined value.
    
    =head2 String
    
    A I<String> is data element containing a non-zero length sequence of
    Unicode characters, such as an ordinary Perl scalar that is not a
    reference.
    
    =head2 List
    
    A I<List> is an ordered collection of zero or more data elements.
    Elements of a List may be of mixed types.
    
    Producers B<must> represent List elements using a data structure which
    unambiguously indicates that multiple values are possible, such as a
    reference to a Perl array (an "arrayref").
    
    Consumers expecting a List B<must> consider a String as equivalent to a
    List of length 1.
    
    =head2 Map
    
    A I<Map> is an unordered collection of zero or more data elements
    ("values"), indexed by associated String elements ("keys").  The Map's
    value elements may be of mixed types.
    
    =head2 License String
    
    A I<License String> is a subtype of String with a restricted set of
    values.  Valid values are described in detail in the description of
    the L</license> field.
    
    =head2 URL
    
    I<URL> is a subtype of String containing a Uniform Resource Locator or
    Identifier.  [ This type is called URL and not URI for historical reasons. ]
    
    =head2 Version
    
    A I<Version> is a subtype of String containing a value that describes
    the version number of packages or distributions.  Restrictions on format
    are described in detail in the L</Version Formats> section.
    
    =head2 Version Range
    
    The I<Version Range> type is a subtype of String.  It describes a range
    of Versions that may be present or installed to fulfill prerequisites.
    It is specified in detail in the L</Version Ranges> section.
    
    =head1 STRUCTURE
    
    The metadata structure is a data element of type Map.  This section
    describes valid keys within the Map.
    
    Any keys not described in this specification document (whether top-level
    or within compound data structures described herein) are considered
    I<custom keys> and B<must> begin with an "x" or "X" and be followed by an
    underscore; i.e. they must match the pattern: C<< qr{\Ax_}i >>.  If a
    custom key refers to a compound data structure, subkeys within it do not
    need an "x_" or "X_" prefix.
    
    Consumers of metadata may ignore any or all custom keys.  All other keys
    not described herein are invalid and should be ignored by consumers.
    Producers must not generate or output invalid keys.
    
    For each key, an example is provided followed by a description.  The
    description begins with the version of spec in which the key was added
    or in which the definition was modified, whether the key is I<required>
    or I<optional> and the data type of the corresponding data element.
    These items are in parentheses, brackets and braces, respectively.
    
    If a data type is a Map or Map subtype, valid subkeys will be described
    as well.
    
    Some fields are marked I<Deprecated>.  These are shown for historical
    context and must not be produced in or consumed from any metadata structure
    of version 2 or higher.
    
    =head2 REQUIRED FIELDS
    
    =head3 abstract
    
    Example:
    
      abstract => 'Build and install Perl modules'
    
    (Spec 1.2) [required] {String}
    
    This is a short description of the purpose of the distribution.
    
    =head3 author
    
    Example:
    
      author => [ 'Ken Williams <kwilliams@cpan.org>' ]
    
    (Spec 1.2) [required] {List of one or more Strings}
    
    This List indicates the person(s) to contact concerning the
    distribution. The preferred form of the contact string is:
    
      contact-name <email-address>
    
    This field provides a general contact list independent of other
    structured fields provided within the L</resources> field, such as
    C<bugtracker>.  The addressee(s) can be contacted for any purpose
    including but not limited to (security) problems with the distribution,
    questions about the distribution or bugs in the distribution.
    
    A distribution's original author is usually the contact listed within
    this field.  Co-maintainers, successor maintainers or mailing lists
    devoted to the distribution may also be listed in addition to or instead
    of the original author.
    
    =head3 dynamic_config
    
    Example:
    
      dynamic_config => 1
    
    (Spec 2) [required] {Boolean}
    
    A boolean flag indicating whether a F<Build.PL> or F<Makefile.PL> (or
    similar) must be executed to determine prerequisites.
    
    This field should be set to a true value if the distribution performs
    some dynamic configuration (asking questions, sensing the environment,
    etc.) as part of its configuration.  This field should be set to a false
    value to indicate that prerequisites included in metadata may be
    considered final and valid for static analysis.
    
    Note: when this field is true, post-configuration prerequisites are not
    guaranteed to bear any relation whatsoever to those stated in the metadata,
    and relying on them doing so is an error. See also
    L</Prerequisites for dynamically configured distributions> in the implementors'
    notes.
    
    This field explicitly B<does not> indicate whether installation may be
    safely performed without using a Makefile or Build file, as there may be
    special files to install or custom installation targets (e.g. for
    dual-life modules that exist on CPAN as well as in the Perl core).  This
    field only defines whether or not prerequisites are exactly as given in the
    metadata.
    
    =head3 generated_by
    
    Example:
    
      generated_by => 'Module::Build version 0.36'
    
    (Spec 1.0) [required] {String}
    
    This field indicates the tool that was used to create this metadata.
    There are no defined semantics for this field, but it is traditional to
    use a string in the form "Generating::Package version 1.23" or the
    author's name, if the file was generated by hand.
    
    =head3 license
    
    Example:
    
      license => [ 'perl_5' ]
    
      license => [ 'apache_2_0', 'mozilla_1_0' ]
    
    (Spec 2) [required] {List of one or more License Strings}
    
    One or more licenses that apply to some or all of the files in the
    distribution.  If multiple licenses are listed, the distribution
    documentation should be consulted to clarify the interpretation of
    multiple licenses.
    
    The following list of license strings are valid:
    
     string          description
     -------------   -----------------------------------------------
     agpl_3          GNU Affero General Public License, Version 3
     apache_1_1      Apache Software License, Version 1.1
     apache_2_0      Apache License, Version 2.0
     artistic_1      Artistic License, (Version 1)
     artistic_2      Artistic License, Version 2.0
     bsd             BSD License (three-clause)
     freebsd         FreeBSD License (two-clause)
     gfdl_1_2        GNU Free Documentation License, Version 1.2
     gfdl_1_3        GNU Free Documentation License, Version 1.3
     gpl_1           GNU General Public License, Version 1
     gpl_2           GNU General Public License, Version 2
     gpl_3           GNU General Public License, Version 3
     lgpl_2_1        GNU Lesser General Public License, Version 2.1
     lgpl_3_0        GNU Lesser General Public License, Version 3.0
     mit             MIT (aka X11) License
     mozilla_1_0     Mozilla Public License, Version 1.0
     mozilla_1_1     Mozilla Public License, Version 1.1
     openssl         OpenSSL License
     perl_5          The Perl 5 License (Artistic 1 & GPL 1 or later)
     qpl_1_0         Q Public License, Version 1.0
     ssleay          Original SSLeay License
     sun             Sun Internet Standards Source License (SISSL)
     zlib            zlib License
    
    The following license strings are also valid and indicate other
    licensing not described above:
    
     string          description
     -------------   -----------------------------------------------
     open_source     Other Open Source Initiative (OSI) approved license
     restricted      Requires special permission from copyright holder
     unrestricted    Not an OSI approved license, but not restricted
     unknown         License not provided in metadata
    
    All other strings are invalid in the license field.
    
    =head3 meta-spec
    
    Example:
    
      'meta-spec' => {
        version => '2',
        url     => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec',
      }
    
    (Spec 1.2) [required] {Map}
    
    This field indicates the version of the CPAN Meta Spec that should be
    used to interpret the metadata.  Consumers must check this key as soon
    as possible and abort further metadata processing if the meta-spec
    version is not supported by the consumer.
    
    The following keys are valid, but only C<version> is required.
    
    =over
    
    =item version
    
    This subkey gives the integer I<Version> of the CPAN Meta Spec against
    which the document was generated.
    
    =item url
    
    This is a I<URL> of the metadata specification document corresponding to
    the given version.  This is strictly for human-consumption and should
    not impact the interpretation of the document.
    
    For the version 2 spec, either of these are recommended:
    
    =over 4
    
    =item *
    
    C<https://metacpan.org/pod/CPAN::Meta::Spec>
    
    =item *
    
    C<http://search.cpan.org/perldoc?CPAN::Meta::Spec>
    
    =back
    
    =back
    
    =head3 name
    
    Example:
    
      name => 'Module-Build'
    
    (Spec 1.0) [required] {String}
    
    This field is the name of the distribution.  This is often created by
    taking the "main package" in the distribution and changing C<::> to
    C<->, but the name may be completely unrelated to the packages within
    the distribution.  For example, L<LWP::UserAgent> is distributed as part
    of the distribution name "libwww-perl".
    
    =head3 release_status
    
    Example:
    
      release_status => 'stable'
    
    (Spec 2) [required] {String}
    
    This field provides the  release status of this distribution.  If the
    C<version> field contains an underscore character, then
    C<release_status> B<must not> be "stable."
    
    The C<release_status> field B<must> have one of the following values:
    
    =over
    
    =item stable
    
    This indicates an ordinary, "final" release that should be indexed by PAUSE
    or other indexers.
    
    =item testing
    
    This indicates a "beta" release that is substantially complete, but has an
    elevated risk of bugs and requires additional testing.  The distribution
    should not be installed over a stable release without an explicit request
    or other confirmation from a user.  This release status may also be used
    for "release candidate" versions of a distribution.
    
    =item unstable
    
    This indicates an "alpha" release that is under active development, but has
    been released for early feedback or testing and may be missing features or
    may have serious bugs.  The distribution should not be installed over a
    stable release without an explicit request or other confirmation from a
    user.
    
    =back
    
    Consumers B<may> use this field to determine how to index the
    distribution for CPAN or other repositories in addition to or in
    replacement of heuristics based on version number or file name.
    
    =head3 version
    
    Example:
    
      version => '0.36'
    
    (Spec 1.0) [required] {Version}
    
    This field gives the version of the distribution to which the metadata
    structure refers.
    
    =head2 OPTIONAL FIELDS
    
    =head3 description
    
    Example:
    
        description =>  "Module::Build is a system for "
          . "building, testing, and installing Perl modules. "
          . "It is meant to ... blah blah blah ...",
    
    (Spec 2) [optional] {String}
    
    A longer, more complete description of the purpose or intended use of
    the distribution than the one provided by the C<abstract> key.
    
    =head3 keywords
    
    Example:
    
      keywords => [ qw/ toolchain cpan dual-life / ]
    
    (Spec 1.1) [optional] {List of zero or more Strings}
    
    A List of keywords that describe this distribution.  Keywords
    B<must not> include whitespace.
    
    =head3 no_index
    
    Example:
    
      no_index => {
        file      => [ 'My/Module.pm' ],
        directory => [ 'My/Private' ],
        package   => [ 'My::Module::Secret' ],
        namespace => [ 'My::Module::Sample' ],
      }
    
    (Spec 1.2) [optional] {Map}
    
    This Map describes any files, directories, packages, and namespaces that
    are private to the packaging or implementation of the distribution and
    should be ignored by indexing or search tools. Note that this is a list of
    exclusions, and the spec does not define what to I<include> - see
    L</Indexing distributions a la PAUSE> in the implementors notes for more
    information.
    
    Valid subkeys are as follows:
    
    =over
    
    =item file
    
    A I<List> of relative paths to files.  Paths B<must be> specified with
    unix conventions.
    
    =item directory
    
    A I<List> of relative paths to directories.  Paths B<must be> specified
    with unix conventions.
    
    [ Note: previous editions of the spec had C<dir> instead of C<directory> ]
    
    =item package
    
    A I<List> of package names.
    
    =item namespace
    
    A I<List> of package namespaces, where anything below the namespace
    must be ignored, but I<not> the namespace itself.
    
    In the example above for C<no_index>, C<My::Module::Sample::Foo> would
    be ignored, but C<My::Module::Sample> would not.
    
    =back
    
    =head3 optional_features
    
    Example:
    
      optional_features => {
        sqlite => {
          description => 'Provides SQLite support',
          prereqs => {
            runtime => {
              requires => {
                'DBD::SQLite' => '1.25'
              }
            }
          }
        }
      }
    
    (Spec 2) [optional] {Map}
    
    This Map describes optional features with incremental prerequisites.
    Each key of the C<optional_features> Map is a String used to identify
    the feature and each value is a Map with additional information about
    the feature.  Valid subkeys include:
    
    =over
    
    =item description
    
    This is a String describing the feature.  Every optional feature
    should provide a description
    
    =item prereqs
    
    This entry is required and has the same structure as that of the
    C<L</prereqs>> key.  It provides a list of package requirements
    that must be satisfied for the feature to be supported or enabled.
    
    There is one crucial restriction:  the prereqs of an optional feature
    B<must not> include C<configure> phase prereqs.
    
    =back
    
    Consumers B<must not> include optional features as prerequisites without
    explicit instruction from users (whether via interactive prompting,
    a function parameter or a configuration value, etc. ).
    
    If an optional feature is used by a consumer to add additional
    prerequisites, the consumer should merge the optional feature
    prerequisites into those given by the C<prereqs> key using the same
    semantics.  See L</Merging and Resolving Prerequisites> for details on
    merging prerequisites.
    
    I<Suggestion for disuse:> Because there is currently no way for a
    distribution to specify a dependency on an optional feature of another
    dependency, the use of C<optional_feature> is discouraged.  Instead,
    create a separate, installable distribution that ensures the desired
    feature is available.  For example, if C<Foo::Bar> has a C<Baz> feature,
    release a separate C<Foo-Bar-Baz> distribution that satisfies
    requirements for the feature.
    
    =head3 prereqs
    
    Example:
    
      prereqs => {
        runtime => {
          requires => {
            'perl'          => '5.006',
            'File::Spec'    => '0.86',
            'JSON'          => '2.16',
          },
          recommends => {
            'JSON::XS'      => '2.26',
          },
          suggests => {
            'Archive::Tar'  => '0',
          },
        },
        build => {
          requires => {
            'Alien::SDL'    => '1.00',
          },
        },
        test => {
          recommends => {
            'Test::Deep'    => '0.10',
          },
        }
      }
    
    (Spec 2) [optional] {Map}
    
    This is a Map that describes all the prerequisites of the distribution.
    The keys are phases of activity, such as C<configure>, C<build>, C<test>
    or C<runtime>.  Values are Maps in which the keys name the type of
    prerequisite relationship such as C<requires>, C<recommends>, or
    C<suggests> and the value provides a set of prerequisite relations.  The
    set of relations B<must> be specified as a Map of package names to
    version ranges.
    
    The full definition for this field is given in the L</Prereq Spec>
    section.
    
    =head3 provides
    
    Example:
    
      provides => {
        'Foo::Bar' => {
          file    => 'lib/Foo/Bar.pm',
          version => '0.27_02',
        },
        'Foo::Bar::Blah' => {
          file    => 'lib/Foo/Bar/Blah.pm',
        },
        'Foo::Bar::Baz' => {
          file    => 'lib/Foo/Bar/Baz.pm',
          version => '0.3',
        },
      }
    
    (Spec 1.2) [optional] {Map}
    
    This describes all packages provided by this distribution.  This
    information is used by distribution and automation mechanisms like
    PAUSE, CPAN, metacpan.org and search.cpan.org to build indexes saying in
    which distribution various packages can be found.
    
    The keys of C<provides> are package names that can be found within
    the distribution.  If a package name key is provided, it must
    have a Map with the following valid subkeys:
    
    =over
    
    =item file
    
    This field is required.  It must contain a Unix-style relative file path
    from the root of the distribution directory to a file that contains or
    generates the package.  It may be given as C<META.yml> or C<META.json>
    to claim a package for indexing without needing a C<*.pm>.
    
    =item version
    
    If it exists, this field must contains a I<Version> String for the
    package.  If the package does not have a C<$VERSION>, this field must
    be omitted.
    
    =back
    
    =head3 resources
    
    Example:
    
      resources => {
        license     => [ 'http://dev.perl.org/licenses/' ],
        homepage    => 'http://sourceforge.net/projects/module-build',
        bugtracker  => {
          web    => 'http://rt.cpan.org/Public/Dist/Display.html?Name=CPAN-Meta',
          mailto => 'meta-bugs@example.com',
        },
        repository  => {
          url  => 'git://github.com/dagolden/cpan-meta.git',
          web  => 'http://github.com/dagolden/cpan-meta',
          type => 'git',
        },
        x_twitter   => 'http://twitter.com/cpan_linked/',
      }
    
    (Spec 2) [optional] {Map}
    
    This field describes resources related to this distribution.
    
    Valid subkeys include:
    
    =over
    
    =item homepage
    
    The official home of this project on the web.
    
    =item license
    
    A List of I<URL>'s that relate to this distribution's license.  As with the
    top-level C<license> field, distribution documentation should be consulted
    to clarify the interpretation of multiple licenses provided here.
    
    =item bugtracker
    
    This entry describes the bug tracking system for this distribution.  It
    is a Map with the following valid keys:
    
      web    - a URL pointing to a web front-end for the bug tracker
      mailto - an email address to which bugs can be sent
    
    =item repository
    
    This entry describes the source control repository for this distribution.  It
    is a Map with the following valid keys:
    
      url  - a URL pointing to the repository itself
      web  - a URL pointing to a web front-end for the repository
      type - a lowercase string indicating the VCS used
    
    Because a url like C<http://myrepo.example.com/> is ambiguous as to
    type, producers should provide a C<type> whenever a C<url> key is given.
    The C<type> field should be the name of the most common program used
    to work with the repository, e.g. C<git>, C<svn>, C<cvs>, C<darcs>,
    C<bzr> or C<hg>.
    
    =back
    
    =head2 DEPRECATED FIELDS
    
    =head3 build_requires
    
    I<(Deprecated in Spec 2)> [optional] {String}
    
    Replaced by C<prereqs>
    
    =head3 configure_requires
    
    I<(Deprecated in Spec 2)> [optional] {String}
    
    Replaced by C<prereqs>
    
    =head3 conflicts
    
    I<(Deprecated in Spec 2)> [optional] {String}
    
    Replaced by C<prereqs>
    
    =head3 distribution_type
    
    I<(Deprecated in Spec 2)> [optional] {String}
    
    This field indicated 'module' or 'script' but was considered
    meaningless, since many distributions are hybrids of several kinds of
    things.
    
    =head3 license_uri
    
    I<(Deprecated in Spec 1.2)> [optional] {URL}
    
    Replaced by C<license> in C<resources>
    
    =head3 private
    
    I<(Deprecated in Spec 1.2)> [optional] {Map}
    
    This field has been renamed to L</"no_index">.
    
    =head3 recommends
    
    I<(Deprecated in Spec 2)> [optional] {String}
    
    Replaced by C<prereqs>
    
    =head3 requires
    
    I<(Deprecated in Spec 2)> [optional] {String}
    
    Replaced by C<prereqs>
    
    =head1 VERSION NUMBERS
    
    =head2 Version Formats
    
    This section defines the Version type, used by several fields in the
    CPAN Meta Spec.
    
    Version numbers must be treated as strings, not numbers.  For
    example, C<1.200> B<must not> be serialized as C<1.2>.  Version
    comparison should be delegated to the Perl L<version> module, version
    0.80 or newer.
    
    Unless otherwise specified, version numbers B<must> appear in one of two
    formats:
    
    =over
    
    =item Decimal versions
    
    Decimal versions are regular "decimal numbers", with some limitations.
    They B<must> be non-negative and B<must> begin and end with a digit.  A
    single underscore B<may> be included, but B<must> be between two digits.
    They B<must not> use exponential notation ("1.23e-2").
    
       version => '1.234'       # OK
       version => '1.23_04'     # OK
    
       version => '1.23_04_05'  # Illegal
       version => '1.'          # Illegal
       version => '.1'          # Illegal
    
    =item Dotted-integer versions
    
    Dotted-integer (also known as dotted-decimal) versions consist of
    positive integers separated by full stop characters (i.e. "dots",
    "periods" or "decimal points").  This are equivalent in format to Perl
    "v-strings", with some additional restrictions on form.  They must be
    given in "normal" form, which has a leading "v" character and at least
    three integer components.  To retain a one-to-one mapping with decimal
    versions, all components after the first B<should> be restricted to the
    range 0 to 999.  The final component B<may> be separated by an
    underscore character instead of a period.
    
       version => 'v1.2.3'      # OK
       version => 'v1.2_3'      # OK
       version => 'v1.2.3.4'    # OK
       version => 'v1.2.3_4'    # OK
       version => 'v2009.10.31' # OK
    
       version => 'v1.2'          # Illegal
       version => '1.2.3'         # Illegal
       version => 'v1.2_3_4'      # Illegal
       version => 'v1.2009.10.31' # Not recommended
    
    =back
    
    =head2 Version Ranges
    
    Some fields (prereq, optional_features) indicate the particular
    version(s) of some other module that may be required as a prerequisite.
    This section details the Version Range type used to provide this
    information.
    
    The simplest format for a Version Range is just the version
    number itself, e.g. C<2.4>.  This means that B<at least> version 2.4
    must be present.  To indicate that B<any> version of a prerequisite is
    okay, even if the prerequisite doesn't define a version at all, use
    the version C<0>.
    
    Alternatively, a version range B<may> use the operators E<lt> (less than),
    E<lt>= (less than or equal), E<gt> (greater than), E<gt>= (greater than
    or equal), == (equal), and != (not equal).  For example, the
    specification C<E<lt> 2.0> means that any version of the prerequisite
    less than 2.0 is suitable.
    
    For more complicated situations, version specifications B<may> be AND-ed
    together using commas.  The specification C<E<gt>= 1.2, != 1.5, E<lt>
    2.0> indicates a version that must be B<at least> 1.2, B<less than> 2.0,
    and B<not equal to> 1.5.
    
    =head1 PREREQUISITES
    
    =head2 Prereq Spec
    
    The C<prereqs> key in the top-level metadata and within
    C<optional_features> define the relationship between a distribution and
    other packages.  The prereq spec structure is a hierarchical data
    structure which divides prerequisites into I<Phases> of activity in the
    installation process and I<Relationships> that indicate how
    prerequisites should be resolved.
    
    For example, to specify that C<Data::Dumper> is C<required> during the
    C<test> phase, this entry would appear in the distribution metadata:
    
      prereqs => {
        test => {
          requires => {
            'Data::Dumper' => '2.00'
          }
        }
      }
    
    =head3 Phases
    
    Requirements for regular use must be listed in the C<runtime> phase.
    Other requirements should be listed in the earliest stage in which they
    are required and consumers must accumulate and satisfy requirements
    across phases before executing the activity. For example, C<build>
    requirements must also be available during the C<test> phase.
    
      before action       requirements that must be met
      ----------------    --------------------------------
      perl Build.PL       configure
      perl Makefile.PL
    
      make                configure, runtime, build
      Build
    
      make test           configure, runtime, build, test
      Build test
    
    Consumers that install the distribution must ensure that
    I<runtime> requirements are also installed and may install
    dependencies from other phases.
    
      after action        requirements that must be met
      ----------------    --------------------------------
      make install        runtime
      Build install
    
    =over
    
    =item configure
    
    The configure phase occurs before any dynamic configuration has been
    attempted.  Libraries required by the configure phase B<must> be
    available for use before the distribution building tool has been
    executed.
    
    =item build
    
    The build phase is when the distribution's source code is compiled (if
    necessary) and otherwise made ready for installation.
    
    =item test
    
    The test phase is when the distribution's automated test suite is run.
    Any library that is needed only for testing and not for subsequent use
    should be listed here.
    
    =item runtime
    
    The runtime phase refers not only to when the distribution's contents
    are installed, but also to its continued use.  Any library that is a
    prerequisite for regular use of this distribution should be indicated
    here.
    
    =item develop
    
    The develop phase's prereqs are libraries needed to work on the
    distribution's source code as its author does.  These tools might be
    needed to build a release tarball, to run author-only tests, or to
    perform other tasks related to developing new versions of the
    distribution.
    
    =back
    
    =head3 Relationships
    
    =over
    
    =item requires
    
    These dependencies B<must> be installed for proper completion of the
    phase.
    
    =item recommends
    
    Recommended dependencies are I<strongly> encouraged and should be
    satisfied except in resource constrained environments.
    
    =item suggests
    
    These dependencies are optional, but are suggested for enhanced operation
    of the described distribution.
    
    =item conflicts
    
    These libraries cannot be installed when the phase is in operation.
    This is a very rare situation, and the C<conflicts> relationship should
    be used with great caution, or not at all.
    
    =back
    
    =head2 Merging and Resolving Prerequisites
    
    Whenever metadata consumers merge prerequisites, either from different
    phases or from C<optional_features>, they should merged in a way which
    preserves the intended semantics of the prerequisite structure.  Generally,
    this means concatenating the version specifications using commas, as
    described in the L<Version Ranges> section.
    
    Another subtle error that can occur in resolving prerequisites comes from
    the way that modules in prerequisites are indexed to distribution files on
    CPAN.  When a module is deleted from a distribution, prerequisites calling
    for that module could indicate an older distribution should be installed,
    potentially overwriting files from a newer distribution.
    
    For example, as of Oct 31, 2009, the CPAN index file contained these
    module-distribution mappings:
    
      Class::MOP                   0.94  D/DR/DROLSKY/Class-MOP-0.94.tar.gz
      Class::MOP::Class            0.94  D/DR/DROLSKY/Class-MOP-0.94.tar.gz
      Class::MOP::Class::Immutable 0.04  S/ST/STEVAN/Class-MOP-0.36.tar.gz
    
    Consider the case where "Class::MOP" 0.94 is installed.  If a
    distribution specified "Class::MOP::Class::Immutable" as a prerequisite,
    it could result in Class-MOP-0.36.tar.gz being installed, overwriting
    any files from Class-MOP-0.94.tar.gz.
    
    Consumers of metadata B<should> test whether prerequisites would result
    in installed module files being "downgraded" to an older version and
    B<may> warn users or ignore the prerequisite that would cause such a
    result.
    
    =head1 SERIALIZATION
    
    Distribution metadata should be serialized (as a hashref) as
    JSON-encoded data and packaged with distributions as the file
    F<META.json>.
    
    In the past, the distribution metadata structure had been packed with
    distributions as F<META.yml>, a file in the YAML Tiny format (for which,
    see L<YAML::Tiny>).  Tools that consume distribution metadata from disk
    should be capable of loading F<META.yml>, but should prefer F<META.json>
    if both are found.
    
    =head1 NOTES FOR IMPLEMENTORS
    
    =head2 Extracting Version Numbers from Perl Modules
    
    To get the version number from a Perl module, consumers should use the
    C<< MM->parse_version($file) >> method provided by
    L<ExtUtils::MakeMaker> or L<Module::Metadata>.  For example, for the
    module given by C<$mod>, the version may be retrieved in one of the
    following ways:
    
      # via ExtUtils::MakeMaker
      my $file = MM->_installed_file_for_module($mod);
      my $version = MM->parse_version($file)
    
    The private C<_installed_file_for_module> method may be replaced with
    other methods for locating a module in C<@INC>.
    
      # via Module::Metadata
      my $info = Module::Metadata->new_from_module($mod);
      my $version = $info->version;
    
    If only a filename is available, the following approach may be used:
    
      # via Module::Build
      my $info = Module::Metadata->new_from_file($file);
      my $version = $info->version;
    
    =head2 Comparing Version Numbers
    
    The L<version> module provides the most reliable way to compare version
    numbers in all the various ways they might be provided or might exist
    within modules.  Given two strings containing version numbers, C<$v1> and
    C<$v2>, they should be converted to C<version> objects before using
    ordinary comparison operators.  For example:
    
      use version;
      if ( version->new($v1) <=> version->new($v2) ) {
        print "Versions are not equal\n";
      }
    
    If the only comparison needed is whether an installed module is of a
    sufficiently high version, a direct test may be done using the string
    form of C<eval> and the C<use> function.  For example, for module C<$mod>
    and version prerequisite C<$prereq>:
    
      if ( eval "use $mod $prereq (); 1" ) {
        print "Module $mod version is OK.\n";
      }
    
    If the values of C<$mod> and C<$prereq> have not been scrubbed, however,
    this presents security implications.
    
    =head2 Prerequisites for dynamically configured distributions
    
    When C<dynamic_config> is true, it is an error to presume that the
    prerequisites given in distribution metadata will have any relationship
    whatsoever to the actual prerequisites of the distribution.
    
    In practice, however, one can generally expect such prerequisites to be
    one of two things:
    
    =over 4
    
    =item *
    
    The minimum prerequisites for the distribution, to which dynamic configuration will only add items
    
    =item *
    
    Whatever the distribution configured with on the releaser's machine at release time
    
    =back
    
    The second case often turns out to have identical results to the first case,
    albeit only by accident.
    
    As such, consumers may use this data for informational analysis, but
    presenting it to the user as canonical or relying on it as such is
    invariably the height of folly.
    
    =head2 Indexing distributions a la PAUSE
    
    While no_index tells you what must be ignored when indexing, this spec holds
    no opinion on how you should get your initial candidate list of things to
    possibly index. For "normal" distributions you might consider simply indexing
    the contents of lib/, but there are many fascinating oddities on CPAN and
    many dists from the days when it was normal to put the main .pm file in the
    root of the distribution archive - so PAUSE currently indexes all .pm and .PL
    files that are not either (a) specifically excluded by no_index (b) in
    C<inc>, C<xt>, or C<t> directories, or common 'mistake' directories such as
    C<perl5>.
    
    Or: If you're trying to be PAUSE-like, make sure you skip C<inc>, C<xt> and
    C<t> as well as anything marked as no_index.
    
    Also remember: If the META file contains a provides field, you shouldn't be
    indexing anything in the first place - just use that.
    
    =head1 SEE ALSO
    
    =over 4
    
    =item *
    
    CPAN, L<http://www.cpan.org/>
    
    =item *
    
    JSON, L<http://json.org/>
    
    =item *
    
    YAML, L<http://www.yaml.org/>
    
    =item *
    
    L<CPAN>
    
    =item *
    
    L<CPANPLUS>
    
    =item *
    
    L<ExtUtils::MakeMaker>
    
    =item *
    
    L<Module::Build>
    
    =item *
    
    L<Module::Install>
    
    =back
    
    =head1 HISTORY
    
    Ken Williams wrote the original CPAN Meta Spec (also known as the
    "META.yml spec") in 2003 and maintained it through several revisions
    with input from various members of the community.  In 2005, Randy
    Sims redrafted it from HTML to POD for the version 1.2 release.  Ken
    continued to maintain the spec through version 1.4.
    
    In late 2009, David Golden organized the version 2 proposal review
    process.  David and Ricardo Signes drafted the final version 2 spec
    in April 2010 based on the version 1.4 spec and patches contributed
    during the proposal process.
    
    =head1 AUTHORS
    
    =over 4
    
    =item *
    
    David Golden <dagolden@cpan.org>
    
    =item *
    
    Ricardo Signes <rjbs@cpan.org>
    
    =back
    
    =head1 COPYRIGHT AND LICENSE
    
    This software is copyright (c) 2010 by David Golden and Ricardo Signes.
    
    This is free software; you can redistribute it and/or modify it under
    the same terms as the Perl 5 programming language system itself.
    
    =cut
  CPAN_META_SPEC
  
  $fatpacked{"CPAN/Meta/Validator.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CPAN_META_VALIDATOR';
    use 5.006;
    use strict;
    use warnings;
    package CPAN::Meta::Validator;
    # VERSION
    $CPAN::Meta::Validator::VERSION = '2.143240';
    #pod =head1 SYNOPSIS
    #pod
    #pod   my $struct = decode_json_file('META.json');
    #pod
    #pod   my $cmv = CPAN::Meta::Validator->new( $struct );
    #pod
    #pod   unless ( $cmv->is_valid ) {
    #pod     my $msg = "Invalid META structure.  Errors found:\n";
    #pod     $msg .= join( "\n", $cmv->errors );
    #pod     die $msg;
    #pod   }
    #pod
    #pod =head1 DESCRIPTION
    #pod
    #pod This module validates a CPAN Meta structure against the version of the
    #pod the specification claimed in the C<meta-spec> field of the structure.
    #pod
    #pod =cut
    
    #--------------------------------------------------------------------------#
    # This code copied and adapted from Test::CPAN::Meta
    # by Barbie, <barbie@cpan.org> for Miss Barbell Productions,
    # L<http://www.missbarbell.co.uk>
    #--------------------------------------------------------------------------#
    
    #--------------------------------------------------------------------------#
    # Specification Definitions
    #--------------------------------------------------------------------------#
    
    my %known_specs = (
        '1.4' => 'http://module-build.sourceforge.net/META-spec-v1.4.html',
        '1.3' => 'http://module-build.sourceforge.net/META-spec-v1.3.html',
        '1.2' => 'http://module-build.sourceforge.net/META-spec-v1.2.html',
        '1.1' => 'http://module-build.sourceforge.net/META-spec-v1.1.html',
        '1.0' => 'http://module-build.sourceforge.net/META-spec-v1.0.html'
    );
    my %known_urls = map {$known_specs{$_} => $_} keys %known_specs;
    
    my $module_map1 = { 'map' => { ':key' => { name => \&module, value => \&exversion } } };
    
    my $module_map2 = { 'map' => { ':key' => { name => \&module, value => \&version   } } };
    
    my $no_index_2 = {
        'map'       => { file       => { list => { value => \&string } },
                         directory  => { list => { value => \&string } },
                         'package'  => { list => { value => \&string } },
                         namespace  => { list => { value => \&string } },
                        ':key'      => { name => \&custom_2, value => \&anything },
        }
    };
    
    my $no_index_1_3 = {
        'map'       => { file       => { list => { value => \&string } },
                         directory  => { list => { value => \&string } },
                         'package'  => { list => { value => \&string } },
                         namespace  => { list => { value => \&string } },
                         ':key'     => { name => \&string, value => \&anything },
        }
    };
    
    my $no_index_1_2 = {
        'map'       => { file       => { list => { value => \&string } },
                         dir        => { list => { value => \&string } },
                         'package'  => { list => { value => \&string } },
                         namespace  => { list => { value => \&string } },
                         ':key'     => { name => \&string, value => \&anything },
        }
    };
    
    my $no_index_1_1 = {
        'map'       => { ':key'     => { name => \&string, list => { value => \&string } },
        }
    };
    
    my $prereq_map = {
      map => {
        ':key' => {
          name => \&phase,
          'map' => {
            ':key'  => {
              name => \&relation,
              %$module_map1,
            },
          },
        }
      },
    };
    
    my %definitions = (
      '2' => {
        # REQUIRED
        'abstract'            => { mandatory => 1, value => \&string  },
        'author'              => { mandatory => 1, list => { value => \&string } },
        'dynamic_config'      => { mandatory => 1, value => \&boolean },
        'generated_by'        => { mandatory => 1, value => \&string  },
        'license'             => { mandatory => 1, list => { value => \&license } },
        'meta-spec' => {
          mandatory => 1,
          'map' => {
            version => { mandatory => 1, value => \&version},
            url     => { value => \&url },
            ':key' => { name => \&custom_2, value => \&anything },
          }
        },
        'name'                => { mandatory => 1, value => \&string  },
        'release_status'      => { mandatory => 1, value => \&release_status },
        'version'             => { mandatory => 1, value => \&version },
    
        # OPTIONAL
        'description' => { value => \&string },
        'keywords'    => { list => { value => \&string } },
        'no_index'    => $no_index_2,
        'optional_features'   => {
          'map'       => {
            ':key'  => {
              name => \&string,
              'map'   => {
                description        => { value => \&string },
                prereqs => $prereq_map,
                ':key' => { name => \&custom_2, value => \&anything },
              }
            }
          }
        },
        'prereqs' => $prereq_map,
        'provides'    => {
          'map'       => {
            ':key' => {
              name  => \&module,
              'map' => {
                file    => { mandatory => 1, value => \&file },
                version => { value => \&version },
                ':key' => { name => \&custom_2, value => \&anything },
              }
            }
          }
        },
        'resources'   => {
          'map'       => {
            license    => { list => { value => \&url } },
            homepage   => { value => \&url },
            bugtracker => {
              'map' => {
                web => { value => \&url },
                mailto => { value => \&string},
                ':key' => { name => \&custom_2, value => \&anything },
              }
            },
            repository => {
              'map' => {
                web => { value => \&url },
                url => { value => \&url },
                type => { value => \&string },
                ':key' => { name => \&custom_2, value => \&anything },
              }
            },
            ':key'     => { value => \&string, name => \&custom_2 },
          }
        },
    
        # CUSTOM -- additional user defined key/value pairs
        # note we can only validate the key name, as the structure is user defined
        ':key'        => { name => \&custom_2, value => \&anything },
      },
    
    '1.4' => {
      'meta-spec'           => {
        mandatory => 1,
        'map' => {
          version => { mandatory => 1, value => \&version},
          url     => { mandatory => 1, value => \&urlspec },
          ':key'  => { name => \&string, value => \&anything },
        },
      },
    
      'name'                => { mandatory => 1, value => \&string  },
      'version'             => { mandatory => 1, value => \&version },
      'abstract'            => { mandatory => 1, value => \&string  },
      'author'              => { mandatory => 1, list  => { value => \&string } },
      'license'             => { mandatory => 1, value => \&license },
      'generated_by'        => { mandatory => 1, value => \&string  },
    
      'distribution_type'   => { value => \&string  },
      'dynamic_config'      => { value => \&boolean },
    
      'requires'            => $module_map1,
      'recommends'          => $module_map1,
      'build_requires'      => $module_map1,
      'configure_requires'  => $module_map1,
      'conflicts'           => $module_map2,
    
      'optional_features'   => {
        'map'       => {
            ':key'  => { name => \&string,
                'map'   => { description        => { value => \&string },
                             requires           => $module_map1,
                             recommends         => $module_map1,
                             build_requires     => $module_map1,
                             conflicts          => $module_map2,
                             ':key'  => { name => \&string, value => \&anything },
                }
            }
         }
      },
    
      'provides'    => {
        'map'       => {
          ':key' => { name  => \&module,
            'map' => {
              file    => { mandatory => 1, value => \&file },
              version => { value => \&version },
              ':key'  => { name => \&string, value => \&anything },
            }
          }
        }
      },
    
      'no_index'    => $no_index_1_3,
      'private'     => $no_index_1_3,
    
      'keywords'    => { list => { value => \&string } },
    
      'resources'   => {
        'map'       => { license    => { value => \&url },
                         homepage   => { value => \&url },
                         bugtracker => { value => \&url },
                         repository => { value => \&url },
                         ':key'     => { value => \&string, name => \&custom_1 },
        }
      },
    
      # additional user defined key/value pairs
      # note we can only validate the key name, as the structure is user defined
      ':key'        => { name => \&string, value => \&anything },
    },
    
    '1.3' => {
      'meta-spec'           => {
        mandatory => 1,
        'map' => {
          version => { mandatory => 1, value => \&version},
          url     => { mandatory => 1, value => \&urlspec },
          ':key'  => { name => \&string, value => \&anything },
        },
      },
    
      'name'                => { mandatory => 1, value => \&string  },
      'version'             => { mandatory => 1, value => \&version },
      'abstract'            => { mandatory => 1, value => \&string  },
      'author'              => { mandatory => 1, list  => { value => \&string } },
      'license'             => { mandatory => 1, value => \&license },
      'generated_by'        => { mandatory => 1, value => \&string  },
    
      'distribution_type'   => { value => \&string  },
      'dynamic_config'      => { value => \&boolean },
    
      'requires'            => $module_map1,
      'recommends'          => $module_map1,
      'build_requires'      => $module_map1,
      'conflicts'           => $module_map2,
    
      'optional_features'   => {
        'map'       => {
            ':key'  => { name => \&string,
                'map'   => { description        => { value => \&string },
                             requires           => $module_map1,
                             recommends         => $module_map1,
                             build_requires     => $module_map1,
                             conflicts          => $module_map2,
                             ':key'  => { name => \&string, value => \&anything },
                }
            }
         }
      },
    
      'provides'    => {
        'map'       => {
          ':key' => { name  => \&module,
            'map' => {
              file    => { mandatory => 1, value => \&file },
              version => { value => \&version },
              ':key'  => { name => \&string, value => \&anything },
            }
          }
        }
      },
    
    
      'no_index'    => $no_index_1_3,
      'private'     => $no_index_1_3,
    
      'keywords'    => { list => { value => \&string } },
    
      'resources'   => {
        'map'       => { license    => { value => \&url },
                         homepage   => { value => \&url },
                         bugtracker => { value => \&url },
                         repository => { value => \&url },
                         ':key'     => { value => \&string, name => \&custom_1 },
        }
      },
    
      # additional user defined key/value pairs
      # note we can only validate the key name, as the structure is user defined
      ':key'        => { name => \&string, value => \&anything },
    },
    
    # v1.2 is misleading, it seems to assume that a number of fields where created
    # within v1.1, when they were created within v1.2. This may have been an
    # original mistake, and that a v1.1 was retro fitted into the timeline, when
    # v1.2 was originally slated as v1.1. But I could be wrong ;)
    '1.2' => {
      'meta-spec'           => {
        mandatory => 1,
        'map' => {
          version => { mandatory => 1, value => \&version},
          url     => { mandatory => 1, value => \&urlspec },
          ':key'  => { name => \&string, value => \&anything },
        },
      },
    
    
      'name'                => { mandatory => 1, value => \&string  },
      'version'             => { mandatory => 1, value => \&version },
      'license'             => { mandatory => 1, value => \&license },
      'generated_by'        => { mandatory => 1, value => \&string  },
      'author'              => { mandatory => 1, list => { value => \&string } },
      'abstract'            => { mandatory => 1, value => \&string  },
    
      'distribution_type'   => { value => \&string  },
      'dynamic_config'      => { value => \&boolean },
    
      'keywords'            => { list => { value => \&string } },
    
      'private'             => $no_index_1_2,
      '$no_index'           => $no_index_1_2,
    
      'requires'            => $module_map1,
      'recommends'          => $module_map1,
      'build_requires'      => $module_map1,
      'conflicts'           => $module_map2,
    
      'optional_features'   => {
        'map'       => {
            ':key'  => { name => \&string,
                'map'   => { description        => { value => \&string },
                             requires           => $module_map1,
                             recommends         => $module_map1,
                             build_requires     => $module_map1,
                             conflicts          => $module_map2,
                             ':key'  => { name => \&string, value => \&anything },
                }
            }
         }
      },
    
      'provides'    => {
        'map'       => {
          ':key' => { name  => \&module,
            'map' => {
              file    => { mandatory => 1, value => \&file },
              version => { value => \&version },
              ':key'  => { name => \&string, value => \&anything },
            }
          }
        }
      },
    
      'resources'   => {
        'map'       => { license    => { value => \&url },
                         homepage   => { value => \&url },
                         bugtracker => { value => \&url },
                         repository => { value => \&url },
                         ':key'     => { value => \&string, name => \&custom_1 },
        }
      },
    
      # additional user defined key/value pairs
      # note we can only validate the key name, as the structure is user defined
      ':key'        => { name => \&string, value => \&anything },
    },
    
    # note that the 1.1 spec only specifies 'version' as mandatory
    '1.1' => {
      'name'                => { value => \&string  },
      'version'             => { mandatory => 1, value => \&version },
      'license'             => { value => \&license },
      'generated_by'        => { value => \&string  },
    
      'license_uri'         => { value => \&url },
      'distribution_type'   => { value => \&string  },
      'dynamic_config'      => { value => \&boolean },
    
      'private'             => $no_index_1_1,
    
      'requires'            => $module_map1,
      'recommends'          => $module_map1,
      'build_requires'      => $module_map1,
      'conflicts'           => $module_map2,
    
      # additional user defined key/value pairs
      # note we can only validate the key name, as the structure is user defined
      ':key'        => { name => \&string, value => \&anything },
    },
    
    # note that the 1.0 spec doesn't specify optional or mandatory fields
    # but we will treat version as mandatory since otherwise META 1.0 is
    # completely arbitrary and pointless
    '1.0' => {
      'name'                => { value => \&string  },
      'version'             => { mandatory => 1, value => \&version },
      'license'             => { value => \&license },
      'generated_by'        => { value => \&string  },
    
      'license_uri'         => { value => \&url },
      'distribution_type'   => { value => \&string  },
      'dynamic_config'      => { value => \&boolean },
    
      'requires'            => $module_map1,
      'recommends'          => $module_map1,
      'build_requires'      => $module_map1,
      'conflicts'           => $module_map2,
    
      # additional user defined key/value pairs
      # note we can only validate the key name, as the structure is user defined
      ':key'        => { name => \&string, value => \&anything },
    },
    );
    
    #--------------------------------------------------------------------------#
    # Code
    #--------------------------------------------------------------------------#
    
    #pod =method new
    #pod
    #pod   my $cmv = CPAN::Meta::Validator->new( $struct )
    #pod
    #pod The constructor must be passed a metadata structure.
    #pod
    #pod =cut
    
    sub new {
      my ($class,$data) = @_;
    
      # create an attributes hash
      my $self = {
        'data'    => $data,
        'spec'    => eval { $data->{'meta-spec'}{'version'} } || "1.0",
        'errors'  => undef,
      };
    
      # create the object
      return bless $self, $class;
    }
    
    #pod =method is_valid
    #pod
    #pod   if ( $cmv->is_valid ) {
    #pod     ...
    #pod   }
    #pod
    #pod Returns a boolean value indicating whether the metadata provided
    #pod is valid.
    #pod
    #pod =cut
    
    sub is_valid {
        my $self = shift;
        my $data = $self->{data};
        my $spec_version = $self->{spec};
        $self->check_map($definitions{$spec_version},$data);
        return ! $self->errors;
    }
    
    #pod =method errors
    #pod
    #pod   warn( join "\n", $cmv->errors );
    #pod
    #pod Returns a list of errors seen during validation.
    #pod
    #pod =cut
    
    sub errors {
        my $self = shift;
        return ()   unless(defined $self->{errors});
        return @{$self->{errors}};
    }
    
    #pod =begin :internals
    #pod
    #pod =head2 Check Methods
    #pod
    #pod =over
    #pod
    #pod =item *
    #pod
    #pod check_map($spec,$data)
    #pod
    #pod Checks whether a map (or hash) part of the data structure conforms to the
    #pod appropriate specification definition.
    #pod
    #pod =item *
    #pod
    #pod check_list($spec,$data)
    #pod
    #pod Checks whether a list (or array) part of the data structure conforms to
    #pod the appropriate specification definition.
    #pod
    #pod =item *
    #pod
    #pod =back
    #pod
    #pod =cut
    
    my $spec_error = "Missing validation action in specification. "
      . "Must be one of 'map', 'list', or 'value'";
    
    sub check_map {
        my ($self,$spec,$data) = @_;
    
        if(ref($spec) ne 'HASH') {
            $self->_error( "Unknown META specification, cannot validate." );
            return;
        }
    
        if(ref($data) ne 'HASH') {
            $self->_error( "Expected a map structure from string or file." );
            return;
        }
    
        for my $key (keys %$spec) {
            next    unless($spec->{$key}->{mandatory});
            next    if(defined $data->{$key});
            push @{$self->{stack}}, $key;
            $self->_error( "Missing mandatory field, '$key'" );
            pop @{$self->{stack}};
        }
    
        for my $key (keys %$data) {
            push @{$self->{stack}}, $key;
            if($spec->{$key}) {
                if($spec->{$key}{value}) {
                    $spec->{$key}{value}->($self,$key,$data->{$key});
                } elsif($spec->{$key}{'map'}) {
                    $self->check_map($spec->{$key}{'map'},$data->{$key});
                } elsif($spec->{$key}{'list'}) {
                    $self->check_list($spec->{$key}{'list'},$data->{$key});
                } else {
                    $self->_error( "$spec_error for '$key'" );
                }
    
            } elsif ($spec->{':key'}) {
                $spec->{':key'}{name}->($self,$key,$key);
                if($spec->{':key'}{value}) {
                    $spec->{':key'}{value}->($self,$key,$data->{$key});
                } elsif($spec->{':key'}{'map'}) {
                    $self->check_map($spec->{':key'}{'map'},$data->{$key});
                } elsif($spec->{':key'}{'list'}) {
                    $self->check_list($spec->{':key'}{'list'},$data->{$key});
                } else {
                    $self->_error( "$spec_error for ':key'" );
                }
    
    
            } else {
                $self->_error( "Unknown key, '$key', found in map structure" );
            }
            pop @{$self->{stack}};
        }
    }
    
    sub check_list {
        my ($self,$spec,$data) = @_;
    
        if(ref($data) ne 'ARRAY') {
            $self->_error( "Expected a list structure" );
            return;
        }
    
        if(defined $spec->{mandatory}) {
            if(!defined $data->[0]) {
                $self->_error( "Missing entries from mandatory list" );
            }
        }
    
        for my $value (@$data) {
            push @{$self->{stack}}, $value || "<undef>";
            if(defined $spec->{value}) {
                $spec->{value}->($self,'list',$value);
            } elsif(defined $spec->{'map'}) {
                $self->check_map($spec->{'map'},$value);
            } elsif(defined $spec->{'list'}) {
                $self->check_list($spec->{'list'},$value);
            } elsif ($spec->{':key'}) {
                $self->check_map($spec,$value);
            } else {
              $self->_error( "$spec_error associated with '$self->{stack}[-2]'" );
            }
            pop @{$self->{stack}};
        }
    }
    
    #pod =head2 Validator Methods
    #pod
    #pod =over
    #pod
    #pod =item *
    #pod
    #pod header($self,$key,$value)
    #pod
    #pod Validates that the header is valid.
    #pod
    #pod Note: No longer used as we now read the data structure, not the file.
    #pod
    #pod =item *
    #pod
    #pod url($self,$key,$value)
    #pod
    #pod Validates that a given value is in an acceptable URL format
    #pod
    #pod =item *
    #pod
    #pod urlspec($self,$key,$value)
    #pod
    #pod Validates that the URL to a META specification is a known one.
    #pod
    #pod =item *
    #pod
    #pod string_or_undef($self,$key,$value)
    #pod
    #pod Validates that the value is either a string or an undef value. Bit of a
    #pod catchall function for parts of the data structure that are completely user
    #pod defined.
    #pod
    #pod =item *
    #pod
    #pod string($self,$key,$value)
    #pod
    #pod Validates that a string exists for the given key.
    #pod
    #pod =item *
    #pod
    #pod file($self,$key,$value)
    #pod
    #pod Validate that a file is passed for the given key. This may be made more
    #pod thorough in the future. For now it acts like \&string.
    #pod
    #pod =item *
    #pod
    #pod exversion($self,$key,$value)
    #pod
    #pod Validates a list of versions, e.g. '<= 5, >=2, ==3, !=4, >1, <6, 0'.
    #pod
    #pod =item *
    #pod
    #pod version($self,$key,$value)
    #pod
    #pod Validates a single version string. Versions of the type '5.8.8' and '0.00_00'
    #pod are both valid. A leading 'v' like 'v1.2.3' is also valid.
    #pod
    #pod =item *
    #pod
    #pod boolean($self,$key,$value)
    #pod
    #pod Validates for a boolean value. Currently these values are '1', '0', 'true',
    #pod 'false', however the latter 2 may be removed.
    #pod
    #pod =item *
    #pod
    #pod license($self,$key,$value)
    #pod
    #pod Validates that a value is given for the license. Returns 1 if an known license
    #pod type, or 2 if a value is given but the license type is not a recommended one.
    #pod
    #pod =item *
    #pod
    #pod custom_1($self,$key,$value)
    #pod
    #pod Validates that the given key is in CamelCase, to indicate a user defined
    #pod keyword and only has characters in the class [-_a-zA-Z].  In version 1.X
    #pod of the spec, this was only explicitly stated for 'resources'.
    #pod
    #pod =item *
    #pod
    #pod custom_2($self,$key,$value)
    #pod
    #pod Validates that the given key begins with 'x_' or 'X_', to indicate a user
    #pod defined keyword and only has characters in the class [-_a-zA-Z]
    #pod
    #pod =item *
    #pod
    #pod identifier($self,$key,$value)
    #pod
    #pod Validates that key is in an acceptable format for the META specification,
    #pod for an identifier, i.e. any that matches the regular expression
    #pod qr/[a-z][a-z_]/i.
    #pod
    #pod =item *
    #pod
    #pod module($self,$key,$value)
    #pod
    #pod Validates that a given key is in an acceptable module name format, e.g.
    #pod 'Test::CPAN::Meta::Version'.
    #pod
    #pod =back
    #pod
    #pod =end :internals
    #pod
    #pod =cut
    
    sub header {
        my ($self,$key,$value) = @_;
        if(defined $value) {
            return 1    if($value && $value =~ /^--- #YAML:1.0/);
        }
        $self->_error( "file does not have a valid YAML header." );
        return 0;
    }
    
    sub release_status {
      my ($self,$key,$value) = @_;
      if(defined $value) {
        my $version = $self->{data}{version} || '';
        if ( $version =~ /_/ ) {
          return 1 if ( $value =~ /\A(?:testing|unstable)\z/ );
          $self->_error( "'$value' for '$key' is invalid for version '$version'" );
        }
        else {
          return 1 if ( $value =~ /\A(?:stable|testing|unstable)\z/ );
          $self->_error( "'$value' for '$key' is invalid" );
        }
      }
      else {
        $self->_error( "'$key' is not defined" );
      }
      return 0;
    }
    
    # _uri_split taken from URI::Split by Gisle Aas, Copyright 2003
    sub _uri_split {
         return $_[0] =~ m,(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?,;
    }
    
    sub url {
        my ($self,$key,$value) = @_;
        if(defined $value) {
          my ($scheme, $auth, $path, $query, $frag) = _uri_split($value);
          unless ( defined $scheme && length $scheme ) {
            $self->_error( "'$value' for '$key' does not have a URL scheme" );
            return 0;
          }
          unless ( defined $auth && length $auth ) {
            $self->_error( "'$value' for '$key' does not have a URL authority" );
            return 0;
          }
          return 1;
        }
        $value ||= '';
        $self->_error( "'$value' for '$key' is not a valid URL." );
        return 0;
    }
    
    sub urlspec {
        my ($self,$key,$value) = @_;
        if(defined $value) {
            return 1    if($value && $known_specs{$self->{spec}} eq $value);
            if($value && $known_urls{$value}) {
                $self->_error( 'META specification URL does not match version' );
                return 0;
            }
        }
        $self->_error( 'Unknown META specification' );
        return 0;
    }
    
    sub anything { return 1 }
    
    sub string {
        my ($self,$key,$value) = @_;
        if(defined $value) {
            return 1    if($value || $value =~ /^0$/);
        }
        $self->_error( "value is an undefined string" );
        return 0;
    }
    
    sub string_or_undef {
        my ($self,$key,$value) = @_;
        return 1    unless(defined $value);
        return 1    if($value || $value =~ /^0$/);
        $self->_error( "No string defined for '$key'" );
        return 0;
    }
    
    sub file {
        my ($self,$key,$value) = @_;
        return 1    if(defined $value);
        $self->_error( "No file defined for '$key'" );
        return 0;
    }
    
    sub exversion {
        my ($self,$key,$value) = @_;
        if(defined $value && ($value || $value =~ /0/)) {
            my $pass = 1;
            for(split(",",$value)) { $self->version($key,$_) or ($pass = 0); }
            return $pass;
        }
        $value = '<undef>'  unless(defined $value);
        $self->_error( "'$value' for '$key' is not a valid version." );
        return 0;
    }
    
    sub version {
        my ($self,$key,$value) = @_;
        if(defined $value) {
            return 0    unless($value || $value =~ /0/);
            return 1    if($value =~ /^\s*((<|<=|>=|>|!=|==)\s*)?v?\d+((\.\d+((_|\.)\d+)?)?)/);
        } else {
            $value = '<undef>';
        }
        $self->_error( "'$value' for '$key' is not a valid version." );
        return 0;
    }
    
    sub boolean {
        my ($self,$key,$value) = @_;
        if(defined $value) {
            return 1    if($value =~ /^(0|1|true|false)$/);
        } else {
            $value = '<undef>';
        }
        $self->_error( "'$value' for '$key' is not a boolean value." );
        return 0;
    }
    
    my %v1_licenses = (
        'perl'         => 'http://dev.perl.org/licenses/',
        'gpl'          => 'http://www.opensource.org/licenses/gpl-license.php',
        'apache'       => 'http://apache.org/licenses/LICENSE-2.0',
        'artistic'     => 'http://opensource.org/licenses/artistic-license.php',
        'artistic_2'   => 'http://opensource.org/licenses/artistic-license-2.0.php',
        'lgpl'         => 'http://www.opensource.org/licenses/lgpl-license.php',
        'bsd'          => 'http://www.opensource.org/licenses/bsd-license.php',
        'gpl'          => 'http://www.opensource.org/licenses/gpl-license.php',
        'mit'          => 'http://opensource.org/licenses/mit-license.php',
        'mozilla'      => 'http://opensource.org/licenses/mozilla1.1.php',
        'open_source'  => undef,
        'unrestricted' => undef,
        'restrictive'  => undef,
        'unknown'      => undef,
    );
    
    my %v2_licenses = map { $_ => 1 } qw(
      agpl_3
      apache_1_1
      apache_2_0
      artistic_1
      artistic_2
      bsd
      freebsd
      gfdl_1_2
      gfdl_1_3
      gpl_1
      gpl_2
      gpl_3
      lgpl_2_1
      lgpl_3_0
      mit
      mozilla_1_0
      mozilla_1_1
      openssl
      perl_5
      qpl_1_0
      ssleay
      sun
      zlib
      open_source
      restricted
      unrestricted
      unknown
    );
    
    sub license {
        my ($self,$key,$value) = @_;
        my $licenses = $self->{spec} < 2 ? \%v1_licenses : \%v2_licenses;
        if(defined $value) {
            return 1    if($value && exists $licenses->{$value});
        } else {
            $value = '<undef>';
        }
        $self->_error( "License '$value' is invalid" );
        return 0;
    }
    
    sub custom_1 {
        my ($self,$key) = @_;
        if(defined $key) {
            # a valid user defined key should be alphabetic
            # and contain at least one capital case letter.
            return 1    if($key && $key =~ /^[_a-z]+$/i && $key =~ /[A-Z]/);
        } else {
            $key = '<undef>';
        }
        $self->_error( "Custom resource '$key' must be in CamelCase." );
        return 0;
    }
    
    sub custom_2 {
        my ($self,$key) = @_;
        if(defined $key) {
            return 1    if($key && $key =~ /^x_/i);  # user defined
        } else {
            $key = '<undef>';
        }
        $self->_error( "Custom key '$key' must begin with 'x_' or 'X_'." );
        return 0;
    }
    
    sub identifier {
        my ($self,$key) = @_;
        if(defined $key) {
            return 1    if($key && $key =~ /^([a-z][_a-z]+)$/i);    # spec 2.0 defined
        } else {
            $key = '<undef>';
        }
        $self->_error( "Key '$key' is not a legal identifier." );
        return 0;
    }
    
    sub module {
        my ($self,$key) = @_;
        if(defined $key) {
            return 1    if($key && $key =~ /^[A-Za-z0-9_]+(::[A-Za-z0-9_]+)*$/);
        } else {
            $key = '<undef>';
        }
        $self->_error( "Key '$key' is not a legal module name." );
        return 0;
    }
    
    my @valid_phases = qw/ configure build test runtime develop /;
    sub phase {
        my ($self,$key) = @_;
        if(defined $key) {
            return 1 if( length $key && grep { $key eq $_ } @valid_phases );
            return 1 if $key =~ /x_/i;
        } else {
            $key = '<undef>';
        }
        $self->_error( "Key '$key' is not a legal phase." );
        return 0;
    }
    
    my @valid_relations = qw/ requires recommends suggests conflicts /;
    sub relation {
        my ($self,$key) = @_;
        if(defined $key) {
            return 1 if( length $key && grep { $key eq $_ } @valid_relations );
            return 1 if $key =~ /x_/i;
        } else {
            $key = '<undef>';
        }
        $self->_error( "Key '$key' is not a legal prereq relationship." );
        return 0;
    }
    
    sub _error {
        my $self = shift;
        my $mess = shift;
    
        $mess .= ' ('.join(' -> ',@{$self->{stack}}).')'  if($self->{stack});
        $mess .= " [Validation: $self->{spec}]";
    
        push @{$self->{errors}}, $mess;
    }
    
    1;
    
    # ABSTRACT: validate CPAN distribution metadata structures
    
    __END__
    
    =pod
    
    =encoding UTF-8
    
    =head1 NAME
    
    CPAN::Meta::Validator - validate CPAN distribution metadata structures
    
    =head1 VERSION
    
    version 2.143240
    
    =head1 SYNOPSIS
    
      my $struct = decode_json_file('META.json');
    
      my $cmv = CPAN::Meta::Validator->new( $struct );
    
      unless ( $cmv->is_valid ) {
        my $msg = "Invalid META structure.  Errors found:\n";
        $msg .= join( "\n", $cmv->errors );
        die $msg;
      }
    
    =head1 DESCRIPTION
    
    This module validates a CPAN Meta structure against the version of the
    the specification claimed in the C<meta-spec> field of the structure.
    
    =head1 METHODS
    
    =head2 new
    
      my $cmv = CPAN::Meta::Validator->new( $struct )
    
    The constructor must be passed a metadata structure.
    
    =head2 is_valid
    
      if ( $cmv->is_valid ) {
        ...
      }
    
    Returns a boolean value indicating whether the metadata provided
    is valid.
    
    =head2 errors
    
      warn( join "\n", $cmv->errors );
    
    Returns a list of errors seen during validation.
    
    =begin :internals
    
    =head2 Check Methods
    
    =over
    
    =item *
    
    check_map($spec,$data)
    
    Checks whether a map (or hash) part of the data structure conforms to the
    appropriate specification definition.
    
    =item *
    
    check_list($spec,$data)
    
    Checks whether a list (or array) part of the data structure conforms to
    the appropriate specification definition.
    
    =item *
    
    =back
    
    =head2 Validator Methods
    
    =over
    
    =item *
    
    header($self,$key,$value)
    
    Validates that the header is valid.
    
    Note: No longer used as we now read the data structure, not the file.
    
    =item *
    
    url($self,$key,$value)
    
    Validates that a given value is in an acceptable URL format
    
    =item *
    
    urlspec($self,$key,$value)
    
    Validates that the URL to a META specification is a known one.
    
    =item *
    
    string_or_undef($self,$key,$value)
    
    Validates that the value is either a string or an undef value. Bit of a
    catchall function for parts of the data structure that are completely user
    defined.
    
    =item *
    
    string($self,$key,$value)
    
    Validates that a string exists for the given key.
    
    =item *
    
    file($self,$key,$value)
    
    Validate that a file is passed for the given key. This may be made more
    thorough in the future. For now it acts like \&string.
    
    =item *
    
    exversion($self,$key,$value)
    
    Validates a list of versions, e.g. '<= 5, >=2, ==3, !=4, >1, <6, 0'.
    
    =item *
    
    version($self,$key,$value)
    
    Validates a single version string. Versions of the type '5.8.8' and '0.00_00'
    are both valid. A leading 'v' like 'v1.2.3' is also valid.
    
    =item *
    
    boolean($self,$key,$value)
    
    Validates for a boolean value. Currently these values are '1', '0', 'true',
    'false', however the latter 2 may be removed.
    
    =item *
    
    license($self,$key,$value)
    
    Validates that a value is given for the license. Returns 1 if an known license
    type, or 2 if a value is given but the license type is not a recommended one.
    
    =item *
    
    custom_1($self,$key,$value)
    
    Validates that the given key is in CamelCase, to indicate a user defined
    keyword and only has characters in the class [-_a-zA-Z].  In version 1.X
    of the spec, this was only explicitly stated for 'resources'.
    
    =item *
    
    custom_2($self,$key,$value)
    
    Validates that the given key begins with 'x_' or 'X_', to indicate a user
    defined keyword and only has characters in the class [-_a-zA-Z]
    
    =item *
    
    identifier($self,$key,$value)
    
    Validates that key is in an acceptable format for the META specification,
    for an identifier, i.e. any that matches the regular expression
    qr/[a-z][a-z_]/i.
    
    =item *
    
    module($self,$key,$value)
    
    Validates that a given key is in an acceptable module name format, e.g.
    'Test::CPAN::Meta::Version'.
    
    =back
    
    =end :internals
    
    =for Pod::Coverage anything boolean check_list custom_1 custom_2 exversion file
    identifier license module phase relation release_status string string_or_undef
    url urlspec version header check_map
    
    =head1 BUGS
    
    Please report any bugs or feature using the CPAN Request Tracker.
    Bugs can be submitted through the web interface at
    L<http://rt.cpan.org/Dist/Display.html?Queue=CPAN-Meta>
    
    When submitting a bug or request, please include a test-file or a patch to an
    existing test-file that illustrates the bug or desired feature.
    
    =head1 AUTHORS
    
    =over 4
    
    =item *
    
    David Golden <dagolden@cpan.org>
    
    =item *
    
    Ricardo Signes <rjbs@cpan.org>
    
    =back
    
    =head1 COPYRIGHT AND LICENSE
    
    This software is copyright (c) 2010 by David Golden and Ricardo Signes.
    
    This is free software; you can redistribute it and/or modify it under
    the same terms as the Perl 5 programming language system itself.
    
    =cut
  CPAN_META_VALIDATOR
  
  $fatpacked{"CPAN/Meta/YAML.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CPAN_META_YAML';
    use 5.008001; # sane UTF-8 support
    use strict;
    use warnings;
    package CPAN::Meta::YAML;
    $CPAN::Meta::YAML::VERSION = '0.012';
    BEGIN {
      $CPAN::Meta::YAML::AUTHORITY = 'cpan:ADAMK';
    }
    # git description: v1.60-1-g1c16a0a
    ; # original $VERSION removed by Doppelgaenger
    # XXX-INGY is 5.8.1 too old/broken for utf8?
    # XXX-XDG Lancaster consensus was that it was sufficient until
    # proven otherwise
    
    
    #####################################################################
    # The CPAN::Meta::YAML API.
    #
    # These are the currently documented API functions/methods and
    # exports:
    
    use Exporter;
    our @ISA       = qw{ Exporter  };
    our @EXPORT    = qw{ Load Dump };
    our @EXPORT_OK = qw{ LoadFile DumpFile freeze thaw };
    
    ###
    # Functional/Export API:
    
    sub Dump {
        return CPAN::Meta::YAML->new(@_)->_dump_string;
    }
    
    # XXX-INGY Returning last document seems a bad behavior.
    # XXX-XDG I think first would seem more natural, but I don't know
    # that it's worth changing now
    sub Load {
        my $self = CPAN::Meta::YAML->_load_string(@_);
        if ( wantarray ) {
            return @$self;
        } else {
            # To match YAML.pm, return the last document
            return $self->[-1];
        }
    }
    
    # XXX-INGY Do we really need freeze and thaw?
    # XXX-XDG I don't think so.  I'd support deprecating them.
    BEGIN {
        *freeze = \&Dump;
        *thaw   = \&Load;
    }
    
    sub DumpFile {
        my $file = shift;
        return CPAN::Meta::YAML->new(@_)->_dump_file($file);
    }
    
    sub LoadFile {
        my $file = shift;
        my $self = CPAN::Meta::YAML->_load_file($file);
        if ( wantarray ) {
            return @$self;
        } else {
            # Return only the last document to match YAML.pm,
            return $self->[-1];
        }
    }
    
    
    ###
    # Object Oriented API:
    
    # Create an empty CPAN::Meta::YAML object
    # XXX-INGY Why do we use ARRAY object?
    # NOTE: I get it now, but I think it's confusing and not needed.
    # Will change it on a branch later, for review.
    #
    # XXX-XDG I don't support changing it yet.  It's a very well-documented
    # "API" of CPAN::Meta::YAML.  I'd support deprecating it, but Adam suggested
    # we not change it until YAML.pm's own OO API is established so that
    # users only have one API change to digest, not two
    sub new {
        my $class = shift;
        bless [ @_ ], $class;
    }
    
    # XXX-INGY It probably doesn't matter, and it's probably too late to
    # change, but 'read/write' are the wrong names. Read and Write
    # are actions that take data from storage to memory
    # characters/strings. These take the data to/from storage to native
    # Perl objects, which the terms dump and load are meant. As long as
    # this is a legacy quirk to CPAN::Meta::YAML it's ok, but I'd prefer not
    # to add new {read,write}_* methods to this API.
    
    sub read_string {
        my $self = shift;
        $self->_load_string(@_);
    }
    
    sub write_string {
        my $self = shift;
        $self->_dump_string(@_);
    }
    
    sub read {
        my $self = shift;
        $self->_load_file(@_);
    }
    
    sub write {
        my $self = shift;
        $self->_dump_file(@_);
    }
    
    
    
    
    #####################################################################
    # Constants
    
    # Printed form of the unprintable characters in the lowest range
    # of ASCII characters, listed by ASCII ordinal position.
    my @UNPRINTABLE = qw(
        0    x01  x02  x03  x04  x05  x06  a
        b    t    n    v    f    r    x0E  x0F
        x10  x11  x12  x13  x14  x15  x16  x17
        x18  x19  x1A  e    x1C  x1D  x1E  x1F
    );
    
    # Printable characters for escapes
    my %UNESCAPES = (
        0 => "\x00", z => "\x00", N    => "\x85",
        a => "\x07", b => "\x08", t    => "\x09",
        n => "\x0a", v => "\x0b", f    => "\x0c",
        r => "\x0d", e => "\x1b", '\\' => '\\',
    );
    
    # XXX-INGY
    # I(ngy) need to decide if these values should be quoted in
    # CPAN::Meta::YAML or not. Probably yes.
    
    # These 3 values have special meaning when unquoted and using the
    # default YAML schema. They need quotes if they are strings.
    my %QUOTE = map { $_ => 1 } qw{
        null true false
    };
    
    # The commented out form is simpler, but overloaded the Perl regex
    # engine due to recursion and backtracking problems on strings
    # larger than 32,000ish characters. Keep it for reference purposes.
    # qr/\"((?:\\.|[^\"])*)\"/
    my $re_capture_double_quoted = qr/\"([^\\"]*(?:\\.[^\\"]*)*)\"/;
    my $re_capture_single_quoted = qr/\'([^\']*(?:\'\'[^\']*)*)\'/;
    # unquoted re gets trailing space that needs to be stripped
    my $re_capture_unquoted_key  = qr/([^:]+(?::+\S[^:]*)*)(?=\s*\:(?:\s+|$))/;
    my $re_trailing_comment      = qr/(?:\s+\#.*)?/;
    my $re_key_value_separator   = qr/\s*:(?:\s+(?:\#.*)?|$)/;
    
    
    
    
    
    #####################################################################
    # CPAN::Meta::YAML Implementation.
    #
    # These are the private methods that do all the work. They may change
    # at any time.
    
    
    ###
    # Loader functions:
    
    # Create an object from a file
    sub _load_file {
        my $class = ref $_[0] ? ref shift : shift;
    
        # Check the file
        my $file = shift or $class->_error( 'You did not specify a file name' );
        $class->_error( "File '$file' does not exist" )
            unless -e $file;
        $class->_error( "'$file' is a directory, not a file" )
            unless -f _;
        $class->_error( "Insufficient permissions to read '$file'" )
            unless -r _;
    
        # Open unbuffered with strict UTF-8 decoding and no translation layers
        open( my $fh, "<:unix:encoding(UTF-8)", $file );
        unless ( $fh ) {
            $class->_error("Failed to open file '$file': $!");
        }
    
        # flock if available (or warn if not possible for OS-specific reasons)
        if ( _can_flock() ) {
            flock( $fh, Fcntl::LOCK_SH() )
                or warn "Couldn't lock '$file' for reading: $!";
        }
    
        # slurp the contents
        my $contents = eval {
            use warnings FATAL => 'utf8';
            local $/;
            <$fh>
        };
        if ( my $err = $@ ) {
            $class->_error("Error reading from file '$file': $err");
        }
    
        # close the file (release the lock)
        unless ( close $fh ) {
            $class->_error("Failed to close file '$file': $!");
        }
    
        $class->_load_string( $contents );
    }
    
    # Create an object from a string
    sub _load_string {
        my $class  = ref $_[0] ? ref shift : shift;
        my $self   = bless [], $class;
        my $string = $_[0];
        eval {
            unless ( defined $string ) {
                die \"Did not provide a string to load";
            }
    
            # Check if Perl has it marked as characters, but it's internally
            # inconsistent.  E.g. maybe latin1 got read on a :utf8 layer
            if ( utf8::is_utf8($string) && ! utf8::valid($string) ) {
                die \<<'...';
    Read an invalid UTF-8 string (maybe mixed UTF-8 and 8-bit character set).
    Did you decode with lax ":utf8" instead of strict ":encoding(UTF-8)"?
    ...
            }
    
            # Ensure Unicode character semantics, even for 0x80-0xff
            utf8::upgrade($string);
    
            # Check for and strip any leading UTF-8 BOM
            $string =~ s/^\x{FEFF}//;
    
            # Check for some special cases
            return $self unless length $string;
    
            # Split the file into lines
            my @lines = grep { ! /^\s*(?:\#.*)?\z/ }
                    split /(?:\015{1,2}\012|\015|\012)/, $string;
    
            # Strip the initial YAML header
            @lines and $lines[0] =~ /^\%YAML[: ][\d\.]+.*\z/ and shift @lines;
    
            # A nibbling parser
            my $in_document = 0;
            while ( @lines ) {
                # Do we have a document header?
                if ( $lines[0] =~ /^---\s*(?:(.+)\s*)?\z/ ) {
                    # Handle scalar documents
                    shift @lines;
                    if ( defined $1 and $1 !~ /^(?:\#.+|\%YAML[: ][\d\.]+)\z/ ) {
                        push @$self,
                            $self->_load_scalar( "$1", [ undef ], \@lines );
                        next;
                    }
                    $in_document = 1;
                }
    
                if ( ! @lines or $lines[0] =~ /^(?:---|\.\.\.)/ ) {
                    # A naked document
                    push @$self, undef;
                    while ( @lines and $lines[0] !~ /^---/ ) {
                        shift @lines;
                    }
                    $in_document = 0;
    
                # XXX The final '-+$' is to look for -- which ends up being an
                # error later.
                } elsif ( ! $in_document && @$self ) {
                    # only the first document can be explicit
                    die \"CPAN::Meta::YAML failed to classify the line '$lines[0]'";
                } elsif ( $lines[0] =~ /^\s*\-(?:\s|$|-+$)/ ) {
                    # An array at the root
                    my $document = [ ];
                    push @$self, $document;
                    $self->_load_array( $document, [ 0 ], \@lines );
    
                } elsif ( $lines[0] =~ /^(\s*)\S/ ) {
                    # A hash at the root
                    my $document = { };
                    push @$self, $document;
                    $self->_load_hash( $document, [ length($1) ], \@lines );
    
                } else {
                    # Shouldn't get here.  @lines have whitespace-only lines
                    # stripped, and previous match is a line with any
                    # non-whitespace.  So this clause should only be reachable via
                    # a perlbug where \s is not symmetric with \S
    
                    # uncoverable statement
                    die \"CPAN::Meta::YAML failed to classify the line '$lines[0]'";
                }
            }
        };
        if ( ref $@ eq 'SCALAR' ) {
            $self->_error(${$@});
        } elsif ( $@ ) {
            $self->_error($@);
        }
    
        return $self;
    }
    
    sub _unquote_single {
        my ($self, $string) = @_;
        return '' unless length $string;
        $string =~ s/\'\'/\'/g;
        return $string;
    }
    
    sub _unquote_double {
        my ($self, $string) = @_;
        return '' unless length $string;
        $string =~ s/\\"/"/g;
        $string =~
            s{\\([Nnever\\fartz0b]|x([0-9a-fA-F]{2}))}
             {(length($1)>1)?pack("H2",$2):$UNESCAPES{$1}}gex;
        return $string;
    }
    
    # Load a YAML scalar string to the actual Perl scalar
    sub _load_scalar {
        my ($self, $string, $indent, $lines) = @_;
    
        # Trim trailing whitespace
        $string =~ s/\s*\z//;
    
        # Explitic null/undef
        return undef if $string eq '~';
    
        # Single quote
        if ( $string =~ /^$re_capture_single_quoted$re_trailing_comment\z/ ) {
            return $self->_unquote_single($1);
        }
    
        # Double quote.
        if ( $string =~ /^$re_capture_double_quoted$re_trailing_comment\z/ ) {
            return $self->_unquote_double($1);
        }
    
        # Special cases
        if ( $string =~ /^[\'\"!&]/ ) {
            die \"CPAN::Meta::YAML does not support a feature in line '$string'";
        }
        return {} if $string =~ /^{}(?:\s+\#.*)?\z/;
        return [] if $string =~ /^\[\](?:\s+\#.*)?\z/;
    
        # Regular unquoted string
        if ( $string !~ /^[>|]/ ) {
            die \"CPAN::Meta::YAML found illegal characters in plain scalar: '$string'"
                if $string =~ /^(?:-(?:\s|$)|[\@\%\`])/ or
                    $string =~ /:(?:\s|$)/;
            $string =~ s/\s+#.*\z//;
            return $string;
        }
    
        # Error
        die \"CPAN::Meta::YAML failed to find multi-line scalar content" unless @$lines;
    
        # Check the indent depth
        $lines->[0]   =~ /^(\s*)/;
        $indent->[-1] = length("$1");
        if ( defined $indent->[-2] and $indent->[-1] <= $indent->[-2] ) {
            die \"CPAN::Meta::YAML found bad indenting in line '$lines->[0]'";
        }
    
        # Pull the lines
        my @multiline = ();
        while ( @$lines ) {
            $lines->[0] =~ /^(\s*)/;
            last unless length($1) >= $indent->[-1];
            push @multiline, substr(shift(@$lines), length($1));
        }
    
        my $j = (substr($string, 0, 1) eq '>') ? ' ' : "\n";
        my $t = (substr($string, 1, 1) eq '-') ? ''  : "\n";
        return join( $j, @multiline ) . $t;
    }
    
    # Load an array
    sub _load_array {
        my ($self, $array, $indent, $lines) = @_;
    
        while ( @$lines ) {
            # Check for a new document
            if ( $lines->[0] =~ /^(?:---|\.\.\.)/ ) {
                while ( @$lines and $lines->[0] !~ /^---/ ) {
                    shift @$lines;
                }
                return 1;
            }
    
            # Check the indent level
            $lines->[0] =~ /^(\s*)/;
            if ( length($1) < $indent->[-1] ) {
                return 1;
            } elsif ( length($1) > $indent->[-1] ) {
                die \"CPAN::Meta::YAML found bad indenting in line '$lines->[0]'";
            }
    
            if ( $lines->[0] =~ /^(\s*\-\s+)[^\'\"]\S*\s*:(?:\s+|$)/ ) {
                # Inline nested hash
                my $indent2 = length("$1");
                $lines->[0] =~ s/-/ /;
                push @$array, { };
                $self->_load_hash( $array->[-1], [ @$indent, $indent2 ], $lines );
    
            } elsif ( $lines->[0] =~ /^\s*\-\s*\z/ ) {
                shift @$lines;
                unless ( @$lines ) {
                    push @$array, undef;
                    return 1;
                }
                if ( $lines->[0] =~ /^(\s*)\-/ ) {
                    my $indent2 = length("$1");
                    if ( $indent->[-1] == $indent2 ) {
                        # Null array entry
                        push @$array, undef;
                    } else {
                        # Naked indenter
                        push @$array, [ ];
                        $self->_load_array(
                            $array->[-1], [ @$indent, $indent2 ], $lines
                        );
                    }
    
                } elsif ( $lines->[0] =~ /^(\s*)\S/ ) {
                    push @$array, { };
                    $self->_load_hash(
                        $array->[-1], [ @$indent, length("$1") ], $lines
                    );
    
                } else {
                    die \"CPAN::Meta::YAML failed to classify line '$lines->[0]'";
                }
    
            } elsif ( $lines->[0] =~ /^\s*\-(\s*)(.+?)\s*\z/ ) {
                # Array entry with a value
                shift @$lines;
                push @$array, $self->_load_scalar(
                    "$2", [ @$indent, undef ], $lines
                );
    
            } elsif ( defined $indent->[-2] and $indent->[-1] == $indent->[-2] ) {
                # This is probably a structure like the following...
                # ---
                # foo:
                # - list
                # bar: value
                #
                # ... so lets return and let the hash parser handle it
                return 1;
    
            } else {
                die \"CPAN::Meta::YAML failed to classify line '$lines->[0]'";
            }
        }
    
        return 1;
    }
    
    # Load a hash
    sub _load_hash {
        my ($self, $hash, $indent, $lines) = @_;
    
        while ( @$lines ) {
            # Check for a new document
            if ( $lines->[0] =~ /^(?:---|\.\.\.)/ ) {
                while ( @$lines and $lines->[0] !~ /^---/ ) {
                    shift @$lines;
                }
                return 1;
            }
    
            # Check the indent level
            $lines->[0] =~ /^(\s*)/;
            if ( length($1) < $indent->[-1] ) {
                return 1;
            } elsif ( length($1) > $indent->[-1] ) {
                die \"CPAN::Meta::YAML found bad indenting in line '$lines->[0]'";
            }
    
            # Find the key
            my $key;
    
            # Quoted keys
            if ( $lines->[0] =~
                s/^\s*$re_capture_single_quoted$re_key_value_separator//
            ) {
                $key = $self->_unquote_single($1);
            }
            elsif ( $lines->[0] =~
                s/^\s*$re_capture_double_quoted$re_key_value_separator//
            ) {
                $key = $self->_unquote_double($1);
            }
            elsif ( $lines->[0] =~
                s/^\s*$re_capture_unquoted_key$re_key_value_separator//
            ) {
                $key = $1;
                $key =~ s/\s+$//;
            }
            elsif ( $lines->[0] =~ /^\s*\?/ ) {
                die \"CPAN::Meta::YAML does not support a feature in line '$lines->[0]'";
            }
            else {
                die \"CPAN::Meta::YAML failed to classify line '$lines->[0]'";
            }
    
            # Do we have a value?
            if ( length $lines->[0] ) {
                # Yes
                $hash->{$key} = $self->_load_scalar(
                    shift(@$lines), [ @$indent, undef ], $lines
                );
            } else {
                # An indent
                shift @$lines;
                unless ( @$lines ) {
                    $hash->{$key} = undef;
                    return 1;
                }
                if ( $lines->[0] =~ /^(\s*)-/ ) {
                    $hash->{$key} = [];
                    $self->_load_array(
                        $hash->{$key}, [ @$indent, length($1) ], $lines
                    );
                } elsif ( $lines->[0] =~ /^(\s*)./ ) {
                    my $indent2 = length("$1");
                    if ( $indent->[-1] >= $indent2 ) {
                        # Null hash entry
                        $hash->{$key} = undef;
                    } else {
                        $hash->{$key} = {};
                        $self->_load_hash(
                            $hash->{$key}, [ @$indent, length($1) ], $lines
                        );
                    }
                }
            }
        }
    
        return 1;
    }
    
    
    ###
    # Dumper functions:
    
    # Save an object to a file
    sub _dump_file {
        my $self = shift;
    
        require Fcntl;
    
        # Check the file
        my $file = shift or $self->_error( 'You did not specify a file name' );
    
        my $fh;
        # flock if available (or warn if not possible for OS-specific reasons)
        if ( _can_flock() ) {
            # Open without truncation (truncate comes after lock)
            my $flags = Fcntl::O_WRONLY()|Fcntl::O_CREAT();
            sysopen( $fh, $file, $flags );
            unless ( $fh ) {
                $self->_error("Failed to open file '$file' for writing: $!");
            }
    
            # Use no translation and strict UTF-8
            binmode( $fh, ":raw:encoding(UTF-8)");
    
            flock( $fh, Fcntl::LOCK_EX() )
                or warn "Couldn't lock '$file' for reading: $!";
    
            # truncate and spew contents
            truncate $fh, 0;
            seek $fh, 0, 0;
        }
        else {
            open $fh, ">:unix:encoding(UTF-8)", $file;
        }
    
        # serialize and spew to the handle
        print {$fh} $self->_dump_string;
    
        # close the file (release the lock)
        unless ( close $fh ) {
            $self->_error("Failed to close file '$file': $!");
        }
    
        return 1;
    }
    
    # Save an object to a string
    sub _dump_string {
        my $self = shift;
        return '' unless ref $self && @$self;
    
        # Iterate over the documents
        my $indent = 0;
        my @lines  = ();
    
        eval {
            foreach my $cursor ( @$self ) {
                push @lines, '---';
    
                # An empty document
                if ( ! defined $cursor ) {
                    # Do nothing
    
                # A scalar document
                } elsif ( ! ref $cursor ) {
                    $lines[-1] .= ' ' . $self->_dump_scalar( $cursor );
    
                # A list at the root
                } elsif ( ref $cursor eq 'ARRAY' ) {
                    unless ( @$cursor ) {
                        $lines[-1] .= ' []';
                        next;
                    }
                    push @lines, $self->_dump_array( $cursor, $indent, {} );
    
                # A hash at the root
                } elsif ( ref $cursor eq 'HASH' ) {
                    unless ( %$cursor ) {
                        $lines[-1] .= ' {}';
                        next;
                    }
                    push @lines, $self->_dump_hash( $cursor, $indent, {} );
    
                } else {
                    die \("Cannot serialize " . ref($cursor));
                }
            }
        };
        if ( ref $@ eq 'SCALAR' ) {
            $self->_error(${$@});
        } elsif ( $@ ) {
            $self->_error($@);
        }
    
        join '', map { "$_\n" } @lines;
    }
    
    sub _has_internal_string_value {
        my $value = shift;
        my $b_obj = B::svref_2object(\$value);  # for round trip problem
        return $b_obj->FLAGS & B::SVf_POK();
    }
    
    sub _dump_scalar {
        my $string = $_[1];
        my $is_key = $_[2];
        # Check this before checking length or it winds up looking like a string!
        my $has_string_flag = _has_internal_string_value($string);
        return '~'  unless defined $string;
        return "''" unless length  $string;
        if (Scalar::Util::looks_like_number($string)) {
            # keys and values that have been used as strings get quoted
            if ( $is_key || $has_string_flag ) {
                return qq['$string'];
            }
            else {
                return $string;
            }
        }
        if ( $string =~ /[\x00-\x09\x0b-\x0d\x0e-\x1f\x7f-\x9f\'\n]/ ) {
            $string =~ s/\\/\\\\/g;
            $string =~ s/"/\\"/g;
            $string =~ s/\n/\\n/g;
            $string =~ s/[\x85]/\\N/g;
            $string =~ s/([\x00-\x1f])/\\$UNPRINTABLE[ord($1)]/g;
            $string =~ s/([\x7f-\x9f])/'\x' . sprintf("%X",ord($1))/ge;
            return qq|"$string"|;
        }
        if ( $string =~ /(?:^[~!@#%&*|>?:,'"`{}\[\]]|^-+$|\s|:\z)/ or
            $QUOTE{$string}
        ) {
            return "'$string'";
        }
        return $string;
    }
    
    sub _dump_array {
        my ($self, $array, $indent, $seen) = @_;
        if ( $seen->{refaddr($array)}++ ) {
            die \"CPAN::Meta::YAML does not support circular references";
        }
        my @lines  = ();
        foreach my $el ( @$array ) {
            my $line = ('  ' x $indent) . '-';
            my $type = ref $el;
            if ( ! $type ) {
                $line .= ' ' . $self->_dump_scalar( $el );
                push @lines, $line;
    
            } elsif ( $type eq 'ARRAY' ) {
                if ( @$el ) {
                    push @lines, $line;
                    push @lines, $self->_dump_array( $el, $indent + 1, $seen );
                } else {
                    $line .= ' []';
                    push @lines, $line;
                }
    
            } elsif ( $type eq 'HASH' ) {
                if ( keys %$el ) {
                    push @lines, $line;
                    push @lines, $self->_dump_hash( $el, $indent + 1, $seen );
                } else {
                    $line .= ' {}';
                    push @lines, $line;
                }
    
            } else {
                die \"CPAN::Meta::YAML does not support $type references";
            }
        }
    
        @lines;
    }
    
    sub _dump_hash {
        my ($self, $hash, $indent, $seen) = @_;
        if ( $seen->{refaddr($hash)}++ ) {
            die \"CPAN::Meta::YAML does not support circular references";
        }
        my @lines  = ();
        foreach my $name ( sort keys %$hash ) {
            my $el   = $hash->{$name};
            my $line = ('  ' x $indent) . $self->_dump_scalar($name, 1) . ":";
            my $type = ref $el;
            if ( ! $type ) {
                $line .= ' ' . $self->_dump_scalar( $el );
                push @lines, $line;
    
            } elsif ( $type eq 'ARRAY' ) {
                if ( @$el ) {
                    push @lines, $line;
                    push @lines, $self->_dump_array( $el, $indent + 1, $seen );
                } else {
                    $line .= ' []';
                    push @lines, $line;
                }
    
            } elsif ( $type eq 'HASH' ) {
                if ( keys %$el ) {
                    push @lines, $line;
                    push @lines, $self->_dump_hash( $el, $indent + 1, $seen );
                } else {
                    $line .= ' {}';
                    push @lines, $line;
                }
    
            } else {
                die \"CPAN::Meta::YAML does not support $type references";
            }
        }
    
        @lines;
    }
    
    
    
    #####################################################################
    # DEPRECATED API methods:
    
    # Error storage (DEPRECATED as of 1.57)
    our $errstr    = '';
    
    # Set error
    sub _error {
        require Carp;
        $errstr = $_[1];
        $errstr =~ s/ at \S+ line \d+.*//;
        Carp::croak( $errstr );
    }
    
    # Retrieve error
    my $errstr_warned;
    sub errstr {
        require Carp;
        Carp::carp( "CPAN::Meta::YAML->errstr and \$CPAN::Meta::YAML::errstr is deprecated" )
            unless $errstr_warned++;
        $errstr;
    }
    
    
    
    
    #####################################################################
    # Helper functions. Possibly not needed.
    
    
    # Use to detect nv or iv
    use B;
    
    # XXX-INGY Is flock CPAN::Meta::YAML's responsibility?
    # Some platforms can't flock :-(
    # XXX-XDG I think it is.  When reading and writing files, we ought
    # to be locking whenever possible.  People (foolishly) use YAML
    # files for things like session storage, which has race issues.
    my $HAS_FLOCK;
    sub _can_flock {
        if ( defined $HAS_FLOCK ) {
            return $HAS_FLOCK;
        }
        else {
            require Config;
            my $c = \%Config::Config;
            $HAS_FLOCK = grep { $c->{$_} } qw/d_flock d_fcntl_can_lock d_lockf/;
            require Fcntl if $HAS_FLOCK;
            return $HAS_FLOCK;
        }
    }
    
    
    # XXX-INGY Is this core in 5.8.1? Can we remove this?
    # XXX-XDG Scalar::Util 1.18 didn't land until 5.8.8, so we need this
    #####################################################################
    # Use Scalar::Util if possible, otherwise emulate it
    
    BEGIN {
        local $@;
        if ( eval { require Scalar::Util }
          && $Scalar::Util::VERSION
          && eval($Scalar::Util::VERSION) >= 1.18
        ) {
            *refaddr = *Scalar::Util::refaddr;
        }
        else {
            eval <<'END_PERL';
    # Scalar::Util failed to load or too old
    sub refaddr {
        my $pkg = ref($_[0]) or return undef;
        if ( !! UNIVERSAL::can($_[0], 'can') ) {
            bless $_[0], 'Scalar::Util::Fake';
        } else {
            $pkg = undef;
        }
        "$_[0]" =~ /0x(\w+)/;
        my $i = do { no warnings 'portable'; hex $1 };
        bless $_[0], $pkg if defined $pkg;
        $i;
    }
    END_PERL
        }
    }
    
    
    
    
    1;
    
    # XXX-INGY Doc notes I'm putting up here. Changing the doc when it's wrong
    # but leaving grey area stuff up here.
    #
    # I would like to change Read/Write to Load/Dump below without
    # changing the actual API names.
    #
    # It might be better to put Load/Dump API in the SYNOPSIS instead of the
    # dubious OO API.
    #
    # null and bool explanations may be outdated.
    
    =pod
    
    =encoding UTF-8
    
    =head1 NAME
    
    CPAN::Meta::YAML - Read and write a subset of YAML for CPAN Meta files
    
    =head1 VERSION
    
    version 0.012
    
    =head1 SYNOPSIS
    
        use CPAN::Meta::YAML;
    
        # reading a META file
        open $fh, "<:utf8", "META.yml";
        $yaml_text = do { local $/; <$fh> };
        $yaml = CPAN::Meta::YAML->read_string($yaml_text)
          or die CPAN::Meta::YAML->errstr;
    
        # finding the metadata
        $meta = $yaml->[0];
    
        # writing a META file
        $yaml_text = $yaml->write_string
          or die CPAN::Meta::YAML->errstr;
        open $fh, ">:utf8", "META.yml";
        print $fh $yaml_text;
    
    =head1 DESCRIPTION
    
    This module implements a subset of the YAML specification for use in reading
    and writing CPAN metadata files like F<META.yml> and F<MYMETA.yml>.  It should
    not be used for any other general YAML parsing or generation task.
    
    NOTE: F<META.yml> (and F<MYMETA.yml>) files should be UTF-8 encoded.  Users are
    responsible for proper encoding and decoding.  In particular, the C<read> and
    C<write> methods do B<not> support UTF-8 and should not be used.
    
    =head1 SUPPORT
    
    This module is currently derived from L<YAML::Tiny> by Adam Kennedy.  If
    there are bugs in how it parses a particular META.yml file, please file
    a bug report in the YAML::Tiny bugtracker:
    L<https://rt.cpan.org/Public/Dist/Display.html?Name=YAML-Tiny>
    
    =head1 SEE ALSO
    
    L<YAML::Tiny>, L<YAML>, L<YAML::XS>
    
    =for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan
    
    =head1 SUPPORT
    
    =head2 Bugs / Feature Requests
    
    Please report any bugs or feature requests through the issue tracker
    at L<https://github.com/dagolden/CPAN-Meta-YAML/issues>.
    You will be notified automatically of any progress on your issue.
    
    =head2 Source Code
    
    This is open source software.  The code repository is available for
    public review and contribution under the terms of the license.
    
    L<https://github.com/dagolden/CPAN-Meta-YAML>
    
      git clone https://github.com/dagolden/CPAN-Meta-YAML.git
    
    =head1 AUTHORS
    
    =over 4
    
    =item *
    
    Adam Kennedy <adamk@cpan.org>
    
    =item *
    
    David Golden <dagolden@cpan.org>
    
    =back
    
    =head1 COPYRIGHT AND LICENSE
    
    This software is copyright (c) 2010 by Adam Kennedy.
    
    This is free software; you can redistribute it and/or modify it under
    the same terms as the Perl 5 programming language system itself.
    
    =cut
    
    __END__
    
    
    # ABSTRACT: Read and write a subset of YAML for CPAN Meta files
    
    
  CPAN_META_YAML
  
  $fatpacked{"Exporter.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'EXPORTER';
    package Exporter;
    
    require 5.006;
    
    # Be lean.
    #use strict;
    #no strict 'refs';
    
    our $Debug = 0;
    our $ExportLevel = 0;
    our $Verbose ||= 0;
    our $VERSION = '5.70';
    our (%Cache);
    
    sub as_heavy {
      require Exporter::Heavy;
      # Unfortunately, this does not work if the caller is aliased as *name = \&foo
      # Thus the need to create a lot of identical subroutines
      my $c = (caller(1))[3];
      $c =~ s/.*:://;
      \&{"Exporter::Heavy::heavy_$c"};
    }
    
    sub export {
      goto &{as_heavy()};
    }
    
    sub import {
      my $pkg = shift;
      my $callpkg = caller($ExportLevel);
    
      if ($pkg eq "Exporter" and @_ and $_[0] eq "import") {
        *{$callpkg."::import"} = \&import;
        return;
      }
    
      # We *need* to treat @{"$pkg\::EXPORT_FAIL"} since Carp uses it :-(
      my $exports = \@{"$pkg\::EXPORT"};
      # But, avoid creating things if they don't exist, which saves a couple of
      # hundred bytes per package processed.
      my $fail = ${$pkg . '::'}{EXPORT_FAIL} && \@{"$pkg\::EXPORT_FAIL"};
      return export $pkg, $callpkg, @_
        if $Verbose or $Debug or $fail && @$fail > 1;
      my $export_cache = ($Cache{$pkg} ||= {});
      my $args = @_ or @_ = @$exports;
    
      if ($args and not %$export_cache) {
        s/^&//, $export_cache->{$_} = 1
          foreach (@$exports, @{"$pkg\::EXPORT_OK"});
      }
      my $heavy;
      # Try very hard not to use {} and hence have to  enter scope on the foreach
      # We bomb out of the loop with last as soon as heavy is set.
      if ($args or $fail) {
        ($heavy = (/\W/ or $args and not exists $export_cache->{$_}
                   or $fail and @$fail and $_ eq $fail->[0])) and last
                     foreach (@_);
      } else {
        ($heavy = /\W/) and last
          foreach (@_);
      }
      return export $pkg, $callpkg, ($args ? @_ : ()) if $heavy;
      local $SIG{__WARN__} = 
    	sub {require Carp; &Carp::carp} if not $SIG{__WARN__};
      # shortcut for the common case of no type character
      *{"$callpkg\::$_"} = \&{"$pkg\::$_"} foreach @_;
    }
    
    # Default methods
    
    sub export_fail {
        my $self = shift;
        @_;
    }
    
    # Unfortunately, caller(1)[3] "does not work" if the caller is aliased as
    # *name = \&foo.  Thus the need to create a lot of identical subroutines
    # Otherwise we could have aliased them to export().
    
    sub export_to_level {
      goto &{as_heavy()};
    }
    
    sub export_tags {
      goto &{as_heavy()};
    }
    
    sub export_ok_tags {
      goto &{as_heavy()};
    }
    
    sub require_version {
      goto &{as_heavy()};
    }
    
    1;
    __END__
    
    =head1 NAME
    
    Exporter - Implements default import method for modules
    
    =head1 SYNOPSIS
    
    In module F<YourModule.pm>:
    
      package YourModule;
      require Exporter;
      @ISA = qw(Exporter);
      @EXPORT_OK = qw(munge frobnicate);  # symbols to export on request
    
    or
    
      package YourModule;
      use Exporter 'import'; # gives you Exporter's import() method directly
      @EXPORT_OK = qw(munge frobnicate);  # symbols to export on request
    
    In other files which wish to use C<YourModule>:
    
      use YourModule qw(frobnicate);      # import listed symbols
      frobnicate ($left, $right)          # calls YourModule::frobnicate
    
    Take a look at L</Good Practices> for some variants
    you will like to use in modern Perl code.
    
    =head1 DESCRIPTION
    
    The Exporter module implements an C<import> method which allows a module
    to export functions and variables to its users' namespaces.  Many modules
    use Exporter rather than implementing their own C<import> method because
    Exporter provides a highly flexible interface, with an implementation optimised
    for the common case.
    
    Perl automatically calls the C<import> method when processing a
    C<use> statement for a module.  Modules and C<use> are documented
    in L<perlfunc> and L<perlmod>.  Understanding the concept of
    modules and how the C<use> statement operates is important to
    understanding the Exporter.
    
    =head2 How to Export
    
    The arrays C<@EXPORT> and C<@EXPORT_OK> in a module hold lists of
    symbols that are going to be exported into the users name space by
    default, or which they can request to be exported, respectively.  The
    symbols can represent functions, scalars, arrays, hashes, or typeglobs.
    The symbols must be given by full name with the exception that the
    ampersand in front of a function is optional, e.g.
    
        @EXPORT    = qw(afunc $scalar @array);   # afunc is a function
        @EXPORT_OK = qw(&bfunc %hash *typeglob); # explicit prefix on &bfunc
    
    If you are only exporting function names it is recommended to omit the
    ampersand, as the implementation is faster this way.
    
    =head2 Selecting What to Export
    
    Do B<not> export method names!
    
    Do B<not> export anything else by default without a good reason!
    
    Exports pollute the namespace of the module user.  If you must export
    try to use C<@EXPORT_OK> in preference to C<@EXPORT> and avoid short or
    common symbol names to reduce the risk of name clashes.
    
    Generally anything not exported is still accessible from outside the
    module using the C<YourModule::item_name> (or C<< $blessed_ref->method >>)
    syntax.  By convention you can use a leading underscore on names to
    informally indicate that they are 'internal' and not for public use.
    
    (It is actually possible to get private functions by saying:
    
      my $subref = sub { ... };
      $subref->(@args);            # Call it as a function
      $obj->$subref(@args);        # Use it as a method
    
    However if you use them for methods it is up to you to figure out
    how to make inheritance work.)
    
    As a general rule, if the module is trying to be object oriented
    then export nothing.  If it's just a collection of functions then
    C<@EXPORT_OK> anything but use C<@EXPORT> with caution.  For function and
    method names use barewords in preference to names prefixed with
    ampersands for the export lists.
    
    Other module design guidelines can be found in L<perlmod>.
    
    =head2 How to Import
    
    In other files which wish to use your module there are three basic ways for
    them to load your module and import its symbols:
    
    =over 4
    
    =item C<use YourModule;>
    
    This imports all the symbols from YourModule's C<@EXPORT> into the namespace
    of the C<use> statement.
    
    =item C<use YourModule ();>
    
    This causes perl to load your module but does not import any symbols.
    
    =item C<use YourModule qw(...);>
    
    This imports only the symbols listed by the caller into their namespace.
    All listed symbols must be in your C<@EXPORT> or C<@EXPORT_OK>, else an error
    occurs.  The advanced export features of Exporter are accessed like this,
    but with list entries that are syntactically distinct from symbol names.
    
    =back
    
    Unless you want to use its advanced features, this is probably all you
    need to know to use Exporter.
    
    =head1 Advanced Features
    
    =head2 Specialised Import Lists
    
    If any of the entries in an import list begins with !, : or / then
    the list is treated as a series of specifications which either add to
    or delete from the list of names to import.  They are processed left to
    right. Specifications are in the form:
    
        [!]name         This name only
        [!]:DEFAULT     All names in @EXPORT
        [!]:tag         All names in $EXPORT_TAGS{tag} anonymous list
        [!]/pattern/    All names in @EXPORT and @EXPORT_OK which match
    
    A leading ! indicates that matching names should be deleted from the
    list of names to import.  If the first specification is a deletion it
    is treated as though preceded by :DEFAULT.  If you just want to import
    extra names in addition to the default set you will still need to
    include :DEFAULT explicitly.
    
    e.g., F<Module.pm> defines:
    
        @EXPORT      = qw(A1 A2 A3 A4 A5);
        @EXPORT_OK   = qw(B1 B2 B3 B4 B5);
        %EXPORT_TAGS = (T1 => [qw(A1 A2 B1 B2)], T2 => [qw(A1 A2 B3 B4)]);
    
    Note that you cannot use tags in @EXPORT or @EXPORT_OK.
    
    Names in EXPORT_TAGS must also appear in @EXPORT or @EXPORT_OK.
    
    An application using Module can say something like:
    
        use Module qw(:DEFAULT :T2 !B3 A3);
    
    Other examples include:
    
        use Socket qw(!/^[AP]F_/ !SOMAXCONN !SOL_SOCKET);
        use POSIX  qw(:errno_h :termios_h !TCSADRAIN !/^EXIT/);
    
    Remember that most patterns (using //) will need to be anchored
    with a leading ^, e.g., C</^EXIT/> rather than C</EXIT/>.
    
    You can say C<BEGIN { $Exporter::Verbose=1 }> to see how the
    specifications are being processed and what is actually being imported
    into modules.
    
    =head2 Exporting Without Using Exporter's import Method
    
    Exporter has a special method, 'export_to_level' which is used in situations
    where you can't directly call Exporter's
    import method.  The export_to_level
    method looks like:
    
        MyPackage->export_to_level(
    	$where_to_export, $package, @what_to_export
        );
    
    where C<$where_to_export> is an integer telling how far up the calling stack
    to export your symbols, and C<@what_to_export> is an array telling what
    symbols *to* export (usually this is C<@_>).  The C<$package> argument is
    currently unused.
    
    For example, suppose that you have a module, A, which already has an
    import function:
    
        package A;
    
        @ISA = qw(Exporter);
        @EXPORT_OK = qw($b);
    
        sub import
        {
    	$A::b = 1;     # not a very useful import method
        }
    
    and you want to Export symbol C<$A::b> back to the module that called 
    package A.  Since Exporter relies on the import method to work, via 
    inheritance, as it stands Exporter::import() will never get called. 
    Instead, say the following:
    
        package A;
        @ISA = qw(Exporter);
        @EXPORT_OK = qw($b);
    
        sub import
        {
    	$A::b = 1;
    	A->export_to_level(1, @_);
        }
    
    This will export the symbols one level 'above' the current package - ie: to 
    the program or module that used package A. 
    
    Note: Be careful not to modify C<@_> at all before you call export_to_level
    - or people using your package will get very unexplained results!
    
    =head2 Exporting Without Inheriting from Exporter
    
    By including Exporter in your C<@ISA> you inherit an Exporter's import() method
    but you also inherit several other helper methods which you probably don't
    want.  To avoid this you can do:
    
      package YourModule;
      use Exporter qw(import);
    
    which will export Exporter's own import() method into YourModule.
    Everything will work as before but you won't need to include Exporter in
    C<@YourModule::ISA>.
    
    Note: This feature was introduced in version 5.57
    of Exporter, released with perl 5.8.3.
    
    =head2 Module Version Checking
    
    The Exporter module will convert an attempt to import a number from a
    module into a call to C<< $module_name->VERSION($value) >>.  This can
    be used to validate that the version of the module being used is
    greater than or equal to the required version.
    
    For historical reasons, Exporter supplies a C<require_version> method that
    simply delegates to C<VERSION>.  Originally, before C<UNIVERSAL::VERSION>
    existed, Exporter would call C<require_version>.
    
    Since the C<UNIVERSAL::VERSION> method treats the C<$VERSION> number as
    a simple numeric value it will regard version 1.10 as lower than
    1.9.  For this reason it is strongly recommended that you use numbers
    with at least two decimal places, e.g., 1.09.
    
    =head2 Managing Unknown Symbols
    
    In some situations you may want to prevent certain symbols from being
    exported.  Typically this applies to extensions which have functions
    or constants that may not exist on some systems.
    
    The names of any symbols that cannot be exported should be listed
    in the C<@EXPORT_FAIL> array.
    
    If a module attempts to import any of these symbols the Exporter
    will give the module an opportunity to handle the situation before
    generating an error.  The Exporter will call an export_fail method
    with a list of the failed symbols:
    
      @failed_symbols = $module_name->export_fail(@failed_symbols);
    
    If the C<export_fail> method returns an empty list then no error is
    recorded and all the requested symbols are exported.  If the returned
    list is not empty then an error is generated for each symbol and the
    export fails.  The Exporter provides a default C<export_fail> method which
    simply returns the list unchanged.
    
    Uses for the C<export_fail> method include giving better error messages
    for some symbols and performing lazy architectural checks (put more
    symbols into C<@EXPORT_FAIL> by default and then take them out if someone
    actually tries to use them and an expensive check shows that they are
    usable on that platform).
    
    =head2 Tag Handling Utility Functions
    
    Since the symbols listed within C<%EXPORT_TAGS> must also appear in either
    C<@EXPORT> or C<@EXPORT_OK>, two utility functions are provided which allow
    you to easily add tagged sets of symbols to C<@EXPORT> or C<@EXPORT_OK>:
    
      %EXPORT_TAGS = (foo => [qw(aa bb cc)], bar => [qw(aa cc dd)]);
    
      Exporter::export_tags('foo');     # add aa, bb and cc to @EXPORT
      Exporter::export_ok_tags('bar');  # add aa, cc and dd to @EXPORT_OK
    
    Any names which are not tags are added to C<@EXPORT> or C<@EXPORT_OK>
    unchanged but will trigger a warning (with C<-w>) to avoid misspelt tags
    names being silently added to C<@EXPORT> or C<@EXPORT_OK>.  Future versions
    may make this a fatal error.
    
    =head2 Generating Combined Tags
    
    If several symbol categories exist in C<%EXPORT_TAGS>, it's usually
    useful to create the utility ":all" to simplify "use" statements.
    
    The simplest way to do this is:
    
      %EXPORT_TAGS = (foo => [qw(aa bb cc)], bar => [qw(aa cc dd)]);
    
      # add all the other ":class" tags to the ":all" class,
      # deleting duplicates
      {
        my %seen;
    
        push @{$EXPORT_TAGS{all}},
          grep {!$seen{$_}++} @{$EXPORT_TAGS{$_}} foreach keys %EXPORT_TAGS;
      }
    
    F<CGI.pm> creates an ":all" tag which contains some (but not really
    all) of its categories.  That could be done with one small
    change:
    
      # add some of the other ":class" tags to the ":all" class,
      # deleting duplicates
      {
        my %seen;
    
        push @{$EXPORT_TAGS{all}},
          grep {!$seen{$_}++} @{$EXPORT_TAGS{$_}}
            foreach qw/html2 html3 netscape form cgi internal/;
      }
    
    Note that the tag names in C<%EXPORT_TAGS> don't have the leading ':'.
    
    =head2 C<AUTOLOAD>ed Constants
    
    Many modules make use of C<AUTOLOAD>ing for constant subroutines to
    avoid having to compile and waste memory on rarely used values (see
    L<perlsub> for details on constant subroutines).  Calls to such
    constant subroutines are not optimized away at compile time because
    they can't be checked at compile time for constancy.
    
    Even if a prototype is available at compile time, the body of the
    subroutine is not (it hasn't been C<AUTOLOAD>ed yet).  perl needs to
    examine both the C<()> prototype and the body of a subroutine at
    compile time to detect that it can safely replace calls to that
    subroutine with the constant value.
    
    A workaround for this is to call the constants once in a C<BEGIN> block:
    
       package My ;
    
       use Socket ;
    
       foo( SO_LINGER );  ## SO_LINGER NOT optimized away; called at runtime
       BEGIN { SO_LINGER }
       foo( SO_LINGER );  ## SO_LINGER optimized away at compile time.
    
    This forces the C<AUTOLOAD> for C<SO_LINGER> to take place before
    SO_LINGER is encountered later in C<My> package.
    
    If you are writing a package that C<AUTOLOAD>s, consider forcing
    an C<AUTOLOAD> for any constants explicitly imported by other packages
    or which are usually used when your package is C<use>d.
    
    =head1 Good Practices
    
    =head2 Declaring C<@EXPORT_OK> and Friends
    
    When using C<Exporter> with the standard C<strict> and C<warnings>
    pragmas, the C<our> keyword is needed to declare the package
    variables C<@EXPORT_OK>, C<@EXPORT>, C<@ISA>, etc.
    
      our @ISA = qw(Exporter);
      our @EXPORT_OK = qw(munge frobnicate);
    
    If backward compatibility for Perls under 5.6 is important,
    one must write instead a C<use vars> statement.
    
      use vars qw(@ISA @EXPORT_OK);
      @ISA = qw(Exporter);
      @EXPORT_OK = qw(munge frobnicate);
    
    =head2 Playing Safe
    
    There are some caveats with the use of runtime statements
    like C<require Exporter> and the assignment to package
    variables, which can be very subtle for the unaware programmer.
    This may happen for instance with mutually recursive
    modules, which are affected by the time the relevant
    constructions are executed.
    
    The ideal (but a bit ugly) way to never have to think
    about that is to use C<BEGIN> blocks.  So the first part
    of the L</SYNOPSIS> code could be rewritten as:
    
      package YourModule;
    
      use strict;
      use warnings;
    
      our (@ISA, @EXPORT_OK);
      BEGIN {
         require Exporter;
         @ISA = qw(Exporter);
         @EXPORT_OK = qw(munge frobnicate);  # symbols to export on request
      }
    
    The C<BEGIN> will assure that the loading of F<Exporter.pm>
    and the assignments to C<@ISA> and C<@EXPORT_OK> happen
    immediately, leaving no room for something to get awry
    or just plain wrong.
    
    With respect to loading C<Exporter> and inheriting, there
    are alternatives with the use of modules like C<base> and C<parent>.
    
      use base qw(Exporter);
      # or
      use parent qw(Exporter);
    
    Any of these statements are nice replacements for
    C<BEGIN { require Exporter; @ISA = qw(Exporter); }>
    with the same compile-time effect.  The basic difference
    is that C<base> code interacts with declared C<fields>
    while C<parent> is a streamlined version of the older
    C<base> code to just establish the IS-A relationship.
    
    For more details, see the documentation and code of
    L<base> and L<parent>.
    
    Another thorough remedy to that runtime
    vs. compile-time trap is to use L<Exporter::Easy>,
    which is a wrapper of Exporter that allows all
    boilerplate code at a single gulp in the
    use statement.
    
       use Exporter::Easy (
           OK => [ qw(munge frobnicate) ],
       );
       # @ISA setup is automatic
       # all assignments happen at compile time
    
    =head2 What Not to Export
    
    You have been warned already in L</Selecting What to Export>
    to not export:
    
    =over 4
    
    =item *
    
    method names (because you don't need to
    and that's likely to not do what you want),
    
    =item *
    
    anything by default (because you don't want to surprise your users...
    badly)
    
    =item *
    
    anything you don't need to (because less is more)
    
    =back
    
    There's one more item to add to this list.  Do B<not>
    export variable names.  Just because C<Exporter> lets you
    do that, it does not mean you should.
    
      @EXPORT_OK = qw($svar @avar %hvar); # DON'T!
    
    Exporting variables is not a good idea.  They can
    change under the hood, provoking horrible
    effects at-a-distance that are too hard to track
    and to fix.  Trust me: they are not worth it.
    
    To provide the capability to set/get class-wide
    settings, it is best instead to provide accessors
    as subroutines or class methods instead.
    
    =head1 SEE ALSO
    
    C<Exporter> is definitely not the only module with
    symbol exporter capabilities.  At CPAN, you may find
    a bunch of them.  Some are lighter.  Some
    provide improved APIs and features.  Pick the one
    that fits your needs.  The following is
    a sample list of such modules.
    
        Exporter::Easy
        Exporter::Lite
        Exporter::Renaming
        Exporter::Tidy
        Sub::Exporter / Sub::Installer
        Perl6::Export / Perl6::Export::Attrs
    
    =head1 LICENSE
    
    This library is free software.  You can redistribute it
    and/or modify it under the same terms as Perl itself.
    
    =cut
    
    
    
  EXPORTER
  
  $fatpacked{"Exporter/Heavy.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'EXPORTER_HEAVY';
    package Exporter::Heavy;
    
    use strict;
    no strict 'refs';
    
    # On one line so MakeMaker will see it.
    require Exporter;  our $VERSION = $Exporter::VERSION;
    
    =head1 NAME
    
    Exporter::Heavy - Exporter guts
    
    =head1 SYNOPSIS
    
    (internal use only)
    
    =head1 DESCRIPTION
    
    No user-serviceable parts inside.
    
    =cut
    
    #
    # We go to a lot of trouble not to 'require Carp' at file scope,
    #  because Carp requires Exporter, and something has to give.
    #
    
    sub _rebuild_cache {
        my ($pkg, $exports, $cache) = @_;
        s/^&// foreach @$exports;
        @{$cache}{@$exports} = (1) x @$exports;
        my $ok = \@{"${pkg}::EXPORT_OK"};
        if (@$ok) {
    	s/^&// foreach @$ok;
    	@{$cache}{@$ok} = (1) x @$ok;
        }
    }
    
    sub heavy_export {
    
        # Save the old __WARN__ handler in case it was defined
        my $oldwarn = $SIG{__WARN__};
    
        # First make import warnings look like they're coming from the "use".
        local $SIG{__WARN__} = sub {
    	# restore it back so proper stacking occurs
    	local $SIG{__WARN__} = $oldwarn;
    	my $text = shift;
    	if ($text =~ s/ at \S*Exporter\S*.pm line \d+.*\n//) {
    	    require Carp;
    	    local $Carp::CarpLevel = 1;	# ignore package calling us too.
    	    Carp::carp($text);
    	}
    	else {
    	    warn $text;
    	}
        };
        local $SIG{__DIE__} = sub {
    	require Carp;
    	local $Carp::CarpLevel = 1;	# ignore package calling us too.
    	Carp::croak("$_[0]Illegal null symbol in \@${1}::EXPORT")
    	    if $_[0] =~ /^Unable to create sub named "(.*?)::"/;
        };
    
        my($pkg, $callpkg, @imports) = @_;
        my($type, $sym, $cache_is_current, $oops);
        my($exports, $export_cache) = (\@{"${pkg}::EXPORT"},
                                       $Exporter::Cache{$pkg} ||= {});
    
        if (@imports) {
    	if (!%$export_cache) {
    	    _rebuild_cache ($pkg, $exports, $export_cache);
    	    $cache_is_current = 1;
    	}
    
    	if (grep m{^[/!:]}, @imports) {
    	    my $tagsref = \%{"${pkg}::EXPORT_TAGS"};
    	    my $tagdata;
    	    my %imports;
    	    my($remove, $spec, @names, @allexports);
    	    # negated first item implies starting with default set:
    	    unshift @imports, ':DEFAULT' if $imports[0] =~ m/^!/;
    	    foreach $spec (@imports){
    		$remove = $spec =~ s/^!//;
    
    		if ($spec =~ s/^://){
    		    if ($spec eq 'DEFAULT'){
    			@names = @$exports;
    		    }
    		    elsif ($tagdata = $tagsref->{$spec}) {
    			@names = @$tagdata;
    		    }
    		    else {
    			warn qq["$spec" is not defined in %${pkg}::EXPORT_TAGS];
    			++$oops;
    			next;
    		    }
    		}
    		elsif ($spec =~ m:^/(.*)/$:){
    		    my $patn = $1;
    		    @allexports = keys %$export_cache unless @allexports; # only do keys once
    		    @names = grep(/$patn/, @allexports); # not anchored by default
    		}
    		else {
    		    @names = ($spec); # is a normal symbol name
    		}
    
    		warn "Import ".($remove ? "del":"add").": @names "
    		    if $Exporter::Verbose;
    
    		if ($remove) {
    		   foreach $sym (@names) { delete $imports{$sym} } 
    		}
    		else {
    		    @imports{@names} = (1) x @names;
    		}
    	    }
    	    @imports = keys %imports;
    	}
    
            my @carp;
    	foreach $sym (@imports) {
    	    if (!$export_cache->{$sym}) {
    		if ($sym =~ m/^\d/) {
    		    $pkg->VERSION($sym); # inherit from UNIVERSAL
    		    # If the version number was the only thing specified
    		    # then we should act as if nothing was specified:
    		    if (@imports == 1) {
    			@imports = @$exports;
    			last;
    		    }
    		    # We need a way to emulate 'use Foo ()' but still
    		    # allow an easy version check: "use Foo 1.23, ''";
    		    if (@imports == 2 and !$imports[1]) {
    			@imports = ();
    			last;
    		    }
    		} elsif ($sym !~ s/^&// || !$export_cache->{$sym}) {
    		    # Last chance - see if they've updated EXPORT_OK since we
    		    # cached it.
    
    		    unless ($cache_is_current) {
    			%$export_cache = ();
    			_rebuild_cache ($pkg, $exports, $export_cache);
    			$cache_is_current = 1;
    		    }
    
    		    if (!$export_cache->{$sym}) {
    			# accumulate the non-exports
    			push @carp,
    			  qq["$sym" is not exported by the $pkg module\n];
    			$oops++;
    		    }
    		}
    	    }
    	}
    	if ($oops) {
    	    require Carp;
    	    Carp::croak("@{carp}Can't continue after import errors");
    	}
        }
        else {
    	@imports = @$exports;
        }
    
        my($fail, $fail_cache) = (\@{"${pkg}::EXPORT_FAIL"},
                                  $Exporter::FailCache{$pkg} ||= {});
    
        if (@$fail) {
    	if (!%$fail_cache) {
    	    # Build cache of symbols. Optimise the lookup by adding
    	    # barewords twice... both with and without a leading &.
    	    # (Technique could be applied to $export_cache at cost of memory)
    	    my @expanded = map { /^\w/ ? ($_, '&'.$_) : $_ } @$fail;
    	    warn "${pkg}::EXPORT_FAIL cached: @expanded" if $Exporter::Verbose;
    	    @{$fail_cache}{@expanded} = (1) x @expanded;
    	}
    	my @failed;
    	foreach $sym (@imports) { push(@failed, $sym) if $fail_cache->{$sym} }
    	if (@failed) {
    	    @failed = $pkg->export_fail(@failed);
    	    foreach $sym (@failed) {
                    require Carp;
    		Carp::carp(qq["$sym" is not implemented by the $pkg module ],
    			"on this architecture");
    	    }
    	    if (@failed) {
    		require Carp;
    		Carp::croak("Can't continue after import errors");
    	    }
    	}
        }
    
        warn "Importing into $callpkg from $pkg: ",
    		join(", ",sort @imports) if $Exporter::Verbose;
    
        foreach $sym (@imports) {
    	# shortcut for the common case of no type character
    	(*{"${callpkg}::$sym"} = \&{"${pkg}::$sym"}, next)
    	    unless $sym =~ s/^(\W)//;
    	$type = $1;
    	no warnings 'once';
    	*{"${callpkg}::$sym"} =
    	    $type eq '&' ? \&{"${pkg}::$sym"} :
    	    $type eq '$' ? \${"${pkg}::$sym"} :
    	    $type eq '@' ? \@{"${pkg}::$sym"} :
    	    $type eq '%' ? \%{"${pkg}::$sym"} :
    	    $type eq '*' ?  *{"${pkg}::$sym"} :
    	    do { require Carp; Carp::croak("Can't export symbol: $type$sym") };
        }
    }
    
    sub heavy_export_to_level
    {
          my $pkg = shift;
          my $level = shift;
          (undef) = shift;			# XXX redundant arg
          my $callpkg = caller($level);
          $pkg->export($callpkg, @_);
    }
    
    # Utility functions
    
    sub _push_tags {
        my($pkg, $var, $syms) = @_;
        my @nontag = ();
        my $export_tags = \%{"${pkg}::EXPORT_TAGS"};
        push(@{"${pkg}::$var"},
    	map { $export_tags->{$_} ? @{$export_tags->{$_}} 
                                     : scalar(push(@nontag,$_),$_) }
    		(@$syms) ? @$syms : keys %$export_tags);
        if (@nontag and $^W) {
    	# This may change to a die one day
    	require Carp;
    	Carp::carp(join(", ", @nontag)." are not tags of $pkg");
        }
    }
    
    sub heavy_require_version {
        my($self, $wanted) = @_;
        my $pkg = ref $self || $self;
        return ${pkg}->VERSION($wanted);
    }
    
    sub heavy_export_tags {
      _push_tags((caller)[0], "EXPORT",    \@_);
    }
    
    sub heavy_export_ok_tags {
      _push_tags((caller)[0], "EXPORT_OK", \@_);
    }
    
    1;
  EXPORTER_HEAVY
  
  $fatpacked{"File/pushd.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'FILE_PUSHD';
    use strict;
    use warnings;
    
    package File::pushd;
    # ABSTRACT: change directory temporarily for a limited scope
    our $VERSION = '1.009'; # VERSION
    
    our @EXPORT = qw( pushd tempd );
    our @ISA    = qw( Exporter );
    
    use Exporter;
    use Carp;
    use Cwd qw( getcwd abs_path );
    use File::Path qw( rmtree );
    use File::Temp qw();
    use File::Spec;
    
    use overload
      q{""}    => sub { File::Spec->canonpath( $_[0]->{_pushd} ) },
      fallback => 1;
    
    #--------------------------------------------------------------------------#
    # pushd()
    #--------------------------------------------------------------------------#
    
    sub pushd {
        my ( $target_dir, $options ) = @_;
        $options->{untaint_pattern} ||= qr{^([-+@\w./]+)$};
    
        $target_dir = "." unless defined $target_dir;
        croak "Can't locate directory $target_dir" unless -d $target_dir;
    
        my $tainted_orig = getcwd;
        my $orig;
        if ( $tainted_orig =~ $options->{untaint_pattern} ) {
            $orig = $1;
        }
        else {
            $orig = $tainted_orig;
        }
    
        my $tainted_dest;
        eval { $tainted_dest = $target_dir ? abs_path($target_dir) : $orig };
        croak "Can't locate absolute path for $target_dir: $@" if $@;
    
        my $dest;
        if ( $tainted_dest =~ $options->{untaint_pattern} ) {
            $dest = $1;
        }
        else {
            $dest = $tainted_dest;
        }
    
        if ( $dest ne $orig ) {
            chdir $dest or croak "Can't chdir to $dest\: $!";
        }
    
        my $self = bless {
            _pushd    => $dest,
            _original => $orig
          },
          __PACKAGE__;
    
        return $self;
    }
    
    #--------------------------------------------------------------------------#
    # tempd()
    #--------------------------------------------------------------------------#
    
    sub tempd {
        my ($options) = @_;
        my $dir;
        eval { $dir = pushd( File::Temp::tempdir( CLEANUP => 0 ), $options ) };
        croak $@ if $@;
        $dir->{_tempd} = 1;
        return $dir;
    }
    
    #--------------------------------------------------------------------------#
    # preserve()
    #--------------------------------------------------------------------------#
    
    sub preserve {
        my $self = shift;
        return 1 if !$self->{"_tempd"};
        if ( @_ == 0 ) {
            return $self->{_preserve} = 1;
        }
        else {
            return $self->{_preserve} = $_[0] ? 1 : 0;
        }
    }
    
    #--------------------------------------------------------------------------#
    # DESTROY()
    # Revert to original directory as object is destroyed and cleanup
    # if necessary
    #--------------------------------------------------------------------------#
    
    sub DESTROY {
        my ($self) = @_;
        my $orig = $self->{_original};
        chdir $orig if $orig; # should always be so, but just in case...
        if ( $self->{_tempd}
            && !$self->{_preserve} )
        {
            # don't destroy existing $@ if there is no error.
            my $err = do {
                local $@;
                eval { rmtree( $self->{_pushd} ) };
                $@;
            };
            carp $err if $err;
        }
    }
    
    1;
    
    =pod
    
    =encoding UTF-8
    
    =head1 NAME
    
    File::pushd - change directory temporarily for a limited scope
    
    =head1 VERSION
    
    version 1.009
    
    =head1 SYNOPSIS
    
     use File::pushd;
    
     chdir $ENV{HOME};
    
     # change directory again for a limited scope
     {
         my $dir = pushd( '/tmp' );
         # working directory changed to /tmp
     }
     # working directory has reverted to $ENV{HOME}
    
     # tempd() is equivalent to pushd( File::Temp::tempdir )
     {
         my $dir = tempd();
     }
    
     # object stringifies naturally as an absolute path
     {
        my $dir = pushd( '/tmp' );
        my $filename = File::Spec->catfile( $dir, "somefile.txt" );
        # gives /tmp/somefile.txt
     }
    
    =head1 DESCRIPTION
    
    File::pushd does a temporary C<chdir> that is easily and automatically
    reverted, similar to C<pushd> in some Unix command shells.  It works by
    creating an object that caches the original working directory.  When the object
    is destroyed, the destructor calls C<chdir> to revert to the original working
    directory.  By storing the object in a lexical variable with a limited scope,
    this happens automatically at the end of the scope.
    
    This is very handy when working with temporary directories for tasks like
    testing; a function is provided to streamline getting a temporary
    directory from L<File::Temp>.
    
    For convenience, the object stringifies as the canonical form of the absolute
    pathname of the directory entered.
    
    B<Warning>: if you create multiple C<pushd> objects in the same lexical scope,
    their destruction order is not guaranteed and you might not wind up in the
    directory you expect.
    
    =head1 USAGE
    
     use File::pushd;
    
    Using File::pushd automatically imports the C<pushd> and C<tempd> functions.
    
    =head2 pushd
    
     {
         my $dir = pushd( $target_directory );
     }
    
    Caches the current working directory, calls C<chdir> to change to the target
    directory, and returns a File::pushd object.  When the object is
    destroyed, the working directory reverts to the original directory.
    
    The provided target directory can be a relative or absolute path. If
    called with no arguments, it uses the current directory as its target and
    returns to the current directory when the object is destroyed.
    
    If the target directory does not exist or if the directory change fails
    for some reason, C<pushd> will die with an error message.
    
    Can be given a hashref as an optional second argument.  The only supported
    option is C<untaint_pattern>, which is used to untaint file paths involved.
    It defaults to {qr{^(L<-+@\w./>+)$}}, which is reasonably restrictive (e.g.
    it does not even allow spaces in the path).  Change this to suit your
    circumstances and security needs if running under taint mode. *Note*: you
    must include the parentheses in the pattern to capture the untainted
    portion of the path.
    
    =head2 tempd
    
     {
         my $dir = tempd();
     }
    
    This function is like C<pushd> but automatically creates and calls C<chdir> to
    a temporary directory created by L<File::Temp>. Unlike normal L<File::Temp>
    cleanup which happens at the end of the program, this temporary directory is
    removed when the object is destroyed. (But also see C<preserve>.)  A warning
    will be issued if the directory cannot be removed.
    
    As with C<pushd>, C<tempd> will die if C<chdir> fails.
    
    It may be given a single options hash that will be passed internally
    to C<pushd>.
    
    =head2 preserve
    
     {
         my $dir = tempd();
         $dir->preserve;      # mark to preserve at end of scope
         $dir->preserve(0);   # mark to delete at end of scope
     }
    
    Controls whether a temporary directory will be cleaned up when the object is
    destroyed.  With no arguments, C<preserve> sets the directory to be preserved.
    With an argument, the directory will be preserved if the argument is true, or
    marked for cleanup if the argument is false.  Only C<tempd> objects may be
    marked for cleanup.  (Target directories to C<pushd> are always preserved.)
    C<preserve> returns true if the directory will be preserved, and false
    otherwise.
    
    =head1 SEE ALSO
    
    =over 4
    
    =item *
    
    L<File::chdir>
    
    =back
    
    =for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan
    
    =head1 SUPPORT
    
    =head2 Bugs / Feature Requests
    
    Please report any bugs or feature requests through the issue tracker
    at L<https://github.com/dagolden/File-pushd/issues>.
    You will be notified automatically of any progress on your issue.
    
    =head2 Source Code
    
    This is open source software.  The code repository is available for
    public review and contribution under the terms of the license.
    
    L<https://github.com/dagolden/File-pushd>
    
      git clone https://github.com/dagolden/File-pushd.git
    
    =head1 AUTHOR
    
    David Golden <dagolden@cpan.org>
    
    =head1 CONTRIBUTORS
    
    =over 4
    
    =item *
    
    Diab Jerius <djerius@cfa.harvard.edu>
    
    =item *
    
    Graham Ollis <plicease@cpan.org>
    
    =back
    
    =head1 COPYRIGHT AND LICENSE
    
    This software is Copyright (c) 2014 by David A Golden.
    
    This is free software, licensed under:
    
      The Apache License, Version 2.0, January 2004
    
    =cut
    
    __END__
    
    
    # vim: ts=4 sts=4 sw=4 et:
  FILE_PUSHD
  
  $fatpacked{"HTTP/Tiny.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'HTTP_TINY';
    # vim: ts=4 sts=4 sw=4 et:
    package HTTP::Tiny;
    use strict;
    use warnings;
    # ABSTRACT: A small, simple, correct HTTP/1.1 client
    
    our $VERSION = '0.054';
    
    use Carp ();
    
    #pod =method new
    #pod
    #pod     $http = HTTP::Tiny->new( %attributes );
    #pod
    #pod This constructor returns a new HTTP::Tiny object.  Valid attributes include:
    #pod
    #pod =for :list
    #pod * C<agent> —
    #pod     A user-agent string (defaults to 'HTTP-Tiny/$VERSION'). If C<agent> — ends in a space character, the default user-agent string is appended.
    #pod * C<cookie_jar> —
    #pod     An instance of L<HTTP::CookieJar> — or equivalent class that supports the C<add> and C<cookie_header> methods
    #pod * C<default_headers> —
    #pod     A hashref of default headers to apply to requests
    #pod * C<local_address> —
    #pod     The local IP address to bind to
    #pod * C<keep_alive> —
    #pod     Whether to reuse the last connection (if for the same scheme, host and port) (defaults to 1)
    #pod * C<max_redirect> —
    #pod     Maximum number of redirects allowed (defaults to 5)
    #pod * C<max_size> —
    #pod     Maximum response size (only when not using a data callback).  If defined, responses larger than this will return an exception.
    #pod * C<http_proxy> —
    #pod     URL of a proxy server to use for HTTP connections (default is C<$ENV{http_proxy}> — if set)
    #pod * C<https_proxy> —
    #pod     URL of a proxy server to use for HTTPS connections (default is C<$ENV{https_proxy}> — if set)
    #pod * C<proxy> —
    #pod     URL of a generic proxy server for both HTTP and HTTPS connections (default is C<$ENV{all_proxy}> — if set)
    #pod * C<no_proxy> —
    #pod     List of domain suffixes that should not be proxied.  Must be a comma-separated string or an array reference. (default is C<$ENV{no_proxy}> —)
    #pod * C<timeout> —
    #pod     Request timeout in seconds (default is 60)
    #pod * C<verify_SSL> —
    #pod     A boolean that indicates whether to validate the SSL certificate of an C<https> —
    #pod     connection (default is false)
    #pod * C<SSL_options> —
    #pod     A hashref of C<SSL_*> — options to pass through to L<IO::Socket::SSL>
    #pod
    #pod Passing an explicit C<undef> for C<proxy>, C<http_proxy> or C<https_proxy> will
    #pod prevent getting the corresponding proxies from the environment.
    #pod
    #pod Exceptions from C<max_size>, C<timeout> or other errors will result in a
    #pod pseudo-HTTP status code of 599 and a reason of "Internal Exception". The
    #pod content field in the response will contain the text of the exception.
    #pod
    #pod The C<keep_alive> parameter enables a persistent connection, but only to a
    #pod single destination scheme, host and port.  Also, if any connection-relevant
    #pod attributes are modified, or if the process ID or thread ID change, the
    #pod persistent connection will be dropped.  If you want persistent connections
    #pod across multiple destinations, use multiple HTTP::Tiny objects.
    #pod
    #pod See L</SSL SUPPORT> for more on the C<verify_SSL> and C<SSL_options> attributes.
    #pod
    #pod =cut
    
    my @attributes;
    BEGIN {
        @attributes = qw(
            cookie_jar default_headers http_proxy https_proxy keep_alive
            local_address max_redirect max_size proxy no_proxy timeout
            SSL_options verify_SSL
        );
        my %persist_ok = map {; $_ => 1 } qw(
            cookie_jar default_headers max_redirect max_size
        );
        no strict 'refs';
        no warnings 'uninitialized';
        for my $accessor ( @attributes ) {
            *{$accessor} = sub {
                @_ > 1
                    ? do {
                        delete $_[0]->{handle} if !$persist_ok{$accessor} && $_[1] ne $_[0]->{$accessor};
                        $_[0]->{$accessor} = $_[1]
                    }
                    : $_[0]->{$accessor};
            };
        }
    }
    
    sub agent {
        my($self, $agent) = @_;
        if( @_ > 1 ){
            $self->{agent} =
                (defined $agent && $agent =~ / $/) ? $agent . $self->_agent : $agent;
        }
        return $self->{agent};
    }
    
    sub new {
        my($class, %args) = @_;
    
        my $self = {
            max_redirect => 5,
            timeout      => 60,
            keep_alive   => 1,
            verify_SSL   => $args{verify_SSL} || $args{verify_ssl} || 0, # no verification by default
            no_proxy     => $ENV{no_proxy},
        };
    
        bless $self, $class;
    
        $class->_validate_cookie_jar( $args{cookie_jar} ) if $args{cookie_jar};
    
        for my $key ( @attributes ) {
            $self->{$key} = $args{$key} if exists $args{$key}
        }
    
        $self->agent( exists $args{agent} ? $args{agent} : $class->_agent );
    
        $self->_set_proxies;
    
        return $self;
    }
    
    sub _set_proxies {
        my ($self) = @_;
    
        # get proxies from %ENV only if not provided; explicit undef will disable
        # getting proxies from the environment
    
        # generic proxy
        if (! exists $self->{proxy} ) {
            $self->{proxy} = $ENV{all_proxy} || $ENV{ALL_PROXY};
        }
    
        if ( defined $self->{proxy} ) {
            $self->_split_proxy( 'generic proxy' => $self->{proxy} ); # validate
        }
        else {
            delete $self->{proxy};
        }
    
        # http proxy
        if (! exists $self->{http_proxy} ) {
            # under CGI, bypass HTTP_PROXY as request sets it from Proxy header
            local $ENV{HTTP_PROXY} if $ENV{REQUEST_METHOD};
            $self->{http_proxy} = $ENV{http_proxy} || $ENV{HTTP_PROXY} || $self->{proxy};
        }
    
        if ( defined $self->{http_proxy} ) {
            $self->_split_proxy( http_proxy => $self->{http_proxy} ); # validate
            $self->{_has_proxy}{http} = 1;
        }
        else {
            delete $self->{http_proxy};
        }
    
        # https proxy
        if (! exists $self->{https_proxy} ) {
            $self->{https_proxy} = $ENV{https_proxy} || $ENV{HTTPS_PROXY} || $self->{proxy};
        }
    
        if ( $self->{https_proxy} ) {
            $self->_split_proxy( https_proxy => $self->{https_proxy} ); # validate
            $self->{_has_proxy}{https} = 1;
        }
        else {
            delete $self->{https_proxy};
        }
    
        # Split no_proxy to array reference if not provided as such
        unless ( ref $self->{no_proxy} eq 'ARRAY' ) {
            $self->{no_proxy} =
                (defined $self->{no_proxy}) ? [ split /\s*,\s*/, $self->{no_proxy} ] : [];
        }
    
        return;
    }
    
    #pod =method get|head|put|post|delete
    #pod
    #pod     $response = $http->get($url);
    #pod     $response = $http->get($url, \%options);
    #pod     $response = $http->head($url);
    #pod
    #pod These methods are shorthand for calling C<request()> for the given method.  The
    #pod URL must have unsafe characters escaped and international domain names encoded.
    #pod See C<request()> for valid options and a description of the response.
    #pod
    #pod The C<success> field of the response will be true if the status code is 2XX.
    #pod
    #pod =cut
    
    for my $sub_name ( qw/get head put post delete/ ) {
        my $req_method = uc $sub_name;
        no strict 'refs';
        eval <<"HERE"; ## no critic
        sub $sub_name {
            my (\$self, \$url, \$args) = \@_;
            \@_ == 2 || (\@_ == 3 && ref \$args eq 'HASH')
            or Carp::croak(q/Usage: \$http->$sub_name(URL, [HASHREF])/ . "\n");
            return \$self->request('$req_method', \$url, \$args || {});
        }
    HERE
    }
    
    #pod =method post_form
    #pod
    #pod     $response = $http->post_form($url, $form_data);
    #pod     $response = $http->post_form($url, $form_data, \%options);
    #pod
    #pod This method executes a C<POST> request and sends the key/value pairs from a
    #pod form data hash or array reference to the given URL with a C<content-type> of
    #pod C<application/x-www-form-urlencoded>.  If data is provided as an array
    #pod reference, the order is preserved; if provided as a hash reference, the terms
    #pod are sorted on key and value for consistency.  See documentation for the
    #pod C<www_form_urlencode> method for details on the encoding.
    #pod
    #pod The URL must have unsafe characters escaped and international domain names
    #pod encoded.  See C<request()> for valid options and a description of the response.
    #pod Any C<content-type> header or content in the options hashref will be ignored.
    #pod
    #pod The C<success> field of the response will be true if the status code is 2XX.
    #pod
    #pod =cut
    
    sub post_form {
        my ($self, $url, $data, $args) = @_;
        (@_ == 3 || @_ == 4 && ref $args eq 'HASH')
            or Carp::croak(q/Usage: $http->post_form(URL, DATAREF, [HASHREF])/ . "\n");
    
        my $headers = {};
        while ( my ($key, $value) = each %{$args->{headers} || {}} ) {
            $headers->{lc $key} = $value;
        }
        delete $args->{headers};
    
        return $self->request('POST', $url, {
                %$args,
                content => $self->www_form_urlencode($data),
                headers => {
                    %$headers,
                    'content-type' => 'application/x-www-form-urlencoded'
                },
            }
        );
    }
    
    #pod =method mirror
    #pod
    #pod     $response = $http->mirror($url, $file, \%options)
    #pod     if ( $response->{success} ) {
    #pod         print "$file is up to date\n";
    #pod     }
    #pod
    #pod Executes a C<GET> request for the URL and saves the response body to the file
    #pod name provided.  The URL must have unsafe characters escaped and international
    #pod domain names encoded.  If the file already exists, the request will include an
    #pod C<If-Modified-Since> header with the modification timestamp of the file.  You
    #pod may specify a different C<If-Modified-Since> header yourself in the C<<
    #pod $options->{headers} >> hash.
    #pod
    #pod The C<success> field of the response will be true if the status code is 2XX
    #pod or if the status code is 304 (unmodified).
    #pod
    #pod If the file was modified and the server response includes a properly
    #pod formatted C<Last-Modified> header, the file modification time will
    #pod be updated accordingly.
    #pod
    #pod =cut
    
    sub mirror {
        my ($self, $url, $file, $args) = @_;
        @_ == 3 || (@_ == 4 && ref $args eq 'HASH')
          or Carp::croak(q/Usage: $http->mirror(URL, FILE, [HASHREF])/ . "\n");
        if ( -e $file and my $mtime = (stat($file))[9] ) {
            $args->{headers}{'if-modified-since'} ||= $self->_http_date($mtime);
        }
        my $tempfile = $file . int(rand(2**31));
    
        require Fcntl;
        sysopen my $fh, $tempfile, Fcntl::O_CREAT()|Fcntl::O_EXCL()|Fcntl::O_WRONLY()
           or Carp::croak(qq/Error: Could not create temporary file $tempfile for downloading: $!\n/);
        binmode $fh;
        $args->{data_callback} = sub { print {$fh} $_[0] };
        my $response = $self->request('GET', $url, $args);
        close $fh
            or Carp::croak(qq/Error: Caught error closing temporary file $tempfile: $!\n/);
    
        if ( $response->{success} ) {
            rename $tempfile, $file
                or Carp::croak(qq/Error replacing $file with $tempfile: $!\n/);
            my $lm = $response->{headers}{'last-modified'};
            if ( $lm and my $mtime = $self->_parse_http_date($lm) ) {
                utime $mtime, $mtime, $file;
            }
        }
        $response->{success} ||= $response->{status} eq '304';
        unlink $tempfile;
        return $response;
    }
    
    #pod =method request
    #pod
    #pod     $response = $http->request($method, $url);
    #pod     $response = $http->request($method, $url, \%options);
    #pod
    #pod Executes an HTTP request of the given method type ('GET', 'HEAD', 'POST',
    #pod 'PUT', etc.) on the given URL.  The URL must have unsafe characters escaped and
    #pod international domain names encoded.
    #pod
    #pod If the URL includes a "user:password" stanza, they will be used for Basic-style
    #pod authorization headers.  (Authorization headers will not be included in a
    #pod redirected request.) For example:
    #pod
    #pod     $http->request('GET', 'http://Aladdin:open sesame@example.com/');
    #pod
    #pod If the "user:password" stanza contains reserved characters, they must
    #pod be percent-escaped:
    #pod
    #pod     $http->request('GET', 'http://john%40example.com:password@example.com/');
    #pod
    #pod A hashref of options may be appended to modify the request.
    #pod
    #pod Valid options are:
    #pod
    #pod =for :list
    #pod * C<headers> —
    #pod     A hashref containing headers to include with the request.  If the value for
    #pod     a header is an array reference, the header will be output multiple times with
    #pod     each value in the array.  These headers over-write any default headers.
    #pod * C<content> —
    #pod     A scalar to include as the body of the request OR a code reference
    #pod     that will be called iteratively to produce the body of the request
    #pod * C<trailer_callback> —
    #pod     A code reference that will be called if it exists to provide a hashref
    #pod     of trailing headers (only used with chunked transfer-encoding)
    #pod * C<data_callback> —
    #pod     A code reference that will be called for each chunks of the response
    #pod     body received.
    #pod
    #pod The C<Host> header is generated from the URL in accordance with RFC 2616.  It
    #pod is a fatal error to specify C<Host> in the C<headers> option.  Other headers
    #pod may be ignored or overwritten if necessary for transport compliance.
    #pod
    #pod If the C<content> option is a code reference, it will be called iteratively
    #pod to provide the content body of the request.  It should return the empty
    #pod string or undef when the iterator is exhausted.
    #pod
    #pod If the C<content> option is the empty string, no C<content-type> or
    #pod C<content-length> headers will be generated.
    #pod
    #pod If the C<data_callback> option is provided, it will be called iteratively until
    #pod the entire response body is received.  The first argument will be a string
    #pod containing a chunk of the response body, the second argument will be the
    #pod in-progress response hash reference, as described below.  (This allows
    #pod customizing the action of the callback based on the C<status> or C<headers>
    #pod received prior to the content body.)
    #pod
    #pod The C<request> method returns a hashref containing the response.  The hashref
    #pod will have the following keys:
    #pod
    #pod =for :list
    #pod * C<success> —
    #pod     Boolean indicating whether the operation returned a 2XX status code
    #pod * C<url> —
    #pod     URL that provided the response. This is the URL of the request unless
    #pod     there were redirections, in which case it is the last URL queried
    #pod     in a redirection chain
    #pod * C<status> —
    #pod     The HTTP status code of the response
    #pod * C<reason> —
    #pod     The response phrase returned by the server
    #pod * C<content> —
    #pod     The body of the response.  If the response does not have any content
    #pod     or if a data callback is provided to consume the response body,
    #pod     this will be the empty string
    #pod * C<headers> —
    #pod     A hashref of header fields.  All header field names will be normalized
    #pod     to be lower case. If a header is repeated, the value will be an arrayref;
    #pod     it will otherwise be a scalar string containing the value
    #pod
    #pod On an exception during the execution of the request, the C<status> field will
    #pod contain 599, and the C<content> field will contain the text of the exception.
    #pod
    #pod =cut
    
    my %idempotent = map { $_ => 1 } qw/GET HEAD PUT DELETE OPTIONS TRACE/;
    
    sub request {
        my ($self, $method, $url, $args) = @_;
        @_ == 3 || (@_ == 4 && ref $args eq 'HASH')
          or Carp::croak(q/Usage: $http->request(METHOD, URL, [HASHREF])/ . "\n");
        $args ||= {}; # we keep some state in this during _request
    
        # RFC 2616 Section 8.1.4 mandates a single retry on broken socket
        my $response;
        for ( 0 .. 1 ) {
            $response = eval { $self->_request($method, $url, $args) };
            last unless $@ && $idempotent{$method}
                && $@ =~ m{^(?:Socket closed|Unexpected end)};
        }
    
        if (my $e = $@) {
            # maybe we got a response hash thrown from somewhere deep
            if ( ref $e eq 'HASH' && exists $e->{status} ) {
                return $e;
            }
    
            # otherwise, stringify it
            $e = "$e";
            $response = {
                url     => $url,
                success => q{},
                status  => 599,
                reason  => 'Internal Exception',
                content => $e,
                headers => {
                    'content-type'   => 'text/plain',
                    'content-length' => length $e,
                }
            };
        }
        return $response;
    }
    
    #pod =method www_form_urlencode
    #pod
    #pod     $params = $http->www_form_urlencode( $data );
    #pod     $response = $http->get("http://example.com/query?$params");
    #pod
    #pod This method converts the key/value pairs from a data hash or array reference
    #pod into a C<x-www-form-urlencoded> string.  The keys and values from the data
    #pod reference will be UTF-8 encoded and escaped per RFC 3986.  If a value is an
    #pod array reference, the key will be repeated with each of the values of the array
    #pod reference.  If data is provided as a hash reference, the key/value pairs in the
    #pod resulting string will be sorted by key and value for consistent ordering.
    #pod
    #pod =cut
    
    sub www_form_urlencode {
        my ($self, $data) = @_;
        (@_ == 2 && ref $data)
            or Carp::croak(q/Usage: $http->www_form_urlencode(DATAREF)/ . "\n");
        (ref $data eq 'HASH' || ref $data eq 'ARRAY')
            or Carp::croak("form data must be a hash or array reference\n");
    
        my @params = ref $data eq 'HASH' ? %$data : @$data;
        @params % 2 == 0
            or Carp::croak("form data reference must have an even number of terms\n");
    
        my @terms;
        while( @params ) {
            my ($key, $value) = splice(@params, 0, 2);
            if ( ref $value eq 'ARRAY' ) {
                unshift @params, map { $key => $_ } @$value;
            }
            else {
                push @terms, join("=", map { $self->_uri_escape($_) } $key, $value);
            }
        }
    
        return join("&", (ref $data eq 'ARRAY') ? (@terms) : (sort @terms) );
    }
    
    #--------------------------------------------------------------------------#
    # private methods
    #--------------------------------------------------------------------------#
    
    my %DefaultPort = (
        http => 80,
        https => 443,
    );
    
    sub _agent {
        my $class = ref($_[0]) || $_[0];
        (my $default_agent = $class) =~ s{::}{-}g;
        return $default_agent . "/" . $class->VERSION;
    }
    
    sub _request {
        my ($self, $method, $url, $args) = @_;
    
        my ($scheme, $host, $port, $path_query, $auth) = $self->_split_url($url);
    
        my $request = {
            method    => $method,
            scheme    => $scheme,
            host      => $host,
            port      => $port,
            host_port => ($port == $DefaultPort{$scheme} ? $host : "$host:$port"),
            uri       => $path_query,
            headers   => {},
        };
    
        # We remove the cached handle so it is not reused in the case of redirect.
        # If all is well, it will be recached at the end of _request.  We only
        # reuse for the same scheme, host and port
        my $handle = delete $self->{handle};
        if ( $handle ) {
            unless ( $handle->can_reuse( $scheme, $host, $port ) ) {
                $handle->close;
                undef $handle;
            }
        }
        $handle ||= $self->_open_handle( $request, $scheme, $host, $port );
    
        $self->_prepare_headers_and_cb($request, $args, $url, $auth);
        $handle->write_request($request);
    
        my $response;
        do { $response = $handle->read_response_header }
            until (substr($response->{status},0,1) ne '1');
    
        $self->_update_cookie_jar( $url, $response ) if $self->{cookie_jar};
    
        if ( my @redir_args = $self->_maybe_redirect($request, $response, $args) ) {
            $handle->close;
            return $self->_request(@redir_args, $args);
        }
    
        my $known_message_length;
        if ($method eq 'HEAD' || $response->{status} =~ /^[23]04/) {
            # response has no message body
            $known_message_length = 1;
        }
        else {
            my $data_cb = $self->_prepare_data_cb($response, $args);
            $known_message_length = $handle->read_body($data_cb, $response);
        }
    
        if ( $self->{keep_alive}
            && $known_message_length
            && $response->{protocol} eq 'HTTP/1.1'
            && ($response->{headers}{connection} || '') ne 'close'
        ) {
            $self->{handle} = $handle;
        }
        else {
            $handle->close;
        }
    
        $response->{success} = substr( $response->{status}, 0, 1 ) eq '2';
        $response->{url} = $url;
        return $response;
    }
    
    sub _open_handle {
        my ($self, $request, $scheme, $host, $port) = @_;
    
        my $handle  = HTTP::Tiny::Handle->new(
            timeout         => $self->{timeout},
            SSL_options     => $self->{SSL_options},
            verify_SSL      => $self->{verify_SSL},
            local_address   => $self->{local_address},
            keep_alive      => $self->{keep_alive}
        );
    
        if ($self->{_has_proxy}{$scheme} && ! grep { $host =~ /\Q$_\E$/ } @{$self->{no_proxy}}) {
            return $self->_proxy_connect( $request, $handle );
        }
        else {
            return $handle->connect($scheme, $host, $port);
        }
    }
    
    sub _proxy_connect {
        my ($self, $request, $handle) = @_;
    
        my @proxy_vars;
        if ( $request->{scheme} eq 'https' ) {
            Carp::croak(qq{No https_proxy defined}) unless $self->{https_proxy};
            @proxy_vars = $self->_split_proxy( https_proxy => $self->{https_proxy} );
            if ( $proxy_vars[0] eq 'https' ) {
                Carp::croak(qq{Can't proxy https over https: $request->{uri} via $self->{https_proxy}});
            }
        }
        else {
            Carp::croak(qq{No http_proxy defined}) unless $self->{http_proxy};
            @proxy_vars = $self->_split_proxy( http_proxy => $self->{http_proxy} );
        }
    
        my ($p_scheme, $p_host, $p_port, $p_auth) = @proxy_vars;
    
        if ( length $p_auth && ! defined $request->{headers}{'proxy-authorization'} ) {
            $self->_add_basic_auth_header( $request, 'proxy-authorization' => $p_auth );
        }
    
        $handle->connect($p_scheme, $p_host, $p_port);
    
        if ($request->{scheme} eq 'https') {
            $self->_create_proxy_tunnel( $request, $handle );
        }
        else {
            # non-tunneled proxy requires absolute URI
            $request->{uri} = "$request->{scheme}://$request->{host_port}$request->{uri}";
        }
    
        return $handle;
    }
    
    sub _split_proxy {
        my ($self, $type, $proxy) = @_;
    
        my ($scheme, $host, $port, $path_query, $auth) = eval { $self->_split_url($proxy) };
    
        unless(
            defined($scheme) && length($scheme) && length($host) && length($port)
            && $path_query eq '/'
        ) {
            Carp::croak(qq{$type URL must be in format http[s]://[auth@]<host>:<port>/\n});
        }
    
        return ($scheme, $host, $port, $auth);
    }
    
    sub _create_proxy_tunnel {
        my ($self, $request, $handle) = @_;
    
        $handle->_assert_ssl;
    
        my $agent = exists($request->{headers}{'user-agent'})
            ? $request->{headers}{'user-agent'} : $self->{agent};
    
        my $connect_request = {
            method    => 'CONNECT',
            uri       => "$request->{host}:$request->{port}",
            headers   => {
                host => "$request->{host}:$request->{port}",
                'user-agent' => $agent,
            }
        };
    
        if ( $request->{headers}{'proxy-authorization'} ) {
            $connect_request->{headers}{'proxy-authorization'} =
                delete $request->{headers}{'proxy-authorization'};
        }
    
        $handle->write_request($connect_request);
        my $response;
        do { $response = $handle->read_response_header }
            until (substr($response->{status},0,1) ne '1');
    
        # if CONNECT failed, throw the response so it will be
        # returned from the original request() method;
        unless (substr($response->{status},0,1) eq '2') {
            die $response;
        }
    
        # tunnel established, so start SSL handshake
        $handle->start_ssl( $request->{host} );
    
        return;
    }
    
    sub _prepare_headers_and_cb {
        my ($self, $request, $args, $url, $auth) = @_;
    
        for ($self->{default_headers}, $args->{headers}) {
            next unless defined;
            while (my ($k, $v) = each %$_) {
                $request->{headers}{lc $k} = $v;
            }
        }
    
        if (exists $request->{headers}{'host'}) {
            die(qq/The 'Host' header must not be provided as header option\n/);
        }
    
        $request->{headers}{'host'}         = $request->{host_port};
        $request->{headers}{'user-agent'} ||= $self->{agent};
        $request->{headers}{'connection'}   = "close"
            unless $self->{keep_alive};
    
        if ( defined $args->{content} ) {
            if (ref $args->{content} eq 'CODE') {
                $request->{headers}{'content-type'} ||= "application/octet-stream";
                $request->{headers}{'transfer-encoding'} = 'chunked'
                  unless $request->{headers}{'content-length'}
                      || $request->{headers}{'transfer-encoding'};
                $request->{cb} = $args->{content};
            }
            elsif ( length $args->{content} ) {
                my $content = $args->{content};
                if ( $] ge '5.008' ) {
                    utf8::downgrade($content, 1)
                        or die(qq/Wide character in request message body\n/);
                }
                $request->{headers}{'content-type'} ||= "application/octet-stream";
                $request->{headers}{'content-length'} = length $content
                  unless $request->{headers}{'content-length'}
                      || $request->{headers}{'transfer-encoding'};
                $request->{cb} = sub { substr $content, 0, length $content, '' };
            }
            $request->{trailer_cb} = $args->{trailer_callback}
                if ref $args->{trailer_callback} eq 'CODE';
        }
    
        ### If we have a cookie jar, then maybe add relevant cookies
        if ( $self->{cookie_jar} ) {
            my $cookies = $self->cookie_jar->cookie_header( $url );
            $request->{headers}{cookie} = $cookies if length $cookies;
        }
    
        # if we have Basic auth parameters, add them
        if ( length $auth && ! defined $request->{headers}{authorization} ) {
            $self->_add_basic_auth_header( $request, 'authorization' => $auth );
        }
    
        return;
    }
    
    sub _add_basic_auth_header {
        my ($self, $request, $header, $auth) = @_;
        require MIME::Base64;
        $request->{headers}{$header} =
            "Basic " . MIME::Base64::encode_base64($auth, "");
        return;
    }
    
    sub _prepare_data_cb {
        my ($self, $response, $args) = @_;
        my $data_cb = $args->{data_callback};
        $response->{content} = '';
    
        if (!$data_cb || $response->{status} !~ /^2/) {
            if (defined $self->{max_size}) {
                $data_cb = sub {
                    $_[1]->{content} .= $_[0];
                    die(qq/Size of response body exceeds the maximum allowed of $self->{max_size}\n/)
                      if length $_[1]->{content} > $self->{max_size};
                };
            }
            else {
                $data_cb = sub { $_[1]->{content} .= $_[0] };
            }
        }
        return $data_cb;
    }
    
    sub _update_cookie_jar {
        my ($self, $url, $response) = @_;
    
        my $cookies = $response->{headers}->{'set-cookie'};
        return unless defined $cookies;
    
        my @cookies = ref $cookies ? @$cookies : $cookies;
    
        $self->cookie_jar->add( $url, $_ ) for @cookies;
    
        return;
    }
    
    sub _validate_cookie_jar {
        my ($class, $jar) = @_;
    
        # duck typing
        for my $method ( qw/add cookie_header/ ) {
            Carp::croak(qq/Cookie jar must provide the '$method' method\n/)
                unless ref($jar) && ref($jar)->can($method);
        }
    
        return;
    }
    
    sub _maybe_redirect {
        my ($self, $request, $response, $args) = @_;
        my $headers = $response->{headers};
        my ($status, $method) = ($response->{status}, $request->{method});
        if (($status eq '303' or ($status =~ /^30[127]/ && $method =~ /^GET|HEAD$/))
            and $headers->{location}
            and ++$args->{redirects} <= $self->{max_redirect}
        ) {
            my $location = ($headers->{location} =~ /^\//)
                ? "$request->{scheme}://$request->{host_port}$headers->{location}"
                : $headers->{location} ;
            return (($status eq '303' ? 'GET' : $method), $location);
        }
        return;
    }
    
    sub _split_url {
        my $url = pop;
    
        # URI regex adapted from the URI module
        my ($scheme, $host, $path_query) = $url =~ m<\A([^:/?#]+)://([^/?#]*)([^#]*)>
          or die(qq/Cannot parse URL: '$url'\n/);
    
        $scheme     = lc $scheme;
        $path_query = "/$path_query" unless $path_query =~ m<\A/>;
    
        my $auth = '';
        if ( (my $i = index $host, '@') != -1 ) {
            # user:pass@host
            $auth = substr $host, 0, $i, ''; # take up to the @ for auth
            substr $host, 0, 1, '';          # knock the @ off the host
    
            # userinfo might be percent escaped, so recover real auth info
            $auth =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg;
        }
        my $port = $host =~ s/:(\d*)\z// && length $1 ? $1
                 : $scheme eq 'http'                  ? 80
                 : $scheme eq 'https'                 ? 443
                 : undef;
    
        return ($scheme, (length $host ? lc $host : "localhost") , $port, $path_query, $auth);
    }
    
    # Date conversions adapted from HTTP::Date
    my $DoW = "Sun|Mon|Tue|Wed|Thu|Fri|Sat";
    my $MoY = "Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec";
    sub _http_date {
        my ($sec, $min, $hour, $mday, $mon, $year, $wday) = gmtime($_[1]);
        return sprintf("%s, %02d %s %04d %02d:%02d:%02d GMT",
            substr($DoW,$wday*4,3),
            $mday, substr($MoY,$mon*4,3), $year+1900,
            $hour, $min, $sec
        );
    }
    
    sub _parse_http_date {
        my ($self, $str) = @_;
        require Time::Local;
        my @tl_parts;
        if ($str =~ /^[SMTWF][a-z]+, +(\d{1,2}) ($MoY) +(\d\d\d\d) +(\d\d):(\d\d):(\d\d) +GMT$/) {
            @tl_parts = ($6, $5, $4, $1, (index($MoY,$2)/4), $3);
        }
        elsif ($str =~ /^[SMTWF][a-z]+, +(\d\d)-($MoY)-(\d{2,4}) +(\d\d):(\d\d):(\d\d) +GMT$/ ) {
            @tl_parts = ($6, $5, $4, $1, (index($MoY,$2)/4), $3);
        }
        elsif ($str =~ /^[SMTWF][a-z]+ +($MoY) +(\d{1,2}) +(\d\d):(\d\d):(\d\d) +(?:[^0-9]+ +)?(\d\d\d\d)$/ ) {
            @tl_parts = ($5, $4, $3, $2, (index($MoY,$1)/4), $6);
        }
        return eval {
            my $t = @tl_parts ? Time::Local::timegm(@tl_parts) : -1;
            $t < 0 ? undef : $t;
        };
    }
    
    # URI escaping adapted from URI::Escape
    # c.f. http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1
    # perl 5.6 ready UTF-8 encoding adapted from JSON::PP
    my %escapes = map { chr($_) => sprintf("%%%02X", $_) } 0..255;
    $escapes{' '}="+";
    my $unsafe_char = qr/[^A-Za-z0-9\-\._~]/;
    
    sub _uri_escape {
        my ($self, $str) = @_;
        if ( $] ge '5.008' ) {
            utf8::encode($str);
        }
        else {
            $str = pack("U*", unpack("C*", $str)) # UTF-8 encode a byte string
                if ( length $str == do { use bytes; length $str } );
            $str = pack("C*", unpack("C*", $str)); # clear UTF-8 flag
        }
        $str =~ s/($unsafe_char)/$escapes{$1}/ge;
        return $str;
    }
    
    package
        HTTP::Tiny::Handle; # hide from PAUSE/indexers
    use strict;
    use warnings;
    
    use Errno      qw[EINTR EPIPE];
    use IO::Socket qw[SOCK_STREAM];
    
    # PERL_HTTP_TINY_IPV4_ONLY is a private environment variable to force old
    # behavior if someone is unable to boostrap CPAN from a new perl install; it is
    # not intended for general, per-client use and may be removed in the future
    my $SOCKET_CLASS =
        $ENV{PERL_HTTP_TINY_IPV4_ONLY} ? 'IO::Socket::INET' :
        eval { require IO::Socket::IP; IO::Socket::IP->VERSION(0.25) } ? 'IO::Socket::IP' :
        'IO::Socket::INET';
    
    sub BUFSIZE () { 32768 } ## no critic
    
    my $Printable = sub {
        local $_ = shift;
        s/\r/\\r/g;
        s/\n/\\n/g;
        s/\t/\\t/g;
        s/([^\x20-\x7E])/sprintf('\\x%.2X', ord($1))/ge;
        $_;
    };
    
    my $Token = qr/[\x21\x23-\x27\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5A\x5E-\x7A\x7C\x7E]/;
    
    sub new {
        my ($class, %args) = @_;
        return bless {
            rbuf             => '',
            timeout          => 60,
            max_line_size    => 16384,
            max_header_lines => 64,
            verify_SSL       => 0,
            SSL_options      => {},
            %args
        }, $class;
    }
    
    sub connect {
        @_ == 4 || die(q/Usage: $handle->connect(scheme, host, port)/ . "\n");
        my ($self, $scheme, $host, $port) = @_;
    
        if ( $scheme eq 'https' ) {
            $self->_assert_ssl;
        }
        elsif ( $scheme ne 'http' ) {
          die(qq/Unsupported URL scheme '$scheme'\n/);
        }
        $self->{fh} = $SOCKET_CLASS->new(
            PeerHost  => $host,
            PeerPort  => $port,
            $self->{local_address} ?
                ( LocalAddr => $self->{local_address} ) : (),
            Proto     => 'tcp',
            Type      => SOCK_STREAM,
            Timeout   => $self->{timeout},
            KeepAlive => !!$self->{keep_alive}
        ) or die(qq/Could not connect to '$host:$port': $@\n/);
    
        binmode($self->{fh})
          or die(qq/Could not binmode() socket: '$!'\n/);
    
        $self->start_ssl($host) if $scheme eq 'https';
    
        $self->{scheme} = $scheme;
        $self->{host} = $host;
        $self->{port} = $port;
        $self->{pid} = $$;
        $self->{tid} = _get_tid();
    
        return $self;
    }
    
    sub start_ssl {
        my ($self, $host) = @_;
    
        # As this might be used via CONNECT after an SSL session
        # to a proxy, we shut down any existing SSL before attempting
        # the handshake
        if ( ref($self->{fh}) eq 'IO::Socket::SSL' ) {
            unless ( $self->{fh}->stop_SSL ) {
                my $ssl_err = IO::Socket::SSL->errstr;
                die(qq/Error halting prior SSL connection: $ssl_err/);
            }
        }
    
        my $ssl_args = $self->_ssl_args($host);
        IO::Socket::SSL->start_SSL(
            $self->{fh},
            %$ssl_args,
            SSL_create_ctx_callback => sub {
                my $ctx = shift;
                Net::SSLeay::CTX_set_mode($ctx, Net::SSLeay::MODE_AUTO_RETRY());
            },
        );
    
        unless ( ref($self->{fh}) eq 'IO::Socket::SSL' ) {
            my $ssl_err = IO::Socket::SSL->errstr;
            die(qq/SSL connection failed for $host: $ssl_err\n/);
        }
    }
    
    sub close {
        @_ == 1 || die(q/Usage: $handle->close()/ . "\n");
        my ($self) = @_;
        CORE::close($self->{fh})
          or die(qq/Could not close socket: '$!'\n/);
    }
    
    sub write {
        @_ == 2 || die(q/Usage: $handle->write(buf)/ . "\n");
        my ($self, $buf) = @_;
    
        if ( $] ge '5.008' ) {
            utf8::downgrade($buf, 1)
                or die(qq/Wide character in write()\n/);
        }
    
        my $len = length $buf;
        my $off = 0;
    
        local $SIG{PIPE} = 'IGNORE';
    
        while () {
            $self->can_write
              or die(qq/Timed out while waiting for socket to become ready for writing\n/);
            my $r = syswrite($self->{fh}, $buf, $len, $off);
            if (defined $r) {
                $len -= $r;
                $off += $r;
                last unless $len > 0;
            }
            elsif ($! == EPIPE) {
                die(qq/Socket closed by remote server: $!\n/);
            }
            elsif ($! != EINTR) {
                if ($self->{fh}->can('errstr')){
                    my $err = $self->{fh}->errstr();
                    die (qq/Could not write to SSL socket: '$err'\n /);
                }
                else {
                    die(qq/Could not write to socket: '$!'\n/);
                }
    
            }
        }
        return $off;
    }
    
    sub read {
        @_ == 2 || @_ == 3 || die(q/Usage: $handle->read(len [, allow_partial])/ . "\n");
        my ($self, $len, $allow_partial) = @_;
    
        my $buf  = '';
        my $got = length $self->{rbuf};
    
        if ($got) {
            my $take = ($got < $len) ? $got : $len;
            $buf  = substr($self->{rbuf}, 0, $take, '');
            $len -= $take;
        }
    
        while ($len > 0) {
            $self->can_read
              or die(q/Timed out while waiting for socket to become ready for reading/ . "\n");
            my $r = sysread($self->{fh}, $buf, $len, length $buf);
            if (defined $r) {
                last unless $r;
                $len -= $r;
            }
            elsif ($! != EINTR) {
                if ($self->{fh}->can('errstr')){
                    my $err = $self->{fh}->errstr();
                    die (qq/Could not read from SSL socket: '$err'\n /);
                }
                else {
                    die(qq/Could not read from socket: '$!'\n/);
                }
            }
        }
        if ($len && !$allow_partial) {
            die(qq/Unexpected end of stream\n/);
        }
        return $buf;
    }
    
    sub readline {
        @_ == 1 || die(q/Usage: $handle->readline()/ . "\n");
        my ($self) = @_;
    
        while () {
            if ($self->{rbuf} =~ s/\A ([^\x0D\x0A]* \x0D?\x0A)//x) {
                return $1;
            }
            if (length $self->{rbuf} >= $self->{max_line_size}) {
                die(qq/Line size exceeds the maximum allowed size of $self->{max_line_size}\n/);
            }
            $self->can_read
              or die(qq/Timed out while waiting for socket to become ready for reading\n/);
            my $r = sysread($self->{fh}, $self->{rbuf}, BUFSIZE, length $self->{rbuf});
            if (defined $r) {
                last unless $r;
            }
            elsif ($! != EINTR) {
                if ($self->{fh}->can('errstr')){
                    my $err = $self->{fh}->errstr();
                    die (qq/Could not read from SSL socket: '$err'\n /);
                }
                else {
                    die(qq/Could not read from socket: '$!'\n/);
                }
            }
        }
        die(qq/Unexpected end of stream while looking for line\n/);
    }
    
    sub read_header_lines {
        @_ == 1 || @_ == 2 || die(q/Usage: $handle->read_header_lines([headers])/ . "\n");
        my ($self, $headers) = @_;
        $headers ||= {};
        my $lines   = 0;
        my $val;
    
        while () {
             my $line = $self->readline;
    
             if (++$lines >= $self->{max_header_lines}) {
                 die(qq/Header lines exceeds maximum number allowed of $self->{max_header_lines}\n/);
             }
             elsif ($line =~ /\A ([^\x00-\x1F\x7F:]+) : [\x09\x20]* ([^\x0D\x0A]*)/x) {
                 my ($field_name) = lc $1;
                 if (exists $headers->{$field_name}) {
                     for ($headers->{$field_name}) {
                         $_ = [$_] unless ref $_ eq "ARRAY";
                         push @$_, $2;
                         $val = \$_->[-1];
                     }
                 }
                 else {
                     $val = \($headers->{$field_name} = $2);
                 }
             }
             elsif ($line =~ /\A [\x09\x20]+ ([^\x0D\x0A]*)/x) {
                 $val
                   or die(qq/Unexpected header continuation line\n/);
                 next unless length $1;
                 $$val .= ' ' if length $$val;
                 $$val .= $1;
             }
             elsif ($line =~ /\A \x0D?\x0A \z/x) {
                last;
             }
             else {
                die(q/Malformed header line: / . $Printable->($line) . "\n");
             }
        }
        return $headers;
    }
    
    sub write_request {
        @_ == 2 || die(q/Usage: $handle->write_request(request)/ . "\n");
        my($self, $request) = @_;
        $self->write_request_header(@{$request}{qw/method uri headers/});
        $self->write_body($request) if $request->{cb};
        return;
    }
    
    my %HeaderCase = (
        'content-md5'      => 'Content-MD5',
        'etag'             => 'ETag',
        'te'               => 'TE',
        'www-authenticate' => 'WWW-Authenticate',
        'x-xss-protection' => 'X-XSS-Protection',
    );
    
    # to avoid multiple small writes and hence nagle, you can pass the method line or anything else to
    # combine writes.
    sub write_header_lines {
        (@_ == 2 || @_ == 3 && ref $_[1] eq 'HASH') || die(q/Usage: $handle->write_header_lines(headers[,prefix])/ . "\n");
        my($self, $headers, $prefix_data) = @_;
    
        my $buf = (defined $prefix_data ? $prefix_data : '');
        while (my ($k, $v) = each %$headers) {
            my $field_name = lc $k;
            if (exists $HeaderCase{$field_name}) {
                $field_name = $HeaderCase{$field_name};
            }
            else {
                $field_name =~ /\A $Token+ \z/xo
                  or die(q/Invalid HTTP header field name: / . $Printable->($field_name) . "\n");
                $field_name =~ s/\b(\w)/\u$1/g;
                $HeaderCase{lc $field_name} = $field_name;
            }
            for (ref $v eq 'ARRAY' ? @$v : $v) {
                $_ = '' unless defined $_;
                $buf .= "$field_name: $_\x0D\x0A";
            }
        }
        $buf .= "\x0D\x0A";
        return $self->write($buf);
    }
    
    # return value indicates whether message length was defined; this is generally
    # true unless there was no content-length header and we just read until EOF.
    # Other message length errors are thrown as exceptions
    sub read_body {
        @_ == 3 || die(q/Usage: $handle->read_body(callback, response)/ . "\n");
        my ($self, $cb, $response) = @_;
        my $te = $response->{headers}{'transfer-encoding'} || '';
        my $chunked = grep { /chunked/i } ( ref $te eq 'ARRAY' ? @$te : $te ) ;
        return $chunked
            ? $self->read_chunked_body($cb, $response)
            : $self->read_content_body($cb, $response);
    }
    
    sub write_body {
        @_ == 2 || die(q/Usage: $handle->write_body(request)/ . "\n");
        my ($self, $request) = @_;
        if ($request->{headers}{'content-length'}) {
            return $self->write_content_body($request);
        }
        else {
            return $self->write_chunked_body($request);
        }
    }
    
    sub read_content_body {
        @_ == 3 || @_ == 4 || die(q/Usage: $handle->read_content_body(callback, response, [read_length])/ . "\n");
        my ($self, $cb, $response, $content_length) = @_;
        $content_length ||= $response->{headers}{'content-length'};
    
        if ( defined $content_length ) {
            my $len = $content_length;
            while ($len > 0) {
                my $read = ($len > BUFSIZE) ? BUFSIZE : $len;
                $cb->($self->read($read, 0), $response);
                $len -= $read;
            }
            return length($self->{rbuf}) == 0;
        }
    
        my $chunk;
        $cb->($chunk, $response) while length( $chunk = $self->read(BUFSIZE, 1) );
    
        return;
    }
    
    sub write_content_body {
        @_ == 2 || die(q/Usage: $handle->write_content_body(request)/ . "\n");
        my ($self, $request) = @_;
    
        my ($len, $content_length) = (0, $request->{headers}{'content-length'});
        while () {
            my $data = $request->{cb}->();
    
            defined $data && length $data
              or last;
    
            if ( $] ge '5.008' ) {
                utf8::downgrade($data, 1)
                    or die(qq/Wide character in write_content()\n/);
            }
    
            $len += $self->write($data);
        }
    
        $len == $content_length
          or die(qq/Content-Length mismatch (got: $len expected: $content_length)\n/);
    
        return $len;
    }
    
    sub read_chunked_body {
        @_ == 3 || die(q/Usage: $handle->read_chunked_body(callback, $response)/ . "\n");
        my ($self, $cb, $response) = @_;
    
        while () {
            my $head = $self->readline;
    
            $head =~ /\A ([A-Fa-f0-9]+)/x
              or die(q/Malformed chunk head: / . $Printable->($head) . "\n");
    
            my $len = hex($1)
              or last;
    
            $self->read_content_body($cb, $response, $len);
    
            $self->read(2) eq "\x0D\x0A"
              or die(qq/Malformed chunk: missing CRLF after chunk data\n/);
        }
        $self->read_header_lines($response->{headers});
        return 1;
    }
    
    sub write_chunked_body {
        @_ == 2 || die(q/Usage: $handle->write_chunked_body(request)/ . "\n");
        my ($self, $request) = @_;
    
        my $len = 0;
        while () {
            my $data = $request->{cb}->();
    
            defined $data && length $data
              or last;
    
            if ( $] ge '5.008' ) {
                utf8::downgrade($data, 1)
                    or die(qq/Wide character in write_chunked_body()\n/);
            }
    
            $len += length $data;
    
            my $chunk  = sprintf '%X', length $data;
               $chunk .= "\x0D\x0A";
               $chunk .= $data;
               $chunk .= "\x0D\x0A";
    
            $self->write($chunk);
        }
        $self->write("0\x0D\x0A");
        $self->write_header_lines($request->{trailer_cb}->())
            if ref $request->{trailer_cb} eq 'CODE';
        return $len;
    }
    
    sub read_response_header {
        @_ == 1 || die(q/Usage: $handle->read_response_header()/ . "\n");
        my ($self) = @_;
    
        my $line = $self->readline;
    
        $line =~ /\A (HTTP\/(0*\d+\.0*\d+)) [\x09\x20]+ ([0-9]{3}) [\x09\x20]+ ([^\x0D\x0A]*) \x0D?\x0A/x
          or die(q/Malformed Status-Line: / . $Printable->($line). "\n");
    
        my ($protocol, $version, $status, $reason) = ($1, $2, $3, $4);
    
        die (qq/Unsupported HTTP protocol: $protocol\n/)
            unless $version =~ /0*1\.0*[01]/;
    
        return {
            status       => $status,
            reason       => $reason,
            headers      => $self->read_header_lines,
            protocol     => $protocol,
        };
    }
    
    sub write_request_header {
        @_ == 4 || die(q/Usage: $handle->write_request_header(method, request_uri, headers)/ . "\n");
        my ($self, $method, $request_uri, $headers) = @_;
    
        return $self->write_header_lines($headers, "$method $request_uri HTTP/1.1\x0D\x0A");
    }
    
    sub _do_timeout {
        my ($self, $type, $timeout) = @_;
        $timeout = $self->{timeout}
            unless defined $timeout && $timeout >= 0;
    
        my $fd = fileno $self->{fh};
        defined $fd && $fd >= 0
          or die(qq/select(2): 'Bad file descriptor'\n/);
    
        my $initial = time;
        my $pending = $timeout;
        my $nfound;
    
        vec(my $fdset = '', $fd, 1) = 1;
    
        while () {
            $nfound = ($type eq 'read')
                ? select($fdset, undef, undef, $pending)
                : select(undef, $fdset, undef, $pending) ;
            if ($nfound == -1) {
                $! == EINTR
                  or die(qq/select(2): '$!'\n/);
                redo if !$timeout || ($pending = $timeout - (time - $initial)) > 0;
                $nfound = 0;
            }
            last;
        }
        $! = 0;
        return $nfound;
    }
    
    sub can_read {
        @_ == 1 || @_ == 2 || die(q/Usage: $handle->can_read([timeout])/ . "\n");
        my $self = shift;
        if ( ref($self->{fh}) eq 'IO::Socket::SSL' ) {
            return 1 if $self->{fh}->pending;
        }
        return $self->_do_timeout('read', @_)
    }
    
    sub can_write {
        @_ == 1 || @_ == 2 || die(q/Usage: $handle->can_write([timeout])/ . "\n");
        my $self = shift;
        return $self->_do_timeout('write', @_)
    }
    
    sub _assert_ssl {
        # Need IO::Socket::SSL 1.42 for SSL_create_ctx_callback
        die(qq/IO::Socket::SSL 1.42 must be installed for https support\n/)
            unless eval {require IO::Socket::SSL; IO::Socket::SSL->VERSION(1.42)};
        # Need Net::SSLeay 1.49 for MODE_AUTO_RETRY
        die(qq/Net::SSLeay 1.49 must be installed for https support\n/)
            unless eval {require Net::SSLeay; Net::SSLeay->VERSION(1.49)};
    }
    
    sub can_reuse {
        my ($self,$scheme,$host,$port) = @_;
        return 0 if
            $self->{pid} != $$
            || $self->{tid} != _get_tid()
            || length($self->{rbuf})
            || $scheme ne $self->{scheme}
            || $host ne $self->{host}
            || $port ne $self->{port}
            || eval { $self->can_read(0) }
            || $@ ;
            return 1;
    }
    
    # Try to find a CA bundle to validate the SSL cert,
    # prefer Mozilla::CA or fallback to a system file
    sub _find_CA_file {
        my $self = shift();
    
        return $self->{SSL_options}->{SSL_ca_file}
            if $self->{SSL_options}->{SSL_ca_file} and -e $self->{SSL_options}->{SSL_ca_file};
    
        return Mozilla::CA::SSL_ca_file()
            if eval { require Mozilla::CA };
    
        # cert list copied from golang src/crypto/x509/root_unix.go
        foreach my $ca_bundle (
            "/etc/ssl/certs/ca-certificates.crt",     # Debian/Ubuntu/Gentoo etc.
            "/etc/pki/tls/certs/ca-bundle.crt",       # Fedora/RHEL
            "/etc/ssl/ca-bundle.pem",                 # OpenSUSE
            "/etc/openssl/certs/ca-certificates.crt", # NetBSD
            "/etc/ssl/cert.pem",                      # OpenBSD
            "/usr/local/share/certs/ca-root-nss.crt", # FreeBSD/DragonFly
            "/etc/pki/tls/cacert.pem",                # OpenELEC
            "/etc/certs/ca-certificates.crt",         # Solaris 11.2+
        ) {
            return $ca_bundle if -e $ca_bundle;
        }
    
        die qq/Couldn't find a CA bundle with which to verify the SSL certificate.\n/
          . qq/Try installing Mozilla::CA from CPAN\n/;
    }
    
    # for thread safety, we need to know thread id if threads are loaded
    sub _get_tid {
        no warnings 'reserved'; # for 'threads'
        return threads->can("tid") ? threads->tid : 0;
    }
    
    sub _ssl_args {
        my ($self, $host) = @_;
    
        my %ssl_args;
    
        # This test reimplements IO::Socket::SSL::can_client_sni(), which wasn't
        # added until IO::Socket::SSL 1.84
        if ( Net::SSLeay::OPENSSL_VERSION_NUMBER() >= 0x01000000 ) {
            $ssl_args{SSL_hostname} = $host,          # Sane SNI support
        }
    
        if ($self->{verify_SSL}) {
            $ssl_args{SSL_verifycn_scheme}  = 'http'; # enable CN validation
            $ssl_args{SSL_verifycn_name}    = $host;  # set validation hostname
            $ssl_args{SSL_verify_mode}      = 0x01;   # enable cert validation
            $ssl_args{SSL_ca_file}          = $self->_find_CA_file;
        }
        else {
            $ssl_args{SSL_verifycn_scheme}  = 'none'; # disable CN validation
            $ssl_args{SSL_verify_mode}      = 0x00;   # disable cert validation
        }
    
        # user options override settings from verify_SSL
        for my $k ( keys %{$self->{SSL_options}} ) {
            $ssl_args{$k} = $self->{SSL_options}{$k} if $k =~ m/^SSL_/;
        }
    
        return \%ssl_args;
    }
    
    1;
    
    __END__
    
    =pod
    
    =encoding UTF-8
    
    =head1 NAME
    
    HTTP::Tiny - A small, simple, correct HTTP/1.1 client
    
    =head1 VERSION
    
    version 0.054
    
    =head1 SYNOPSIS
    
        use HTTP::Tiny;
    
        my $response = HTTP::Tiny->new->get('http://example.com/');
    
        die "Failed!\n" unless $response->{success};
    
        print "$response->{status} $response->{reason}\n";
    
        while (my ($k, $v) = each %{$response->{headers}}) {
            for (ref $v eq 'ARRAY' ? @$v : $v) {
                print "$k: $_\n";
            }
        }
    
        print $response->{content} if length $response->{content};
    
    =head1 DESCRIPTION
    
    This is a very simple HTTP/1.1 client, designed for doing simple
    requests without the overhead of a large framework like L<LWP::UserAgent>.
    
    It is more correct and more complete than L<HTTP::Lite>.  It supports
    proxies and redirection.  It also correctly resumes after EINTR.
    
    If L<IO::Socket::IP> 0.25 or later is installed, HTTP::Tiny will use it instead
    of L<IO::Socket::INET> for transparent support for both IPv4 and IPv6.
    
    Cookie support requires L<HTTP::CookieJar> or an equivalent class.
    
    =head1 METHODS
    
    =head2 new
    
        $http = HTTP::Tiny->new( %attributes );
    
    This constructor returns a new HTTP::Tiny object.  Valid attributes include:
    
    =over 4
    
    =item *
    
    C<agent> — A user-agent string (defaults to 'HTTP-Tiny/$VERSION'). If C<agent> — ends in a space character, the default user-agent string is appended.
    
    =item *
    
    C<cookie_jar> — An instance of L<HTTP::CookieJar> — or equivalent class that supports the C<add> and C<cookie_header> methods
    
    =item *
    
    C<default_headers> — A hashref of default headers to apply to requests
    
    =item *
    
    C<local_address> — The local IP address to bind to
    
    =item *
    
    C<keep_alive> — Whether to reuse the last connection (if for the same scheme, host and port) (defaults to 1)
    
    =item *
    
    C<max_redirect> — Maximum number of redirects allowed (defaults to 5)
    
    =item *
    
    C<max_size> — Maximum response size (only when not using a data callback).  If defined, responses larger than this will return an exception.
    
    =item *
    
    C<http_proxy> — URL of a proxy server to use for HTTP connections (default is C<$ENV{http_proxy}> — if set)
    
    =item *
    
    C<https_proxy> — URL of a proxy server to use for HTTPS connections (default is C<$ENV{https_proxy}> — if set)
    
    =item *
    
    C<proxy> — URL of a generic proxy server for both HTTP and HTTPS connections (default is C<$ENV{all_proxy}> — if set)
    
    =item *
    
    C<no_proxy> — List of domain suffixes that should not be proxied.  Must be a comma-separated string or an array reference. (default is C<$ENV{no_proxy}> —)
    
    =item *
    
    C<timeout> — Request timeout in seconds (default is 60)
    
    =item *
    
    C<verify_SSL> — A boolean that indicates whether to validate the SSL certificate of an C<https> — connection (default is false)
    
    =item *
    
    C<SSL_options> — A hashref of C<SSL_*> — options to pass through to L<IO::Socket::SSL>
    
    =back
    
    Passing an explicit C<undef> for C<proxy>, C<http_proxy> or C<https_proxy> will
    prevent getting the corresponding proxies from the environment.
    
    Exceptions from C<max_size>, C<timeout> or other errors will result in a
    pseudo-HTTP status code of 599 and a reason of "Internal Exception". The
    content field in the response will contain the text of the exception.
    
    The C<keep_alive> parameter enables a persistent connection, but only to a
    single destination scheme, host and port.  Also, if any connection-relevant
    attributes are modified, or if the process ID or thread ID change, the
    persistent connection will be dropped.  If you want persistent connections
    across multiple destinations, use multiple HTTP::Tiny objects.
    
    See L</SSL SUPPORT> for more on the C<verify_SSL> and C<SSL_options> attributes.
    
    =head2 get|head|put|post|delete
    
        $response = $http->get($url);
        $response = $http->get($url, \%options);
        $response = $http->head($url);
    
    These methods are shorthand for calling C<request()> for the given method.  The
    URL must have unsafe characters escaped and international domain names encoded.
    See C<request()> for valid options and a description of the response.
    
    The C<success> field of the response will be true if the status code is 2XX.
    
    =head2 post_form
    
        $response = $http->post_form($url, $form_data);
        $response = $http->post_form($url, $form_data, \%options);
    
    This method executes a C<POST> request and sends the key/value pairs from a
    form data hash or array reference to the given URL with a C<content-type> of
    C<application/x-www-form-urlencoded>.  If data is provided as an array
    reference, the order is preserved; if provided as a hash reference, the terms
    are sorted on key and value for consistency.  See documentation for the
    C<www_form_urlencode> method for details on the encoding.
    
    The URL must have unsafe characters escaped and international domain names
    encoded.  See C<request()> for valid options and a description of the response.
    Any C<content-type> header or content in the options hashref will be ignored.
    
    The C<success> field of the response will be true if the status code is 2XX.
    
    =head2 mirror
    
        $response = $http->mirror($url, $file, \%options)
        if ( $response->{success} ) {
            print "$file is up to date\n";
        }
    
    Executes a C<GET> request for the URL and saves the response body to the file
    name provided.  The URL must have unsafe characters escaped and international
    domain names encoded.  If the file already exists, the request will include an
    C<If-Modified-Since> header with the modification timestamp of the file.  You
    may specify a different C<If-Modified-Since> header yourself in the C<<
    $options->{headers} >> hash.
    
    The C<success> field of the response will be true if the status code is 2XX
    or if the status code is 304 (unmodified).
    
    If the file was modified and the server response includes a properly
    formatted C<Last-Modified> header, the file modification time will
    be updated accordingly.
    
    =head2 request
    
        $response = $http->request($method, $url);
        $response = $http->request($method, $url, \%options);
    
    Executes an HTTP request of the given method type ('GET', 'HEAD', 'POST',
    'PUT', etc.) on the given URL.  The URL must have unsafe characters escaped and
    international domain names encoded.
    
    If the URL includes a "user:password" stanza, they will be used for Basic-style
    authorization headers.  (Authorization headers will not be included in a
    redirected request.) For example:
    
        $http->request('GET', 'http://Aladdin:open sesame@example.com/');
    
    If the "user:password" stanza contains reserved characters, they must
    be percent-escaped:
    
        $http->request('GET', 'http://john%40example.com:password@example.com/');
    
    A hashref of options may be appended to modify the request.
    
    Valid options are:
    
    =over 4
    
    =item *
    
    C<headers> — A hashref containing headers to include with the request.  If the value for a header is an array reference, the header will be output multiple times with each value in the array.  These headers over-write any default headers.
    
    =item *
    
    C<content> — A scalar to include as the body of the request OR a code reference that will be called iteratively to produce the body of the request
    
    =item *
    
    C<trailer_callback> — A code reference that will be called if it exists to provide a hashref of trailing headers (only used with chunked transfer-encoding)
    
    =item *
    
    C<data_callback> — A code reference that will be called for each chunks of the response body received.
    
    =back
    
    The C<Host> header is generated from the URL in accordance with RFC 2616.  It
    is a fatal error to specify C<Host> in the C<headers> option.  Other headers
    may be ignored or overwritten if necessary for transport compliance.
    
    If the C<content> option is a code reference, it will be called iteratively
    to provide the content body of the request.  It should return the empty
    string or undef when the iterator is exhausted.
    
    If the C<content> option is the empty string, no C<content-type> or
    C<content-length> headers will be generated.
    
    If the C<data_callback> option is provided, it will be called iteratively until
    the entire response body is received.  The first argument will be a string
    containing a chunk of the response body, the second argument will be the
    in-progress response hash reference, as described below.  (This allows
    customizing the action of the callback based on the C<status> or C<headers>
    received prior to the content body.)
    
    The C<request> method returns a hashref containing the response.  The hashref
    will have the following keys:
    
    =over 4
    
    =item *
    
    C<success> — Boolean indicating whether the operation returned a 2XX status code
    
    =item *
    
    C<url> — URL that provided the response. This is the URL of the request unless there were redirections, in which case it is the last URL queried in a redirection chain
    
    =item *
    
    C<status> — The HTTP status code of the response
    
    =item *
    
    C<reason> — The response phrase returned by the server
    
    =item *
    
    C<content> — The body of the response.  If the response does not have any content or if a data callback is provided to consume the response body, this will be the empty string
    
    =item *
    
    C<headers> — A hashref of header fields.  All header field names will be normalized to be lower case. If a header is repeated, the value will be an arrayref; it will otherwise be a scalar string containing the value
    
    =back
    
    On an exception during the execution of the request, the C<status> field will
    contain 599, and the C<content> field will contain the text of the exception.
    
    =head2 www_form_urlencode
    
        $params = $http->www_form_urlencode( $data );
        $response = $http->get("http://example.com/query?$params");
    
    This method converts the key/value pairs from a data hash or array reference
    into a C<x-www-form-urlencoded> string.  The keys and values from the data
    reference will be UTF-8 encoded and escaped per RFC 3986.  If a value is an
    array reference, the key will be repeated with each of the values of the array
    reference.  If data is provided as a hash reference, the key/value pairs in the
    resulting string will be sorted by key and value for consistent ordering.
    
    =for Pod::Coverage SSL_options
    agent
    cookie_jar
    default_headers
    http_proxy
    https_proxy
    keep_alive
    local_address
    max_redirect
    max_size
    no_proxy
    proxy
    timeout
    verify_SSL
    
    =head1 SSL SUPPORT
    
    Direct C<https> connections are supported only if L<IO::Socket::SSL> 1.56 or
    greater and L<Net::SSLeay> 1.49 or greater are installed. An exception will be
    thrown if new enough versions of these modules are not installed or if the SSL
    encryption fails. An C<https> connection may be made via an C<http> proxy that
    supports the CONNECT command (i.e. RFC 2817).  You may not proxy C<https> via
    a proxy that itself requires C<https> to communicate.
    
    SSL provides two distinct capabilities:
    
    =over 4
    
    =item *
    
    Encrypted communication channel
    
    =item *
    
    Verification of server identity
    
    =back
    
    B<By default, HTTP::Tiny does not verify server identity>.
    
    Server identity verification is controversial and potentially tricky because it
    depends on a (usually paid) third-party Certificate Authority (CA) trust model
    to validate a certificate as legitimate.  This discriminates against servers
    with self-signed certificates or certificates signed by free, community-driven
    CA's such as L<CAcert.org|http://cacert.org>.
    
    By default, HTTP::Tiny does not make any assumptions about your trust model,
    threat level or risk tolerance.  It just aims to give you an encrypted channel
    when you need one.
    
    Setting the C<verify_SSL> attribute to a true value will make HTTP::Tiny verify
    that an SSL connection has a valid SSL certificate corresponding to the host
    name of the connection and that the SSL certificate has been verified by a CA.
    Assuming you trust the CA, this will protect against a L<man-in-the-middle
    attack|http://en.wikipedia.org/wiki/Man-in-the-middle_attack>.  If you are
    concerned about security, you should enable this option.
    
    Certificate verification requires a file containing trusted CA certificates.
    If the L<Mozilla::CA> module is installed, HTTP::Tiny will use the CA file
    included with it as a source of trusted CA's.  (This means you trust Mozilla,
    the author of Mozilla::CA, the CPAN mirror where you got Mozilla::CA, the
    toolchain used to install it, and your operating system security, right?)
    
    If that module is not available, then HTTP::Tiny will search several
    system-specific default locations for a CA certificate file:
    
    =over 4
    
    =item *
    
    /etc/ssl/certs/ca-certificates.crt
    
    =item *
    
    /etc/pki/tls/certs/ca-bundle.crt
    
    =item *
    
    /etc/ssl/ca-bundle.pem
    
    =back
    
    An exception will be raised if C<verify_SSL> is true and no CA certificate file
    is available.
    
    If you desire complete control over SSL connections, the C<SSL_options> attribute
    lets you provide a hash reference that will be passed through to
    C<IO::Socket::SSL::start_SSL()>, overriding any options set by HTTP::Tiny. For
    example, to provide your own trusted CA file:
    
        SSL_options => {
            SSL_ca_file => $file_path,
        }
    
    The C<SSL_options> attribute could also be used for such things as providing a
    client certificate for authentication to a server or controlling the choice of
    cipher used for the SSL connection. See L<IO::Socket::SSL> documentation for
    details.
    
    =head1 PROXY SUPPORT
    
    HTTP::Tiny can proxy both C<http> and C<https> requests.  Only Basic proxy
    authorization is supported and it must be provided as part of the proxy URL:
    C<http://user:pass@proxy.example.com/>.
    
    HTTP::Tiny supports the following proxy environment variables:
    
    =over 4
    
    =item *
    
    http_proxy or HTTP_PROXY
    
    =item *
    
    https_proxy or HTTPS_PROXY
    
    =item *
    
    all_proxy or ALL_PROXY
    
    =back
    
    If the C<REQUEST_METHOD> environment variable is set, then this might be a CGI
    process and C<HTTP_PROXY> would be set from the C<Proxy:> header, which is a
    security risk.  If C<REQUEST_METHOD> is set, C<HTTP_PROXY> (the upper case
    variant only) is ignored.
    
    Tunnelling C<https> over an C<http> proxy using the CONNECT method is
    supported.  If your proxy uses C<https> itself, you can not tunnel C<https>
    over it.
    
    Be warned that proxying an C<https> connection opens you to the risk of a
    man-in-the-middle attack by the proxy server.
    
    The C<no_proxy> environment variable is supported in the format of a
    comma-separated list of domain extensions proxy should not be used for.
    
    Proxy arguments passed to C<new> will override their corresponding
    environment variables.
    
    =head1 LIMITATIONS
    
    HTTP::Tiny is I<conditionally compliant> with the
    L<HTTP/1.1 specifications|http://www.w3.org/Protocols/>:
    
    =over 4
    
    =item *
    
    "Message Syntax and Routing" [RFC7230]
    
    =item *
    
    "Semantics and Content" [RFC7231]
    
    =item *
    
    "Conditional Requests" [RFC7232]
    
    =item *
    
    "Range Requests" [RFC7233]
    
    =item *
    
    "Caching" [RFC7234]
    
    =item *
    
    "Authentication" [RFC7235]
    
    =back
    
    It attempts to meet all "MUST" requirements of the specification, but does not
    implement all "SHOULD" requirements.  (Note: it was developed against the
    earlier RFC 2616 specification and may not yet meet the revised RFC 7230-7235
    spec.)
    
    Some particular limitations of note include:
    
    =over
    
    =item *
    
    HTTP::Tiny focuses on correct transport.  Users are responsible for ensuring
    that user-defined headers and content are compliant with the HTTP/1.1
    specification.
    
    =item *
    
    Users must ensure that URLs are properly escaped for unsafe characters and that
    international domain names are properly encoded to ASCII. See L<URI::Escape>,
    L<URI::_punycode> and L<Net::IDN::Encode>.
    
    =item *
    
    Redirection is very strict against the specification.  Redirection is only
    automatic for response codes 301, 302 and 307 if the request method is 'GET' or
    'HEAD'.  Response code 303 is always converted into a 'GET' redirection, as
    mandated by the specification.  There is no automatic support for status 305
    ("Use proxy") redirections.
    
    =item *
    
    There is no provision for delaying a request body using an C<Expect> header.
    Unexpected C<1XX> responses are silently ignored as per the specification.
    
    =item *
    
    Only 'chunked' C<Transfer-Encoding> is supported.
    
    =item *
    
    There is no support for a Request-URI of '*' for the 'OPTIONS' request.
    
    =back
    
    Despite the limitations listed above, HTTP::Tiny is considered
    feature-complete.  New feature requests should be directed to
    L<HTTP::Tiny::UA>.
    
    =head1 SEE ALSO
    
    =over 4
    
    =item *
    
    L<HTTP::Tiny::UA> - Higher level UA features for HTTP::Tiny
    
    =item *
    
    L<HTTP::Thin> - HTTP::Tiny wrapper with L<HTTP::Request>/L<HTTP::Response> compatibility
    
    =item *
    
    L<HTTP::Tiny::Mech> - Wrap L<WWW::Mechanize> instance in HTTP::Tiny compatible interface
    
    =item *
    
    L<IO::Socket::IP> - Required for IPv6 support
    
    =item *
    
    L<IO::Socket::SSL> - Required for SSL support
    
    =item *
    
    L<LWP::UserAgent> - If HTTP::Tiny isn't enough for you, this is the "standard" way to do things
    
    =item *
    
    L<Mozilla::CA> - Required if you want to validate SSL certificates
    
    =item *
    
    L<Net::SSLeay> - Required for SSL support
    
    =back
    
    =for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan
    
    =head1 SUPPORT
    
    =head2 Bugs / Feature Requests
    
    Please report any bugs or feature requests through the issue tracker
    at L<https://github.com/chansen/p5-http-tiny/issues>.
    You will be notified automatically of any progress on your issue.
    
    =head2 Source Code
    
    This is open source software.  The code repository is available for
    public review and contribution under the terms of the license.
    
    L<https://github.com/chansen/p5-http-tiny>
    
      git clone https://github.com/chansen/p5-http-tiny.git
    
    =head1 AUTHORS
    
    =over 4
    
    =item *
    
    Christian Hansen <chansen@cpan.org>
    
    =item *
    
    David Golden <dagolden@cpan.org>
    
    =back
    
    =head1 CONTRIBUTORS
    
    =for stopwords Alan Gardner Alessandro Ghedini Brad Gilbert Chris Nehren Weyl Claes Jakobsson Clinton Gormley Craig Berry David Mitchell Dean Pearce Edward Zborowski James Raspass Jess Robinson Lukas Eklund Martin J. Evans Martin-Louis Bright Mike Doherty Olaf Alders Petr Písař Serguei Trouchelle Sören Kornetzki Syohei YOSHIDA Tom Hukins Tony Cook
    
    =over 4
    
    =item *
    
    Alan Gardner <gardner@pythian.com>
    
    =item *
    
    Alessandro Ghedini <al3xbio@gmail.com>
    
    =item *
    
    Brad Gilbert <bgills@cpan.org>
    
    =item *
    
    Chris Nehren <apeiron@cpan.org>
    
    =item *
    
    Chris Weyl <cweyl@alumni.drew.edu>
    
    =item *
    
    Claes Jakobsson <claes@surfar.nu>
    
    =item *
    
    Clinton Gormley <clint@traveljury.com>
    
    =item *
    
    Craig Berry <cberry@cpan.org>
    
    =item *
    
    David Mitchell <davem@iabyn.com>
    
    =item *
    
    Dean Pearce <pearce@pythian.com>
    
    =item *
    
    Edward Zborowski <ed@rubensteintech.com>
    
    =item *
    
    James Raspass <jraspass@gmail.com>
    
    =item *
    
    Jess Robinson <castaway@desert-island.me.uk>
    
    =item *
    
    Lukas Eklund <leklund@gmail.com>
    
    =item *
    
    Martin J. Evans <mjegh@ntlworld.com>
    
    =item *
    
    Martin-Louis Bright <mlbright@gmail.com>
    
    =item *
    
    Mike Doherty <doherty@cpan.org>
    
    =item *
    
    Olaf Alders <olaf@wundersolutions.com>
    
    =item *
    
    Petr Písař <ppisar@redhat.com>
    
    =item *
    
    Serguei Trouchelle <stro@cpan.org>
    
    =item *
    
    Sören Kornetzki <soeren.kornetzki@delti.com>
    
    =item *
    
    Syohei YOSHIDA <syohex@gmail.com>
    
    =item *
    
    Tom Hukins <tom@eborcom.com>
    
    =item *
    
    Tony Cook <tony@develop-help.com>
    
    =back
    
    =head1 COPYRIGHT AND LICENSE
    
    This software is copyright (c) 2015 by Christian Hansen.
    
    This is free software; you can redistribute it and/or modify it under
    the same terms as the Perl 5 programming language system itself.
    
    =cut
  HTTP_TINY
  
  $fatpacked{"JSON/PP.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'JSON_PP';
    package JSON::PP;
    
    # JSON-2.0
    
    use 5.005;
    use strict;
    use base qw(Exporter);
    use overload ();
    
    use Carp ();
    use B ();
    #use Devel::Peek;
    
    $JSON::PP::VERSION = '2.27300';
    
    @JSON::PP::EXPORT = qw(encode_json decode_json from_json to_json);
    
    # instead of hash-access, i tried index-access for speed.
    # but this method is not faster than what i expected. so it will be changed.
    
    use constant P_ASCII                => 0;
    use constant P_LATIN1               => 1;
    use constant P_UTF8                 => 2;
    use constant P_INDENT               => 3;
    use constant P_CANONICAL            => 4;
    use constant P_SPACE_BEFORE         => 5;
    use constant P_SPACE_AFTER          => 6;
    use constant P_ALLOW_NONREF         => 7;
    use constant P_SHRINK               => 8;
    use constant P_ALLOW_BLESSED        => 9;
    use constant P_CONVERT_BLESSED      => 10;
    use constant P_RELAXED              => 11;
    
    use constant P_LOOSE                => 12;
    use constant P_ALLOW_BIGNUM         => 13;
    use constant P_ALLOW_BAREKEY        => 14;
    use constant P_ALLOW_SINGLEQUOTE    => 15;
    use constant P_ESCAPE_SLASH         => 16;
    use constant P_AS_NONBLESSED        => 17;
    
    use constant P_ALLOW_UNKNOWN        => 18;
    
    use constant OLD_PERL => $] < 5.008 ? 1 : 0;
    
    BEGIN {
        my @xs_compati_bit_properties = qw(
                latin1 ascii utf8 indent canonical space_before space_after allow_nonref shrink
                allow_blessed convert_blessed relaxed allow_unknown
        );
        my @pp_bit_properties = qw(
                allow_singlequote allow_bignum loose
                allow_barekey escape_slash as_nonblessed
        );
    
        # Perl version check, Unicode handling is enable?
        # Helper module sets @JSON::PP::_properties.
        if ($] < 5.008 ) {
            my $helper = $] >= 5.006 ? 'JSON::PP::Compat5006' : 'JSON::PP::Compat5005';
            eval qq| require $helper |;
            if ($@) { Carp::croak $@; }
        }
    
        for my $name (@xs_compati_bit_properties, @pp_bit_properties) {
            my $flag_name = 'P_' . uc($name);
    
            eval qq/
                sub $name {
                    my \$enable = defined \$_[1] ? \$_[1] : 1;
    
                    if (\$enable) {
                        \$_[0]->{PROPS}->[$flag_name] = 1;
                    }
                    else {
                        \$_[0]->{PROPS}->[$flag_name] = 0;
                    }
    
                    \$_[0];
                }
    
                sub get_$name {
                    \$_[0]->{PROPS}->[$flag_name] ? 1 : '';
                }
            /;
        }
    
    }
    
    
    
    # Functions
    
    my %encode_allow_method
         = map {($_ => 1)} qw/utf8 pretty allow_nonref latin1 self_encode escape_slash
                              allow_blessed convert_blessed indent indent_length allow_bignum
                              as_nonblessed
                            /;
    my %decode_allow_method
         = map {($_ => 1)} qw/utf8 allow_nonref loose allow_singlequote allow_bignum
                              allow_barekey max_size relaxed/;
    
    
    my $JSON; # cache
    
    sub encode_json ($) { # encode
        ($JSON ||= __PACKAGE__->new->utf8)->encode(@_);
    }
    
    
    sub decode_json { # decode
        ($JSON ||= __PACKAGE__->new->utf8)->decode(@_);
    }
    
    # Obsoleted
    
    sub to_json($) {
       Carp::croak ("JSON::PP::to_json has been renamed to encode_json.");
    }
    
    
    sub from_json($) {
       Carp::croak ("JSON::PP::from_json has been renamed to decode_json.");
    }
    
    
    # Methods
    
    sub new {
        my $class = shift;
        my $self  = {
            max_depth   => 512,
            max_size    => 0,
            indent      => 0,
            FLAGS       => 0,
            fallback      => sub { encode_error('Invalid value. JSON can only reference.') },
            indent_length => 3,
        };
    
        bless $self, $class;
    }
    
    
    sub encode {
        return $_[0]->PP_encode_json($_[1]);
    }
    
    
    sub decode {
        return $_[0]->PP_decode_json($_[1], 0x00000000);
    }
    
    
    sub decode_prefix {
        return $_[0]->PP_decode_json($_[1], 0x00000001);
    }
    
    
    # accessor
    
    
    # pretty printing
    
    sub pretty {
        my ($self, $v) = @_;
        my $enable = defined $v ? $v : 1;
    
        if ($enable) { # indent_length(3) for JSON::XS compatibility
            $self->indent(1)->indent_length(3)->space_before(1)->space_after(1);
        }
        else {
            $self->indent(0)->space_before(0)->space_after(0);
        }
    
        $self;
    }
    
    # etc
    
    sub max_depth {
        my $max  = defined $_[1] ? $_[1] : 0x80000000;
        $_[0]->{max_depth} = $max;
        $_[0];
    }
    
    
    sub get_max_depth { $_[0]->{max_depth}; }
    
    
    sub max_size {
        my $max  = defined $_[1] ? $_[1] : 0;
        $_[0]->{max_size} = $max;
        $_[0];
    }
    
    
    sub get_max_size { $_[0]->{max_size}; }
    
    
    sub filter_json_object {
        $_[0]->{cb_object} = defined $_[1] ? $_[1] : 0;
        $_[0]->{F_HOOK} = ($_[0]->{cb_object} or $_[0]->{cb_sk_object}) ? 1 : 0;
        $_[0];
    }
    
    sub filter_json_single_key_object {
        if (@_ > 1) {
            $_[0]->{cb_sk_object}->{$_[1]} = $_[2];
        }
        $_[0]->{F_HOOK} = ($_[0]->{cb_object} or $_[0]->{cb_sk_object}) ? 1 : 0;
        $_[0];
    }
    
    sub indent_length {
        if (!defined $_[1] or $_[1] > 15 or $_[1] < 0) {
            Carp::carp "The acceptable range of indent_length() is 0 to 15.";
        }
        else {
            $_[0]->{indent_length} = $_[1];
        }
        $_[0];
    }
    
    sub get_indent_length {
        $_[0]->{indent_length};
    }
    
    sub sort_by {
        $_[0]->{sort_by} = defined $_[1] ? $_[1] : 1;
        $_[0];
    }
    
    sub allow_bigint {
        Carp::carp("allow_bigint() is obsoleted. use allow_bignum() insted.");
    }
    
    ###############################
    
    ###
    ### Perl => JSON
    ###
    
    
    { # Convert
    
        my $max_depth;
        my $indent;
        my $ascii;
        my $latin1;
        my $utf8;
        my $space_before;
        my $space_after;
        my $canonical;
        my $allow_blessed;
        my $convert_blessed;
    
        my $indent_length;
        my $escape_slash;
        my $bignum;
        my $as_nonblessed;
    
        my $depth;
        my $indent_count;
        my $keysort;
    
    
        sub PP_encode_json {
            my $self = shift;
            my $obj  = shift;
    
            $indent_count = 0;
            $depth        = 0;
    
            my $idx = $self->{PROPS};
    
            ($ascii, $latin1, $utf8, $indent, $canonical, $space_before, $space_after, $allow_blessed,
                $convert_blessed, $escape_slash, $bignum, $as_nonblessed)
             = @{$idx}[P_ASCII .. P_SPACE_AFTER, P_ALLOW_BLESSED, P_CONVERT_BLESSED,
                        P_ESCAPE_SLASH, P_ALLOW_BIGNUM, P_AS_NONBLESSED];
    
            ($max_depth, $indent_length) = @{$self}{qw/max_depth indent_length/};
    
            $keysort = $canonical ? sub { $a cmp $b } : undef;
    
            if ($self->{sort_by}) {
                $keysort = ref($self->{sort_by}) eq 'CODE' ? $self->{sort_by}
                         : $self->{sort_by} =~ /\D+/       ? $self->{sort_by}
                         : sub { $a cmp $b };
            }
    
            encode_error("hash- or arrayref expected (not a simple scalar, use allow_nonref to allow this)")
                 if(!ref $obj and !$idx->[ P_ALLOW_NONREF ]);
    
            my $str  = $self->object_to_json($obj);
    
            $str .= "\n" if ( $indent ); # JSON::XS 2.26 compatible
    
            unless ($ascii or $latin1 or $utf8) {
                utf8::upgrade($str);
            }
    
            if ($idx->[ P_SHRINK ]) {
                utf8::downgrade($str, 1);
            }
    
            return $str;
        }
    
    
        sub object_to_json {
            my ($self, $obj) = @_;
            my $type = ref($obj);
    
            if($type eq 'HASH'){
                return $self->hash_to_json($obj);
            }
            elsif($type eq 'ARRAY'){
                return $self->array_to_json($obj);
            }
            elsif ($type) { # blessed object?
                if (blessed($obj)) {
    
                    return $self->value_to_json($obj) if ( $obj->isa('JSON::PP::Boolean') );
    
                    if ( $convert_blessed and $obj->can('TO_JSON') ) {
                        my $result = $obj->TO_JSON();
                        if ( defined $result and ref( $result ) ) {
                            if ( refaddr( $obj ) eq refaddr( $result ) ) {
                                encode_error( sprintf(
                                    "%s::TO_JSON method returned same object as was passed instead of a new one",
                                    ref $obj
                                ) );
                            }
                        }
    
                        return $self->object_to_json( $result );
                    }
    
                    return "$obj" if ( $bignum and _is_bignum($obj) );
                    return $self->blessed_to_json($obj) if ($allow_blessed and $as_nonblessed); # will be removed.
    
                    encode_error( sprintf("encountered object '%s', but neither allow_blessed "
                        . "nor convert_blessed settings are enabled", $obj)
                    ) unless ($allow_blessed);
    
                    return 'null';
                }
                else {
                    return $self->value_to_json($obj);
                }
            }
            else{
                return $self->value_to_json($obj);
            }
        }
    
    
        sub hash_to_json {
            my ($self, $obj) = @_;
            my @res;
    
            encode_error("json text or perl structure exceeds maximum nesting level (max_depth set too low?)")
                                             if (++$depth > $max_depth);
    
            my ($pre, $post) = $indent ? $self->_up_indent() : ('', '');
            my $del = ($space_before ? ' ' : '') . ':' . ($space_after ? ' ' : '');
    
            for my $k ( _sort( $obj ) ) {
                if ( OLD_PERL ) { utf8::decode($k) } # key for Perl 5.6 / be optimized
                push @res, string_to_json( $self, $k )
                              .  $del
                              . ( $self->object_to_json( $obj->{$k} ) || $self->value_to_json( $obj->{$k} ) );
            }
    
            --$depth;
            $self->_down_indent() if ($indent);
    
            return   '{' . ( @res ? $pre : '' ) . ( @res ? join( ",$pre", @res ) . $post : '' )  . '}';
        }
    
    
        sub array_to_json {
            my ($self, $obj) = @_;
            my @res;
    
            encode_error("json text or perl structure exceeds maximum nesting level (max_depth set too low?)")
                                             if (++$depth > $max_depth);
    
            my ($pre, $post) = $indent ? $self->_up_indent() : ('', '');
    
            for my $v (@$obj){
                push @res, $self->object_to_json($v) || $self->value_to_json($v);
            }
    
            --$depth;
            $self->_down_indent() if ($indent);
    
            return '[' . ( @res ? $pre : '' ) . ( @res ? join( ",$pre", @res ) . $post : '' ) . ']';
        }
    
    
        sub value_to_json {
            my ($self, $value) = @_;
    
            return 'null' if(!defined $value);
    
            my $b_obj = B::svref_2object(\$value);  # for round trip problem
            my $flags = $b_obj->FLAGS;
    
            return $value # as is 
                if $flags & ( B::SVp_IOK | B::SVp_NOK ) and !( $flags & B::SVp_POK ); # SvTYPE is IV or NV?
    
            my $type = ref($value);
    
            if(!$type){
                return string_to_json($self, $value);
            }
            elsif( blessed($value) and  $value->isa('JSON::PP::Boolean') ){
                return $$value == 1 ? 'true' : 'false';
            }
            elsif ($type) {
                if ((overload::StrVal($value) =~ /=(\w+)/)[0]) {
                    return $self->value_to_json("$value");
                }
    
                if ($type eq 'SCALAR' and defined $$value) {
                    return   $$value eq '1' ? 'true'
                           : $$value eq '0' ? 'false'
                           : $self->{PROPS}->[ P_ALLOW_UNKNOWN ] ? 'null'
                           : encode_error("cannot encode reference to scalar");
                }
    
                 if ( $self->{PROPS}->[ P_ALLOW_UNKNOWN ] ) {
                     return 'null';
                 }
                 else {
                     if ( $type eq 'SCALAR' or $type eq 'REF' ) {
                        encode_error("cannot encode reference to scalar");
                     }
                     else {
                        encode_error("encountered $value, but JSON can only represent references to arrays or hashes");
                     }
                 }
    
            }
            else {
                return $self->{fallback}->($value)
                     if ($self->{fallback} and ref($self->{fallback}) eq 'CODE');
                return 'null';
            }
    
        }
    
    
        my %esc = (
            "\n" => '\n',
            "\r" => '\r',
            "\t" => '\t',
            "\f" => '\f',
            "\b" => '\b',
            "\"" => '\"',
            "\\" => '\\\\',
            "\'" => '\\\'',
        );
    
    
        sub string_to_json {
            my ($self, $arg) = @_;
    
            $arg =~ s/([\x22\x5c\n\r\t\f\b])/$esc{$1}/g;
            $arg =~ s/\//\\\//g if ($escape_slash);
            $arg =~ s/([\x00-\x08\x0b\x0e-\x1f])/'\\u00' . unpack('H2', $1)/eg;
    
            if ($ascii) {
                $arg = JSON_PP_encode_ascii($arg);
            }
    
            if ($latin1) {
                $arg = JSON_PP_encode_latin1($arg);
            }
    
            if ($utf8) {
                utf8::encode($arg);
            }
    
            return '"' . $arg . '"';
        }
    
    
        sub blessed_to_json {
            my $reftype = reftype($_[1]) || '';
            if ($reftype eq 'HASH') {
                return $_[0]->hash_to_json($_[1]);
            }
            elsif ($reftype eq 'ARRAY') {
                return $_[0]->array_to_json($_[1]);
            }
            else {
                return 'null';
            }
        }
    
    
        sub encode_error {
            my $error  = shift;
            Carp::croak "$error";
        }
    
    
        sub _sort {
            defined $keysort ? (sort $keysort (keys %{$_[0]})) : keys %{$_[0]};
        }
    
    
        sub _up_indent {
            my $self  = shift;
            my $space = ' ' x $indent_length;
    
            my ($pre,$post) = ('','');
    
            $post = "\n" . $space x $indent_count;
    
            $indent_count++;
    
            $pre = "\n" . $space x $indent_count;
    
            return ($pre,$post);
        }
    
    
        sub _down_indent { $indent_count--; }
    
    
        sub PP_encode_box {
            {
                depth        => $depth,
                indent_count => $indent_count,
            };
        }
    
    } # Convert
    
    
    sub _encode_ascii {
        join('',
            map {
                $_ <= 127 ?
                    chr($_) :
                $_ <= 65535 ?
                    sprintf('\u%04x', $_) : sprintf('\u%x\u%x', _encode_surrogates($_));
            } unpack('U*', $_[0])
        );
    }
    
    
    sub _encode_latin1 {
        join('',
            map {
                $_ <= 255 ?
                    chr($_) :
                $_ <= 65535 ?
                    sprintf('\u%04x', $_) : sprintf('\u%x\u%x', _encode_surrogates($_));
            } unpack('U*', $_[0])
        );
    }
    
    
    sub _encode_surrogates { # from perlunicode
        my $uni = $_[0] - 0x10000;
        return ($uni / 0x400 + 0xD800, $uni % 0x400 + 0xDC00);
    }
    
    
    sub _is_bignum {
        $_[0]->isa('Math::BigInt') or $_[0]->isa('Math::BigFloat');
    }
    
    
    
    #
    # JSON => Perl
    #
    
    my $max_intsize;
    
    BEGIN {
        my $checkint = 1111;
        for my $d (5..64) {
            $checkint .= 1;
            my $int   = eval qq| $checkint |;
            if ($int =~ /[eE]/) {
                $max_intsize = $d - 1;
                last;
            }
        }
    }
    
    { # PARSE 
    
        my %escapes = ( #  by Jeremy Muhlich <jmuhlich [at] bitflood.org>
            b    => "\x8",
            t    => "\x9",
            n    => "\xA",
            f    => "\xC",
            r    => "\xD",
            '\\' => '\\',
            '"'  => '"',
            '/'  => '/',
        );
    
        my $text; # json data
        my $at;   # offset
        my $ch;   # 1chracter
        my $len;  # text length (changed according to UTF8 or NON UTF8)
        # INTERNAL
        my $depth;          # nest counter
        my $encoding;       # json text encoding
        my $is_valid_utf8;  # temp variable
        my $utf8_len;       # utf8 byte length
        # FLAGS
        my $utf8;           # must be utf8
        my $max_depth;      # max nest nubmer of objects and arrays
        my $max_size;
        my $relaxed;
        my $cb_object;
        my $cb_sk_object;
    
        my $F_HOOK;
    
        my $allow_bigint;   # using Math::BigInt
        my $singlequote;    # loosely quoting
        my $loose;          # 
        my $allow_barekey;  # bareKey
    
        # $opt flag
        # 0x00000001 .... decode_prefix
        # 0x10000000 .... incr_parse
    
        sub PP_decode_json {
            my ($self, $opt); # $opt is an effective flag during this decode_json.
    
            ($self, $text, $opt) = @_;
    
            ($at, $ch, $depth) = (0, '', 0);
    
            if ( !defined $text or ref $text ) {
                decode_error("malformed JSON string, neither array, object, number, string or atom");
            }
    
            my $idx = $self->{PROPS};
    
            ($utf8, $relaxed, $loose, $allow_bigint, $allow_barekey, $singlequote)
                = @{$idx}[P_UTF8, P_RELAXED, P_LOOSE .. P_ALLOW_SINGLEQUOTE];
    
            if ( $utf8 ) {
                utf8::downgrade( $text, 1 ) or Carp::croak("Wide character in subroutine entry");
            }
            else {
                utf8::upgrade( $text );
                utf8::encode( $text );
            }
    
            $len = length $text;
    
            ($max_depth, $max_size, $cb_object, $cb_sk_object, $F_HOOK)
                 = @{$self}{qw/max_depth  max_size cb_object cb_sk_object F_HOOK/};
    
            if ($max_size > 1) {
                use bytes;
                my $bytes = length $text;
                decode_error(
                    sprintf("attempted decode of JSON text of %s bytes size, but max_size is set to %s"
                        , $bytes, $max_size), 1
                ) if ($bytes > $max_size);
            }
    
            # Currently no effect
            # should use regexp
            my @octets = unpack('C4', $text);
            $encoding =   ( $octets[0] and  $octets[1]) ? 'UTF-8'
                        : (!$octets[0] and  $octets[1]) ? 'UTF-16BE'
                        : (!$octets[0] and !$octets[1]) ? 'UTF-32BE'
                        : ( $octets[2]                ) ? 'UTF-16LE'
                        : (!$octets[2]                ) ? 'UTF-32LE'
                        : 'unknown';
    
            white(); # remove head white space
    
            my $valid_start = defined $ch; # Is there a first character for JSON structure?
    
            my $result = value();
    
            return undef if ( !$result && ( $opt & 0x10000000 ) ); # for incr_parse
    
            decode_error("malformed JSON string, neither array, object, number, string or atom") unless $valid_start;
    
            if ( !$idx->[ P_ALLOW_NONREF ] and !ref $result ) {
                    decode_error(
                    'JSON text must be an object or array (but found number, string, true, false or null,'
                           . ' use allow_nonref to allow this)', 1);
            }
    
            Carp::croak('something wrong.') if $len < $at; # we won't arrive here.
    
            my $consumed = defined $ch ? $at - 1 : $at; # consumed JSON text length
    
            white(); # remove tail white space
    
            if ( $ch ) {
                return ( $result, $consumed ) if ($opt & 0x00000001); # all right if decode_prefix
                decode_error("garbage after JSON object");
            }
    
            ( $opt & 0x00000001 ) ? ( $result, $consumed ) : $result;
        }
    
    
        sub next_chr {
            return $ch = undef if($at >= $len);
            $ch = substr($text, $at++, 1);
        }
    
    
        sub value {
            white();
            return          if(!defined $ch);
            return object() if($ch eq '{');
            return array()  if($ch eq '[');
            return string() if($ch eq '"' or ($singlequote and $ch eq "'"));
            return number() if($ch =~ /[0-9]/ or $ch eq '-');
            return word();
        }
    
        sub string {
            my ($i, $s, $t, $u);
            my $utf16;
            my $is_utf8;
    
            ($is_valid_utf8, $utf8_len) = ('', 0);
    
            $s = ''; # basically UTF8 flag on
    
            if($ch eq '"' or ($singlequote and $ch eq "'")){
                my $boundChar = $ch;
    
                OUTER: while( defined(next_chr()) ){
    
                    if($ch eq $boundChar){
                        next_chr();
    
                        if ($utf16) {
                            decode_error("missing low surrogate character in surrogate pair");
                        }
    
                        utf8::decode($s) if($is_utf8);
    
                        return $s;
                    }
                    elsif($ch eq '\\'){
                        next_chr();
                        if(exists $escapes{$ch}){
                            $s .= $escapes{$ch};
                        }
                        elsif($ch eq 'u'){ # UNICODE handling
                            my $u = '';
    
                            for(1..4){
                                $ch = next_chr();
                                last OUTER if($ch !~ /[0-9a-fA-F]/);
                                $u .= $ch;
                            }
    
                            # U+D800 - U+DBFF
                            if ($u =~ /^[dD][89abAB][0-9a-fA-F]{2}/) { # UTF-16 high surrogate?
                                $utf16 = $u;
                            }
                            # U+DC00 - U+DFFF
                            elsif ($u =~ /^[dD][c-fC-F][0-9a-fA-F]{2}/) { # UTF-16 low surrogate?
                                unless (defined $utf16) {
                                    decode_error("missing high surrogate character in surrogate pair");
                                }
                                $is_utf8 = 1;
                                $s .= JSON_PP_decode_surrogates($utf16, $u) || next;
                                $utf16 = undef;
                            }
                            else {
                                if (defined $utf16) {
                                    decode_error("surrogate pair expected");
                                }
    
                                if ( ( my $hex = hex( $u ) ) > 127 ) {
                                    $is_utf8 = 1;
                                    $s .= JSON_PP_decode_unicode($u) || next;
                                }
                                else {
                                    $s .= chr $hex;
                                }
                            }
    
                        }
                        else{
                            unless ($loose) {
                                $at -= 2;
                                decode_error('illegal backslash escape sequence in string');
                            }
                            $s .= $ch;
                        }
                    }
                    else{
    
                        if ( ord $ch  > 127 ) {
                            unless( $ch = is_valid_utf8($ch) ) {
                                $at -= 1;
                                decode_error("malformed UTF-8 character in JSON string");
                            }
                            else {
                                $at += $utf8_len - 1;
                            }
    
                            $is_utf8 = 1;
                        }
    
                        if (!$loose) {
                            if ($ch =~ /[\x00-\x1f\x22\x5c]/)  { # '/' ok
                                $at--;
                                decode_error('invalid character encountered while parsing JSON string');
                            }
                        }
    
                        $s .= $ch;
                    }
                }
            }
    
            decode_error("unexpected end of string while parsing JSON string");
        }
    
    
        sub white {
            while( defined $ch  ){
                if($ch le ' '){
                    next_chr();
                }
                elsif($ch eq '/'){
                    next_chr();
                    if(defined $ch and $ch eq '/'){
                        1 while(defined(next_chr()) and $ch ne "\n" and $ch ne "\r");
                    }
                    elsif(defined $ch and $ch eq '*'){
                        next_chr();
                        while(1){
                            if(defined $ch){
                                if($ch eq '*'){
                                    if(defined(next_chr()) and $ch eq '/'){
                                        next_chr();
                                        last;
                                    }
                                }
                                else{
                                    next_chr();
                                }
                            }
                            else{
                                decode_error("Unterminated comment");
                            }
                        }
                        next;
                    }
                    else{
                        $at--;
                        decode_error("malformed JSON string, neither array, object, number, string or atom");
                    }
                }
                else{
                    if ($relaxed and $ch eq '#') { # correctly?
                        pos($text) = $at;
                        $text =~ /\G([^\n]*(?:\r\n|\r|\n|$))/g;
                        $at = pos($text);
                        next_chr;
                        next;
                    }
    
                    last;
                }
            }
        }
    
    
        sub array {
            my $a  = $_[0] || []; # you can use this code to use another array ref object.
    
            decode_error('json text or perl structure exceeds maximum nesting level (max_depth set too low?)')
                                                        if (++$depth > $max_depth);
    
            next_chr();
            white();
    
            if(defined $ch and $ch eq ']'){
                --$depth;
                next_chr();
                return $a;
            }
            else {
                while(defined($ch)){
                    push @$a, value();
    
                    white();
    
                    if (!defined $ch) {
                        last;
                    }
    
                    if($ch eq ']'){
                        --$depth;
                        next_chr();
                        return $a;
                    }
    
                    if($ch ne ','){
                        last;
                    }
    
                    next_chr();
                    white();
    
                    if ($relaxed and $ch eq ']') {
                        --$depth;
                        next_chr();
                        return $a;
                    }
    
                }
            }
    
            decode_error(", or ] expected while parsing array");
        }
    
    
        sub object {
            my $o = $_[0] || {}; # you can use this code to use another hash ref object.
            my $k;
    
            decode_error('json text or perl structure exceeds maximum nesting level (max_depth set too low?)')
                                                    if (++$depth > $max_depth);
            next_chr();
            white();
    
            if(defined $ch and $ch eq '}'){
                --$depth;
                next_chr();
                if ($F_HOOK) {
                    return _json_object_hook($o);
                }
                return $o;
            }
            else {
                while (defined $ch) {
                    $k = ($allow_barekey and $ch ne '"' and $ch ne "'") ? bareKey() : string();
                    white();
    
                    if(!defined $ch or $ch ne ':'){
                        $at--;
                        decode_error("':' expected");
                    }
    
                    next_chr();
                    $o->{$k} = value();
                    white();
    
                    last if (!defined $ch);
    
                    if($ch eq '}'){
                        --$depth;
                        next_chr();
                        if ($F_HOOK) {
                            return _json_object_hook($o);
                        }
                        return $o;
                    }
    
                    if($ch ne ','){
                        last;
                    }
    
                    next_chr();
                    white();
    
                    if ($relaxed and $ch eq '}') {
                        --$depth;
                        next_chr();
                        if ($F_HOOK) {
                            return _json_object_hook($o);
                        }
                        return $o;
                    }
    
                }
    
            }
    
            $at--;
            decode_error(", or } expected while parsing object/hash");
        }
    
    
        sub bareKey { # doesn't strictly follow Standard ECMA-262 3rd Edition
            my $key;
            while($ch =~ /[^\x00-\x23\x25-\x2F\x3A-\x40\x5B-\x5E\x60\x7B-\x7F]/){
                $key .= $ch;
                next_chr();
            }
            return $key;
        }
    
    
        sub word {
            my $word =  substr($text,$at-1,4);
    
            if($word eq 'true'){
                $at += 3;
                next_chr;
                return $JSON::PP::true;
            }
            elsif($word eq 'null'){
                $at += 3;
                next_chr;
                return undef;
            }
            elsif($word eq 'fals'){
                $at += 3;
                if(substr($text,$at,1) eq 'e'){
                    $at++;
                    next_chr;
                    return $JSON::PP::false;
                }
            }
    
            $at--; # for decode_error report
    
            decode_error("'null' expected")  if ($word =~ /^n/);
            decode_error("'true' expected")  if ($word =~ /^t/);
            decode_error("'false' expected") if ($word =~ /^f/);
            decode_error("malformed JSON string, neither array, object, number, string or atom");
        }
    
    
        sub number {
            my $n    = '';
            my $v;
    
            # According to RFC4627, hex or oct digts are invalid.
            if($ch eq '0'){
                my $peek = substr($text,$at,1);
                my $hex  = $peek =~ /[xX]/; # 0 or 1
    
                if($hex){
                    decode_error("malformed number (leading zero must not be followed by another digit)");
                    ($n) = ( substr($text, $at+1) =~ /^([0-9a-fA-F]+)/);
                }
                else{ # oct
                    ($n) = ( substr($text, $at) =~ /^([0-7]+)/);
                    if (defined $n and length $n > 1) {
                        decode_error("malformed number (leading zero must not be followed by another digit)");
                    }
                }
    
                if(defined $n and length($n)){
                    if (!$hex and length($n) == 1) {
                       decode_error("malformed number (leading zero must not be followed by another digit)");
                    }
                    $at += length($n) + $hex;
                    next_chr;
                    return $hex ? hex($n) : oct($n);
                }
            }
    
            if($ch eq '-'){
                $n = '-';
                next_chr;
                if (!defined $ch or $ch !~ /\d/) {
                    decode_error("malformed number (no digits after initial minus)");
                }
            }
    
            while(defined $ch and $ch =~ /\d/){
                $n .= $ch;
                next_chr;
            }
    
            if(defined $ch and $ch eq '.'){
                $n .= '.';
    
                next_chr;
                if (!defined $ch or $ch !~ /\d/) {
                    decode_error("malformed number (no digits after decimal point)");
                }
                else {
                    $n .= $ch;
                }
    
                while(defined(next_chr) and $ch =~ /\d/){
                    $n .= $ch;
                }
            }
    
            if(defined $ch and ($ch eq 'e' or $ch eq 'E')){
                $n .= $ch;
                next_chr;
    
                if(defined($ch) and ($ch eq '+' or $ch eq '-')){
                    $n .= $ch;
                    next_chr;
                    if (!defined $ch or $ch =~ /\D/) {
                        decode_error("malformed number (no digits after exp sign)");
                    }
                    $n .= $ch;
                }
                elsif(defined($ch) and $ch =~ /\d/){
                    $n .= $ch;
                }
                else {
                    decode_error("malformed number (no digits after exp sign)");
                }
    
                while(defined(next_chr) and $ch =~ /\d/){
                    $n .= $ch;
                }
    
            }
    
            $v .= $n;
    
            if ($v !~ /[.eE]/ and length $v > $max_intsize) {
                if ($allow_bigint) { # from Adam Sussman
                    require Math::BigInt;
                    return Math::BigInt->new($v);
                }
                else {
                    return "$v";
                }
            }
            elsif ($allow_bigint) {
                require Math::BigFloat;
                return Math::BigFloat->new($v);
            }
    
            return 0+$v;
        }
    
    
        sub is_valid_utf8 {
    
            $utf8_len = $_[0] =~ /[\x00-\x7F]/  ? 1
                      : $_[0] =~ /[\xC2-\xDF]/  ? 2
                      : $_[0] =~ /[\xE0-\xEF]/  ? 3
                      : $_[0] =~ /[\xF0-\xF4]/  ? 4
                      : 0
                      ;
    
            return unless $utf8_len;
    
            my $is_valid_utf8 = substr($text, $at - 1, $utf8_len);
    
            return ( $is_valid_utf8 =~ /^(?:
                 [\x00-\x7F]
                |[\xC2-\xDF][\x80-\xBF]
                |[\xE0][\xA0-\xBF][\x80-\xBF]
                |[\xE1-\xEC][\x80-\xBF][\x80-\xBF]
                |[\xED][\x80-\x9F][\x80-\xBF]
                |[\xEE-\xEF][\x80-\xBF][\x80-\xBF]
                |[\xF0][\x90-\xBF][\x80-\xBF][\x80-\xBF]
                |[\xF1-\xF3][\x80-\xBF][\x80-\xBF][\x80-\xBF]
                |[\xF4][\x80-\x8F][\x80-\xBF][\x80-\xBF]
            )$/x )  ? $is_valid_utf8 : '';
        }
    
    
        sub decode_error {
            my $error  = shift;
            my $no_rep = shift;
            my $str    = defined $text ? substr($text, $at) : '';
            my $mess   = '';
            my $type   = $] >= 5.008           ? 'U*'
                       : $] <  5.006           ? 'C*'
                       : utf8::is_utf8( $str ) ? 'U*' # 5.6
                       : 'C*'
                       ;
    
            for my $c ( unpack( $type, $str ) ) { # emulate pv_uni_display() ?
                $mess .=  $c == 0x07 ? '\a'
                        : $c == 0x09 ? '\t'
                        : $c == 0x0a ? '\n'
                        : $c == 0x0d ? '\r'
                        : $c == 0x0c ? '\f'
                        : $c <  0x20 ? sprintf('\x{%x}', $c)
                        : $c == 0x5c ? '\\\\'
                        : $c <  0x80 ? chr($c)
                        : sprintf('\x{%x}', $c)
                        ;
                if ( length $mess >= 20 ) {
                    $mess .= '...';
                    last;
                }
            }
    
            unless ( length $mess ) {
                $mess = '(end of string)';
            }
    
            Carp::croak (
                $no_rep ? "$error" : "$error, at character offset $at (before \"$mess\")"
            );
    
        }
    
    
        sub _json_object_hook {
            my $o    = $_[0];
            my @ks = keys %{$o};
    
            if ( $cb_sk_object and @ks == 1 and exists $cb_sk_object->{ $ks[0] } and ref $cb_sk_object->{ $ks[0] } ) {
                my @val = $cb_sk_object->{ $ks[0] }->( $o->{$ks[0]} );
                if (@val == 1) {
                    return $val[0];
                }
            }
    
            my @val = $cb_object->($o) if ($cb_object);
            if (@val == 0 or @val > 1) {
                return $o;
            }
            else {
                return $val[0];
            }
        }
    
    
        sub PP_decode_box {
            {
                text    => $text,
                at      => $at,
                ch      => $ch,
                len     => $len,
                depth   => $depth,
                encoding      => $encoding,
                is_valid_utf8 => $is_valid_utf8,
            };
        }
    
    } # PARSE
    
    
    sub _decode_surrogates { # from perlunicode
        my $uni = 0x10000 + (hex($_[0]) - 0xD800) * 0x400 + (hex($_[1]) - 0xDC00);
        my $un  = pack('U*', $uni);
        utf8::encode( $un );
        return $un;
    }
    
    
    sub _decode_unicode {
        my $un = pack('U', hex shift);
        utf8::encode( $un );
        return $un;
    }
    
    #
    # Setup for various Perl versions (the code from JSON::PP58)
    #
    
    BEGIN {
    
        unless ( defined &utf8::is_utf8 ) {
           require Encode;
           *utf8::is_utf8 = *Encode::is_utf8;
        }
    
        if ( $] >= 5.008 ) {
            *JSON::PP::JSON_PP_encode_ascii      = \&_encode_ascii;
            *JSON::PP::JSON_PP_encode_latin1     = \&_encode_latin1;
            *JSON::PP::JSON_PP_decode_surrogates = \&_decode_surrogates;
            *JSON::PP::JSON_PP_decode_unicode    = \&_decode_unicode;
        }
    
        if ($] >= 5.008 and $] < 5.008003) { # join() in 5.8.0 - 5.8.2 is broken.
            package JSON::PP;
            require subs;
            subs->import('join');
            eval q|
                sub join {
                    return '' if (@_ < 2);
                    my $j   = shift;
                    my $str = shift;
                    for (@_) { $str .= $j . $_; }
                    return $str;
                }
            |;
        }
    
    
        sub JSON::PP::incr_parse {
            local $Carp::CarpLevel = 1;
            ( $_[0]->{_incr_parser} ||= JSON::PP::IncrParser->new )->incr_parse( @_ );
        }
    
    
        sub JSON::PP::incr_skip {
            ( $_[0]->{_incr_parser} ||= JSON::PP::IncrParser->new )->incr_skip;
        }
    
    
        sub JSON::PP::incr_reset {
            ( $_[0]->{_incr_parser} ||= JSON::PP::IncrParser->new )->incr_reset;
        }
    
        eval q{
            sub JSON::PP::incr_text : lvalue {
                $_[0]->{_incr_parser} ||= JSON::PP::IncrParser->new;
    
                if ( $_[0]->{_incr_parser}->{incr_parsing} ) {
                    Carp::croak("incr_text can not be called when the incremental parser already started parsing");
                }
                $_[0]->{_incr_parser}->{incr_text};
            }
        } if ( $] >= 5.006 );
    
    } # Setup for various Perl versions (the code from JSON::PP58)
    
    
    ###############################
    # Utilities
    #
    
    BEGIN {
        eval 'require Scalar::Util';
        unless($@){
            *JSON::PP::blessed = \&Scalar::Util::blessed;
            *JSON::PP::reftype = \&Scalar::Util::reftype;
            *JSON::PP::refaddr = \&Scalar::Util::refaddr;
        }
        else{ # This code is from Sclar::Util.
            # warn $@;
            eval 'sub UNIVERSAL::a_sub_not_likely_to_be_here { ref($_[0]) }';
            *JSON::PP::blessed = sub {
                local($@, $SIG{__DIE__}, $SIG{__WARN__});
                ref($_[0]) ? eval { $_[0]->a_sub_not_likely_to_be_here } : undef;
            };
            my %tmap = qw(
                B::NULL   SCALAR
                B::HV     HASH
                B::AV     ARRAY
                B::CV     CODE
                B::IO     IO
                B::GV     GLOB
                B::REGEXP REGEXP
            );
            *JSON::PP::reftype = sub {
                my $r = shift;
    
                return undef unless length(ref($r));
    
                my $t = ref(B::svref_2object($r));
    
                return
                    exists $tmap{$t} ? $tmap{$t}
                  : length(ref($$r)) ? 'REF'
                  :                    'SCALAR';
            };
            *JSON::PP::refaddr = sub {
              return undef unless length(ref($_[0]));
    
              my $addr;
              if(defined(my $pkg = blessed($_[0]))) {
                $addr .= bless $_[0], 'Scalar::Util::Fake';
                bless $_[0], $pkg;
              }
              else {
                $addr .= $_[0]
              }
    
              $addr =~ /0x(\w+)/;
              local $^W;
              #no warnings 'portable';
              hex($1);
            }
        }
    }
    
    
    # shamely copied and modified from JSON::XS code.
    
    $JSON::PP::true  = do { bless \(my $dummy = 1), "JSON::PP::Boolean" };
    $JSON::PP::false = do { bless \(my $dummy = 0), "JSON::PP::Boolean" };
    
    sub is_bool { defined $_[0] and UNIVERSAL::isa($_[0], "JSON::PP::Boolean"); }
    
    sub true  { $JSON::PP::true  }
    sub false { $JSON::PP::false }
    sub null  { undef; }
    
    ###############################
    
    package JSON::PP::Boolean;
    
    use overload (
       "0+"     => sub { ${$_[0]} },
       "++"     => sub { $_[0] = ${$_[0]} + 1 },
       "--"     => sub { $_[0] = ${$_[0]} - 1 },
       fallback => 1,
    );
    
    
    ###############################
    
    package JSON::PP::IncrParser;
    
    use strict;
    
    use constant INCR_M_WS   => 0; # initial whitespace skipping
    use constant INCR_M_STR  => 1; # inside string
    use constant INCR_M_BS   => 2; # inside backslash
    use constant INCR_M_JSON => 3; # outside anything, count nesting
    use constant INCR_M_C0   => 4;
    use constant INCR_M_C1   => 5;
    
    $JSON::PP::IncrParser::VERSION = '1.01';
    
    my $unpack_format = $] < 5.006 ? 'C*' : 'U*';
    
    sub new {
        my ( $class ) = @_;
    
        bless {
            incr_nest    => 0,
            incr_text    => undef,
            incr_parsing => 0,
            incr_p       => 0,
        }, $class;
    }
    
    
    sub incr_parse {
        my ( $self, $coder, $text ) = @_;
    
        $self->{incr_text} = '' unless ( defined $self->{incr_text} );
    
        if ( defined $text ) {
            if ( utf8::is_utf8( $text ) and !utf8::is_utf8( $self->{incr_text} ) ) {
                utf8::upgrade( $self->{incr_text} ) ;
                utf8::decode( $self->{incr_text} ) ;
            }
            $self->{incr_text} .= $text;
        }
    
    
        my $max_size = $coder->get_max_size;
    
        if ( defined wantarray ) {
    
            $self->{incr_mode} = INCR_M_WS unless defined $self->{incr_mode};
    
            if ( wantarray ) {
                my @ret;
    
                $self->{incr_parsing} = 1;
    
                do {
                    push @ret, $self->_incr_parse( $coder, $self->{incr_text} );
    
                    unless ( !$self->{incr_nest} and $self->{incr_mode} == INCR_M_JSON ) {
                        $self->{incr_mode} = INCR_M_WS if $self->{incr_mode} != INCR_M_STR;
                    }
    
                } until ( length $self->{incr_text} >= $self->{incr_p} );
    
                $self->{incr_parsing} = 0;
    
                return @ret;
            }
            else { # in scalar context
                $self->{incr_parsing} = 1;
                my $obj = $self->_incr_parse( $coder, $self->{incr_text} );
                $self->{incr_parsing} = 0 if defined $obj; # pointed by Martin J. Evans
                return $obj ? $obj : undef; # $obj is an empty string, parsing was completed.
            }
    
        }
    
    }
    
    
    sub _incr_parse {
        my ( $self, $coder, $text, $skip ) = @_;
        my $p = $self->{incr_p};
        my $restore = $p;
    
        my @obj;
        my $len = length $text;
    
        if ( $self->{incr_mode} == INCR_M_WS ) {
            while ( $len > $p ) {
                my $s = substr( $text, $p, 1 );
                $p++ and next if ( 0x20 >= unpack($unpack_format, $s) );
                $self->{incr_mode} = INCR_M_JSON;
                last;
           }
        }
    
        while ( $len > $p ) {
            my $s = substr( $text, $p++, 1 );
    
            if ( $s eq '"' ) {
                if (substr( $text, $p - 2, 1 ) eq '\\' ) {
                    next;
                }
    
                if ( $self->{incr_mode} != INCR_M_STR  ) {
                    $self->{incr_mode} = INCR_M_STR;
                }
                else {
                    $self->{incr_mode} = INCR_M_JSON;
                    unless ( $self->{incr_nest} ) {
                        last;
                    }
                }
            }
    
            if ( $self->{incr_mode} == INCR_M_JSON ) {
    
                if ( $s eq '[' or $s eq '{' ) {
                    if ( ++$self->{incr_nest} > $coder->get_max_depth ) {
                        Carp::croak('json text or perl structure exceeds maximum nesting level (max_depth set too low?)');
                    }
                }
                elsif ( $s eq ']' or $s eq '}' ) {
                    last if ( --$self->{incr_nest} <= 0 );
                }
                elsif ( $s eq '#' ) {
                    while ( $len > $p ) {
                        last if substr( $text, $p++, 1 ) eq "\n";
                    }
                }
    
            }
    
        }
    
        $self->{incr_p} = $p;
    
        return if ( $self->{incr_mode} == INCR_M_STR and not $self->{incr_nest} );
        return if ( $self->{incr_mode} == INCR_M_JSON and $self->{incr_nest} > 0 );
    
        return '' unless ( length substr( $self->{incr_text}, 0, $p ) );
    
        local $Carp::CarpLevel = 2;
    
        $self->{incr_p} = $restore;
        $self->{incr_c} = $p;
    
        my ( $obj, $tail ) = $coder->PP_decode_json( substr( $self->{incr_text}, 0, $p ), 0x10000001 );
    
        $self->{incr_text} = substr( $self->{incr_text}, $p );
        $self->{incr_p} = 0;
    
        return $obj || '';
    }
    
    
    sub incr_text {
        if ( $_[0]->{incr_parsing} ) {
            Carp::croak("incr_text can not be called when the incremental parser already started parsing");
        }
        $_[0]->{incr_text};
    }
    
    
    sub incr_skip {
        my $self  = shift;
        $self->{incr_text} = substr( $self->{incr_text}, $self->{incr_c} );
        $self->{incr_p} = 0;
    }
    
    
    sub incr_reset {
        my $self = shift;
        $self->{incr_text}    = undef;
        $self->{incr_p}       = 0;
        $self->{incr_mode}    = 0;
        $self->{incr_nest}    = 0;
        $self->{incr_parsing} = 0;
    }
    
    ###############################
    
    
    1;
    __END__
    =pod
    
    =head1 NAME
    
    JSON::PP - JSON::XS compatible pure-Perl module.
    
    =head1 SYNOPSIS
    
     use JSON::PP;
    
     # exported functions, they croak on error
     # and expect/generate UTF-8
    
     $utf8_encoded_json_text = encode_json $perl_hash_or_arrayref;
     $perl_hash_or_arrayref  = decode_json $utf8_encoded_json_text;
    
     # OO-interface
    
     $coder = JSON::PP->new->ascii->pretty->allow_nonref;
     
     $json_text   = $json->encode( $perl_scalar );
     $perl_scalar = $json->decode( $json_text );
     
     $pretty_printed = $json->pretty->encode( $perl_scalar ); # pretty-printing
     
     # Note that JSON version 2.0 and above will automatically use
     # JSON::XS or JSON::PP, so you should be able to just:
     
     use JSON;
    
    
    =head1 VERSION
    
        2.27300
    
    L<JSON::XS> 2.27 (~2.30) compatible.
    
    =head1 NOTE
    
    JSON::PP had been inculded in JSON distribution (CPAN module).
    It was a perl core module in Perl 5.14.
    
    =head1 DESCRIPTION
    
    This module is L<JSON::XS> compatible pure Perl module.
    (Perl 5.8 or later is recommended)
    
    JSON::XS is the fastest and most proper JSON module on CPAN.
    It is written by Marc Lehmann in C, so must be compiled and
    installed in the used environment.
    
    JSON::PP is a pure-Perl module and has compatibility to JSON::XS.
    
    
    =head2 FEATURES
    
    =over
    
    =item * correct unicode handling
    
    This module knows how to handle Unicode (depending on Perl version).
    
    See to L<JSON::XS/A FEW NOTES ON UNICODE AND PERL> and L<UNICODE HANDLING ON PERLS>.
    
    
    =item * round-trip integrity
    
    When you serialise a perl data structure using only data types supported
    by JSON and Perl, the deserialised data structure is identical on the Perl
    level. (e.g. the string "2.0" doesn't suddenly become "2" just because
    it looks like a number). There I<are> minor exceptions to this, read the
    MAPPING section below to learn about those.
    
    
    =item * strict checking of JSON correctness
    
    There is no guessing, no generating of illegal JSON texts by default,
    and only JSON is accepted as input by default (the latter is a security feature).
    But when some options are set, loose chcking features are available.
    
    =back
    
    =head1 FUNCTIONAL INTERFACE
    
    Some documents are copied and modified from L<JSON::XS/FUNCTIONAL INTERFACE>.
    
    =head2 encode_json
    
        $json_text = encode_json $perl_scalar
    
    Converts the given Perl data structure to a UTF-8 encoded, binary string.
    
    This function call is functionally identical to:
    
        $json_text = JSON::PP->new->utf8->encode($perl_scalar)
    
    =head2 decode_json
    
        $perl_scalar = decode_json $json_text
    
    The opposite of C<encode_json>: expects an UTF-8 (binary) string and tries
    to parse that as an UTF-8 encoded JSON text, returning the resulting
    reference.
    
    This function call is functionally identical to:
    
        $perl_scalar = JSON::PP->new->utf8->decode($json_text)
    
    =head2 JSON::PP::is_bool
    
        $is_boolean = JSON::PP::is_bool($scalar)
    
    Returns true if the passed scalar represents either JSON::PP::true or
    JSON::PP::false, two constants that act like C<1> and C<0> respectively
    and are also used to represent JSON C<true> and C<false> in Perl strings.
    
    =head2 JSON::PP::true
    
    Returns JSON true value which is blessed object.
    It C<isa> JSON::PP::Boolean object.
    
    =head2 JSON::PP::false
    
    Returns JSON false value which is blessed object.
    It C<isa> JSON::PP::Boolean object.
    
    =head2 JSON::PP::null
    
    Returns C<undef>.
    
    See L<MAPPING>, below, for more information on how JSON values are mapped to
    Perl.
    
    
    =head1 HOW DO I DECODE A DATA FROM OUTER AND ENCODE TO OUTER
    
    This section supposes that your perl vresion is 5.8 or later.
    
    If you know a JSON text from an outer world - a network, a file content, and so on,
    is encoded in UTF-8, you should use C<decode_json> or C<JSON> module object
    with C<utf8> enable. And the decoded result will contain UNICODE characters.
    
      # from network
      my $json        = JSON::PP->new->utf8;
      my $json_text   = CGI->new->param( 'json_data' );
      my $perl_scalar = $json->decode( $json_text );
      
      # from file content
      local $/;
      open( my $fh, '<', 'json.data' );
      $json_text   = <$fh>;
      $perl_scalar = decode_json( $json_text );
    
    If an outer data is not encoded in UTF-8, firstly you should C<decode> it.
    
      use Encode;
      local $/;
      open( my $fh, '<', 'json.data' );
      my $encoding = 'cp932';
      my $unicode_json_text = decode( $encoding, <$fh> ); # UNICODE
      
      # or you can write the below code.
      #
      # open( my $fh, "<:encoding($encoding)", 'json.data' );
      # $unicode_json_text = <$fh>;
    
    In this case, C<$unicode_json_text> is of course UNICODE string.
    So you B<cannot> use C<decode_json> nor C<JSON> module object with C<utf8> enable.
    Instead of them, you use C<JSON> module object with C<utf8> disable.
    
      $perl_scalar = $json->utf8(0)->decode( $unicode_json_text );
    
    Or C<encode 'utf8'> and C<decode_json>:
    
      $perl_scalar = decode_json( encode( 'utf8', $unicode_json_text ) );
      # this way is not efficient.
    
    And now, you want to convert your C<$perl_scalar> into JSON data and
    send it to an outer world - a network or a file content, and so on.
    
    Your data usually contains UNICODE strings and you want the converted data to be encoded
    in UTF-8, you should use C<encode_json> or C<JSON> module object with C<utf8> enable.
    
      print encode_json( $perl_scalar ); # to a network? file? or display?
      # or
      print $json->utf8->encode( $perl_scalar );
    
    If C<$perl_scalar> does not contain UNICODE but C<$encoding>-encoded strings
    for some reason, then its characters are regarded as B<latin1> for perl
    (because it does not concern with your $encoding).
    You B<cannot> use C<encode_json> nor C<JSON> module object with C<utf8> enable.
    Instead of them, you use C<JSON> module object with C<utf8> disable.
    Note that the resulted text is a UNICODE string but no problem to print it.
    
      # $perl_scalar contains $encoding encoded string values
      $unicode_json_text = $json->utf8(0)->encode( $perl_scalar );
      # $unicode_json_text consists of characters less than 0x100
      print $unicode_json_text;
    
    Or C<decode $encoding> all string values and C<encode_json>:
    
      $perl_scalar->{ foo } = decode( $encoding, $perl_scalar->{ foo } );
      # ... do it to each string values, then encode_json
      $json_text = encode_json( $perl_scalar );
    
    This method is a proper way but probably not efficient.
    
    See to L<Encode>, L<perluniintro>.
    
    
    =head1 METHODS
    
    Basically, check to L<JSON> or L<JSON::XS>.
    
    =head2 new
    
        $json = JSON::PP->new
    
    Rturns a new JSON::PP object that can be used to de/encode JSON
    strings.
    
    All boolean flags described below are by default I<disabled>.
    
    The mutators for flags all return the JSON object again and thus calls can
    be chained:
    
       my $json = JSON::PP->new->utf8->space_after->encode({a => [1,2]})
       => {"a": [1, 2]}
    
    =head2 ascii
    
        $json = $json->ascii([$enable])
        
        $enabled = $json->get_ascii
    
    If $enable is true (or missing), then the encode method will not generate characters outside
    the code range 0..127. Any Unicode characters outside that range will be escaped using either
    a single \uXXXX or a double \uHHHH\uLLLLL escape sequence, as per RFC4627.
    (See to L<JSON::XS/OBJECT-ORIENTED INTERFACE>).
    
    In Perl 5.005, there is no character having high value (more than 255).
    See to L<UNICODE HANDLING ON PERLS>.
    
    If $enable is false, then the encode method will not escape Unicode characters unless
    required by the JSON syntax or other flags. This results in a faster and more compact format.
    
      JSON::PP->new->ascii(1)->encode([chr 0x10401])
      => ["\ud801\udc01"]
    
    =head2 latin1
    
        $json = $json->latin1([$enable])
        
        $enabled = $json->get_latin1
    
    If $enable is true (or missing), then the encode method will encode the resulting JSON
    text as latin1 (or iso-8859-1), escaping any characters outside the code range 0..255.
    
    If $enable is false, then the encode method will not escape Unicode characters
    unless required by the JSON syntax or other flags.
    
      JSON::XS->new->latin1->encode (["\x{89}\x{abc}"]
      => ["\x{89}\\u0abc"]    # (perl syntax, U+abc escaped, U+89 not)
    
    See to L<UNICODE HANDLING ON PERLS>.
    
    =head2 utf8
    
        $json = $json->utf8([$enable])
        
        $enabled = $json->get_utf8
    
    If $enable is true (or missing), then the encode method will encode the JSON result
    into UTF-8, as required by many protocols, while the decode method expects to be handled
    an UTF-8-encoded string. Please note that UTF-8-encoded strings do not contain any
    characters outside the range 0..255, they are thus useful for bytewise/binary I/O.
    
    (In Perl 5.005, any character outside the range 0..255 does not exist.
    See to L<UNICODE HANDLING ON PERLS>.)
    
    In future versions, enabling this option might enable autodetection of the UTF-16 and UTF-32
    encoding families, as described in RFC4627.
    
    If $enable is false, then the encode method will return the JSON string as a (non-encoded)
    Unicode string, while decode expects thus a Unicode string. Any decoding or encoding
    (e.g. to UTF-8 or UTF-16) needs to be done yourself, e.g. using the Encode module.
    
    Example, output UTF-16BE-encoded JSON:
    
      use Encode;
      $jsontext = encode "UTF-16BE", JSON::PP->new->encode ($object);
    
    Example, decode UTF-32LE-encoded JSON:
    
      use Encode;
      $object = JSON::PP->new->decode (decode "UTF-32LE", $jsontext);
    
    
    =head2 pretty
    
        $json = $json->pretty([$enable])
    
    This enables (or disables) all of the C<indent>, C<space_before> and
    C<space_after> flags in one call to generate the most readable
    (or most compact) form possible.
    
    Equivalent to:
    
       $json->indent->space_before->space_after
    
    =head2 indent
    
        $json = $json->indent([$enable])
        
        $enabled = $json->get_indent
    
    The default indent space length is three.
    You can use C<indent_length> to change the length.
    
    =head2 space_before
    
        $json = $json->space_before([$enable])
        
        $enabled = $json->get_space_before
    
    If C<$enable> is true (or missing), then the C<encode> method will add an extra
    optional space before the C<:> separating keys from values in JSON objects.
    
    If C<$enable> is false, then the C<encode> method will not add any extra
    space at those places.
    
    This setting has no effect when decoding JSON texts.
    
    Example, space_before enabled, space_after and indent disabled:
    
       {"key" :"value"}
    
    =head2 space_after
    
        $json = $json->space_after([$enable])
        
        $enabled = $json->get_space_after
    
    If C<$enable> is true (or missing), then the C<encode> method will add an extra
    optional space after the C<:> separating keys from values in JSON objects
    and extra whitespace after the C<,> separating key-value pairs and array
    members.
    
    If C<$enable> is false, then the C<encode> method will not add any extra
    space at those places.
    
    This setting has no effect when decoding JSON texts.
    
    Example, space_before and indent disabled, space_after enabled:
    
       {"key": "value"}
    
    =head2 relaxed
    
        $json = $json->relaxed([$enable])
        
        $enabled = $json->get_relaxed
    
    If C<$enable> is true (or missing), then C<decode> will accept some
    extensions to normal JSON syntax (see below). C<encode> will not be
    affected in anyway. I<Be aware that this option makes you accept invalid
    JSON texts as if they were valid!>. I suggest only to use this option to
    parse application-specific files written by humans (configuration files,
    resource files etc.)
    
    If C<$enable> is false (the default), then C<decode> will only accept
    valid JSON texts.
    
    Currently accepted extensions are:
    
    =over 4
    
    =item * list items can have an end-comma
    
    JSON I<separates> array elements and key-value pairs with commas. This
    can be annoying if you write JSON texts manually and want to be able to
    quickly append elements, so this extension accepts comma at the end of
    such items not just between them:
    
       [
          1,
          2, <- this comma not normally allowed
       ]
       {
          "k1": "v1",
          "k2": "v2", <- this comma not normally allowed
       }
    
    =item * shell-style '#'-comments
    
    Whenever JSON allows whitespace, shell-style comments are additionally
    allowed. They are terminated by the first carriage-return or line-feed
    character, after which more white-space and comments are allowed.
    
      [
         1, # this comment not allowed in JSON
            # neither this one...
      ]
    
    =back
    
    =head2 canonical
    
        $json = $json->canonical([$enable])
        
        $enabled = $json->get_canonical
    
    If C<$enable> is true (or missing), then the C<encode> method will output JSON objects
    by sorting their keys. This is adding a comparatively high overhead.
    
    If C<$enable> is false, then the C<encode> method will output key-value
    pairs in the order Perl stores them (which will likely change between runs
    of the same script).
    
    This option is useful if you want the same data structure to be encoded as
    the same JSON text (given the same overall settings). If it is disabled,
    the same hash might be encoded differently even if contains the same data,
    as key-value pairs have no inherent ordering in Perl.
    
    This setting has no effect when decoding JSON texts.
    
    If you want your own sorting routine, you can give a code referece
    or a subroutine name to C<sort_by>. See to C<JSON::PP OWN METHODS>.
    
    =head2 allow_nonref
    
        $json = $json->allow_nonref([$enable])
        
        $enabled = $json->get_allow_nonref
    
    If C<$enable> is true (or missing), then the C<encode> method can convert a
    non-reference into its corresponding string, number or null JSON value,
    which is an extension to RFC4627. Likewise, C<decode> will accept those JSON
    values instead of croaking.
    
    If C<$enable> is false, then the C<encode> method will croak if it isn't
    passed an arrayref or hashref, as JSON texts must either be an object
    or array. Likewise, C<decode> will croak if given something that is not a
    JSON object or array.
    
       JSON::PP->new->allow_nonref->encode ("Hello, World!")
       => "Hello, World!"
    
    =head2 allow_unknown
    
        $json = $json->allow_unknown ([$enable])
        
        $enabled = $json->get_allow_unknown
    
    If $enable is true (or missing), then "encode" will *not* throw an
    exception when it encounters values it cannot represent in JSON (for
    example, filehandles) but instead will encode a JSON "null" value.
    Note that blessed objects are not included here and are handled
    separately by c<allow_nonref>.
    
    If $enable is false (the default), then "encode" will throw an
    exception when it encounters anything it cannot encode as JSON.
    
    This option does not affect "decode" in any way, and it is
    recommended to leave it off unless you know your communications
    partner.
    
    =head2 allow_blessed
    
        $json = $json->allow_blessed([$enable])
        
        $enabled = $json->get_allow_blessed
    
    If C<$enable> is true (or missing), then the C<encode> method will not
    barf when it encounters a blessed reference. Instead, the value of the
    B<convert_blessed> option will decide whether C<null> (C<convert_blessed>
    disabled or no C<TO_JSON> method found) or a representation of the
    object (C<convert_blessed> enabled and C<TO_JSON> method found) is being
    encoded. Has no effect on C<decode>.
    
    If C<$enable> is false (the default), then C<encode> will throw an
    exception when it encounters a blessed object.
    
    =head2 convert_blessed
    
        $json = $json->convert_blessed([$enable])
        
        $enabled = $json->get_convert_blessed
    
    If C<$enable> is true (or missing), then C<encode>, upon encountering a
    blessed object, will check for the availability of the C<TO_JSON> method
    on the object's class. If found, it will be called in scalar context
    and the resulting scalar will be encoded instead of the object. If no
    C<TO_JSON> method is found, the value of C<allow_blessed> will decide what
    to do.
    
    The C<TO_JSON> method may safely call die if it wants. If C<TO_JSON>
    returns other blessed objects, those will be handled in the same
    way. C<TO_JSON> must take care of not causing an endless recursion cycle
    (== crash) in this case. The name of C<TO_JSON> was chosen because other
    methods called by the Perl core (== not by the user of the object) are
    usually in upper case letters and to avoid collisions with the C<to_json>
    function or method.
    
    This setting does not yet influence C<decode> in any way.
    
    If C<$enable> is false, then the C<allow_blessed> setting will decide what
    to do when a blessed object is found.
    
    =head2 filter_json_object
    
        $json = $json->filter_json_object([$coderef])
    
    When C<$coderef> is specified, it will be called from C<decode> each
    time it decodes a JSON object. The only argument passed to the coderef
    is a reference to the newly-created hash. If the code references returns
    a single scalar (which need not be a reference), this value
    (i.e. a copy of that scalar to avoid aliasing) is inserted into the
    deserialised data structure. If it returns an empty list
    (NOTE: I<not> C<undef>, which is a valid scalar), the original deserialised
    hash will be inserted. This setting can slow down decoding considerably.
    
    When C<$coderef> is omitted or undefined, any existing callback will
    be removed and C<decode> will not change the deserialised hash in any
    way.
    
    Example, convert all JSON objects into the integer 5:
    
       my $js = JSON::PP->new->filter_json_object (sub { 5 });
       # returns [5]
       $js->decode ('[{}]'); # the given subroutine takes a hash reference.
       # throw an exception because allow_nonref is not enabled
       # so a lone 5 is not allowed.
       $js->decode ('{"a":1, "b":2}');
    
    =head2 filter_json_single_key_object
    
        $json = $json->filter_json_single_key_object($key [=> $coderef])
    
    Works remotely similar to C<filter_json_object>, but is only called for
    JSON objects having a single key named C<$key>.
    
    This C<$coderef> is called before the one specified via
    C<filter_json_object>, if any. It gets passed the single value in the JSON
    object. If it returns a single value, it will be inserted into the data
    structure. If it returns nothing (not even C<undef> but the empty list),
    the callback from C<filter_json_object> will be called next, as if no
    single-key callback were specified.
    
    If C<$coderef> is omitted or undefined, the corresponding callback will be
    disabled. There can only ever be one callback for a given key.
    
    As this callback gets called less often then the C<filter_json_object>
    one, decoding speed will not usually suffer as much. Therefore, single-key
    objects make excellent targets to serialise Perl objects into, especially
    as single-key JSON objects are as close to the type-tagged value concept
    as JSON gets (it's basically an ID/VALUE tuple). Of course, JSON does not
    support this in any way, so you need to make sure your data never looks
    like a serialised Perl hash.
    
    Typical names for the single object key are C<__class_whatever__>, or
    C<$__dollars_are_rarely_used__$> or C<}ugly_brace_placement>, or even
    things like C<__class_md5sum(classname)__>, to reduce the risk of clashing
    with real hashes.
    
    Example, decode JSON objects of the form C<< { "__widget__" => <id> } >>
    into the corresponding C<< $WIDGET{<id>} >> object:
    
       # return whatever is in $WIDGET{5}:
       JSON::PP
          ->new
          ->filter_json_single_key_object (__widget__ => sub {
                $WIDGET{ $_[0] }
             })
          ->decode ('{"__widget__": 5')
    
       # this can be used with a TO_JSON method in some "widget" class
       # for serialisation to json:
       sub WidgetBase::TO_JSON {
          my ($self) = @_;
    
          unless ($self->{id}) {
             $self->{id} = ..get..some..id..;
             $WIDGET{$self->{id}} = $self;
          }
    
          { __widget__ => $self->{id} }
       }
    
    =head2 shrink
    
        $json = $json->shrink([$enable])
        
        $enabled = $json->get_shrink
    
    In JSON::XS, this flag resizes strings generated by either
    C<encode> or C<decode> to their minimum size possible.
    It will also try to downgrade any strings to octet-form if possible.
    
    In JSON::PP, it is noop about resizing strings but tries
    C<utf8::downgrade> to the returned string by C<encode>.
    See to L<utf8>.
    
    See to L<JSON::XS/OBJECT-ORIENTED INTERFACE>
    
    =head2 max_depth
    
        $json = $json->max_depth([$maximum_nesting_depth])
        
        $max_depth = $json->get_max_depth
    
    Sets the maximum nesting level (default C<512>) accepted while encoding
    or decoding. If a higher nesting level is detected in JSON text or a Perl
    data structure, then the encoder and decoder will stop and croak at that
    point.
    
    Nesting level is defined by number of hash- or arrayrefs that the encoder
    needs to traverse to reach a given point or the number of C<{> or C<[>
    characters without their matching closing parenthesis crossed to reach a
    given character in a string.
    
    If no argument is given, the highest possible setting will be used, which
    is rarely useful.
    
    See L<JSON::XS/SSECURITY CONSIDERATIONS> for more info on why this is useful.
    
    When a large value (100 or more) was set and it de/encodes a deep nested object/text,
    it may raise a warning 'Deep recursion on subroutin' at the perl runtime phase.
    
    =head2 max_size
    
        $json = $json->max_size([$maximum_string_size])
        
        $max_size = $json->get_max_size
    
    Set the maximum length a JSON text may have (in bytes) where decoding is
    being attempted. The default is C<0>, meaning no limit. When C<decode>
    is called on a string that is longer then this many bytes, it will not
    attempt to decode the string but throw an exception. This setting has no
    effect on C<encode> (yet).
    
    If no argument is given, the limit check will be deactivated (same as when
    C<0> is specified).
    
    See L<JSON::XS/SSECURITY CONSIDERATIONS> for more info on why this is useful.
    
    =head2 encode
    
        $json_text = $json->encode($perl_scalar)
    
    Converts the given Perl data structure (a simple scalar or a reference
    to a hash or array) to its JSON representation. Simple scalars will be
    converted into JSON string or number sequences, while references to arrays
    become JSON arrays and references to hashes become JSON objects. Undefined
    Perl values (e.g. C<undef>) become JSON C<null> values.
    References to the integers C<0> and C<1> are converted into C<true> and C<false>.
    
    =head2 decode
    
        $perl_scalar = $json->decode($json_text)
    
    The opposite of C<encode>: expects a JSON text and tries to parse it,
    returning the resulting simple scalar or reference. Croaks on error.
    
    JSON numbers and strings become simple Perl scalars. JSON arrays become
    Perl arrayrefs and JSON objects become Perl hashrefs. C<true> becomes
    C<1> (C<JSON::true>), C<false> becomes C<0> (C<JSON::false>) and
    C<null> becomes C<undef>.
    
    =head2 decode_prefix
    
        ($perl_scalar, $characters) = $json->decode_prefix($json_text)
    
    This works like the C<decode> method, but instead of raising an exception
    when there is trailing garbage after the first JSON object, it will
    silently stop parsing there and return the number of characters consumed
    so far.
    
       JSON->new->decode_prefix ("[1] the tail")
       => ([], 3)
    
    =head1 INCREMENTAL PARSING
    
    Most of this section are copied and modified from L<JSON::XS/INCREMENTAL PARSING>.
    
    In some cases, there is the need for incremental parsing of JSON texts.
    This module does allow you to parse a JSON stream incrementally.
    It does so by accumulating text until it has a full JSON object, which
    it then can decode. This process is similar to using C<decode_prefix>
    to see if a full JSON object is available, but is much more efficient
    (and can be implemented with a minimum of method calls).
    
    This module will only attempt to parse the JSON text once it is sure it
    has enough text to get a decisive result, using a very simple but
    truly incremental parser. This means that it sometimes won't stop as
    early as the full parser, for example, it doesn't detect parenthese
    mismatches. The only thing it guarantees is that it starts decoding as
    soon as a syntactically valid JSON text has been seen. This means you need
    to set resource limits (e.g. C<max_size>) to ensure the parser will stop
    parsing in the presence if syntax errors.
    
    The following methods implement this incremental parser.
    
    =head2 incr_parse
    
        $json->incr_parse( [$string] ) # void context
        
        $obj_or_undef = $json->incr_parse( [$string] ) # scalar context
        
        @obj_or_empty = $json->incr_parse( [$string] ) # list context
    
    This is the central parsing function. It can both append new text and
    extract objects from the stream accumulated so far (both of these
    functions are optional).
    
    If C<$string> is given, then this string is appended to the already
    existing JSON fragment stored in the C<$json> object.
    
    After that, if the function is called in void context, it will simply
    return without doing anything further. This can be used to add more text
    in as many chunks as you want.
    
    If the method is called in scalar context, then it will try to extract
    exactly I<one> JSON object. If that is successful, it will return this
    object, otherwise it will return C<undef>. If there is a parse error,
    this method will croak just as C<decode> would do (one can then use
    C<incr_skip> to skip the errornous part). This is the most common way of
    using the method.
    
    And finally, in list context, it will try to extract as many objects
    from the stream as it can find and return them, or the empty list
    otherwise. For this to work, there must be no separators between the JSON
    objects or arrays, instead they must be concatenated back-to-back. If
    an error occurs, an exception will be raised as in the scalar context
    case. Note that in this case, any previously-parsed JSON texts will be
    lost.
    
    Example: Parse some JSON arrays/objects in a given string and return them.
    
        my @objs = JSON->new->incr_parse ("[5][7][1,2]");
    
    =head2 incr_text
    
        $lvalue_string = $json->incr_text
    
    This method returns the currently stored JSON fragment as an lvalue, that
    is, you can manipulate it. This I<only> works when a preceding call to
    C<incr_parse> in I<scalar context> successfully returned an object. Under
    all other circumstances you must not call this function (I mean it.
    although in simple tests it might actually work, it I<will> fail under
    real world conditions). As a special exception, you can also call this
    method before having parsed anything.
    
    This function is useful in two cases: a) finding the trailing text after a
    JSON object or b) parsing multiple JSON objects separated by non-JSON text
    (such as commas).
    
        $json->incr_text =~ s/\s*,\s*//;
    
    In Perl 5.005, C<lvalue> attribute is not available.
    You must write codes like the below:
    
        $string = $json->incr_text;
        $string =~ s/\s*,\s*//;
        $json->incr_text( $string );
    
    =head2 incr_skip
    
        $json->incr_skip
    
    This will reset the state of the incremental parser and will remove the
    parsed text from the input buffer. This is useful after C<incr_parse>
    died, in which case the input buffer and incremental parser state is left
    unchanged, to skip the text parsed so far and to reset the parse state.
    
    =head2 incr_reset
    
        $json->incr_reset
    
    This completely resets the incremental parser, that is, after this call,
    it will be as if the parser had never parsed anything.
    
    This is useful if you want ot repeatedly parse JSON objects and want to
    ignore any trailing data, which means you have to reset the parser after
    each successful decode.
    
    See to L<JSON::XS/INCREMENTAL PARSING> for examples.
    
    
    =head1 JSON::PP OWN METHODS
    
    =head2 allow_singlequote
    
        $json = $json->allow_singlequote([$enable])
    
    If C<$enable> is true (or missing), then C<decode> will accept
    JSON strings quoted by single quotations that are invalid JSON
    format.
    
        $json->allow_singlequote->decode({"foo":'bar'});
        $json->allow_singlequote->decode({'foo':"bar"});
        $json->allow_singlequote->decode({'foo':'bar'});
    
    As same as the C<relaxed> option, this option may be used to parse
    application-specific files written by humans.
    
    
    =head2 allow_barekey
    
        $json = $json->allow_barekey([$enable])
    
    If C<$enable> is true (or missing), then C<decode> will accept
    bare keys of JSON object that are invalid JSON format.
    
    As same as the C<relaxed> option, this option may be used to parse
    application-specific files written by humans.
    
        $json->allow_barekey->decode('{foo:"bar"}');
    
    =head2 allow_bignum
    
        $json = $json->allow_bignum([$enable])
    
    If C<$enable> is true (or missing), then C<decode> will convert
    the big integer Perl cannot handle as integer into a L<Math::BigInt>
    object and convert a floating number (any) into a L<Math::BigFloat>.
    
    On the contary, C<encode> converts C<Math::BigInt> objects and C<Math::BigFloat>
    objects into JSON numbers with C<allow_blessed> enable.
    
       $json->allow_nonref->allow_blessed->allow_bignum;
       $bigfloat = $json->decode('2.000000000000000000000000001');
       print $json->encode($bigfloat);
       # => 2.000000000000000000000000001
    
    See to L<JSON::XS/MAPPING> aboout the normal conversion of JSON number.
    
    =head2 loose
    
        $json = $json->loose([$enable])
    
    The unescaped [\x00-\x1f\x22\x2f\x5c] strings are invalid in JSON strings
    and the module doesn't allow to C<decode> to these (except for \x2f).
    If C<$enable> is true (or missing), then C<decode>  will accept these
    unescaped strings.
    
        $json->loose->decode(qq|["abc
                                       def"]|);
    
    See L<JSON::XS/SSECURITY CONSIDERATIONS>.
    
    =head2 escape_slash
    
        $json = $json->escape_slash([$enable])
    
    According to JSON Grammar, I<slash> (U+002F) is escaped. But default
    JSON::PP (as same as JSON::XS) encodes strings without escaping slash.
    
    If C<$enable> is true (or missing), then C<encode> will escape slashes.
    
    =head2 indent_length
    
        $json = $json->indent_length($length)
    
    JSON::XS indent space length is 3 and cannot be changed.
    JSON::PP set the indent space length with the given $length.
    The default is 3. The acceptable range is 0 to 15.
    
    =head2 sort_by
    
        $json = $json->sort_by($function_name)
        $json = $json->sort_by($subroutine_ref)
    
    If $function_name or $subroutine_ref are set, its sort routine are used
    in encoding JSON objects.
    
       $js = $pc->sort_by(sub { $JSON::PP::a cmp $JSON::PP::b })->encode($obj);
       # is($js, q|{"a":1,"b":2,"c":3,"d":4,"e":5,"f":6,"g":7,"h":8,"i":9}|);
    
       $js = $pc->sort_by('own_sort')->encode($obj);
       # is($js, q|{"a":1,"b":2,"c":3,"d":4,"e":5,"f":6,"g":7,"h":8,"i":9}|);
    
       sub JSON::PP::own_sort { $JSON::PP::a cmp $JSON::PP::b }
    
    As the sorting routine runs in the JSON::PP scope, the given
    subroutine name and the special variables C<$a>, C<$b> will begin
    'JSON::PP::'.
    
    If $integer is set, then the effect is same as C<canonical> on.
    
    =head1 INTERNAL
    
    For developers.
    
    =over
    
    =item PP_encode_box
    
    Returns
    
            {
                depth        => $depth,
                indent_count => $indent_count,
            }
    
    
    =item PP_decode_box
    
    Returns
    
            {
                text    => $text,
                at      => $at,
                ch      => $ch,
                len     => $len,
                depth   => $depth,
                encoding      => $encoding,
                is_valid_utf8 => $is_valid_utf8,
            };
    
    =back
    
    =head1 MAPPING
    
    This section is copied from JSON::XS and modified to C<JSON::PP>.
    JSON::XS and JSON::PP mapping mechanisms are almost equivalent.
    
    See to L<JSON::XS/MAPPING>.
    
    =head2 JSON -> PERL
    
    =over 4
    
    =item object
    
    A JSON object becomes a reference to a hash in Perl. No ordering of object
    keys is preserved (JSON does not preserver object key ordering itself).
    
    =item array
    
    A JSON array becomes a reference to an array in Perl.
    
    =item string
    
    A JSON string becomes a string scalar in Perl - Unicode codepoints in JSON
    are represented by the same codepoints in the Perl string, so no manual
    decoding is necessary.
    
    =item number
    
    A JSON number becomes either an integer, numeric (floating point) or
    string scalar in perl, depending on its range and any fractional parts. On
    the Perl level, there is no difference between those as Perl handles all
    the conversion details, but an integer may take slightly less memory and
    might represent more values exactly than floating point numbers.
    
    If the number consists of digits only, C<JSON> will try to represent
    it as an integer value. If that fails, it will try to represent it as
    a numeric (floating point) value if that is possible without loss of
    precision. Otherwise it will preserve the number as a string value (in
    which case you lose roundtripping ability, as the JSON number will be
    re-encoded toa JSON string).
    
    Numbers containing a fractional or exponential part will always be
    represented as numeric (floating point) values, possibly at a loss of
    precision (in which case you might lose perfect roundtripping ability, but
    the JSON number will still be re-encoded as a JSON number).
    
    Note that precision is not accuracy - binary floating point values cannot
    represent most decimal fractions exactly, and when converting from and to
    floating point, C<JSON> only guarantees precision up to but not including
    the leats significant bit.
    
    When C<allow_bignum> is enable, the big integers 
    and the numeric can be optionally converted into L<Math::BigInt> and
    L<Math::BigFloat> objects.
    
    =item true, false
    
    These JSON atoms become C<JSON::PP::true> and C<JSON::PP::false>,
    respectively. They are overloaded to act almost exactly like the numbers
    C<1> and C<0>. You can check wether a scalar is a JSON boolean by using
    the C<JSON::is_bool> function.
    
       print JSON::PP::true . "\n";
        => true
       print JSON::PP::true + 1;
        => 1
    
       ok(JSON::true eq  '1');
       ok(JSON::true == 1);
    
    C<JSON> will install these missing overloading features to the backend modules.
    
    
    =item null
    
    A JSON null atom becomes C<undef> in Perl.
    
    C<JSON::PP::null> returns C<unddef>.
    
    =back
    
    
    =head2 PERL -> JSON
    
    The mapping from Perl to JSON is slightly more difficult, as Perl is a
    truly typeless language, so we can only guess which JSON type is meant by
    a Perl value.
    
    =over 4
    
    =item hash references
    
    Perl hash references become JSON objects. As there is no inherent ordering
    in hash keys (or JSON objects), they will usually be encoded in a
    pseudo-random order that can change between runs of the same program but
    stays generally the same within a single run of a program. C<JSON>
    optionally sort the hash keys (determined by the I<canonical> flag), so
    the same datastructure will serialise to the same JSON text (given same
    settings and version of JSON::XS), but this incurs a runtime overhead
    and is only rarely useful, e.g. when you want to compare some JSON text
    against another for equality.
    
    
    =item array references
    
    Perl array references become JSON arrays.
    
    =item other references
    
    Other unblessed references are generally not allowed and will cause an
    exception to be thrown, except for references to the integers C<0> and
    C<1>, which get turned into C<false> and C<true> atoms in JSON. You can
    also use C<JSON::false> and C<JSON::true> to improve readability.
    
       to_json [\0,JSON::PP::true]      # yields [false,true]
    
    =item JSON::PP::true, JSON::PP::false, JSON::PP::null
    
    These special values become JSON true and JSON false values,
    respectively. You can also use C<\1> and C<\0> directly if you want.
    
    JSON::PP::null returns C<undef>.
    
    =item blessed objects
    
    Blessed objects are not directly representable in JSON. See the
    C<allow_blessed> and C<convert_blessed> methods on various options on
    how to deal with this: basically, you can choose between throwing an
    exception, encoding the reference as if it weren't blessed, or provide
    your own serialiser method.
    
    See to L<convert_blessed>.
    
    =item simple scalars
    
    Simple Perl scalars (any scalar that is not a reference) are the most
    difficult objects to encode: JSON::XS and JSON::PP will encode undefined scalars as
    JSON C<null> values, scalars that have last been used in a string context
    before encoding as JSON strings, and anything else as number value:
    
       # dump as number
       encode_json [2]                      # yields [2]
       encode_json [-3.0e17]                # yields [-3e+17]
       my $value = 5; encode_json [$value]  # yields [5]
    
       # used as string, so dump as string
       print $value;
       encode_json [$value]                 # yields ["5"]
    
       # undef becomes null
       encode_json [undef]                  # yields [null]
    
    You can force the type to be a string by stringifying it:
    
       my $x = 3.1; # some variable containing a number
       "$x";        # stringified
       $x .= "";    # another, more awkward way to stringify
       print $x;    # perl does it for you, too, quite often
    
    You can force the type to be a number by numifying it:
    
       my $x = "3"; # some variable containing a string
       $x += 0;     # numify it, ensuring it will be dumped as a number
       $x *= 1;     # same thing, the choise is yours.
    
    You can not currently force the type in other, less obscure, ways.
    
    Note that numerical precision has the same meaning as under Perl (so
    binary to decimal conversion follows the same rules as in Perl, which
    can differ to other languages). Also, your perl interpreter might expose
    extensions to the floating point numbers of your platform, such as
    infinities or NaN's - these cannot be represented in JSON, and it is an
    error to pass those in.
    
    =item Big Number
    
    When C<allow_bignum> is enable, 
    C<encode> converts C<Math::BigInt> objects and C<Math::BigFloat>
    objects into JSON numbers.
    
    
    =back
    
    =head1 UNICODE HANDLING ON PERLS
    
    If you do not know about Unicode on Perl well,
    please check L<JSON::XS/A FEW NOTES ON UNICODE AND PERL>.
    
    =head2 Perl 5.8 and later
    
    Perl can handle Unicode and the JSON::PP de/encode methods also work properly.
    
        $json->allow_nonref->encode(chr hex 3042);
        $json->allow_nonref->encode(chr hex 12345);
    
    Reuturns C<"\u3042"> and C<"\ud808\udf45"> respectively.
    
        $json->allow_nonref->decode('"\u3042"');
        $json->allow_nonref->decode('"\ud808\udf45"');
    
    Returns UTF-8 encoded strings with UTF8 flag, regarded as C<U+3042> and C<U+12345>.
    
    Note that the versions from Perl 5.8.0 to 5.8.2, Perl built-in C<join> was broken,
    so JSON::PP wraps the C<join> with a subroutine. Thus JSON::PP works slow in the versions.
    
    
    =head2 Perl 5.6
    
    Perl can handle Unicode and the JSON::PP de/encode methods also work.
    
    =head2 Perl 5.005
    
    Perl 5.005 is a byte sementics world -- all strings are sequences of bytes.
    That means the unicode handling is not available.
    
    In encoding,
    
        $json->allow_nonref->encode(chr hex 3042);  # hex 3042 is 12354.
        $json->allow_nonref->encode(chr hex 12345); # hex 12345 is 74565.
    
    Returns C<B> and C<E>, as C<chr> takes a value more than 255, it treats
    as C<$value % 256>, so the above codes are equivalent to :
    
        $json->allow_nonref->encode(chr 66);
        $json->allow_nonref->encode(chr 69);
    
    In decoding,
    
        $json->decode('"\u00e3\u0081\u0082"');
    
    The returned is a byte sequence C<0xE3 0x81 0x82> for UTF-8 encoded
    japanese character (C<HIRAGANA LETTER A>).
    And if it is represented in Unicode code point, C<U+3042>.
    
    Next, 
    
        $json->decode('"\u3042"');
    
    We ordinary expect the returned value is a Unicode character C<U+3042>.
    But here is 5.005 world. This is C<0xE3 0x81 0x82>.
    
        $json->decode('"\ud808\udf45"');
    
    This is not a character C<U+12345> but bytes - C<0xf0 0x92 0x8d 0x85>.
    
    
    =head1 TODO
    
    =over
    
    =item speed
    
    =item memory saving
    
    =back
    
    
    =head1 SEE ALSO
    
    Most of the document are copied and modified from JSON::XS doc.
    
    L<JSON::XS>
    
    RFC4627 (L<http://www.ietf.org/rfc/rfc4627.txt>)
    
    =head1 AUTHOR
    
    Makamaka Hannyaharamitu, E<lt>makamaka[at]cpan.orgE<gt>
    
    
    =head1 COPYRIGHT AND LICENSE
    
    Copyright 2007-2014 by Makamaka Hannyaharamitu
    
    This library is free software; you can redistribute it and/or modify
    it under the same terms as Perl itself. 
    
    =cut
  JSON_PP
  
  $fatpacked{"JSON/PP/Boolean.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'JSON_PP_BOOLEAN';
    =head1 NAME
    
    JSON::PP::Boolean - dummy module providing JSON::PP::Boolean
    
    =head1 SYNOPSIS
    
     # do not "use" yourself
    
    =head1 DESCRIPTION
    
    This module exists only to provide overload resolution for Storable and similar modules. See
    L<JSON::PP> for more info about this class.
    
    =cut
    
    use JSON::PP ();
    use strict;
    
    1;
    
    =head1 AUTHOR
    
    This idea is from L<JSON::XS::Boolean> written by Marc Lehmann <schmorp[at]schmorp.de>
    
    =cut
    
  JSON_PP_BOOLEAN
  
  $fatpacked{"Module/CPANfile.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MODULE_CPANFILE';
    package Module::CPANfile;
    use strict;
    use warnings;
    use Cwd;
    use Carp ();
    use Module::CPANfile::Environment;
    use Module::CPANfile::Requirement;
    
    our $VERSION = '1.1000';
    
    sub new {
        my($class, $file) = @_;
        bless {}, $class;
    }
    
    sub load {
        my($proto, $file) = @_;
    
        my $self = ref $proto ? $proto : $proto->new;
        $self->parse($file || Cwd::abs_path('cpanfile'));
        $self;
    }
    
    sub save {
        my($self, $path) = @_;
    
        open my $out, ">", $path or die "$path: $!";
        print {$out} $self->to_string;
    }
    
    sub parse {
        my($self, $file) = @_;
    
        my $code = do {
            open my $fh, "<", $file or die "$file: $!";
            join '', <$fh>;
        };
    
        my $env = Module::CPANfile::Environment->new($file);
        $env->parse($code) or die $@;
    
        $self->{_mirrors} = $env->mirrors;
        $self->{_prereqs} = $env->prereqs;
    }
    
    sub from_prereqs {
        my($proto, $prereqs) = @_;
    
        my $self = $proto->new;
        $self->{_prereqs} = Module::CPANfile::Prereqs->from_cpan_meta($prereqs);
    
        $self;
    }
    
    sub mirrors {
        my $self = shift;
        $self->{_mirrors} || [];
    }
    
    sub features {
        my $self = shift;
        map $self->feature($_), $self->{_prereqs}->identifiers;
    }
    
    sub feature {
        my($self, $identifier) = @_;
        $self->{_prereqs}->feature($identifier);
    }
    
    sub prereq { shift->prereqs }
    
    sub prereqs {
        my $self = shift;
        $self->{_prereqs}->as_cpan_meta;
    }
    
    sub merged_requirements {
        my $self = shift;
        $self->{_prereqs}->merged_requirements;
    }
    
    sub effective_prereqs {
        my($self, $features) = @_;
        $self->prereqs_with(@{$features || []});
    }
    
    sub prereqs_with {
        my($self, @feature_identifiers) = @_;
    
        my $prereqs = $self->prereqs;
        my @others = map { $self->feature($_)->prereqs } @feature_identifiers;
    
        $prereqs->with_merged_prereqs(\@others);
    }
    
    sub prereq_specs {
        my $self = shift;
        $self->prereqs->as_string_hash;
    }
    
    sub prereq_for_module {
        my($self, $module) = @_;
        $self->{_prereqs}->find($module);
    }
    
    sub options_for_module {
        my($self, $module) = @_;
        my $prereq = $self->prereq_for_module($module) or return;
        $prereq->requirement->options;
    }
    
    sub merge_meta {
        my($self, $file, $version) = @_;
    
        require CPAN::Meta;
    
        $version ||= $file =~ /\.yml$/ ? '1.4' : '2';
    
        my $prereq = $self->prereqs;
    
        my $meta = CPAN::Meta->load_file($file);
        my $prereqs_hash = $prereq->with_merged_prereqs($meta->effective_prereqs)->as_string_hash;
        my $struct = { %{$meta->as_struct}, prereqs => $prereqs_hash };
    
        CPAN::Meta->new($struct)->save($file, { version => $version });
    }
    
    sub _dump {
        my $str = shift;
        require Data::Dumper;
        chomp(my $value = Data::Dumper->new([$str])->Terse(1)->Dump);
        $value;
    }
    
    sub to_string {
        my($self, $include_empty) = @_;
    
        my $mirrors = $self->mirrors;
        my $prereqs = $self->prereq_specs;
    
        my $code = '';
        $code .= $self->_dump_mirrors($mirrors);
        $code .= $self->_dump_prereqs($prereqs, $include_empty);
    
        for my $feature ($self->features) {
            $code .= sprintf "feature %s, %s => sub {\n", _dump($feature->{identifier}), _dump($feature->{description});
            $code .= $self->_dump_prereqs($feature->{spec}, $include_empty, 4);
            $code .= "}\n\n";
        }
    
        $code =~ s/\n+$/\n/s;
        $code;
    }
    
    sub _dump_mirrors {
        my($self, $mirrors) = @_;
    
        my $code = "";
    
        for my $url (@$mirrors) {
            $code .= "mirror '$url';\n";
        }
    
        $code =~ s/\n+$/\n/s;
        $code;
    }
    
    sub _dump_prereqs {
        my($self, $prereqs, $include_empty, $base_indent) = @_;
    
        my $code = '';
        for my $phase (qw(runtime configure build test develop)) {
            my $indent = $phase eq 'runtime' ? '' : '    ';
            $indent = (' ' x ($base_indent || 0)) . $indent;
    
            my($phase_code, $requirements);
            $phase_code .= "on $phase => sub {\n" unless $phase eq 'runtime';
    
            for my $type (qw(requires recommends suggests conflicts)) {
                for my $mod (sort keys %{$prereqs->{$phase}{$type}}) {
                    my $ver = $prereqs->{$phase}{$type}{$mod};
                    $phase_code .= $ver eq '0'
                                 ? "${indent}$type '$mod';\n"
                                 : "${indent}$type '$mod', '$ver';\n";
                    $requirements++;
                }
            }
    
            $phase_code .= "\n" unless $requirements;
            $phase_code .= "};\n" unless $phase eq 'runtime';
    
            $code .= $phase_code . "\n" if $requirements or $include_empty;
        }
    
        $code =~ s/\n+$/\n/s;
        $code;
    }
    
    1;
    
    __END__
    
    =head1 NAME
    
    Module::CPANfile - Parse cpanfile
    
    =head1 SYNOPSIS
    
      use Module::CPANfile;
    
      my $file = Module::CPANfile->load("cpanfile");
      my $prereqs = $file->prereqs; # CPAN::Meta::Prereqs object
    
      my @features = $file->features; # CPAN::Meta::Feature objects
      my $merged_prereqs = $file->prereqs_with(@identifiers); # CPAN::Meta::Prereqs
    
      $file->merge_meta('MYMETA.json');
    
    =head1 DESCRIPTION
    
    Module::CPANfile is a tool to handle L<cpanfile> format to load application
    specific dependencies, not just for CPAN distributions.
    
    =head1 METHODS
    
    =over 4
    
    =item load
    
      $file = Module::CPANfile->load;
      $file = Module::CPANfile->load('cpanfile');
    
    Load and parse a cpanfile. By default it tries to load C<cpanfile> in
    the current directory, unless you pass the path to its argument.
    
    =item from_prereqs
    
      $file = Module::CPANfile->from_prereqs({
        runtime => { requires => { DBI => '1.000' } },
      });
    
    Creates a new Module::CPANfile object from prereqs hash you can get
    via L<CPAN::Meta>'s C<prereqs>, or L<CPAN::Meta::Prereqs>'
    C<as_string_hash>.
    
      # read MYMETA, then feed the prereqs to create Module::CPANfile
      my $meta = CPAN::Meta->load_file('MYMETA.json');
      my $file = Module::CPANfile->from_prereqs($meta->prereqs);
    
      # load cpanfile, then recreate it with round-trip
      my $file = Module::CPANfile->load('cpanfile');
      $file = Module::CPANfile->from_prereqs($file->prereq_specs);
                                        # or $file->prereqs->as_string_hash
    
    =item prereqs
    
    Returns L<CPAN::Meta::Prereqs> object out of the parsed cpanfile.
    
    =item prereq_specs
    
    Returns a hash reference that should be passed to C<< CPAN::Meta::Prereqs->new >>.
    
    =item features
    
    Returns a list of features available in the cpanfile as L<CPAN::Meta::Feature>.
    
    =item prereqs_with(@identifiers), effective_prereqs(\@identifiers)
    
    Returns L<CPAN::Meta::Prereqs> object, with merged prereqs for
    features identified with the C<@identifiers>.
    
    =item to_string($include_empty)
    
      $file->to_string;
      $file->to_string(1);
    
    Returns a canonical string (code) representation for cpanfile. Useful
    if you want to convert L<CPAN::Meta::Prereqs> to a new cpanfile.
    
      # read MYMETA's prereqs and print cpanfile representation of it
      my $meta = CPAN::Meta->load_file('MYMETA.json');
      my $file = Module::CPANfile->from_prereqs($meta->prereqs);
      print $file->to_string;
    
    By default, it omits the phase where there're no modules
    registered. If you pass the argument of a true value, it will print
    them as well.
    
    =item save
    
      $file->save('cpanfile');
    
    Saves the currently loaded prereqs as a new C<cpanfile> by calling
    C<to_string>. Beware B<this method will overwrite the existing
    cpanfile without any warning or backup>. Taking a backup or giving
    warnings to users is a caller's responsibility.
    
      # Read MYMETA.json and creates a new cpanfile
      my $meta = CPAN::Meta->load_file('MYMETA.json');
      my $file = Module::CPANfile->from_prereqs($meta->prereqs);
      $file->save('cpanfile');
    
    =item merge_meta
    
      $file->merge_meta('META.yml');
      $file->merge_meta('MYMETA.json', '2.0');
    
    Merge the effective prereqs with Meta specification loaded from the
    given META file, using CPAN::Meta. You can specify the META spec
    version in the second argument, which defaults to 1.4 in case the
    given file is YAML, and 2 if it is JSON.
    
    =back
    
    =head1 AUTHOR
    
    Tatsuhiko Miyagawa
    
    =head1 SEE ALSO
    
    L<cpanfile>, L<CPAN::Meta>, L<CPAN::Meta::Spec>
    
    =cut
  MODULE_CPANFILE
  
  $fatpacked{"Module/CPANfile/Environment.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MODULE_CPANFILE_ENVIRONMENT';
    package Module::CPANfile::Environment;
    use strict;
    use warnings;
    use Module::CPANfile::Prereqs;
    use Carp ();
    
    my @bindings = qw(
        on requires recommends suggests conflicts
        feature
        osname
        mirror
        configure_requires build_requires test_requires author_requires
    );
    
    my $file_id = 1;
    
    sub new {
        my($class, $file) = @_;
        bless {
            file     => $file,
            phase    => 'runtime', # default phase
            feature  => undef,
            features => {},
            prereqs  => Module::CPANfile::Prereqs->new,
            mirrors  => [],
        }, $class;
    }
    
    sub bind {
        my $self = shift;
        my $pkg = caller;
    
        for my $binding (@bindings) {
            no strict 'refs';
            *{"$pkg\::$binding"} = sub { $self->$binding(@_) };
        }
    }
    
    sub parse {
        my($self, $code) = @_;
    
        my $err;
        {
            local $@;
            $file_id++;
            $self->_evaluate(<<EVAL);
    package Module::CPANfile::Sandbox$file_id;
    no warnings;
    BEGIN { \$_environment->bind }
    
    # line 1 "$self->{file}"
    $code;
    EVAL
            $err = $@;
        }
    
        if ($err) { die "Parsing $self->{file} failed: $err" };
    
        return 1;
    }
    
    sub _evaluate {
        my $_environment = $_[0];
        eval $_[1];
    }
    
    sub prereqs { $_[0]->{prereqs} }
    
    sub mirrors { $_[0]->{mirrors} }
    
    # DSL goes from here
    
    sub on {
        my($self, $phase, $code) = @_;
        local $self->{phase} = $phase;
        $code->();
    }
    
    sub feature {
        my($self, $identifier, $description, $code) = @_;
    
        # shortcut: feature identifier => sub { ... }
        if (@_ == 3 && ref($description) eq 'CODE') {
            $code = $description;
            $description = $identifier;
        }
    
        unless (ref $description eq '' && ref $code eq 'CODE') {
            Carp::croak("Usage: feature 'identifier', 'Description' => sub { ... }");
        }
    
        local $self->{feature} = $identifier;
        $self->prereqs->add_feature($identifier, $description);
    
        $code->();
    }
    
    sub osname { die "TODO" }
    
    sub mirror {
        my($self, $url) = @_;
        push @{$self->{mirrors}}, $url;
    }
    
    sub requirement_for {
        my($self, $module, @args) = @_;
    
        my $requirement = 0;
        $requirement = shift @args if @args % 2;
    
        return Module::CPANfile::Requirement->new(
            name    => $module,
            version => $requirement,
            @args,
        );
    }
    
    sub requires {
        my $self = shift;
        $self->add_prereq(requires => @_);
    }
    
    sub recommends {
        my $self = shift;
        $self->add_prereq(recommends => @_);
    }
    
    sub suggests {
        my $self = shift;
        $self->add_prereq(suggests => @_);
    }
    
    sub conflicts {
        my $self = shift;
        $self->add_prereq(conflicts => @_);
    }
    
    sub add_prereq {
        my($self, $type, $module, @args) = @_;
    
        $self->prereqs->add_prereq(
            feature => $self->{feature},
            phase   => $self->{phase},
            type    => $type,
            module  => $module,
            requirement => $self->requirement_for($module, @args),
        );
    }
    
    # Module::Install compatible shortcuts
    
    sub configure_requires {
        my($self, @args) = @_;
        $self->on(configure => sub { $self->requires(@args) });
    }
    
    sub build_requires {
        my($self, @args) = @_;
        $self->on(build => sub { $self->requires(@args) });
    }
    
    sub test_requires {
        my($self, @args) = @_;
        $self->on(test => sub { $self->requires(@args) });
    }
    
    sub author_requires {
        my($self, @args) = @_;
        $self->on(develop => sub { $self->requires(@args) });
    }
    
    1;
    
  MODULE_CPANFILE_ENVIRONMENT
  
  $fatpacked{"Module/CPANfile/Prereq.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MODULE_CPANFILE_PREREQ';
    package Module::CPANfile::Prereq;
    use strict;
    
    sub new {
        my($class, %options) = @_;
        bless \%options, $class;
    }
    
    sub feature { $_[0]->{feature} }
    sub phase   { $_[0]->{phase} }
    sub type    { $_[0]->{type} }
    sub module  { $_[0]->{module} }
    sub requirement { $_[0]->{requirement} }
    
    sub match_feature {
        my($self, $identifier) = @_;
        no warnings 'uninitialized';
        $self->feature eq $identifier;
    }
    
    1;
  MODULE_CPANFILE_PREREQ
  
  $fatpacked{"Module/CPANfile/Prereqs.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MODULE_CPANFILE_PREREQS';
    package Module::CPANfile::Prereqs;
    use strict;
    use Carp ();
    use CPAN::Meta::Feature;
    use Module::CPANfile::Prereq;
    
    sub from_cpan_meta {
        my($class, $prereqs) = @_;
    
        my $self = $class->new;
    
        for my $phase (keys %$prereqs) {
            for my $type (keys %{ $prereqs->{$phase} }) {
                while (my($module, $requirement) = each %{ $prereqs->{$phase}{$type} }) {
                    $self->add_prereq(
                        phase => $phase,
                        type  => $type,
                        module => $module,
                        requirement => Module::CPANfile::Requirement->new(name => $module, version => $requirement),
                    );
                }
            }
        }
    
        $self;
    }
    
    sub new {
        my $class = shift;
        bless {
            prereqs => [],
            features => {},
        }, $class;
    }
    
    sub add_feature {
        my($self, $identifier, $description) = @_;
        $self->{features}{$identifier} = { description => $description };
    }
    
    sub add_prereq {
        my($self, %args) = @_;
        $self->add( Module::CPANfile::Prereq->new(%args) );
    }
    
    sub add {
        my($self, $prereq) = @_;
        push @{$self->{prereqs}}, $prereq;
    }
    
    sub as_cpan_meta {
        my $self = shift;
        $self->{cpanmeta} ||= $self->build_cpan_meta;
    }
    
    sub build_cpan_meta {
        my($self, $identifier) = @_;
    
        my $prereq_spec = {};
        $self->prereq_each($identifier, sub {
            my $prereq = shift;
            $prereq_spec->{$prereq->phase}{$prereq->type}{$prereq->module} = $prereq->requirement->version;
        });
    
        CPAN::Meta::Prereqs->new($prereq_spec);
    }
    
    sub prereq_each {
        my($self, $identifier, $code) = @_;
    
        for my $prereq (@{$self->{prereqs}}) {
            next unless $prereq->match_feature($identifier);
            $code->($prereq);
        }
    }
    
    sub merged_requirements {
        my $self = shift;
    
        my $reqs = CPAN::Meta::Requirements->new;
        for my $prereq (@{$self->{prereqs}}) {
            $reqs->add_string_requirement($prereq->module, $prereq->requirement->version);
        }
    
        $reqs;
    }
    
    sub find {
        my($self, $module) = @_;
    
        for my $prereq (@{$self->{prereqs}}) {
            return $prereq if $prereq->module eq $module;
        }
    
        return;
    }
    
    sub identifiers {
        my $self = shift;
        keys %{$self->{features}};
    }
    
    sub feature {
        my($self, $identifier) = @_;
    
        my $data = $self->{features}{$identifier}
          or Carp::croak("Unknown feature '$identifier'");
    
        my $prereqs = $self->build_cpan_meta($identifier);
    
        CPAN::Meta::Feature->new($identifier, {
            description => $data->{description},
            prereqs => $prereqs->as_string_hash,
        });
    }
    
    1;
  MODULE_CPANFILE_PREREQS
  
  $fatpacked{"Module/CPANfile/Requirement.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MODULE_CPANFILE_REQUIREMENT';
    package Module::CPANfile::Requirement;
    use strict;
    
    sub new {
        my ($class, %args) = @_;
    
        $args{version} ||= 0;
    
        bless +{
            name    => delete $args{name},
            version => delete $args{version},
            options => \%args,
        }, $class;
    }
    
    sub name    { $_[0]->{name} }
    sub version { $_[0]->{version} }
    
    sub options { $_[0]->{options} }
    
    sub has_options {
        keys %{$_[0]->{options}} > 0;
    }
    
    1;
  MODULE_CPANFILE_REQUIREMENT
  
  $fatpacked{"Module/Metadata.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MODULE_METADATA';
    # -*- mode: cperl; tab-width: 8; indent-tabs-mode: nil; basic-offset: 2 -*-
    # vim:ts=8:sw=2:et:sta:sts=2
    package Module::Metadata; # git description: v1.000025-7-g47ca1b2
    
    # Adapted from Perl-licensed code originally distributed with
    # Module-Build by Ken Williams
    
    # This module provides routines to gather information about
    # perl modules (assuming this may be expanded in the distant
    # parrot future to look at other types of modules).
    
    sub __clean_eval { eval $_[0] }
    use strict;
    use warnings;
    
    our $VERSION = '1.000026';
    
    use Carp qw/croak/;
    use File::Spec;
    BEGIN {
           # Try really hard to not depend ony any DynaLoaded module, such as IO::File or Fcntl
           eval {
                   require Fcntl; Fcntl->import('SEEK_SET'); 1;
           } or *SEEK_SET = sub { 0 }
    }
    use version 0.87;
    BEGIN {
      if ($INC{'Log/Contextual.pm'}) {
        Log::Contextual->import('log_info');
      } else {
        *log_info = sub (&) { warn $_[0]->() };
      }
    }
    use File::Find qw(find);
    
    my $V_NUM_REGEXP = qr{v?[0-9._]+};  # crudely, a v-string or decimal
    
    my $PKG_FIRST_WORD_REGEXP = qr{ # the FIRST word in a package name
      [a-zA-Z_]                     # the first word CANNOT start with a digit
        (?:
          [\w']?                    # can contain letters, digits, _, or ticks
          \w                        # But, NO multi-ticks or trailing ticks
        )*
    }x;
    
    my $PKG_ADDL_WORD_REGEXP = qr{ # the 2nd+ word in a package name
      \w                           # the 2nd+ word CAN start with digits
        (?:
          [\w']?                   # and can contain letters or ticks
          \w                       # But, NO multi-ticks or trailing ticks
        )*
    }x;
    
    my $PKG_NAME_REGEXP = qr{ # match a package name
      (?: :: )?               # a pkg name can start with arisdottle
      $PKG_FIRST_WORD_REGEXP  # a package word
      (?:
        (?: :: )+             ### arisdottle (allow one or many times)
        $PKG_ADDL_WORD_REGEXP ### a package word
      )*                      # ^ zero, one or many times
      (?:
        ::                    # allow trailing arisdottle
      )?
    }x;
    
    my $PKG_REGEXP  = qr{   # match a package declaration
      ^[\s\{;]*             # intro chars on a line
      package               # the word 'package'
      \s+                   # whitespace
      ($PKG_NAME_REGEXP)    # a package name
      \s*                   # optional whitespace
      ($V_NUM_REGEXP)?        # optional version number
      \s*                   # optional whitesapce
      [;\{]                 # semicolon line terminator or block start (since 5.16)
    }x;
    
    my $VARNAME_REGEXP = qr{ # match fully-qualified VERSION name
      ([\$*])         # sigil - $ or *
      (
        (             # optional leading package name
          (?:::|\')?  # possibly starting like just :: (a la $::VERSION)
          (?:\w+(?:::|\'))*  # Foo::Bar:: ...
        )?
        VERSION
      )\b
    }x;
    
    my $VERS_REGEXP = qr{ # match a VERSION definition
      (?:
        \(\s*$VARNAME_REGEXP\s*\) # with parens
      |
        $VARNAME_REGEXP           # without parens
      )
      \s*
      =[^=~>]  # = but not ==, nor =~, nor =>
    }x;
    
    sub new_from_file {
      my $class    = shift;
      my $filename = File::Spec->rel2abs( shift );
    
      return undef unless defined( $filename ) && -f $filename;
      return $class->_init(undef, $filename, @_);
    }
    
    sub new_from_handle {
      my $class    = shift;
      my $handle   = shift;
      my $filename = shift;
      return undef unless defined($handle) && defined($filename);
      $filename = File::Spec->rel2abs( $filename );
    
      return $class->_init(undef, $filename, @_, handle => $handle);
    
    }
    
    
    sub new_from_module {
      my $class   = shift;
      my $module  = shift;
      my %props   = @_;
    
      $props{inc} ||= \@INC;
      my $filename = $class->find_module_by_name( $module, $props{inc} );
      return undef unless defined( $filename ) && -f $filename;
      return $class->_init($module, $filename, %props);
    }
    
    {
    
      my $compare_versions = sub {
        my ($v1, $op, $v2) = @_;
        $v1 = version->new($v1)
          unless UNIVERSAL::isa($v1,'version');
    
        my $eval_str = "\$v1 $op \$v2";
        my $result   = eval $eval_str;
        log_info { "error comparing versions: '$eval_str' $@" } if $@;
    
        return $result;
      };
    
      my $normalize_version = sub {
        my ($version) = @_;
        if ( $version =~ /[=<>!,]/ ) { # logic, not just version
          # take as is without modification
        }
        elsif ( ref $version eq 'version' ) { # version objects
          $version = $version->is_qv ? $version->normal : $version->stringify;
        }
        elsif ( $version =~ /^[^v][^.]*\.[^.]+\./ ) { # no leading v, multiple dots
          # normalize string tuples without "v": "1.2.3" -> "v1.2.3"
          $version = "v$version";
        }
        else {
          # leave alone
        }
        return $version;
      };
    
      # separate out some of the conflict resolution logic
    
      my $resolve_module_versions = sub {
        my $packages = shift;
    
        my( $file, $version );
        my $err = '';
          foreach my $p ( @$packages ) {
            if ( defined( $p->{version} ) ) {
              if ( defined( $version ) ) {
                if ( $compare_versions->( $version, '!=', $p->{version} ) ) {
                  $err .= "  $p->{file} ($p->{version})\n";
                } else {
                  # same version declared multiple times, ignore
                }
              } else {
                $file    = $p->{file};
                $version = $p->{version};
              }
            }
          $file ||= $p->{file} if defined( $p->{file} );
        }
    
        if ( $err ) {
          $err = "  $file ($version)\n" . $err;
        }
    
        my %result = (
          file    => $file,
          version => $version,
          err     => $err
        );
    
        return \%result;
      };
    
      sub provides {
        my $class = shift;
    
        croak "provides() requires key/value pairs \n" if @_ % 2;
        my %args = @_;
    
        croak "provides() takes only one of 'dir' or 'files'\n"
          if $args{dir} && $args{files};
    
        croak "provides() requires a 'version' argument"
          unless defined $args{version};
    
        croak "provides() does not support version '$args{version}' metadata"
            unless grep { $args{version} eq $_ } qw/1.4 2/;
    
        $args{prefix} = 'lib' unless defined $args{prefix};
    
        my $p;
        if ( $args{dir} ) {
          $p = $class->package_versions_from_directory($args{dir});
        }
        else {
          croak "provides() requires 'files' to be an array reference\n"
            unless ref $args{files} eq 'ARRAY';
          $p = $class->package_versions_from_directory($args{files});
        }
    
        # Now, fix up files with prefix
        if ( length $args{prefix} ) { # check in case disabled with q{}
          $args{prefix} =~ s{/$}{};
          for my $v ( values %$p ) {
            $v->{file} = "$args{prefix}/$v->{file}";
          }
        }
    
        return $p
      }
    
      sub package_versions_from_directory {
        my ( $class, $dir, $files ) = @_;
    
        my @files;
    
        if ( $files ) {
          @files = @$files;
        } else {
          find( {
            wanted => sub {
              push @files, $_ if -f $_ && /\.pm$/;
            },
            no_chdir => 1,
          }, $dir );
        }
    
        # First, we enumerate all packages & versions,
        # separating into primary & alternative candidates
        my( %prime, %alt );
        foreach my $file (@files) {
          my $mapped_filename = File::Spec::Unix->abs2rel( $file, $dir );
          my @path = split( /\//, $mapped_filename );
          (my $prime_package = join( '::', @path )) =~ s/\.pm$//;
    
          my $pm_info = $class->new_from_file( $file );
    
          foreach my $package ( $pm_info->packages_inside ) {
            next if $package eq 'main';  # main can appear numerous times, ignore
            next if $package eq 'DB';    # special debugging package, ignore
            next if grep /^_/, split( /::/, $package ); # private package, ignore
    
            my $version = $pm_info->version( $package );
    
            $prime_package = $package if lc($prime_package) eq lc($package);
            if ( $package eq $prime_package ) {
              if ( exists( $prime{$package} ) ) {
                croak "Unexpected conflict in '$package'; multiple versions found.\n";
              } else {
                $mapped_filename = "$package.pm" if lc("$package.pm") eq lc($mapped_filename);
                $prime{$package}{file} = $mapped_filename;
                $prime{$package}{version} = $version if defined( $version );
              }
            } else {
              push( @{$alt{$package}}, {
                                        file    => $mapped_filename,
                                        version => $version,
                                       } );
            }
          }
        }
    
        # Then we iterate over all the packages found above, identifying conflicts
        # and selecting the "best" candidate for recording the file & version
        # for each package.
        foreach my $package ( keys( %alt ) ) {
          my $result = $resolve_module_versions->( $alt{$package} );
    
          if ( exists( $prime{$package} ) ) { # primary package selected
    
            if ( $result->{err} ) {
            # Use the selected primary package, but there are conflicting
            # errors among multiple alternative packages that need to be
            # reported
              log_info {
                "Found conflicting versions for package '$package'\n" .
                "  $prime{$package}{file} ($prime{$package}{version})\n" .
                $result->{err}
              };
    
            } elsif ( defined( $result->{version} ) ) {
            # There is a primary package selected, and exactly one
            # alternative package
    
            if ( exists( $prime{$package}{version} ) &&
                 defined( $prime{$package}{version} ) ) {
              # Unless the version of the primary package agrees with the
              # version of the alternative package, report a conflict
            if ( $compare_versions->(
                     $prime{$package}{version}, '!=', $result->{version}
                   )
                 ) {
    
                log_info {
                  "Found conflicting versions for package '$package'\n" .
                  "  $prime{$package}{file} ($prime{$package}{version})\n" .
                  "  $result->{file} ($result->{version})\n"
                };
              }
    
            } else {
              # The prime package selected has no version so, we choose to
              # use any alternative package that does have a version
              $prime{$package}{file}    = $result->{file};
              $prime{$package}{version} = $result->{version};
            }
    
            } else {
            # no alt package found with a version, but we have a prime
            # package so we use it whether it has a version or not
            }
    
          } else { # No primary package was selected, use the best alternative
    
            if ( $result->{err} ) {
              log_info {
                "Found conflicting versions for package '$package'\n" .
                $result->{err}
              };
            }
    
            # Despite possible conflicting versions, we choose to record
            # something rather than nothing
            $prime{$package}{file}    = $result->{file};
            $prime{$package}{version} = $result->{version}
              if defined( $result->{version} );
          }
        }
    
        # Normalize versions.  Can't use exists() here because of bug in YAML::Node.
        # XXX "bug in YAML::Node" comment seems irrelevant -- dagolden, 2009-05-18
        for (grep defined $_->{version}, values %prime) {
          $_->{version} = $normalize_version->( $_->{version} );
        }
    
        return \%prime;
      }
    }
    
    
    sub _init {
      my $class    = shift;
      my $module   = shift;
      my $filename = shift;
      my %props = @_;
    
      my $handle = delete $props{handle};
      my( %valid_props, @valid_props );
      @valid_props = qw( collect_pod inc );
      @valid_props{@valid_props} = delete( @props{@valid_props} );
      warn "Unknown properties: @{[keys %props]}\n" if scalar( %props );
    
      my %data = (
        module       => $module,
        filename     => $filename,
        version      => undef,
        packages     => [],
        versions     => {},
        pod          => {},
        pod_headings => [],
        collect_pod  => 0,
    
        %valid_props,
      );
    
      my $self = bless(\%data, $class);
    
      if ( not $handle ) {
        my $filename = $self->{filename};
        open $handle, '<', $filename
          or croak( "Can't open '$filename': $!" );
    
        $self->_handle_bom($handle, $filename);
      }
      $self->_parse_fh($handle);
    
      unless($self->{module} and length($self->{module})) {
        my ($v, $d, $f) = File::Spec->splitpath($self->{filename});
        if($f =~ /\.pm$/) {
          $f =~ s/\..+$//;
          my @candidates = grep /$f$/, @{$self->{packages}};
          $self->{module} = shift(@candidates); # punt
        }
        else {
          if(grep /main/, @{$self->{packages}}) {
            $self->{module} = 'main';
          }
          else {
            $self->{module} = $self->{packages}[0] || '';
          }
        }
      }
    
      $self->{version} = $self->{versions}{$self->{module}}
          if defined( $self->{module} );
    
      return $self;
    }
    
    # class method
    sub _do_find_module {
      my $class   = shift;
      my $module  = shift || croak 'find_module_by_name() requires a package name';
      my $dirs    = shift || \@INC;
    
      my $file = File::Spec->catfile(split( /::/, $module));
      foreach my $dir ( @$dirs ) {
        my $testfile = File::Spec->catfile($dir, $file);
        return [ File::Spec->rel2abs( $testfile ), $dir ]
          if -e $testfile and !-d _;  # For stuff like ExtUtils::xsubpp
        $testfile .= '.pm';
        return [ File::Spec->rel2abs( $testfile ), $dir ]
          if -e $testfile;
      }
      return;
    }
    
    # class method
    sub find_module_by_name {
      my $found = shift()->_do_find_module(@_) or return;
      return $found->[0];
    }
    
    # class method
    sub find_module_dir_by_name {
      my $found = shift()->_do_find_module(@_) or return;
      return $found->[1];
    }
    
    
    # given a line of perl code, attempt to parse it if it looks like a
    # $VERSION assignment, returning sigil, full name, & package name
    sub _parse_version_expression {
      my $self = shift;
      my $line = shift;
    
      my( $sigil, $variable_name, $package);
      if ( $line =~ /$VERS_REGEXP/o ) {
        ( $sigil, $variable_name, $package) = $2 ? ( $1, $2, $3 ) : ( $4, $5, $6 );
        if ( $package ) {
          $package = ($package eq '::') ? 'main' : $package;
          $package =~ s/::$//;
        }
      }
    
      return ( $sigil, $variable_name, $package );
    }
    
    # Look for a UTF-8/UTF-16BE/UTF-16LE BOM at the beginning of the stream.
    # If there's one, then skip it and set the :encoding layer appropriately.
    sub _handle_bom {
      my ($self, $fh, $filename) = @_;
    
      my $pos = tell $fh;
      return unless defined $pos;
    
      my $buf = ' ' x 2;
      my $count = read $fh, $buf, length $buf;
      return unless defined $count and $count >= 2;
    
      my $encoding;
      if ( $buf eq "\x{FE}\x{FF}" ) {
        $encoding = 'UTF-16BE';
      } elsif ( $buf eq "\x{FF}\x{FE}" ) {
        $encoding = 'UTF-16LE';
      } elsif ( $buf eq "\x{EF}\x{BB}" ) {
        $buf = ' ';
        $count = read $fh, $buf, length $buf;
        if ( defined $count and $count >= 1 and $buf eq "\x{BF}" ) {
          $encoding = 'UTF-8';
        }
      }
    
      if ( defined $encoding ) {
        if ( "$]" >= 5.008 ) {
          binmode( $fh, ":encoding($encoding)" );
        }
      } else {
        seek $fh, $pos, SEEK_SET
          or croak( sprintf "Can't reset position to the top of '$filename'" );
      }
    
      return $encoding;
    }
    
    sub _parse_fh {
      my ($self, $fh) = @_;
    
      my( $in_pod, $seen_end, $need_vers ) = ( 0, 0, 0 );
      my( @packages, %vers, %pod, @pod );
      my $package = 'main';
      my $pod_sect = '';
      my $pod_data = '';
      my $in_end = 0;
    
      while (defined( my $line = <$fh> )) {
        my $line_num = $.;
    
        chomp( $line );
    
        # From toke.c : any line that begins by "=X", where X is an alphabetic
        # character, introduces a POD segment.
        my $is_cut;
        if ( $line =~ /^=([a-zA-Z].*)/ ) {
          my $cmd = $1;
          # Then it goes back to Perl code for "=cutX" where X is a non-alphabetic
          # character (which includes the newline, but here we chomped it away).
          $is_cut = $cmd =~ /^cut(?:[^a-zA-Z]|$)/;
          $in_pod = !$is_cut;
        }
    
        if ( $in_pod ) {
    
          if ( $line =~ /^=head[1-4]\s+(.+)\s*$/ ) {
            push( @pod, $1 );
            if ( $self->{collect_pod} && length( $pod_data ) ) {
              $pod{$pod_sect} = $pod_data;
              $pod_data = '';
            }
            $pod_sect = $1;
    
          } elsif ( $self->{collect_pod} ) {
            $pod_data .= "$line\n";
    
          }
    
        } elsif ( $is_cut ) {
    
          if ( $self->{collect_pod} && length( $pod_data ) ) {
            $pod{$pod_sect} = $pod_data;
            $pod_data = '';
          }
          $pod_sect = '';
    
        } else {
    
          # Skip after __END__
          next if $in_end;
    
          # Skip comments in code
          next if $line =~ /^\s*#/;
    
          # Would be nice if we could also check $in_string or something too
          if ($line eq '__END__') {
            $in_end++;
            next;
          }
          last if $line eq '__DATA__';
    
          # parse $line to see if it's a $VERSION declaration
          my( $version_sigil, $version_fullname, $version_package ) =
              index($line, 'VERSION') >= 1
                  ? $self->_parse_version_expression( $line )
                  : ();
    
          if ( $line =~ /$PKG_REGEXP/o ) {
            $package = $1;
            my $version = $2;
            push( @packages, $package ) unless grep( $package eq $_, @packages );
            $need_vers = defined $version ? 0 : 1;
    
            if ( not exists $vers{$package} and defined $version ){
              # Upgrade to a version object.
              my $dwim_version = eval { _dwim_version($version) };
              croak "Version '$version' from $self->{filename} does not appear to be valid:\n$line\n\nThe fatal error was: $@\n"
                  unless defined $dwim_version;  # "0" is OK!
              $vers{$package} = $dwim_version;
            }
    
          # VERSION defined with full package spec, i.e. $Module::VERSION
          } elsif ( $version_fullname && $version_package ) {
            push( @packages, $version_package ) unless grep( $version_package eq $_, @packages );
            $need_vers = 0 if $version_package eq $package;
    
            unless ( defined $vers{$version_package} && length $vers{$version_package} ) {
            $vers{$version_package} = $self->_evaluate_version_line( $version_sigil, $version_fullname, $line );
          }
    
          # first non-comment line in undeclared package main is VERSION
          } elsif ( $package eq 'main' && $version_fullname && !exists($vers{main}) ) {
            $need_vers = 0;
            my $v = $self->_evaluate_version_line( $version_sigil, $version_fullname, $line );
            $vers{$package} = $v;
            push( @packages, 'main' );
    
          # first non-comment line in undeclared package defines package main
          } elsif ( $package eq 'main' && !exists($vers{main}) && $line =~ /\w/ ) {
            $need_vers = 1;
            $vers{main} = '';
            push( @packages, 'main' );
    
          # only keep if this is the first $VERSION seen
          } elsif ( $version_fullname && $need_vers ) {
            $need_vers = 0;
            my $v = $self->_evaluate_version_line( $version_sigil, $version_fullname, $line );
    
            unless ( defined $vers{$package} && length $vers{$package} ) {
              $vers{$package} = $v;
            }
          }
        }
      }
    
      if ( $self->{collect_pod} && length($pod_data) ) {
        $pod{$pod_sect} = $pod_data;
      }
    
      $self->{versions} = \%vers;
      $self->{packages} = \@packages;
      $self->{pod} = \%pod;
      $self->{pod_headings} = \@pod;
    }
    
    {
    my $pn = 0;
    sub _evaluate_version_line {
      my $self = shift;
      my( $sigil, $variable_name, $line ) = @_;
    
      # We compile into a local sub because 'use version' would cause
      # compiletime/runtime issues with local()
      $pn++; # everybody gets their own package
      my $eval = qq{ my \$dummy = q#  Hide from _packages_inside()
        #; package Module::Metadata::_version::p${pn};
        use version;
        sub {
          local $sigil$variable_name;
          $line;
          \$$variable_name
        };
      };
    
      $eval = $1 if $eval =~ m{^(.+)}s;
    
      local $^W;
      # Try to get the $VERSION
      my $vsub = __clean_eval($eval);
      # some modules say $VERSION <equal sign> $Foo::Bar::VERSION, but Foo::Bar isn't
      # installed, so we need to hunt in ./lib for it
      if ( $@ =~ /Can't locate/ && -d 'lib' ) {
        local @INC = ('lib',@INC);
        $vsub = __clean_eval($eval);
      }
      warn "Error evaling version line '$eval' in $self->{filename}: $@\n"
        if $@;
    
      (ref($vsub) eq 'CODE') or
        croak "failed to build version sub for $self->{filename}";
    
      my $result = eval { $vsub->() };
      # FIXME: $eval is not the right thing to print here
      croak "Could not get version from $self->{filename} by executing:\n$eval\n\nThe fatal error was: $@\n"
        if $@;
    
      # Upgrade it into a version object
      my $version = eval { _dwim_version($result) };
    
      # FIXME: $eval is not the right thing to print here
      croak "Version '$result' from $self->{filename} does not appear to be valid:\n$eval\n\nThe fatal error was: $@\n"
        unless defined $version; # "0" is OK!
    
      return $version;
    }
    }
    
    # Try to DWIM when things fail the lax version test in obvious ways
    {
      my @version_prep = (
        # Best case, it just works
        sub { return shift },
    
        # If we still don't have a version, try stripping any
        # trailing junk that is prohibited by lax rules
        sub {
          my $v = shift;
          $v =~ s{([0-9])[a-z-].*$}{$1}i; # 1.23-alpha or 1.23b
          return $v;
        },
    
        # Activestate apparently creates custom versions like '1.23_45_01', which
        # cause version.pm to think it's an invalid alpha.  So check for that
        # and strip them
        sub {
          my $v = shift;
          my $num_dots = () = $v =~ m{(\.)}g;
          my $num_unders = () = $v =~ m{(_)}g;
          my $leading_v = substr($v,0,1) eq 'v';
          if ( ! $leading_v && $num_dots < 2 && $num_unders > 1 ) {
            $v =~ s{_}{}g;
            $num_unders = () = $v =~ m{(_)}g;
          }
          return $v;
        },
    
        # Worst case, try numifying it like we would have before version objects
        sub {
          my $v = shift;
          no warnings 'numeric';
          return 0 + $v;
        },
    
      );
    
      sub _dwim_version {
        my ($result) = shift;
    
        return $result if ref($result) eq 'version';
    
        my ($version, $error);
        for my $f (@version_prep) {
          $result = $f->($result);
          $version = eval { version->new($result) };
          $error ||= $@ if $@; # capture first failure
          last if defined $version;
        }
    
        croak $error unless defined $version;
    
        return $version;
      }
    }
    
    ############################################################
    
    # accessors
    sub name            { $_[0]->{module}            }
    
    sub filename        { $_[0]->{filename}          }
    sub packages_inside { @{$_[0]->{packages}}       }
    sub pod_inside      { @{$_[0]->{pod_headings}}   }
    sub contains_pod    { 0+@{$_[0]->{pod_headings}} }
    
    sub version {
        my $self = shift;
        my $mod  = shift || $self->{module};
        my $vers;
        if ( defined( $mod ) && length( $mod ) &&
             exists( $self->{versions}{$mod} ) ) {
            return $self->{versions}{$mod};
        } else {
            return undef;
        }
    }
    
    sub pod {
        my $self = shift;
        my $sect = shift;
        if ( defined( $sect ) && length( $sect ) &&
             exists( $self->{pod}{$sect} ) ) {
            return $self->{pod}{$sect};
        } else {
            return undef;
        }
    }
    
    sub is_indexable {
      my ($self, $package) = @_;
    
      my @indexable_packages = grep { $_ ne 'main' } $self->packages_inside;
    
      # check for specific package, if provided
      return !! grep { $_ eq $package } @indexable_packages if $package;
    
      # otherwise, check for any indexable packages at all
      return !! @indexable_packages;
    }
    
    1;
    
    =head1 NAME
    
    Module::Metadata - Gather package and POD information from perl module files
    
    =head1 SYNOPSIS
    
      use Module::Metadata;
    
      # information about a .pm file
      my $info = Module::Metadata->new_from_file( $file );
      my $version = $info->version;
    
      # CPAN META 'provides' field for .pm files in a directory
      my $provides = Module::Metadata->provides(
        dir => 'lib', version => 2
      );
    
    =head1 DESCRIPTION
    
    This module provides a standard way to gather metadata about a .pm file through
    (mostly) static analysis and (some) code execution.  When determining the
    version of a module, the C<$VERSION> assignment is C<eval>ed, as is traditional
    in the CPAN toolchain.
    
    =head1 USAGE
    
    =head2 Class methods
    
    =over 4
    
    =item C<< new_from_file($filename, collect_pod => 1) >>
    
    Constructs a C<Module::Metadata> object given the path to a file.  Returns
    undef if the filename does not exist.
    
    C<collect_pod> is a optional boolean argument that determines whether POD
    data is collected and stored for reference.  POD data is not collected by
    default.  POD headings are always collected.
    
    If the file begins by an UTF-8, UTF-16BE or UTF-16LE byte-order mark, then
    it is skipped before processing, and the content of the file is also decoded
    appropriately starting from perl 5.8.
    
    =item C<< new_from_handle($handle, $filename, collect_pod => 1) >>
    
    This works just like C<new_from_file>, except that a handle can be provided
    as the first argument.
    
    Note that there is no validation to confirm that the handle is a handle or
    something that can act like one.  Passing something that isn't a handle will
    cause a exception when trying to read from it.  The C<filename> argument is
    mandatory or undef will be returned.
    
    You are responsible for setting the decoding layers on C<$handle> if
    required.
    
    =item C<< new_from_module($module, collect_pod => 1, inc => \@dirs) >>
    
    Constructs a C<Module::Metadata> object given a module or package name.
    Returns undef if the module cannot be found.
    
    In addition to accepting the C<collect_pod> argument as described above,
    this method accepts a C<inc> argument which is a reference to an array of
    directories to search for the module.  If none are given, the default is
    @INC.
    
    If the file that contains the module begins by an UTF-8, UTF-16BE or
    UTF-16LE byte-order mark, then it is skipped before processing, and the
    content of the file is also decoded appropriately starting from perl 5.8.
    
    =item C<< find_module_by_name($module, \@dirs) >>
    
    Returns the path to a module given the module or package name. A list
    of directories can be passed in as an optional parameter, otherwise
    @INC is searched.
    
    Can be called as either an object or a class method.
    
    =item C<< find_module_dir_by_name($module, \@dirs) >>
    
    Returns the entry in C<@dirs> (or C<@INC> by default) that contains
    the module C<$module>. A list of directories can be passed in as an
    optional parameter, otherwise @INC is searched.
    
    Can be called as either an object or a class method.
    
    =item C<< provides( %options ) >>
    
    This is a convenience wrapper around C<package_versions_from_directory>
    to generate a CPAN META C<provides> data structure.  It takes key/value
    pairs.  Valid option keys include:
    
    =over
    
    =item version B<(required)>
    
    Specifies which version of the L<CPAN::Meta::Spec> should be used as
    the format of the C<provides> output.  Currently only '1.4' and '2'
    are supported (and their format is identical).  This may change in
    the future as the definition of C<provides> changes.
    
    The C<version> option is required.  If it is omitted or if
    an unsupported version is given, then C<provides> will throw an error.
    
    =item dir
    
    Directory to search recursively for F<.pm> files.  May not be specified with
    C<files>.
    
    =item files
    
    Array reference of files to examine.  May not be specified with C<dir>.
    
    =item prefix
    
    String to prepend to the C<file> field of the resulting output. This defaults
    to F<lib>, which is the common case for most CPAN distributions with their
    F<.pm> files in F<lib>.  This option ensures the META information has the
    correct relative path even when the C<dir> or C<files> arguments are
    absolute or have relative paths from a location other than the distribution
    root.
    
    =back
    
    For example, given C<dir> of 'lib' and C<prefix> of 'lib', the return value
    is a hashref of the form:
    
      {
        'Package::Name' => {
          version => '0.123',
          file => 'lib/Package/Name.pm'
        },
        'OtherPackage::Name' => ...
      }
    
    =item C<< package_versions_from_directory($dir, \@files?) >>
    
    Scans C<$dir> for .pm files (unless C<@files> is given, in which case looks
    for those files in C<$dir> - and reads each file for packages and versions,
    returning a hashref of the form:
    
      {
        'Package::Name' => {
          version => '0.123',
          file => 'Package/Name.pm'
        },
        'OtherPackage::Name' => ...
      }
    
    The C<DB> and C<main> packages are always omitted, as are any "private"
    packages that have leading underscores in the namespace (e.g.
    C<Foo::_private>)
    
    Note that the file path is relative to C<$dir> if that is specified.
    This B<must not> be used directly for CPAN META C<provides>.  See
    the C<provides> method instead.
    
    =item C<< log_info (internal) >>
    
    Used internally to perform logging; imported from Log::Contextual if
    Log::Contextual has already been loaded, otherwise simply calls warn.
    
    =back
    
    =head2 Object methods
    
    =over 4
    
    =item C<< name() >>
    
    Returns the name of the package represented by this module. If there
    is more than one package, it makes a best guess based on the
    filename. If it's a script (i.e. not a *.pm) the package name is
    'main'.
    
    =item C<< version($package) >>
    
    Returns the version as defined by the $VERSION variable for the
    package as returned by the C<name> method if no arguments are
    given. If given the name of a package it will attempt to return the
    version of that package if it is specified in the file.
    
    =item C<< filename() >>
    
    Returns the absolute path to the file.
    
    =item C<< packages_inside() >>
    
    Returns a list of packages. Note: this is a raw list of packages
    discovered (or assumed, in the case of C<main>).  It is not
    filtered for C<DB>, C<main> or private packages the way the
    C<provides> method does.  Invalid package names are not returned,
    for example "Foo:Bar".  Strange but valid package names are
    returned, for example "Foo::Bar::", and are left up to the caller
    on how to handle.
    
    =item C<< pod_inside() >>
    
    Returns a list of POD sections.
    
    =item C<< contains_pod() >>
    
    Returns true if there is any POD in the file.
    
    =item C<< pod($section) >>
    
    Returns the POD data in the given section.
    
    =item C<< is_indexable($package) >> or C<< is_indexable() >>
    
    Returns a boolean indicating whether the package (if provided) or any package
    (otherwise) is eligible for indexing by PAUSE, the Perl Authors Upload Server.
    Note This only checks for valid C<package> declarations, and does not take any
    ownership information into account.
    
    =back
    
    =head1 AUTHOR
    
    Original code from Module::Build::ModuleInfo by Ken Williams
    <kwilliams@cpan.org>, Randy W. Sims <RandyS@ThePierianSpring.org>
    
    Released as Module::Metadata by Matt S Trout (mst) <mst@shadowcat.co.uk> with
    assistance from David Golden (xdg) <dagolden@cpan.org>.
    
    =head1 COPYRIGHT & LICENSE
    
    Original code Copyright (c) 2001-2011 Ken Williams.
    Additional code Copyright (c) 2010-2011 Matt Trout and David Golden.
    All rights reserved.
    
    This library is free software; you can redistribute it and/or
    modify it under the same terms as Perl itself.
    
    =cut
    
  MODULE_METADATA
  
  $fatpacked{"Parse/CPAN/Meta.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'PARSE_CPAN_META';
    use 5.008001;
    use strict;
    package Parse::CPAN::Meta;
    # ABSTRACT: Parse META.yml and META.json CPAN metadata files
    our $VERSION = '1.4414'; # VERSION
    
    use Exporter;
    use Carp 'croak';
    
    our @ISA = qw/Exporter/;
    our @EXPORT_OK = qw/Load LoadFile/;
    
    sub load_file {
      my ($class, $filename) = @_;
    
      my $meta = _slurp($filename);
    
      if ($filename =~ /\.ya?ml$/) {
        return $class->load_yaml_string($meta);
      }
      elsif ($filename =~ /\.json$/) {
        return $class->load_json_string($meta);
      }
      else {
        $class->load_string($meta); # try to detect yaml/json
      }
    }
    
    sub load_string {
      my ($class, $string) = @_;
      if ( $string =~ /^---/ ) { # looks like YAML
        return $class->load_yaml_string($string);
      }
      elsif ( $string =~ /^\s*\{/ ) { # looks like JSON
        return $class->load_json_string($string);
      }
      else { # maybe doc-marker-free YAML
        return $class->load_yaml_string($string);
      }
    }
    
    sub load_yaml_string {
      my ($class, $string) = @_;
      my $backend = $class->yaml_backend();
      my $data = eval { no strict 'refs'; &{"$backend\::Load"}($string) };
      croak $@ if $@;
      return $data || {}; # in case document was valid but empty
    }
    
    sub load_json_string {
      my ($class, $string) = @_;
      my $data = eval { $class->json_backend()->new->decode($string) };
      croak $@ if $@;
      return $data || {};
    }
    
    sub yaml_backend {
      if (! defined $ENV{PERL_YAML_BACKEND} ) {
        _can_load( 'CPAN::Meta::YAML', 0.011 )
          or croak "CPAN::Meta::YAML 0.011 is not available\n";
        return "CPAN::Meta::YAML";
      }
      else {
        my $backend = $ENV{PERL_YAML_BACKEND};
        _can_load( $backend )
          or croak "Could not load PERL_YAML_BACKEND '$backend'\n";
        $backend->can("Load")
          or croak "PERL_YAML_BACKEND '$backend' does not implement Load()\n";
        return $backend;
      }
    }
    
    sub json_backend {
      if (! $ENV{PERL_JSON_BACKEND} or $ENV{PERL_JSON_BACKEND} eq 'JSON::PP') {
        _can_load( 'JSON::PP' => 2.27103 )
          or croak "JSON::PP 2.27103 is not available\n";
        return 'JSON::PP';
      }
      else {
        _can_load( 'JSON' => 2.5 )
          or croak  "JSON 2.5 is required for " .
                    "\$ENV{PERL_JSON_BACKEND} = '$ENV{PERL_JSON_BACKEND}'\n";
        return "JSON";
      }
    }
    
    sub _slurp {
      require Encode;
      open my $fh, "<:raw", "$_[0]" ## no critic
        or die "can't open $_[0] for reading: $!";
      my $content = do { local $/; <$fh> };
      $content = Encode::decode('UTF-8', $content, Encode::PERLQQ());
      return $content;
    }
      
    sub _can_load {
      my ($module, $version) = @_;
      (my $file = $module) =~ s{::}{/}g;
      $file .= ".pm";
      return 1 if $INC{$file};
      return 0 if exists $INC{$file}; # prior load failed
      eval { require $file; 1 }
        or return 0;
      if ( defined $version ) {
        eval { $module->VERSION($version); 1 }
          or return 0;
      }
      return 1;
    }
    
    # Kept for backwards compatibility only
    # Create an object from a file
    sub LoadFile ($) {
      return Load(_slurp(shift));
    }
    
    # Parse a document from a string.
    sub Load ($) {
      require CPAN::Meta::YAML;
      my $object = eval { CPAN::Meta::YAML::Load(shift) };
      croak $@ if $@;
      return $object;
    }
    
    1;
    
    __END__
    
    =pod
    
    =encoding UTF-8
    
    =head1 NAME
    
    Parse::CPAN::Meta - Parse META.yml and META.json CPAN metadata files
    
    =head1 VERSION
    
    version 1.4414
    
    =head1 SYNOPSIS
    
        #############################################
        # In your file
        
        ---
        name: My-Distribution
        version: 1.23
        resources:
          homepage: "http://example.com/dist/My-Distribution"
        
        
        #############################################
        # In your program
        
        use Parse::CPAN::Meta;
        
        my $distmeta = Parse::CPAN::Meta->load_file('META.yml');
        
        # Reading properties
        my $name     = $distmeta->{name};
        my $version  = $distmeta->{version};
        my $homepage = $distmeta->{resources}{homepage};
    
    =head1 DESCRIPTION
    
    B<Parse::CPAN::Meta> is a parser for F<META.json> and F<META.yml> files, using
    L<JSON::PP> and/or L<CPAN::Meta::YAML>.
    
    B<Parse::CPAN::Meta> provides three methods: C<load_file>, C<load_json_string>,
    and C<load_yaml_string>.  These will read and deserialize CPAN metafiles, and
    are described below in detail.
    
    B<Parse::CPAN::Meta> provides a legacy API of only two functions,
    based on the YAML functions of the same name. Wherever possible,
    identical calling semantics are used.  These may only be used with YAML sources.
    
    All error reporting is done with exceptions (die'ing).
    
    Note that META files are expected to be in UTF-8 encoding, only.  When
    converted string data, it must first be decoded from UTF-8.
    
    =begin Pod::Coverage
    
    
    
    
    =end Pod::Coverage
    
    =head1 METHODS
    
    =head2 load_file
    
      my $metadata_structure = Parse::CPAN::Meta->load_file('META.json');
    
      my $metadata_structure = Parse::CPAN::Meta->load_file('META.yml');
    
    This method will read the named file and deserialize it to a data structure,
    determining whether it should be JSON or YAML based on the filename.
    The file will be read using the ":utf8" IO layer.
    
    =head2 load_yaml_string
    
      my $metadata_structure = Parse::CPAN::Meta->load_yaml_string($yaml_string);
    
    This method deserializes the given string of YAML and returns the first
    document in it.  (CPAN metadata files should always have only one document.)
    If the source was UTF-8 encoded, the string must be decoded before calling
    C<load_yaml_string>.
    
    =head2 load_json_string
    
      my $metadata_structure = Parse::CPAN::Meta->load_json_string($json_string);
    
    This method deserializes the given string of JSON and the result.  
    If the source was UTF-8 encoded, the string must be decoded before calling
    C<load_json_string>.
    
    =head2 load_string
    
      my $metadata_structure = Parse::CPAN::Meta->load_string($some_string);
    
    If you don't know whether a string contains YAML or JSON data, this method
    will use some heuristics and guess.  If it can't tell, it assumes YAML.
    
    =head2 yaml_backend
    
      my $backend = Parse::CPAN::Meta->yaml_backend;
    
    Returns the module name of the YAML serializer. See L</ENVIRONMENT>
    for details.
    
    =head2 json_backend
    
      my $backend = Parse::CPAN::Meta->json_backend;
    
    Returns the module name of the JSON serializer.  This will either
    be L<JSON::PP> or L<JSON>.  Even if C<PERL_JSON_BACKEND> is set,
    this will return L<JSON> as further delegation is handled by
    the L<JSON> module.  See L</ENVIRONMENT> for details.
    
    =head1 FUNCTIONS
    
    For maintenance clarity, no functions are exported by default.  These functions
    are available for backwards compatibility only and are best avoided in favor of
    C<load_file>.
    
    =head2 Load
    
      my @yaml = Parse::CPAN::Meta::Load( $string );
    
    Parses a string containing a valid YAML stream into a list of Perl data
    structures.
    
    =head2 LoadFile
    
      my @yaml = Parse::CPAN::Meta::LoadFile( 'META.yml' );
    
    Reads the YAML stream from a file instead of a string.
    
    =head1 ENVIRONMENT
    
    =head2 PERL_JSON_BACKEND
    
    By default, L<JSON::PP> will be used for deserializing JSON data. If the
    C<PERL_JSON_BACKEND> environment variable exists, is true and is not
    "JSON::PP", then the L<JSON> module (version 2.5 or greater) will be loaded and
    used to interpret C<PERL_JSON_BACKEND>.  If L<JSON> is not installed or is too
    old, an exception will be thrown.
    
    =head2 PERL_YAML_BACKEND
    
    By default, L<CPAN::Meta::YAML> will be used for deserializing YAML data. If
    the C<PERL_YAML_BACKEND> environment variable is defined, then it is interpreted
    as a module to use for deserialization.  The given module must be installed,
    must load correctly and must implement the C<Load()> function or an exception
    will be thrown.
    
    =for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan
    
    =head1 SUPPORT
    
    =head2 Bugs / Feature Requests
    
    Please report any bugs or feature requests through the issue tracker
    at L<http://rt.cpan.org/Public/Dist/Display.html?Name=Parse-CPAN-Meta>.
    You will be notified automatically of any progress on your issue.
    
    =head2 Source Code
    
    This is open source software.  The code repository is available for
    public review and contribution under the terms of the license.
    
    L<https://github.com/Perl-Toolchain-Gang/Parse-CPAN-Meta>
    
      git clone https://github.com/Perl-Toolchain-Gang/Parse-CPAN-Meta.git
    
    =head1 AUTHORS
    
    =over 4
    
    =item *
    
    Adam Kennedy <adamk@cpan.org>
    
    =item *
    
    David Golden <dagolden@cpan.org>
    
    =back
    
    =head1 CONTRIBUTORS
    
    =over 4
    
    =item *
    
    Graham Knop <haarg@haarg.org>
    
    =item *
    
    Joshua ben Jore <jjore@cpan.org>
    
    =item *
    
    Neil Bowers <neil@bowers.com>
    
    =item *
    
    Ricardo Signes <rjbs@cpan.org>
    
    =item *
    
    Steffen Mueller <smueller@cpan.org>
    
    =back
    
    =head1 COPYRIGHT AND LICENSE
    
    This software is copyright (c) 2014 by Adam Kennedy and Contributors.
    
    This is free software; you can redistribute it and/or modify it under
    the same terms as the Perl 5 programming language system itself.
    
    =cut
  PARSE_CPAN_META
  
  $fatpacked{"Parse/PMFile.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'PARSE_PMFILE';
    package Parse::PMFile;
    
    sub __clean_eval { eval $_[0] } # needs to be here (RT#101273)
    
    use strict;
    use warnings;
    use Safe;
    use JSON::PP ();
    use Dumpvalue;
    use version ();
    use File::Spec ();
    
    our $VERSION = '0.35';
    our $VERBOSE = 0;
    our $ALLOW_DEV_VERSION = 0;
    our $FORK = 0;
    our $UNSAFE = $] < 5.010000 ? 1 : 0;
    
    sub new {
        my ($class, $meta, $opts) = @_;
        bless {%{ $opts || {} }, META_CONTENT => $meta}, $class;
    }
    
    # from PAUSE::pmfile::examine_fio
    sub parse {
        my ($self, $pmfile) = @_;
    
        $pmfile =~ s|\\|/|g;
    
        my($filemtime) = (stat $pmfile)[9];
        $self->{MTIME} = $filemtime;
        $self->{PMFILE} = $pmfile;
    
        unless ($self->_version_from_meta_ok) {
            my $version;
            unless (eval { $version = $self->_parse_version; 1 }) {
              $self->_verbose(1, "error with version in $pmfile: $@");
              return;
            }
    
            $self->{VERSION} = $version;
            if ($self->{VERSION} =~ /^\{.*\}$/) {
                # JSON error message
            } elsif ($self->{VERSION} =~ /[_\s]/ && !$self->{ALLOW_DEV_VERSION} && !$ALLOW_DEV_VERSION){   # ignore developer releases and "You suck!"
                return;
            }
        }
    
        my($ppp) = $self->_packages_per_pmfile;
        my @keys_ppp = $self->_filter_ppps(sort keys %$ppp);
        $self->_verbose(1,"Will check keys_ppp[@keys_ppp]\n");
    
        #
        # Immediately after each package (pmfile) examined contact
        # the database
        #
    
        my ($package, %errors);
        my %checked_in;
      DBPACK: foreach $package (@keys_ppp) {
            # this part is taken from PAUSE::package::examine_pkg
            # and PAUSE::package::_pkg_name_insane
            if ($package !~ /^\w[\w\:\']*\w?\z/
             || $package !~ /\w\z/
             || $package =~ /:/ && $package !~ /::/
             || $package =~ /\w:\w/
             || $package =~ /:::/
            ){
                $self->_verbose(1,"Package[$package] did not pass the ultimate sanity check");
                delete $ppp->{$package};
                next;
            }
    
            if ($self->{USERID} && $self->{PERMISSIONS} && !$self->_perm_check($package)) {
                delete $ppp->{$package};
                next;
            }
    
            # Check that package name matches case of file name
            {
              my (undef, $module) = split m{/lib/}, $self->{PMFILE}, 2;
              if ($module) {
                $module =~ s{\.pm\z}{};
                $module =~ s{/}{::}g;
    
                if (lc $module eq lc $package && $module ne $package) {
                  # warn "/// $self->{PMFILE} vs. $module vs. $package\n";
                  $errors{$package} = {
                    indexing_warning => "Capitalization of package ($package) does not match filename!",
                    infile => $self->{PMFILE},
                  };
                }
              }
            }
    
            my $pp = $ppp->{$package};
            if ($pp->{version} && $pp->{version} =~ /^\{.*\}$/) { # JSON parser error
                my $err = JSON::PP::decode_json($pp->{version});
                if ($err->{x_normalize}) {
                    $errors{$package} = {
                        normalize => $err->{version},
                        infile => $pp->{infile},
                    };
                    $pp->{version} = "undef";
                } elsif ($err->{openerr}) {
                    $pp->{version} = "undef";
                    $self->_verbose(1,
                                  qq{Parse::PMFile was not able to
            read the file. It issued the following error: C< $err->{r} >},
                                  );
                    $errors{$package} = {
                        open => $err->{r},
                        infile => $pp->{infile},
                    };
                } else {
                    $pp->{version} = "undef";
                    $self->_verbose(1, 
                                  qq{Parse::PMFile was not able to
            parse the following line in that file: C< $err->{line} >
    
            Note: the indexer is running in a Safe compartement and cannot
            provide the full functionality of perl in the VERSION line. It
            is trying hard, but sometime it fails. As a workaround, please
            consider writing a META.yml that contains a 'provides'
            attribute or contact the CPAN admins to investigate (yet
            another) workaround against "Safe" limitations.)},
    
                                  );
                    $errors{$package} = {
                        parse_version => $err->{line},
                        infile => $err->{file},
                    };
                }
            }
    
            # Sanity checks
    
            for (
                $package,
                $pp->{version},
            ) {
                if (!defined || /^\s*$/ || /\s/){  # for whatever reason I come here
                    delete $ppp->{$package};
                    next;            # don't screw up 02packages
                }
            }
            $checked_in{$package} = $ppp->{$package};
        }                       # end foreach package
    
        return (wantarray && %errors) ? (\%checked_in, \%errors) : \%checked_in;
    }
    
    sub _perm_check {
        my ($self, $package) = @_;
        my $userid = $self->{USERID};
        my $module = $self->{PERMISSIONS}->module_permissions($package);
        return 1 if !$module; # not listed yet
        return 1 if defined $module->m && $module->m eq $userid;
        return 1 if defined $module->f && $module->f eq $userid;
        return 1 if defined $module->c && grep {$_ eq $userid} @{$module->c};
        return;
    }
    
    # from PAUSE::pmfile;
    sub _parse_version {
        my $self = shift;
    
        use strict;
    
        my $pmfile = $self->{PMFILE};
        my $tmpfile = File::Spec->catfile(File::Spec->tmpdir, "ParsePMFile$$" . rand(1000));
    
        my $pmcp = $pmfile;
        for ($pmcp) {
            s/([^\\](\\\\)*)@/$1\\@/g; # thanks to Raphael Manfredi for the
            # solution to escape @s and \
        }
        my($v);
        {
    
            package main; # seems necessary
    
            # XXX: do we need to fork as PAUSE does?
            # or, is alarm() just fine?
            my $pid;
            if ($self->{FORK} || $FORK) {
                $pid = fork();
                die "Can't fork: $!" unless defined $pid;
            }
            if ($pid) {
                waitpid($pid, 0);
                if (open my $fh, '<', $tmpfile) {
                    $v = <$fh>;
                }
            } else {
                # XXX Limit Resources too
    
                my($comp) = Safe->new;
                my $eval = qq{
                    local(\$^W) = 0;
                    Parse::PMFile::_parse_version_safely("$pmcp");
                };
                $comp->permit("entereval"); # for MBARBON/Module-Info-0.30.tar.gz
                $comp->share("*Parse::PMFile::_parse_version_safely");
                $comp->share("*version::new");
                $comp->share("*version::numify");
                $comp->share_from('main', ['*version::',
                                            '*charstar::',
                                            '*Exporter::',
                                            '*DynaLoader::']);
                $comp->share_from('version', ['&qv']);
                $comp->permit(":base_math"); # atan2 (Acme-Pi)
                # $comp->permit("require"); # no strict!
                $comp->deny(qw/enteriter iter unstack goto/); # minimum protection against Acme::BadExample
    
                version->import('qv') if $self->{UNSAFE} || $UNSAFE;
                {
                    no strict;
                    $v = ($self->{UNSAFE} || $UNSAFE) ? eval $eval : $comp->reval($eval);
                }
                if ($@){ # still in the child process, out of Safe::reval
                    my $err = $@;
                    # warn ">>>>>>>err[$err]<<<<<<<<";
                    if (ref $err) {
                        if ($err->{line} =~ /([\$*])([\w\:\']*)\bVERSION\b.*?\=(.*)/) {
                            local($^W) = 0;
                            my ($sigil, $vstr) = ($1, $3);
                            $self->_restore_overloaded_stuff(1) if $err->{line} =~ /use\s+version\b|version\->|qv\(/;
                            $v = ($self->{UNSAFE} || $UNSAFE) ? eval $vstr : $comp->reval($vstr);
                            $v = $$v if $sigil eq '*' && ref $v;
                        }
                        if ($@ or !$v) {
                            $self->_verbose(1, sprintf("reval failed: err[%s] for eval[%s]",
                                          JSON::PP::encode_json($err),
                                          $eval,
                                        ));
                            $v = JSON::PP::encode_json($err);
                        }
                    } else {
                        $v = JSON::PP::encode_json({ openerr => $err });
                    }
                }
                if (defined $v) {
                    $v = $v->numify if ref($v) =~ /^version(::vpp)?$/;
                } else {
                    $v = "";
                }
                if ($self->{FORK} || $FORK) {
                    open my $fh, '>:utf8', $tmpfile;
                    print $fh $v;
                    exit 0;
                } else {
                    utf8::encode($v);
                    # undefine empty $v as if read from the tmpfile
                    $v = undef if defined $v && !length $v;
                    $comp->erase;
                    $self->_restore_overloaded_stuff;
                }
            }
        }
        unlink $tmpfile if ($self->{FORK} || $FORK) && -e $tmpfile;
    
        return $self->_normalize_version($v);
    }
    
    sub _restore_overloaded_stuff {
        my ($self, $used_version_in_safe) = @_;
        return if $self->{UNSAFE} || $UNSAFE;
    
        no strict 'refs';
        no warnings 'redefine';
    
        # version XS in CPAN
        my $restored;
        if ($INC{'version/vxs.pm'}) {
            *{'version::(""'} = \&version::vxs::stringify;
            *{'version::(0+'} = \&version::vxs::numify;
            *{'version::(cmp'} = \&version::vxs::VCMP;
            *{'version::(<=>'} = \&version::vxs::VCMP;
            *{'version::(bool'} = \&version::vxs::boolean;
            $restored = 1;
        }
        # version PP in CPAN
        if ($INC{'version/vpp.pm'}) {
            {
                package # hide from PAUSE
                    charstar;
                overload->import;
            }
            if (!$used_version_in_safe) {
                package # hide from PAUSE
                    version::vpp;
                overload->import;
            }
            unless ($restored) {
                *{'version::(""'} = \&version::vpp::stringify;
                *{'version::(0+'} = \&version::vpp::numify;
                *{'version::(cmp'} = \&version::vpp::vcmp;
                *{'version::(<=>'} = \&version::vpp::vcmp;
                *{'version::(bool'} = \&version::vpp::vbool;
            }
            *{'version::vpp::(""'} = \&version::vpp::stringify;
            *{'version::vpp::(0+'} = \&version::vpp::numify;
            *{'version::vpp::(cmp'} = \&version::vpp::vcmp;
            *{'version::vpp::(<=>'} = \&version::vpp::vcmp;
            *{'version::vpp::(bool'} = \&version::vpp::vbool;
            *{'charstar::(""'} = \&charstar::thischar;
            *{'charstar::(0+'} = \&charstar::thischar;
            *{'charstar::(++'} = \&charstar::increment;
            *{'charstar::(--'} = \&charstar::decrement;
            *{'charstar::(+'} = \&charstar::plus;
            *{'charstar::(-'} = \&charstar::minus;
            *{'charstar::(*'} = \&charstar::multiply;
            *{'charstar::(cmp'} = \&charstar::cmp;
            *{'charstar::(<=>'} = \&charstar::spaceship;
            *{'charstar::(bool'} = \&charstar::thischar;
            *{'charstar::(='} = \&charstar::clone;
            $restored = 1;
        }
        # version in core
        if (!$restored) {
            *{'version::(""'} = \&version::stringify;
            *{'version::(0+'} = \&version::numify;
            *{'version::(cmp'} = \&version::vcmp;
            *{'version::(<=>'} = \&version::vcmp;
            *{'version::(bool'} = \&version::boolean;
        }
    }
    
    # from PAUSE::pmfile;
    sub _packages_per_pmfile {
        my $self = shift;
    
        my $ppp = {};
        my $pmfile = $self->{PMFILE};
        my $filemtime = $self->{MTIME};
        my $version = $self->{VERSION};
    
        $DB::single++;
        open my $fh, "<", "$pmfile" or return $ppp;
    
        local $/ = "\n";
        my $inpod = 0;
    
      PLINE: while (<$fh>) {
            chomp;
            my($pline) = $_;
            $inpod = $pline =~ /^=(?!cut)/ ? 1 :
                $pline =~ /^=cut/ ? 0 : $inpod;
            next if $inpod;
            next if substr($pline,0,4) eq "=cut";
    
            $pline =~ s/\#.*//;
            next if $pline =~ /^\s*$/;
            if ($pline =~ /^__(?:END|DATA)__\b/
                and $pmfile !~ /\.PL$/   # PL files may well have code after __DATA__
                ){
                last PLINE;
            }
    
            my $pkg;
            my $strict_version;
    
            if (
                $pline =~ m{
                          # (.*) # takes too much time if $pline is long
                          (?<![*\$\\@%&]) # no sigils
                          \bpackage\s+
                          ([\w\:\']+)
                          \s*
                          (?: $ | [\}\;] | \{ | \s+($version::STRICT) )
                        }x) {
                $pkg = $1;
                $strict_version = $2;
                if ($pkg eq "DB"){
                    # XXX if pumpkin and perl make him comaintainer! I
                    # think I always made the pumpkins comaint on DB
                    # without further ado (?)
                    next PLINE;
                }
            }
    
            if ($pkg) {
                # Found something
    
                # from package
                $pkg =~ s/\'/::/;
                next PLINE unless $pkg =~ /^[A-Za-z]/;
                next PLINE unless $pkg =~ /\w$/;
                next PLINE if $pkg eq "main";
                # Perl::Critic::Policy::TestingAndDebugging::ProhibitShebangWarningsArg
                # database for modid in mods, package in packages, package in perms
                # alter table mods modify modid varchar(128) binary NOT NULL default '';
                # alter table packages modify package varchar(128) binary NOT NULL default '';
                next PLINE if length($pkg) > 128;
                #restriction
                $ppp->{$pkg}{parsed}++;
                $ppp->{$pkg}{infile} = $pmfile;
                if ($self->_simile($pmfile,$pkg)) {
                    $ppp->{$pkg}{simile} = $pmfile;
                    if ($self->_version_from_meta_ok) {
                        my $provides = $self->{META_CONTENT}{provides};
                        if (exists $provides->{$pkg}) {
                            if (defined $provides->{$pkg}{version}) {
                                my $v = $provides->{$pkg}{version};
                                if ($v =~ /[_\s]/ && !$self->{ALLOW_DEV_VERSION} && !$ALLOW_DEV_VERSION){   # ignore developer releases and "You suck!"
                                    next PLINE;
                                }
    
                                unless (eval { $version = $self->_normalize_version($v); 1 }) {
                                  $self->_verbose(1, "error with version in $pmfile: $@");
                                  next;
    
                                }
                                $ppp->{$pkg}{version} = $version;
                            } else {
                                $ppp->{$pkg}{version} = "undef";
                            }
                        }
                    } else {
                        if (defined $strict_version){
                            $ppp->{$pkg}{version} = $strict_version ;
                        } else {
                            $ppp->{$pkg}{version} = defined $version ? $version : "";
                        }
                        no warnings;
                        if ($version eq 'undef') {
                            $ppp->{$pkg}{version} = $version unless defined $ppp->{$pkg}{version};
                        } else {
                            $ppp->{$pkg}{version} =
                                $version
                                    if $version
                                        > $ppp->{$pkg}{version} ||
                                            $version
                                                gt $ppp->{$pkg}{version};
                        }
                    }
                } else {        # not simile
                    #### it comes later, it would be nonsense
                    #### to set to "undef". MM_Unix gives us
                    #### the best we can reasonably consider
                    $ppp->{$pkg}{version} =
                        $version
                            unless defined $ppp->{$pkg}{version} &&
                                length($ppp->{$pkg}{version});
                }
                $ppp->{$pkg}{filemtime} = $filemtime;
            } else {
                # $self->_verbose(2,"no pkg found");
            }
        }
    
        close $fh;
        $ppp;
    }
    
    # from PAUSE::pmfile;
    {
        no strict;
        sub _parse_version_safely {
            my($parsefile) = @_;
            my $result;
            local *FH;
            local $/ = "\n";
            open(FH,$parsefile) or die "Could not open '$parsefile': $!";
            my $inpod = 0;
            while (<FH>) {
                $inpod = /^=(?!cut)/ ? 1 : /^=cut/ ? 0 : $inpod;
                next if $inpod || /^\s*#/;
                last if /^__(?:END|DATA)__\b/; # fails on quoted __END__ but this is rare -> __END__ in the middle of a line is rarer
                chop;
    
                if (my ($ver) = /package \s+ \S+ \s+ (\S+) \s* [;{]/x) {
                  # XXX: should handle this better if version is bogus -- rjbs,
                  # 2014-03-16
                  return $ver if version::is_lax($ver);
                }
    
                # next unless /\$(([\w\:\']*)\bVERSION)\b.*\=/;
                next unless /(?<!\\)([\$*])(([\w\:\']*)\bVERSION)\b.*(?<![!><=])\=(?![=>])/;
                my $current_parsed_line = $_;
                my $eval = qq{
                    package #
                        ExtUtils::MakeMaker::_version;
    
                    local $1$2;
                    \$$2=undef; do {
                        $_
                    }; \$$2
                };
                local $^W = 0;
                local $SIG{__WARN__} = sub {};
                $result = __clean_eval($eval);
                # warn "current_parsed_line[$current_parsed_line]\$\@[$@]";
                if ($@ or !defined $result){
                    die +{
                          eval => $eval,
                          line => $current_parsed_line,
                          file => $parsefile,
                          err => $@,
                          };
                }
                last;
            } #;
            close FH;
    
            $result = "undef" unless defined $result;
            if ((ref $result) =~ /^version(?:::vpp)?\b/) {
                $result = $result->numify;
            }
            return $result;
        }
    }
    
    # from PAUSE::pmfile;
    sub _filter_ppps {
        my($self,@ppps) = @_;
        my @res;
    
        # very similar code is in PAUSE::dist::filter_pms
      MANI: for my $ppp ( @ppps ) {
            if ($self->{META_CONTENT}){
                my $no_index = $self->{META_CONTENT}{no_index}
                                || $self->{META_CONTENT}{private}; # backward compat
                if (ref($no_index) eq 'HASH') {
                    my %map = (
                                package => qr{\z},
                                namespace => qr{::},
                              );
                    for my $k (qw(package namespace)) {
                        next unless my $v = $no_index->{$k};
                        my $rest = $map{$k};
                        if (ref $v eq "ARRAY") {
                            for my $ve (@$v) {
                                $ve =~ s|::$||;
                                if ($ppp =~ /^$ve$rest/){
                                    $self->_verbose(1,"Skipping ppp[$ppp] due to ve[$ve]");
                                    next MANI;
                                } else {
                                    $self->_verbose(1,"NOT skipping ppp[$ppp] due to ve[$ve]");
                                }
                            }
                        } else {
                            $v =~ s|::$||;
                            if ($ppp =~ /^$v$rest/){
                                $self->_verbose(1,"Skipping ppp[$ppp] due to v[$v]");
                                next MANI;
                            } else {
                                $self->_verbose(1,"NOT skipping ppp[$ppp] due to v[$v]");
                            }
                        }
                    }
                } else {
                    $self->_verbose(1,"No keyword 'no_index' or 'private' in META_CONTENT");
                }
            } else {
                # $self->_verbose(1,"no META_CONTENT"); # too noisy
            }
            push @res, $ppp;
        }
        $self->_verbose(1,"Result of filter_ppps: res[@res]");
        @res;
    }
    
    # from PAUSE::pmfile;
    sub _simile {
        my($self,$file,$package) = @_;
        # MakeMaker gives them the chance to have the file Simple.pm in
        # this directory but have the package HTML::Simple in it.
        # Afaik, they wouldn't be able to do so with deeper nested packages
        $file =~ s|.*/||;
        $file =~ s|\.pm(?:\.PL)?||;
        my $ret = $package =~ m/\b\Q$file\E$/;
        $ret ||= 0;
        unless ($ret) {
            # Apache::mod_perl_guide stuffs it into Version.pm
            $ret = 1 if lc $file eq 'version';
        }
        $self->_verbose(1,"Result of simile(): file[$file] package[$package] ret[$ret]\n");
        $ret;
    }
    
    # from PAUSE::pmfile
    sub _normalize_version {
        my($self,$v) = @_;
        $v = "undef" unless defined $v;
        my $dv = Dumpvalue->new;
        my $sdv = $dv->stringify($v,1); # second argument prevents ticks
        $self->_verbose(1,"Result of normalize_version: sdv[$sdv]\n");
    
        return $v if $v eq "undef";
        return $v if $v =~ /^\{.*\}$/; # JSON object
        $v =~ s/^\s+//;
        $v =~ s/\s+\z//;
        if ($v =~ /_/) {
            # XXX should pass something like EDEVELOPERRELEASE up e.g.
            # SIXTEASE/XML-Entities-0.0306.tar.gz had nothing but one
            # such modules and the mesage was not helpful that "nothing
            # was found".
            return $v ;
        }
        if (!version::is_lax($v)) {
            return JSON::PP::encode_json({ x_normalize => 'version::is_lax failed', version => $v });
        }
        # may warn "Integer overflow"
        my $vv = eval { no warnings; version->new($v)->numify };
        if ($@) {
            # warn "$v: $@";
            return JSON::PP::encode_json({ x_normalize => $@, version => $v });
            # return "undef";
        }
        if ($vv eq $v) {
            # the boring 3.14
        } else {
            my $forced = $self->_force_numeric($v);
            if ($forced eq $vv) {
            } elsif ($forced =~ /^v(.+)/) {
                # rare case where a v1.0.23 slipped in (JANL/w3mir-1.0.10.tar.gz)
                $vv = version->new($1)->numify;
            } else {
                # warn "Unequal forced[$forced] and vv[$vv]";
                if ($forced == $vv) {
                    # the trailing zeroes would cause unnecessary havoc
                    $vv = $forced;
                }
            }
        }
        return $vv;
    }
    
    # from PAUSE::pmfile;
    sub _force_numeric {
        my($self,$v) = @_;
        $v = $self->_readable($v);
    
        if (
            $v =~
            /^(\+?)(\d*)(\.(\d*))?/ &&
            # "$2$4" ne ''
            (
              defined $2 && length $2
              ||
              defined $4 && length $4
            )
            ) {
            my $two = defined $2 ? $2 : "";
            my $three = defined $3 ? $3 : "";
            $v = "$two$three";
        }
        # no else branch! We simply say, everything else is a string.
        $v;
    }
    
    # from PAUSE::dist
    sub _version_from_meta_ok {
      my($self) = @_;
      return $self->{VERSION_FROM_META_OK} if exists $self->{VERSION_FROM_META_OK};
      my $c = $self->{META_CONTENT};
    
      # If there's no provides hash, we can't get our module versions from the
      # provides hash! -- rjbs, 2012-03-31
      return($self->{VERSION_FROM_META_OK} = 0) unless $c->{provides};
    
      # Some versions of Module::Build geneated an empty provides hash.  If we're
      # *not* looking at a Module::Build-generated metafile, then it's okay.
      my ($mb_v) = (defined $c->{generated_by} ? $c->{generated_by} : '') =~ /Module::Build version ([\d\.]+)/;
      return($self->{VERSION_FROM_META_OK} = 1) unless $mb_v;
    
      # ??? I don't know why this is here.
      return($self->{VERSION_FROM_META_OK} = 1) if $mb_v eq '0.250.0';
    
      if ($mb_v >= 0.19 && $mb_v < 0.26 && ! keys %{$c->{provides}}) {
          # RSAVAGE/Javascript-SHA1-1.01.tgz had an empty provides hash. Ron
          # did not find the reason why this happened, but let's not go
          # overboard, 0.26 seems a good threshold from the statistics: there
          # are not many empty provides hashes from 0.26 up.
          return($self->{VERSION_FROM_META_OK} = 0);
      }
    
      # We're not in the suspect range of M::B versions.  It's good to go.
      return($self->{VERSION_FROM_META_OK} = 1);
    }
    
    sub _verbose {
        my($self,$level,@what) = @_;
        warn @what if $level <= ((ref $self && $self->{VERBOSE}) || $VERBOSE);
    }
    
    # all of the following methods are stripped from CPAN::Version
    # (as of version 5.5001, bundled in CPAN 2.03), and slightly
    # modified (ie. made private, as well as CPAN->debug(...) are
    # replaced with $self->_verbose(9, ...).)
    
    # CPAN::Version::vcmp courtesy Jost Krieger
    sub _vcmp {
        my($self,$l,$r) = @_;
        local($^W) = 0;
        $self->_verbose(9, "l[$l] r[$r]");
    
        return 0 if $l eq $r; # short circuit for quicker success
    
        for ($l,$r) {
            s/_//g;
        }
        $self->_verbose(9, "l[$l] r[$r]");
        for ($l,$r) {
            next unless tr/.// > 1 || /^v/;
            s/^v?/v/;
            1 while s/\.0+(\d)/.$1/; # remove leading zeroes per group
        }
        $self->_verbose(9, "l[$l] r[$r]");
        if ($l=~/^v/ <=> $r=~/^v/) {
            for ($l,$r) {
                next if /^v/;
                $_ = $self->_float2vv($_);
            }
        }
        $self->_verbose(9, "l[$l] r[$r]");
        my $lvstring = "v0";
        my $rvstring = "v0";
        if ($] >= 5.006
         && $l =~ /^v/
         && $r =~ /^v/) {
            $lvstring = $self->_vstring($l);
            $rvstring = $self->_vstring($r);
            $self->_verbose(9, sprintf "lv[%vd] rv[%vd]", $lvstring, $rvstring);
        }
    
        return (
                ($l ne "undef") <=> ($r ne "undef")
                ||
                $lvstring cmp $rvstring
                ||
                $l <=> $r
                ||
                $l cmp $r
        );
    }
    
    sub _vgt {
        my($self,$l,$r) = @_;
        $self->_vcmp($l,$r) > 0;
    }
    
    sub _vlt {
        my($self,$l,$r) = @_;
        $self->_vcmp($l,$r) < 0;
    }
    
    sub _vge {
        my($self,$l,$r) = @_;
        $self->_vcmp($l,$r) >= 0;
    }
    
    sub _vle {
        my($self,$l,$r) = @_;
        $self->_vcmp($l,$r) <= 0;
    }
    
    sub _vstring {
        my($self,$n) = @_;
        $n =~ s/^v// or die "Parse::PMFile::_vstring() called with invalid arg [$n]";
        pack "U*", split /\./, $n;
    }
    
    # vv => visible vstring
    sub _float2vv {
        my($self,$n) = @_;
        my($rev) = int($n);
        $rev ||= 0;
        my($mantissa) = $n =~ /\.(\d{1,12})/; # limit to 12 digits to limit
                                              # architecture influence
        $mantissa ||= 0;
        $mantissa .= "0" while length($mantissa)%3;
        my $ret = "v" . $rev;
        while ($mantissa) {
            $mantissa =~ s/(\d{1,3})// or
                die "Panic: length>0 but not a digit? mantissa[$mantissa]";
            $ret .= ".".int($1);
        }
        # warn "n[$n]ret[$ret]";
        $ret =~ s/(\.0)+/.0/; # v1.0.0 => v1.0
        $ret;
    }
    
    sub _readable {
        my($self,$n) = @_;
        $n =~ /^([\w\-\+\.]+)/;
    
        return $1 if defined $1 && length($1)>0;
        # if the first user reaches version v43, he will be treated as "+".
        # We'll have to decide about a new rule here then, depending on what
        # will be the prevailing versioning behavior then.
    
        if ($] < 5.006) { # or whenever v-strings were introduced
            # we get them wrong anyway, whatever we do, because 5.005 will
            # have already interpreted 0.2.4 to be "0.24". So even if he
            # indexer sends us something like "v0.2.4" we compare wrongly.
    
            # And if they say v1.2, then the old perl takes it as "v12"
    
            $self->_verbose(9, "Suspicious version string seen [$n]\n");
            return $n;
        }
        my $better = sprintf "v%vd", $n;
        $self->_verbose(9, "n[$n] better[$better]");
        return $better;
    }
    
    1;
    
    __END__
    
    =head1 NAME
    
    Parse::PMFile - parses .pm file as PAUSE does
    
    =head1 SYNOPSIS
    
        use Parse::PMFile;
    
        my $parser = Parse::PMFile->new($metadata, {VERBOSE => 1});
        my $packages_info = $parser->parse($pmfile);
    
        # if you need info about invalid versions
        my ($packages_info, $errors) = $parser->parse($pmfile);
    
        # to check permissions
        my $parser = Parse::PMFile->new($metadata, {
            USERID => 'ISHIGAKI',
            PERMISSIONS => PAUSE::Permissions->new,
        });
    
    =head1 DESCRIPTION
    
    The most of the code of this module is taken from the PAUSE code as of April 2013 almost verbatim. Thus, the heart of this module should be quite stable. However, I made it not to use pipe ("-|") as well as I stripped database-related code. If you encounter any issue, that's most probably because of my modification.
    
    This module doesn't provide features to extract a distribution or parse meta files intentionally.
    
    =head1 METHODS
    
    =head2 new
    
    creates an object. You can also pass a hashref taken from META.yml etc, and an optional hashref. Options are:
    
    =over 4
    
    =item ALLOW_DEV_VERSION
    
    Parse::PMFile usually ignores a version with an underscore as PAUSE does (because it's for a developer release, and should not be indexed). Set this option to true if you happen to need to keep such a version for better analysis.
    
    =item VERBOSE
    
    Set this to true if you need to know some details.
    
    =item FORK
    
    As of version 0.17, Parse::PMFile stops forking while parsing a version for better performance. Parse::PMFile should return the same result no matter how this option is set, but if you do care, set this to true to fork as PAUSE does.
    
    =item USERID, PERMISSIONS
    
    As of version 0.21, Parse::PMFile checks permissions of a package if both USERID and PERMISSIONS (which should be an instance of L<PAUSE::Permissions>) are provided. Unauthorized packages are removed.
    
    =item UNSAFE
    
    Parse::PMFile usually parses a module version in a Safe compartment. However, this approach doesn't work smoothly under older perls (prior to 5.10) plus some combinations of recent versions of Safe.pm (2.24 and above) and version.pm (0.9905 and above) for various reasons. As of version 0.27, Parse::PMFile simply uses C<eval> to parse a version under older perls. If you want it to use always C<eval> (even under recent perls), set this to true.
    
    =back
    
    =head2 parse
    
    takes a path to a .pm file, and returns a hash reference that holds information for package(s) found in the file.
    
    =head1 SEE ALSO
    
    L<Parse::LocalDistribution>, L<PAUSE::Permissions>
    
    Most part of this module is derived from PAUSE and CPAN::Version.
    
    L<https://github.com/andk/pause>
    
    L<https://github.com/andk/cpanpm>
    
    =head1 AUTHOR
    
    Andreas Koenig E<lt>andreas.koenig@anima.deE<gt>
    
    Kenichi Ishigaki, E<lt>ishigaki@cpan.orgE<gt>
    
    =head1 COPYRIGHT AND LICENSE
    
    Copyright 1995 - 2013 by Andreas Koenig E<lt>andk@cpan.orgE<gt> for most of the code.
    
    Copyright 2013 by Kenichi Ishigaki for some.
    
    This program is free software; you can redistribute it and/or
    modify it under the same terms as Perl itself.
    
    =cut
  PARSE_PMFILE
  
  $fatpacked{"String/ShellQuote.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'STRING_SHELLQUOTE';
    # $Id: ShellQuote.pm,v 1.11 2010-06-11 20:08:57 roderick Exp $
    #
    # Copyright (c) 1997 Roderick Schertler.  All rights reserved.  This
    # program is free software; you can redistribute it and/or modify it
    # under the same terms as Perl itself.
    
    =head1 NAME
    
    String::ShellQuote - quote strings for passing through the shell
    
    =head1 SYNOPSIS
    
        $string = shell_quote @list;
        $string = shell_quote_best_effort @list;
        $string = shell_comment_quote $string;
    
    =head1 DESCRIPTION
    
    This module contains some functions which are useful for quoting strings
    which are going to pass through the shell or a shell-like object.
    
    =over
    
    =cut
    
    package String::ShellQuote;
    
    use strict;
    use vars qw($VERSION @ISA @EXPORT);
    
    require Exporter;
    
    $VERSION	= '1.04';
    @ISA		= qw(Exporter);
    @EXPORT		= qw(shell_quote shell_quote_best_effort shell_comment_quote);
    
    sub croak {
        require Carp;
        goto &Carp::croak;
    }
    
    sub _shell_quote_backend {
        my @in = @_;
        my @err = ();
    
        if (0) {
    	require RS::Handy;
    	print RS::Handy::data_dump(\@in);
        }
    
        return \@err, '' unless @in;
    
        my $ret = '';
        my $saw_non_equal = 0;
        foreach (@in) {
    	if (!defined $_ or $_ eq '') {
    	    $_ = "''";
    	    next;
    	}
    
    	if (s/\x00//g) {
    	    push @err, "No way to quote string containing null (\\000) bytes";
    	}
    
        	my $escape = 0;
    
    	# = needs quoting when it's the first element (or part of a
    	# series of such elements), as in command position it's a
    	# program-local environment setting
    
    	if (/=/) {
    	    if (!$saw_non_equal) {
    	    	$escape = 1;
    	    }
    	}
    	else {
    	    $saw_non_equal = 1;
    	}
    
    	if (m|[^\w!%+,\-./:=@^]|) {
    	    $escape = 1;
    	}
    
    	if ($escape
    		|| (!$saw_non_equal && /=/)) {
    
    	    # ' -> '\''
        	    s/'/'\\''/g;
    
    	    # make multiple ' in a row look simpler
    	    # '\'''\'''\'' -> '"'''"'
        	    s|((?:'\\''){2,})|q{'"} . (q{'} x (length($1) / 4)) . q{"'}|ge;
    
    	    $_ = "'$_'";
    	    s/^''//;
    	    s/''$//;
    	}
        }
        continue {
    	$ret .= "$_ ";
        }
    
        chop $ret;
        return \@err, $ret;
    }
    
    =item B<shell_quote> [I<string>]...
    
    B<shell_quote> quotes strings so they can be passed through the shell.
    Each I<string> is quoted so that the shell will pass it along as a
    single argument and without further interpretation.  If no I<string>s
    are given an empty string is returned.
    
    If any I<string> can't be safely quoted B<shell_quote> will B<croak>.
    
    =cut
    
    sub shell_quote {
        my ($rerr, $s) = _shell_quote_backend @_;
    
        if (@$rerr) {
        	my %seen;
        	@$rerr = grep { !$seen{$_}++ } @$rerr;
    	my $s = join '', map { "shell_quote(): $_\n" } @$rerr;
    	chomp $s;
    	croak $s;
        }
        return $s;
    }
    
    =item B<shell_quote_best_effort> [I<string>]...
    
    This is like B<shell_quote>, excpet if the string can't be safely quoted
    it does the best it can and returns the result, instead of dying.
    
    =cut
    
    sub shell_quote_best_effort {
        my ($rerr, $s) = _shell_quote_backend @_;
    
        return $s;
    }
    
    =item B<shell_comment_quote> [I<string>]
    
    B<shell_comment_quote> quotes the I<string> so that it can safely be
    included in a shell-style comment (the current algorithm is that a sharp
    character is placed after any newlines in the string).
    
    This routine might be changed to accept multiple I<string> arguments
    in the future.  I haven't done this yet because I'm not sure if the
    I<string>s should be joined with blanks ($") or nothing ($,).  Cast
    your vote today!  Be sure to justify your answer.
    
    =cut
    
    sub shell_comment_quote {
        return '' unless @_;
        unless (@_ == 1) {
    	croak "Too many arguments to shell_comment_quote "
    	    	    . "(got " . @_ . " expected 1)";
        }
        local $_ = shift;
        s/\n/\n#/g;
        return $_;
    }
    
    1;
    
    __END__
    
    =back
    
    =head1 EXAMPLES
    
        $cmd = 'fuser 2>/dev/null ' . shell_quote @files;
        @pids = split ' ', `$cmd`;
    
        print CFG "# Configured by: ",
    		shell_comment_quote($ENV{LOGNAME}), "\n";
    
    =head1 BUGS
    
    Only Bourne shell quoting is supported.  I'd like to add other shells
    (particularly cmd.exe), but I'm not familiar with them.  It would be a
    big help if somebody supplied the details.
    
    =head1 AUTHOR
    
    Roderick Schertler <F<roderick@argon.org>>
    
    =head1 SEE ALSO
    
    perl(1).
    
    =cut
  STRING_SHELLQUOTE
  
  $fatpacked{"lib/core/only.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'LIB_CORE_ONLY';
    package lib::core::only;
    
    use strict;
    use warnings FATAL => 'all';
    use Config;
    
    sub import {
      @INC = @Config{qw(privlibexp archlibexp)};
      return
    }
    
    =head1 NAME
    
    lib::core::only - Remove all non-core paths from @INC to avoid site/vendor dirs
    
    =head1 SYNOPSIS
    
      use lib::core::only; # now @INC contains only the two core directories
    
    To get only the core directories plus the ones for the local::lib in scope:
    
      $ perl -mlocal::lib -Mlib::core::only -Mlocal::lib=~/perl5 myscript.pl
    
    To attempt to do a self-contained build (but note this will not reliably
    propagate into subprocesses, see the CAVEATS below):
    
      $ PERL5OPT='-mlocal::lib -Mlib::core::only -Mlocal::lib=~/perl5' cpan
    
    Please note that it is necessary to use C<local::lib> twice for this to work.
    First so that C<lib::core::only> doesn't prevent C<local::lib> from loading
    (it's not currently in core) and then again after C<lib::core::only> so that
    the local paths are not removed.
    
    =head1 DESCRIPTION
    
    lib::core::only is simply a shortcut to say "please reduce my @INC to only
    the core lib and archlib (architecture-specific lib) directories of this perl".
    
    You might want to do this to ensure a local::lib contains only the code you
    need, or to test an L<App::FatPacker|App::FatPacker> tree, or to avoid known
    bad vendor packages.
    
    You might want to use this to try and install a self-contained tree of perl
    modules. Be warned that that probably won't work (see L</CAVEATS>).
    
    This module was extracted from L<local::lib|local::lib>'s --self-contained
    feature, and contains the only part that ever worked. I apologise to anybody
    who thought anything else did.
    
    =head1 CAVEATS
    
    This does B<not> propagate properly across perl invocations like local::lib's
    stuff does. It can't. It's only a module import, so it B<only affects the
    specific perl VM instance in which you load and import() it>.
    
    If you want to cascade it across invocations, you can set the PERL5OPT
    environment variable to '-Mlib::core::only' and it'll sort of work. But be
    aware that taint mode ignores this, so some modules' build and test code
    probably will as well.
    
    You also need to be aware that perl's command line options are not processed
    in order - -I options take effect before -M options, so
    
      perl -Mlib::core::only -Ilib
    
    is unlike to do what you want - it's exactly equivalent to:
    
      perl -Mlib::core::only
    
    If you want to combine a core-only @INC with additional paths, you need to
    add the additional paths using -M options and the L<lib|lib> module:
    
      perl -Mlib::core::only -Mlib=lib
    
      # or if you're trying to test compiled code:
    
      perl -Mlib::core::only -Mblib
    
    For more information on the impossibility of sanely propagating this across
    module builds without help from the build program, see
    L<http://www.shadowcat.co.uk/blog/matt-s-trout/tainted-love> - and for ways
    to achieve the old --self-contained feature's results, look at
    L<App::FatPacker|App::FatPacker>'s tree function, and at
    L<App::cpanminus|cpanm>'s --local-lib-contained feature.
    
    =head1 AUTHOR
    
    Matt S. Trout <mst@shadowcat.co.uk>
    
    =head1 LICENSE
    
    This library is free software under the same terms as perl itself.
    
    =head1 COPYRIGHT
    
    (c) 2010 the lib::core::only L</AUTHOR> as specified above.
    
    =cut
    
    1;
  LIB_CORE_ONLY
  
  $fatpacked{"local/lib.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'LOCAL_LIB';
    package local::lib;
    use 5.006;
    use strict;
    use warnings;
    use Config;
    
    our $VERSION = '2.000015';
    $VERSION = eval $VERSION;
    
    BEGIN {
      *_WIN32 = ($^O eq 'MSWin32' || $^O eq 'NetWare' || $^O eq 'symbian')
        ? sub(){1} : sub(){0};
      # punt on these systems
      *_USE_FSPEC = ($^O eq 'MacOS' || $^O eq 'VMS' || $INC{'File/Spec.pm'})
        ? sub(){1} : sub(){0};
    }
    our $_DIR_JOIN = _WIN32 ? '\\' : '/';
    our $_DIR_SPLIT = (_WIN32 || $^O eq 'cygwin') ? qr{[\\/]}
                                                  : qr{/};
    our $_ROOT = _WIN32 ? do {
      my $UNC = qr{[\\/]{2}[^\\/]+[\\/][^\\/]+};
      qr{^(?:$UNC|[A-Za-z]:|)$_DIR_SPLIT};
    } : qr{^/};
    our $_PERL;
    
    sub _cwd {
      my $drive = shift;
      if (!$_PERL) {
        ($_PERL) = $^X =~ /(.+)/; # $^X is internal how could it be tainted?!
        if (_is_abs($_PERL)) {
        }
        elsif (-x $Config{perlpath}) {
          $_PERL = $Config{perlpath};
        }
        else {
          ($_PERL) =
            map { /(.*)/ }
            grep { -x $_ }
            map { join($_DIR_JOIN, $_, $_PERL) }
            split /\Q$Config{path_sep}\E/, $ENV{PATH};
        }
      }
      local @ENV{qw(PATH IFS CDPATH ENV BASH_ENV)};
      my $cmd = $drive ? "eval { Cwd::getdcwd(q($drive)) }"
                       : 'getcwd';
      my $cwd = `"$_PERL" -MCwd -le "print $cmd"`;
      chomp $cwd;
      if (!length $cwd && $drive) {
        $cwd = $drive;
      }
      $cwd =~ s/$_DIR_SPLIT?$/$_DIR_JOIN/;
      $cwd;
    }
    
    sub _catdir {
      if (_USE_FSPEC) {
        require File::Spec;
        File::Spec->catdir(@_);
      }
      else {
        my $dir = join($_DIR_JOIN, @_);
        $dir =~ s{($_DIR_SPLIT)(?:\.?$_DIR_SPLIT)+}{$1}g;
        $dir;
      }
    }
    
    sub _is_abs {
      if (_USE_FSPEC) {
        require File::Spec;
        File::Spec->file_name_is_absolute($_[0]);
      }
      else {
        $_[0] =~ $_ROOT;
      }
    }
    
    sub _rel2abs {
      my ($dir, $base) = @_;
      return $dir
        if _is_abs($dir);
    
      $base = _WIN32 && $dir =~ s/^([A-Za-z]:)// ? _cwd("$1")
            : $base                              ? $base
                                                 : _cwd;
      return _catdir($base, $dir);
    }
    
    sub import {
      my ($class, @args) = @_;
      push @args, @ARGV
        if $0 eq '-';
    
      my @steps;
      my %opts;
      my $shelltype;
    
      while (@args) {
        my $arg = shift @args;
        # check for lethal dash first to stop processing before causing problems
        # the fancy dash is U+2212 or \xE2\x88\x92
        if ($arg =~ /\xE2\x88\x92/ or $arg =~ /−/) {
          die <<'DEATH';
    WHOA THERE! It looks like you've got some fancy dashes in your commandline!
    These are *not* the traditional -- dashes that software recognizes. You
    probably got these by copy-pasting from the perldoc for this module as
    rendered by a UTF8-capable formatter. This most typically happens on an OS X
    terminal, but can happen elsewhere too. Please try again after replacing the
    dashes with normal minus signs.
    DEATH
        }
        elsif ($arg eq '--self-contained') {
          die <<'DEATH';
    FATAL: The local::lib --self-contained flag has never worked reliably and the
    original author, Mark Stosberg, was unable or unwilling to maintain it. As
    such, this flag has been removed from the local::lib codebase in order to
    prevent misunderstandings and potentially broken builds. The local::lib authors
    recommend that you look at the lib::core::only module shipped with this
    distribution in order to create a more robust environment that is equivalent to
    what --self-contained provided (although quite possibly not what you originally
    thought it provided due to the poor quality of the documentation, for which we
    apologise).
    DEATH
        }
        elsif( $arg =~ /^--deactivate(?:=(.*))?$/ ) {
          my $path = defined $1 ? $1 : shift @args;
          push @steps, ['deactivate', $path];
        }
        elsif ( $arg eq '--deactivate-all' ) {
          push @steps, ['deactivate_all'];
        }
        elsif ( $arg =~ /^--shelltype(?:=(.*))?$/ ) {
          $shelltype = defined $1 ? $1 : shift @args;
        }
        elsif ( $arg eq '--no-create' ) {
          $opts{no_create} = 1;
        }
        elsif ( $arg =~ /^--/ ) {
          die "Unknown import argument: $arg";
        }
        else {
          push @steps, ['activate', $arg];
        }
      }
      if (!@steps) {
        push @steps, ['activate', undef];
      }
    
      my $self = $class->new(%opts);
    
      for (@steps) {
        my ($method, @args) = @$_;
        $self = $self->$method(@args);
      }
    
      if ($0 eq '-') {
        print $self->environment_vars_string($shelltype);
        exit 0;
      }
      else {
        $self->setup_local_lib;
      }
    }
    
    sub new {
      my $class = shift;
      bless {@_}, $class;
    }
    
    sub clone {
      my $self = shift;
      bless {%$self, @_}, ref $self;
    }
    
    sub inc { $_[0]->{inc}     ||= \@INC }
    sub libs { $_[0]->{libs}   ||= [ \'PERL5LIB' ] }
    sub bins { $_[0]->{bins}   ||= [ \'PATH' ] }
    sub roots { $_[0]->{roots} ||= [ \'PERL_LOCAL_LIB_ROOT' ] }
    sub extra { $_[0]->{extra} ||= {} }
    sub no_create { $_[0]->{no_create} }
    
    my $_archname = $Config{archname};
    my $_version  = $Config{version};
    my @_inc_version_list = reverse split / /, $Config{inc_version_list};
    my $_path_sep = $Config{path_sep};
    
    sub _as_list {
      my $list = shift;
      grep length, map {
        !(ref $_ && ref $_ eq 'SCALAR') ? $_ : (
          defined $ENV{$$_} ? split(/\Q$_path_sep/, $ENV{$$_})
                            : ()
        )
      } ref $list ? @$list : $list;
    }
    sub _remove_from {
      my ($list, @remove) = @_;
      return @$list
        if !@remove;
      my %remove = map { $_ => 1 } @remove;
      grep !$remove{$_}, _as_list($list);
    }
    
    my @_lib_subdirs = (
      [$_version, $_archname],
      [$_version],
      [$_archname],
      (@_inc_version_list ? \@_inc_version_list : ()),
      [],
    );
    
    sub install_base_bin_path {
      my ($class, $path) = @_;
      return _catdir($path, 'bin');
    }
    sub install_base_perl_path {
      my ($class, $path) = @_;
      return _catdir($path, 'lib', 'perl5');
    }
    sub install_base_arch_path {
      my ($class, $path) = @_;
      _catdir($class->install_base_perl_path($path), $_archname);
    }
    
    sub lib_paths_for {
      my ($class, $path) = @_;
      my $base = $class->install_base_perl_path($path);
      return map { _catdir($base, @$_) } @_lib_subdirs;
    }
    
    sub _mm_escape_path {
      my $path = shift;
      $path =~ s/\\/\\\\/g;
      if ($path =~ s/ /\\ /g) {
        $path = qq{"$path"};
      }
      return $path;
    }
    
    sub _mb_escape_path {
      my $path = shift;
      $path =~ s/\\/\\\\/g;
      return qq{"$path"};
    }
    
    sub installer_options_for {
      my ($class, $path) = @_;
      return (
        PERL_MM_OPT =>
          defined $path ? "INSTALL_BASE="._mm_escape_path($path) : undef,
        PERL_MB_OPT =>
          defined $path ? "--install_base "._mb_escape_path($path) : undef,
      );
    }
    
    sub active_paths {
      my ($self) = @_;
      $self = ref $self ? $self : $self->new;
    
      return grep {
        # screen out entries that aren't actually reflected in @INC
        my $active_ll = $self->install_base_perl_path($_);
        grep { $_ eq $active_ll } @{$self->inc};
      } _as_list($self->roots);
    }
    
    
    sub deactivate {
      my ($self, $path) = @_;
      $self = $self->new unless ref $self;
      $path = $self->resolve_path($path);
      $path = $self->normalize_path($path);
    
      my @active_lls = $self->active_paths;
    
      if (!grep { $_ eq $path } @active_lls) {
        warn "Tried to deactivate inactive local::lib '$path'\n";
        return $self;
      }
    
      my %args = (
        bins  => [ _remove_from($self->bins,
          $self->install_base_bin_path($path)) ],
        libs  => [ _remove_from($self->libs,
          $self->install_base_perl_path($path)) ],
        inc   => [ _remove_from($self->inc,
          $self->lib_paths_for($path)) ],
        roots => [ _remove_from($self->roots, $path) ],
      );
    
      $args{extra} = { $self->installer_options_for($args{roots}[0]) };
    
      $self->clone(%args);
    }
    
    sub deactivate_all {
      my ($self) = @_;
      $self = $self->new unless ref $self;
    
      my @active_lls = $self->active_paths;
    
      my %args;
      if (@active_lls) {
        %args = (
          bins => [ _remove_from($self->bins,
            map $self->install_base_bin_path($_), @active_lls) ],
          libs => [ _remove_from($self->libs,
            map $self->install_base_perl_path($_), @active_lls) ],
          inc => [ _remove_from($self->inc,
            map $self->lib_paths_for($_), @active_lls) ],
          roots => [ _remove_from($self->roots, @active_lls) ],
        );
      }
    
      $args{extra} = { $self->installer_options_for(undef) };
    
      $self->clone(%args);
    }
    
    sub activate {
      my ($self, $path) = @_;
      $self = $self->new unless ref $self;
      $path = $self->resolve_path($path);
      $self->ensure_dir_structure_for($path)
        unless $self->no_create;
    
      $path = $self->normalize_path($path);
    
      my @active_lls = $self->active_paths;
    
      if (grep { $_ eq $path } @active_lls[1 .. $#active_lls]) {
        $self = $self->deactivate($path);
      }
    
      my %args;
      if (!@active_lls || $active_lls[0] ne $path) {
        %args = (
          bins  => [ $self->install_base_bin_path($path), @{$self->bins} ],
          libs  => [ $self->install_base_perl_path($path), @{$self->libs} ],
          inc   => [ $self->lib_paths_for($path), @{$self->inc} ],
          roots => [ $path, @{$self->roots} ],
        );
      }
    
      $args{extra} = { $self->installer_options_for($path) };
    
      $self->clone(%args);
    }
    
    sub normalize_path {
      my ($self, $path) = @_;
      $path = ( Win32::GetShortPathName($path) || $path )
        if $^O eq 'MSWin32';
      return $path;
    }
    
    sub build_environment_vars_for {
      my $self = $_[0]->new->activate($_[1]);
      $self->build_environment_vars;
    }
    sub build_activate_environment_vars_for {
      my $self = $_[0]->new->activate($_[1]);
      $self->build_environment_vars;
    }
    sub build_deactivate_environment_vars_for {
      my $self = $_[0]->new->deactivate($_[1]);
      $self->build_environment_vars;
    }
    sub build_deact_all_environment_vars_for {
      my $self = $_[0]->new->deactivate_all;
      $self->build_environment_vars;
    }
    sub build_environment_vars {
      my $self = shift;
      (
        PATH                => join($_path_sep, _as_list($self->bins)),
        PERL5LIB            => join($_path_sep, _as_list($self->libs)),
        PERL_LOCAL_LIB_ROOT => join($_path_sep, _as_list($self->roots)),
        %{$self->extra},
      );
    }
    
    sub setup_local_lib_for {
      my $self = $_[0]->new->activate($_[1]);
      $self->setup_local_lib;
    }
    
    sub setup_local_lib {
      my $self = shift;
    
      # if Carp is already loaded, ensure Carp::Heavy is also loaded, to avoid
      # $VERSION mismatch errors (Carp::Heavy loads Carp, so we do not need to
      # check in the other direction)
      require Carp::Heavy if $INC{'Carp.pm'};
    
      $self->setup_env_hash;
      @INC = @{$self->inc};
    }
    
    sub setup_env_hash_for {
      my $self = $_[0]->new->activate($_[1]);
      $self->setup_env_hash;
    }
    sub setup_env_hash {
      my $self = shift;
      my %env = $self->build_environment_vars;
      for my $key (keys %env) {
        if (defined $env{$key}) {
          $ENV{$key} = $env{$key};
        }
        else {
          delete $ENV{$key};
        }
      }
    }
    
    sub print_environment_vars_for {
      print $_[0]->environment_vars_string_for(@_[1..$#_]);
    }
    
    sub environment_vars_string_for {
      my $self = $_[0]->new->activate($_[1]);
      $self->environment_vars_string;
    }
    sub environment_vars_string {
      my ($self, $shelltype) = @_;
    
      $shelltype ||= $self->guess_shelltype;
    
      my $extra = $self->extra;
      my @envs = (
        PATH                => $self->bins,
        PERL5LIB            => $self->libs,
        PERL_LOCAL_LIB_ROOT => $self->roots,
        map { $_ => $extra->{$_} } sort keys %$extra,
      );
      $self->_build_env_string($shelltype, \@envs);
    }
    
    sub _build_env_string {
      my ($self, $shelltype, $envs) = @_;
      my @envs = @$envs;
    
      my $build_method = "build_${shelltype}_env_declaration";
    
      my $out = '';
      while (@envs) {
        my ($name, $value) = (shift(@envs), shift(@envs));
        if (
            ref $value
            && @$value == 1
            && ref $value->[0]
            && ref $value->[0] eq 'SCALAR'
            && ${$value->[0]} eq $name) {
          next;
        }
        $out .= $self->$build_method($name, $value);
      }
      my $wrap_method = "wrap_${shelltype}_output";
      if ($self->can($wrap_method)) {
        return $self->$wrap_method($out);
      }
      return $out;
    }
    
    sub build_bourne_env_declaration {
      my ($class, $name, $args) = @_;
      my $value = $class->_interpolate($args, '${%s}', qr/["\\\$!`]/, '\\%s');
    
      if (!defined $value) {
        return qq{unset $name;\n};
      }
    
      $value =~ s/(^|\G|$_path_sep)\$\{$name\}$_path_sep/$1\${$name}\${$name+$_path_sep}/g;
      $value =~ s/$_path_sep\$\{$name\}$/\${$name+$_path_sep}\${$name}/;
    
      qq{${name}="$value"; export ${name};\n}
    }
    
    sub build_csh_env_declaration {
      my ($class, $name, $args) = @_;
      my ($value, @vars) = $class->_interpolate($args, '${%s}', '"', '"\\%s"');
      if (!defined $value) {
        return qq{unsetenv $name;\n};
      }
    
      my $out = '';
      for my $var (@vars) {
        $out .= qq{if ! \$?$name setenv $name '';\n};
      }
    
      my $value_without = $value;
      if ($value_without =~ s/(?:^|$_path_sep)\$\{$name\}(?:$_path_sep|$)//g) {
        $out .= qq{if "\${$name}" != '' setenv $name "$value";\n};
        $out .= qq{if "\${$name}" == '' };
      }
      $out .= qq{setenv $name "$value_without";\n};
      return $out;
    }
    
    sub build_cmd_env_declaration {
      my ($class, $name, $args) = @_;
      my $value = $class->_interpolate($args, '%%%s%%', qr(%), '%s');
      if (!$value) {
        return qq{\@set $name=\n};
      }
    
      my $out = '';
      my $value_without = $value;
      if ($value_without =~ s/(?:^|$_path_sep)%$name%(?:$_path_sep|$)//g) {
        $out .= qq{\@if not "%$name%"=="" set "$name=$value"\n};
        $out .= qq{\@if "%$name%"=="" };
      }
      $out .= qq{\@set "$name=$value_without"\n};
      return $out;
    }
    
    sub build_powershell_env_declaration {
      my ($class, $name, $args) = @_;
      my $value = $class->_interpolate($args, '$env:%s', '"', '`%s');
    
      if (!$value) {
        return qq{Remove-Item -ErrorAction 0 Env:\\$name;\n};
      }
    
      my $maybe_path_sep = qq{\$(if("\$env:$name"-eq""){""}else{"$_path_sep"})};
      $value =~ s/(^|\G|$_path_sep)\$env:$name$_path_sep/$1\$env:$name"+$maybe_path_sep+"/g;
      $value =~ s/$_path_sep\$env:$name$/"+$maybe_path_sep+\$env:$name+"/;
    
      qq{\$env:$name = \$("$value");\n};
    }
    sub wrap_powershell_output {
      my ($class, $out) = @_;
      return $out || " \n";
    }
    
    sub build_fish_env_declaration {
      my ($class, $name, $args) = @_;
      my $value = $class->_interpolate($args, '$%s', qr/[\\"' ]/, '\\%s');
      if (!defined $value) {
        return qq{set -e $name;\n};
      }
      $value =~ s/$_path_sep/ /g;
      qq{set -x $name $value;\n};
    }
    
    sub _interpolate {
      my ($class, $args, $var_pat, $escape, $escape_pat) = @_;
      return
        unless defined $args;
      my @args = ref $args ? @$args : $args;
      return
        unless @args;
      my @vars = map { $$_ } grep { ref $_ eq 'SCALAR' } @args;
      my $string = join $_path_sep, map {
        ref $_ eq 'SCALAR' ? sprintf($var_pat, $$_) : do {
          s/($escape)/sprintf($escape_pat, $1)/ge; $_;
        };
      } @args;
      return wantarray ? ($string, \@vars) : $string;
    }
    
    sub pipeline;
    
    sub pipeline {
      my @methods = @_;
      my $last = pop(@methods);
      if (@methods) {
        \sub {
          my ($obj, @args) = @_;
          $obj->${pipeline @methods}(
            $obj->$last(@args)
          );
        };
      } else {
        \sub {
          shift->$last(@_);
        };
      }
    }
    
    sub resolve_path {
      my ($class, $path) = @_;
    
      $path = $class->${pipeline qw(
        resolve_relative_path
        resolve_home_path
        resolve_empty_path
      )}($path);
    
      $path;
    }
    
    sub resolve_empty_path {
      my ($class, $path) = @_;
      if (defined $path) {
        $path;
      } else {
        '~/perl5';
      }
    }
    
    sub resolve_home_path {
      my ($class, $path) = @_;
      $path =~ /^~([^\/]*)/ or return $path;
      my $user = $1;
      my $homedir = do {
        if (! length($user) && defined $ENV{HOME}) {
          $ENV{HOME};
        }
        else {
          require File::Glob;
          File::Glob::bsd_glob("~$user", File::Glob::GLOB_TILDE());
        }
      };
      unless (defined $homedir) {
        require Carp; require Carp::Heavy;
        Carp::croak(
          "Couldn't resolve homedir for "
          .(defined $user ? $user : 'current user')
        );
      }
      $path =~ s/^~[^\/]*/$homedir/;
      $path;
    }
    
    sub resolve_relative_path {
      my ($class, $path) = @_;
      _rel2abs($path);
    }
    
    sub ensure_dir_structure_for {
      my ($class, $path) = @_;
      unless (-d $path) {
        warn "Attempting to create directory ${path}\n";
      }
      require File::Basename;
      my @dirs;
      while(!-d $path) {
        push @dirs, $path;
        $path = File::Basename::dirname($path);
      }
      mkdir $_ for reverse @dirs;
      return;
    }
    
    sub guess_shelltype {
      my $shellbin
        = defined $ENV{SHELL}
          ? ($ENV{SHELL} =~ /([\w.]+)$/)[-1]
        : ( $^O eq 'MSWin32' && exists $ENV{'!EXITCODE'} )
          ? 'bash'
        : ( $^O eq 'MSWin32' && $ENV{PROMPT} && $ENV{COMSPEC} )
          ? ($ENV{COMSPEC} =~ /([\w.]+)$/)[-1]
        : ( $^O eq 'MSWin32' && !$ENV{PROMPT} )
          ? 'powershell.exe'
        : 'sh';
    
      for ($shellbin) {
        return
            /csh$/                   ? 'csh'
          : /fish/                   ? 'fish'
          : /command(?:\.com)?$/i    ? 'cmd'
          : /cmd(?:\.exe)?$/i        ? 'cmd'
          : /4nt(?:\.exe)?$/i        ? 'cmd'
          : /powershell(?:\.exe)?$/i ? 'powershell'
                                     : 'bourne';
      }
    }
    
    1;
    __END__
    
    =encoding utf8
    
    =head1 NAME
    
    local::lib - create and use a local lib/ for perl modules with PERL5LIB
    
    =head1 SYNOPSIS
    
    In code -
    
      use local::lib; # sets up a local lib at ~/perl5
    
      use local::lib '~/foo'; # same, but ~/foo
    
      # Or...
      use FindBin;
      use local::lib "$FindBin::Bin/../support";  # app-local support library
    
    From the shell -
    
      # Install LWP and its missing dependencies to the '~/perl5' directory
      perl -MCPAN -Mlocal::lib -e 'CPAN::install(LWP)'
    
      # Just print out useful shell commands
      $ perl -Mlocal::lib
      PERL_MB_OPT='--install_base /home/username/perl5'; export PERL_MB_OPT;
      PERL_MM_OPT='INSTALL_BASE=/home/username/perl5'; export PERL_MM_OPT;
      PERL5LIB="/home/username/perl5/lib/perl5"; export PERL5LIB;
      PATH="/home/username/perl5/bin:$PATH"; export PATH;
      PERL_LOCAL_LIB_ROOT="/home/usename/perl5:$PERL_LOCAL_LIB_ROOT"; export PERL_LOCAL_LIB_ROOT;
    
    From a .bashrc file -
    
      [ $SHLVL -eq 1 ] && eval "$(perl -I$HOME/perl5/lib/perl5 -Mlocal::lib)"
    
    =head2 The bootstrapping technique
    
    A typical way to install local::lib is using what is known as the
    "bootstrapping" technique.  You would do this if your system administrator
    hasn't already installed local::lib.  In this case, you'll need to install
    local::lib in your home directory.
    
    Even if you do have administrative privileges, you will still want to set up your
    environment variables, as discussed in step 4. Without this, you would still
    install the modules into the system CPAN installation and also your Perl scripts
    will not use the lib/ path you bootstrapped with local::lib.
    
    By default local::lib installs itself and the CPAN modules into ~/perl5.
    
    Windows users must also see L</Differences when using this module under Win32>.
    
    =over 4
    
    =item 1.
    
    Download and unpack the local::lib tarball from CPAN (search for "Download"
    on the CPAN page about local::lib).  Do this as an ordinary user, not as root
    or administrator.  Unpack the file in your home directory or in any other
    convenient location.
    
    =item 2.
    
    Run this:
    
      perl Makefile.PL --bootstrap
    
    If the system asks you whether it should automatically configure as much
    as possible, you would typically answer yes.
    
    In order to install local::lib into a directory other than the default, you need
    to specify the name of the directory when you call bootstrap, as follows:
    
      perl Makefile.PL --bootstrap=~/foo
    
    =item 3.
    
    Run this: (local::lib assumes you have make installed on your system)
    
      make test && make install
    
    =item 4.
    
    Now we need to setup the appropriate environment variables, so that Perl
    starts using our newly generated lib/ directory. If you are using bash or
    any other Bourne shells, you can add this to your shell startup script this
    way:
    
      echo '[ $SHLVL -eq 1 ] && eval "$(perl -I$HOME/perl5/lib/perl5 -Mlocal::lib)"' >>~/.bashrc
    
    If you are using C shell, you can do this as follows:
    
      /bin/csh
      echo $SHELL
      /bin/csh
      echo 'eval `perl -I$HOME/perl5/lib/perl5 -Mlocal::lib`' >> ~/.cshrc
    
    If you passed to bootstrap a directory other than default, you also need to
    give that as import parameter to the call of the local::lib module like this
    way:
    
      echo '[ $SHLVL -eq 1 ] && eval "$(perl -I$HOME/foo/lib/perl5 -Mlocal::lib=$HOME/foo)"' >>~/.bashrc
    
    After writing your shell configuration file, be sure to re-read it to get the
    changed settings into your current shell's environment. Bourne shells use
    C<. ~/.bashrc> for this, whereas C shells use C<source ~/.cshrc>.
    
    =back
    
    If you're on a slower machine, or are operating under draconian disk space
    limitations, you can disable the automatic generation of manpages from POD when
    installing modules by using the C<--no-manpages> argument when bootstrapping:
    
      perl Makefile.PL --bootstrap --no-manpages
    
    To avoid doing several bootstrap for several Perl module environments on the
    same account, for example if you use it for several different deployed
    applications independently, you can use one bootstrapped local::lib
    installation to install modules in different directories directly this way:
    
      cd ~/mydir1
      perl -Mlocal::lib=./
      eval $(perl -Mlocal::lib=./)  ### To set the environment for this shell alone
      printenv                      ### You will see that ~/mydir1 is in the PERL5LIB
      perl -MCPAN -e install ...    ### whatever modules you want
      cd ../mydir2
      ... REPEAT ...
    
    When used in a C<.bashrc> file, it is recommended that you protect against
    re-activating a directory in a sub-shell.  This can be done by checking the
    C<$SHLVL> variable as shown in synopsis.  Without this, sub-shells created by
    the user or other programs will override changes made to the parent shell's
    environment.
    
    If you are working with several C<local::lib> environments, you may want to
    remove some of them from the current environment without disturbing the others.
    You can deactivate one environment like this (using bourne sh):
    
      eval $(perl -Mlocal::lib=--deactivate,~/path)
    
    which will generate and run the commands needed to remove C<~/path> from your
    various search paths. Whichever environment was B<activated most recently> will
    remain the target for module installations. That is, if you activate
    C<~/path_A> and then you activate C<~/path_B>, new modules you install will go
    in C<~/path_B>. If you deactivate C<~/path_B> then modules will be installed
    into C<~/pathA> -- but if you deactivate C<~/path_A> then they will still be
    installed in C<~/pathB> because pathB was activated later.
    
    You can also ask C<local::lib> to clean itself completely out of the current
    shell's environment with the C<--deactivate-all> option.
    For multiple environments for multiple apps you may need to include a modified
    version of the C<< use FindBin >> instructions in the "In code" sample above.
    If you did something like the above, you have a set of Perl modules at C<<
    ~/mydir1/lib >>. If you have a script at C<< ~/mydir1/scripts/myscript.pl >>,
    you need to tell it where to find the modules you installed for it at C<<
    ~/mydir1/lib >>.
    
    In C<< ~/mydir1/scripts/myscript.pl >>:
    
      use strict;
      use warnings;
      use local::lib "$FindBin::Bin/..";  ### points to ~/mydir1 and local::lib finds lib
      use lib "$FindBin::Bin/../lib";     ### points to ~/mydir1/lib
    
    Put this before any BEGIN { ... } blocks that require the modules you installed.
    
    =head2 Differences when using this module under Win32
    
    To set up the proper environment variables for your current session of
    C<CMD.exe>, you can use this:
    
      C:\>perl -Mlocal::lib
      set PERL_MB_OPT=--install_base C:\DOCUME~1\ADMINI~1\perl5
      set PERL_MM_OPT=INSTALL_BASE=C:\DOCUME~1\ADMINI~1\perl5
      set PERL5LIB=C:\DOCUME~1\ADMINI~1\perl5\lib\perl5
      set PATH=C:\DOCUME~1\ADMINI~1\perl5\bin;%PATH%
    
      ### To set the environment for this shell alone
      C:\>perl -Mlocal::lib > %TEMP%\tmp.bat && %TEMP%\tmp.bat && del %TEMP%\tmp.bat
      ### instead of $(perl -Mlocal::lib=./)
    
    If you want the environment entries to persist, you'll need to add them to the
    Control Panel's System applet yourself or use L<App::local::lib::Win32Helper>.
    
    The "~" is translated to the user's profile directory (the directory named for
    the user under "Documents and Settings" (Windows XP or earlier) or "Users"
    (Windows Vista or later)) unless $ENV{HOME} exists. After that, the home
    directory is translated to a short name (which means the directory must exist)
    and the subdirectories are created.
    
    =head3 PowerShell
    
    local::lib also supports PowerShell, and can be used with the
    C<Invoke-Expression> cmdlet.
    
      Invoke-Expression "$(perl -Mlocal::lib)"
    
    =head1 RATIONALE
    
    The version of a Perl package on your machine is not always the version you
    need.  Obviously, the best thing to do would be to update to the version you
    need.  However, you might be in a situation where you're prevented from doing
    this.  Perhaps you don't have system administrator privileges; or perhaps you
    are using a package management system such as Debian, and nobody has yet gotten
    around to packaging up the version you need.
    
    local::lib solves this problem by allowing you to create your own directory of
    Perl packages downloaded from CPAN (in a multi-user system, this would typically
    be within your own home directory).  The existing system Perl installation is
    not affected; you simply invoke Perl with special options so that Perl uses the
    packages in your own local package directory rather than the system packages.
    local::lib arranges things so that your locally installed version of the Perl
    packages takes precedence over the system installation.
    
    If you are using a package management system (such as Debian), you don't need to
    worry about Debian and CPAN stepping on each other's toes.  Your local version
    of the packages will be written to an entirely separate directory from those
    installed by Debian.
    
    =head1 DESCRIPTION
    
    This module provides a quick, convenient way of bootstrapping a user-local Perl
    module library located within the user's home directory. It also constructs and
    prints out for the user the list of environment variables using the syntax
    appropriate for the user's current shell (as specified by the C<SHELL>
    environment variable), suitable for directly adding to one's shell
    configuration file.
    
    More generally, local::lib allows for the bootstrapping and usage of a
    directory containing Perl modules outside of Perl's C<@INC>. This makes it
    easier to ship an application with an app-specific copy of a Perl module, or
    collection of modules. Useful in cases like when an upstream maintainer hasn't
    applied a patch to a module of theirs that you need for your application.
    
    On import, local::lib sets the following environment variables to appropriate
    values:
    
    =over 4
    
    =item PERL_MB_OPT
    
    =item PERL_MM_OPT
    
    =item PERL5LIB
    
    =item PATH
    
    =item PERL_LOCAL_LIB_ROOT
    
    =back
    
    When possible, these will be appended to instead of overwritten entirely.
    
    These values are then available for reference by any code after import.
    
    =head1 CREATING A SELF-CONTAINED SET OF MODULES
    
    See L<lib::core::only> for one way to do this - but note that
    there are a number of caveats, and the best approach is always to perform a
    build against a clean perl (i.e. site and vendor as close to empty as possible).
    
    =head1 IMPORT OPTIONS
    
    Options are values that can be passed to the C<local::lib> import besides the
    directory to use. They are specified as C<use local::lib '--option'[, path];>
    or C<perl -Mlocal::lib=--option[,path]>.
    
    =head2 --deactivate
    
    Remove the chosen path (or the default path) from the module search paths if it
    was added by C<local::lib>, instead of adding it.
    
    =head2 --deactivate-all
    
    Remove all directories that were added to search paths by C<local::lib> from the
    search paths.
    
    =head2 --shelltype
    
    Specify the shell type to use for output.  By default, the shell will be
    detected based on the environment.  Should be one of: C<bourne>, C<csh>,
    C<cmd>, or C<powershell>.
    
    =head2 --no-create
    
    Prevents C<local::lib> from creating directories when activating dirs.  This is
    likely to cause issues on Win32 systems.
    
    =head1 CLASS METHODS
    
    =head2 ensure_dir_structure_for
    
    =over 4
    
    =item Arguments: $path
    
    =item Return value: None
    
    =back
    
    Attempts to create the given path, and all required parent directories. Throws
    an exception on failure.
    
    =head2 print_environment_vars_for
    
    =over 4
    
    =item Arguments: $path
    
    =item Return value: None
    
    =back
    
    Prints to standard output the variables listed above, properly set to use the
    given path as the base directory.
    
    =head2 build_environment_vars_for
    
    =over 4
    
    =item Arguments: $path
    
    =item Return value: %environment_vars
    
    =back
    
    Returns a hash with the variables listed above, properly set to use the
    given path as the base directory.
    
    =head2 setup_env_hash_for
    
    =over 4
    
    =item Arguments: $path
    
    =item Return value: None
    
    =back
    
    Constructs the C<%ENV> keys for the given path, by calling
    L</build_environment_vars_for>.
    
    =head2 active_paths
    
    =over 4
    
    =item Arguments: None
    
    =item Return value: @paths
    
    =back
    
    Returns a list of active C<local::lib> paths, according to the
    C<PERL_LOCAL_LIB_ROOT> environment variable and verified against
    what is really in C<@INC>.
    
    =head2 install_base_perl_path
    
    =over 4
    
    =item Arguments: $path
    
    =item Return value: $install_base_perl_path
    
    =back
    
    Returns a path describing where to install the Perl modules for this local
    library installation. Appends the directories C<lib> and C<perl5> to the given
    path.
    
    =head2 lib_paths_for
    
    =over 4
    
    =item Arguments: $path
    
    =item Return value: @lib_paths
    
    =back
    
    Returns the list of paths perl will search for libraries, given a base path.
    This includes the base path itself, the architecture specific subdirectory, and
    perl version specific subdirectories.  These paths may not all exist.
    
    =head2 install_base_bin_path
    
    =over 4
    
    =item Arguments: $path
    
    =item Return value: $install_base_bin_path
    
    =back
    
    Returns a path describing where to install the executable programs for this
    local library installation. Appends the directory C<bin> to the given path.
    
    =head2 installer_options_for
    
    =over 4
    
    =item Arguments: $path
    
    =item Return value: %installer_env_vars
    
    =back
    
    Returns a hash of environment variables that should be set to cause
    installation into the given path.
    
    =head2 resolve_empty_path
    
    =over 4
    
    =item Arguments: $path
    
    =item Return value: $base_path
    
    =back
    
    Builds and returns the base path into which to set up the local module
    installation. Defaults to C<~/perl5>.
    
    =head2 resolve_home_path
    
    =over 4
    
    =item Arguments: $path
    
    =item Return value: $home_path
    
    =back
    
    Attempts to find the user's home directory. If installed, uses C<File::HomeDir>
    for this purpose. If no definite answer is available, throws an exception.
    
    =head2 resolve_relative_path
    
    =over 4
    
    =item Arguments: $path
    
    =item Return value: $absolute_path
    
    =back
    
    Translates the given path into an absolute path.
    
    =head2 resolve_path
    
    =over 4
    
    =item Arguments: $path
    
    =item Return value: $absolute_path
    
    =back
    
    Calls the following in a pipeline, passing the result from the previous to the
    next, in an attempt to find where to configure the environment for a local
    library installation: L</resolve_empty_path>, L</resolve_home_path>,
    L</resolve_relative_path>. Passes the given path argument to
    L</resolve_empty_path> which then returns a result that is passed to
    L</resolve_home_path>, which then has its result passed to
    L</resolve_relative_path>. The result of this final call is returned from
    L</resolve_path>.
    
    =head1 OBJECT INTERFACE
    
    =head2 new
    
    =over 4
    
    =item Arguments: %attributes
    
    =item Return value: $local_lib
    
    =back
    
    Constructs a new C<local::lib> object, representing the current state of
    C<@INC> and the relevant environment variables.
    
    =head1 ATTRIBUTES
    
    =head2 roots
    
    An arrayref representing active C<local::lib> directories.
    
    =head2 inc
    
    An arrayref representing C<@INC>.
    
    =head2 libs
    
    An arrayref representing the PERL5LIB environment variable.
    
    =head2 bins
    
    An arrayref representing the PATH environment variable.
    
    =head2 extra
    
    A hashref of extra environment variables (e.g. C<PERL_MM_OPT> and
    C<PERL_MB_OPT>)
    
    =head2 no_create
    
    If set, C<local::lib> will not try to create directories when activating them.
    
    =head1 OBJECT METHODS
    
    =head2 clone
    
    =over 4
    
    =item Arguments: %attributes
    
    =item Return value: $local_lib
    
    =back
    
    Constructs a new C<local::lib> object based on the existing one, overriding the
    specified attributes.
    
    =head2 activate
    
    =over 4
    
    =item Arguments: $path
    
    =item Return value: $new_local_lib
    
    =back
    
    Constructs a new instance with the specified path active.
    
    =head2 deactivate
    
    =over 4
    
    =item Arguments: $path
    
    =item Return value: $new_local_lib
    
    =back
    
    Constructs a new instance with the specified path deactivated.
    
    =head2 deactivate_all
    
    =over 4
    
    =item Arguments: None
    
    =item Return value: $new_local_lib
    
    =back
    
    Constructs a new instance with all C<local::lib> directories deactivated.
    
    =head2 environment_vars_string
    
    =over 4
    
    =item Arguments: [ $shelltype ]
    
    =item Return value: $shell_env_string
    
    =back
    
    Returns a string to set up the C<local::lib>, meant to be run by a shell.
    
    =head2 build_environment_vars
    
    =over 4
    
    =item Arguments: None
    
    =item Return value: %environment_vars
    
    =back
    
    Returns a hash with the variables listed above, properly set to use the
    given path as the base directory.
    
    =head2 setup_env_hash
    
    =over 4
    
    =item Arguments: None
    
    =item Return value: None
    
    =back
    
    Constructs the C<%ENV> keys for the given path, by calling
    L</build_environment_vars>.
    
    =head2 setup_local_lib
    
    Constructs the C<%ENV> hash using L</setup_env_hash>, and set up C<@INC>.
    
    =head1 A WARNING ABOUT UNINST=1
    
    Be careful about using local::lib in combination with "make install UNINST=1".
    The idea of this feature is that will uninstall an old version of a module
    before installing a new one. However it lacks a safety check that the old
    version and the new version will go in the same directory. Used in combination
    with local::lib, you can potentially delete a globally accessible version of a
    module while installing the new version in a local place. Only combine "make
    install UNINST=1" and local::lib if you understand these possible consequences.
    
    =head1 LIMITATIONS
    
    =over 4
    
    =item * Directory names with spaces in them are not well supported by the perl
    toolchain and the programs it uses.  Pure-perl distributions should support
    spaces, but problems are more likely with dists that require compilation. A
    workaround you can do is moving your local::lib to a directory with spaces
    B<after> you installed all modules inside your local::lib bootstrap. But be
    aware that you can't update or install CPAN modules after the move.
    
    =item * Rather basic shell detection. Right now anything with csh in its name is
    assumed to be a C shell or something compatible, and everything else is assumed
    to be Bourne, except on Win32 systems. If the C<SHELL> environment variable is
    not set, a Bourne-compatible shell is assumed.
    
    =item * Kills any existing PERL_MM_OPT or PERL_MB_OPT.
    
    =item * Should probably auto-fixup CPAN config if not already done.
    
    =item * On VMS and MacOS Classic (pre-OS X), local::lib loads L<File::Spec>.
    This means any L<File::Spec> version installed in the local::lib will be
    ignored by scripts using local::lib.  A workaround for this is using
    C<use lib "$local_lib/lib/perl5";> instead of using C<local::lib> directly.
    
    =item * Conflicts with L<ExtUtils::MakeMaker>'s C<PREFIX> option.
    C<local::lib> uses the C<INSTALL_BASE> option, as it has more predictable and
    sane behavior.  If something attempts to use the C<PREFIX> option when running
    a F<Makefile.PL>, L<ExtUtils::MakeMaker> will refuse to run, as the two
    options conflict.  This can be worked around by temporarily unsetting the
    C<PERL_MM_OPT> environment variable.
    
    =item * Conflicts with L<Module::Build>'s C<--prefix> option.  Similar to the
    previous limitation, but any C<--prefix> option specified will be ignored.
    This can be worked around by temporarily unsetting the C<PERL_MB_OPT>
    environment variable.
    
    =back
    
    Patches very much welcome for any of the above.
    
    =over 4
    
    =item * On Win32 systems, does not have a way to write the created environment
    variables to the registry, so that they can persist through a reboot.
    
    =back
    
    =head1 TROUBLESHOOTING
    
    If you've configured local::lib to install CPAN modules somewhere in to your
    home directory, and at some point later you try to install a module with C<cpan
    -i Foo::Bar>, but it fails with an error like: C<Warning: You do not have
    permissions to install into /usr/lib64/perl5/site_perl/5.8.8/x86_64-linux at
    /usr/lib64/perl5/5.8.8/Foo/Bar.pm> and buried within the install log is an
    error saying C<'INSTALL_BASE' is not a known MakeMaker parameter name>, then
    you've somehow lost your updated ExtUtils::MakeMaker module.
    
    To remedy this situation, rerun the bootstrapping procedure documented above.
    
    Then, run C<rm -r ~/.cpan/build/Foo-Bar*>
    
    Finally, re-run C<cpan -i Foo::Bar> and it should install without problems.
    
    =head1 ENVIRONMENT
    
    =over 4
    
    =item SHELL
    
    =item COMSPEC
    
    local::lib looks at the user's C<SHELL> environment variable when printing out
    commands to add to the shell configuration file.
    
    On Win32 systems, C<COMSPEC> is also examined.
    
    =back
    
    =head1 SEE ALSO
    
    =over 4
    
    =item * L<Perl Advent article, 2011|http://perladvent.org/2011/2011-12-01.html>
    
    =back
    
    =head1 SUPPORT
    
    IRC:
    
        Join #local-lib on irc.perl.org.
    
    =head1 AUTHOR
    
    Matt S Trout <mst@shadowcat.co.uk> http://www.shadowcat.co.uk/
    
    auto_install fixes kindly sponsored by http://www.takkle.com/
    
    =head1 CONTRIBUTORS
    
    Patches to correctly output commands for csh style shells, as well as some
    documentation additions, contributed by Christopher Nehren <apeiron@cpan.org>.
    
    Doc patches for a custom local::lib directory, more cleanups in the english
    documentation and a L<german documentation|POD2::DE::local::lib> contributed by
    Torsten Raudssus <torsten@raudssus.de>.
    
    Hans Dieter Pearcey <hdp@cpan.org> sent in some additional tests for ensuring
    things will install properly, submitted a fix for the bug causing problems with
    writing Makefiles during bootstrapping, contributed an example program, and
    submitted yet another fix to ensure that local::lib can install and bootstrap
    properly. Many, many thanks!
    
    pattern of Freenode IRC contributed the beginnings of the Troubleshooting
    section. Many thanks!
    
    Patch to add Win32 support contributed by Curtis Jewell <csjewell@cpan.org>.
    
    Warnings for missing PATH/PERL5LIB (as when not running interactively) silenced
    by a patch from Marco Emilio Poleggi.
    
    Mark Stosberg <mark@summersault.com> provided the code for the now deleted
    '--self-contained' option.
    
    Documentation patches to make win32 usage clearer by
    David Mertens <dcmertens.perl@gmail.com> (run4flat).
    
    Brazilian L<portuguese translation|POD2::PT_BR::local::lib> and minor doc
    patches contributed by Breno G. de Oliveira <garu@cpan.org>.
    
    Improvements to stacking multiple local::lib dirs and removing them from the
    environment later on contributed by Andrew Rodland <arodland@cpan.org>.
    
    Patch for Carp version mismatch contributed by Hakim Cassimally
    <osfameron@cpan.org>.
    
    Rewrite of internals and numerous bug fixes and added features contributed by
    Graham Knop <haarg@haarg.org>.
    
    =head1 COPYRIGHT
    
    Copyright (c) 2007 - 2013 the local::lib L</AUTHOR> and L</CONTRIBUTORS> as
    listed above.
    
    =head1 LICENSE
    
    This is free software; you can redistribute it and/or modify it under
    the same terms as the Perl 5 programming language system itself.
    
    =cut
  LOCAL_LIB
  
  $fatpacked{"parent.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'PARENT';
    package parent;
    use strict;
    use vars qw($VERSION);
    $VERSION = '0.228';
    
    sub import {
        my $class = shift;
    
        my $inheritor = caller(0);
    
        if ( @_ and $_[0] eq '-norequire' ) {
            shift @_;
        } else {
            for ( my @filename = @_ ) {
                if ( $_ eq $inheritor ) {
                    warn "Class '$inheritor' tried to inherit from itself\n";
                };
    
                s{::|'}{/}g;
                require "$_.pm"; # dies if the file is not found
            }
        }
    
        {
            no strict 'refs';
            push @{"$inheritor\::ISA"}, @_;
        };
    };
    
    "All your base are belong to us"
    
    __END__
    
    =encoding utf8
    
    =head1 NAME
    
    parent - Establish an ISA relationship with base classes at compile time
    
    =head1 SYNOPSIS
    
        package Baz;
        use parent qw(Foo Bar);
    
    =head1 DESCRIPTION
    
    Allows you to both load one or more modules, while setting up inheritance from
    those modules at the same time.  Mostly similar in effect to
    
        package Baz;
        BEGIN {
            require Foo;
            require Bar;
            push @ISA, qw(Foo Bar);
        }
    
    By default, every base class needs to live in a file of its own.
    If you want to have a subclass and its parent class in the same file, you
    can tell C<parent> not to load any modules by using the C<-norequire> switch:
    
      package Foo;
      sub exclaim { "I CAN HAS PERL" }
    
      package DoesNotLoadFooBar;
      use parent -norequire, 'Foo', 'Bar';
      # will not go looking for Foo.pm or Bar.pm
    
    This is equivalent to the following code:
    
      package Foo;
      sub exclaim { "I CAN HAS PERL" }
    
      package DoesNotLoadFooBar;
      push @DoesNotLoadFooBar::ISA, 'Foo', 'Bar';
    
    This is also helpful for the case where a package lives within
    a differently named file:
    
      package MyHash;
      use Tie::Hash;
      use parent -norequire, 'Tie::StdHash';
    
    This is equivalent to the following code:
    
      package MyHash;
      require Tie::Hash;
      push @ISA, 'Tie::StdHash';
    
    If you want to load a subclass from a file that C<require> would
    not consider an eligible filename (that is, it does not end in
    either C<.pm> or C<.pmc>), use the following code:
    
      package MySecondPlugin;
      require './plugins/custom.plugin'; # contains Plugin::Custom
      use parent -norequire, 'Plugin::Custom';
    
    =head1 DIAGNOSTICS
    
    =over 4
    
    =item Class 'Foo' tried to inherit from itself
    
    Attempting to inherit from yourself generates a warning.
    
        package Foo;
        use parent 'Foo';
    
    =back
    
    =head1 HISTORY
    
    This module was forked from L<base> to remove the cruft
    that had accumulated in it.
    
    =head1 CAVEATS
    
    =head1 SEE ALSO
    
    L<base>
    
    =head1 AUTHORS AND CONTRIBUTORS
    
    Rafaël Garcia-Suarez, Bart Lateur, Max Maischein, Anno Siegel, Michael Schwern
    
    =head1 MAINTAINER
    
    Max Maischein C< corion@cpan.org >
    
    Copyright (c) 2007-10 Max Maischein C<< <corion@cpan.org> >>
    Based on the idea of C<base.pm>, which was introduced with Perl 5.004_04.
    
    =head1 LICENSE
    
    This module is released under the same terms as Perl itself.
    
    =cut
  PARENT
  
  $fatpacked{"version.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'VERSION';
    #!perl -w
    package version;
    
    use 5.006002;
    use strict;
    use warnings::register;
    if ($] >= 5.015) {
        warnings::register_categories(qw/version/);
    }
    
    use vars qw(@ISA $VERSION $CLASS $STRICT $LAX *declare *qv);
    
    $VERSION = 0.9912;
    $CLASS = 'version';
    
    # !!!!Delete this next block completely when adding to Perl core!!!!
    {
        local $SIG{'__DIE__'};
        if (1) { # always pretend there's no XS
    	eval "use version::vpp $VERSION"; # don't tempt fate
    	die "$@" if ( $@ );
    	push @ISA, "version::vpp";
    	local $^W;
    	*version::qv = \&version::vpp::qv;
    	*version::declare = \&version::vpp::declare;
    	*version::_VERSION = \&version::vpp::_VERSION;
    	*version::vcmp = \&version::vpp::vcmp;
    	*version::new = \&version::vpp::new;
    	*version::numify = \&version::vpp::numify;
    	*version::normal = \&version::vpp::normal;
    	if ($] >= 5.009000) {
    	    no strict 'refs';
    	    *version::stringify = \&version::vpp::stringify;
    	    *{'version::(""'} = \&version::vpp::stringify;
    	    *{'version::(<=>'} = \&version::vpp::vcmp;
    	    *version::parse = \&version::vpp::parse;
    	}
        }
        else { # use XS module
    	push @ISA, "version::vxs";
    	local $^W;
    	*version::declare = \&version::vxs::declare;
    	*version::qv = \&version::vxs::qv;
    	*version::_VERSION = \&version::vxs::_VERSION;
    	*version::vcmp = \&version::vxs::VCMP;
    	*version::new = \&version::vxs::new;
    	*version::numify = \&version::vxs::numify;
    	*version::normal = \&version::vxs::normal;
    	if ($] >= 5.009000) {
    	    no strict 'refs';
    	    *version::stringify = \&version::vxs::stringify;
    	    *{'version::(""'} = \&version::vxs::stringify;
    	    *{'version::(<=>'} = \&version::vxs::VCMP;
    	    *version::parse = \&version::vxs::parse;
    	}
        }
    }
    
    # avoid using Exporter
    require version::regex;
    *version::is_lax = \&version::regex::is_lax;
    *version::is_strict = \&version::regex::is_strict;
    *LAX = \$version::regex::LAX;
    *STRICT = \$version::regex::STRICT;
    
    sub import {
        no strict 'refs';
        my ($class) = shift;
    
        # Set up any derived class
        unless ($class eq $CLASS) {
    	local $^W;
    	*{$class.'::declare'} =  \&{$CLASS.'::declare'};
    	*{$class.'::qv'} = \&{$CLASS.'::qv'};
        }
    
        my %args;
        if (@_) { # any remaining terms are arguments
    	map { $args{$_} = 1 } @_
        }
        else { # no parameters at all on use line
    	%args =
    	(
    	    qv => 1,
    	    'UNIVERSAL::VERSION' => 1,
    	);
        }
    
        my $callpkg = caller();
    
        if (exists($args{declare})) {
    	*{$callpkg.'::declare'} =
    	    sub {return $class->declare(shift) }
    	  unless defined(&{$callpkg.'::declare'});
        }
    
        if (exists($args{qv})) {
    	*{$callpkg.'::qv'} =
    	    sub {return $class->qv(shift) }
    	  unless defined(&{$callpkg.'::qv'});
        }
    
        if (exists($args{'UNIVERSAL::VERSION'})) {
    	local $^W;
    	*UNIVERSAL::VERSION
    		= \&{$CLASS.'::_VERSION'};
        }
    
        if (exists($args{'VERSION'})) {
    	*{$callpkg.'::VERSION'} = \&{$CLASS.'::_VERSION'};
        }
    
        if (exists($args{'is_strict'})) {
    	*{$callpkg.'::is_strict'} = \&{$CLASS.'::is_strict'}
    	  unless defined(&{$callpkg.'::is_strict'});
        }
    
        if (exists($args{'is_lax'})) {
    	*{$callpkg.'::is_lax'} = \&{$CLASS.'::is_lax'}
    	  unless defined(&{$callpkg.'::is_lax'});
        }
    }
    
    
    1;
  VERSION
  
  $fatpacked{"version/regex.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'VERSION_REGEX';
    package version::regex;
    
    use strict;
    
    use vars qw($VERSION $CLASS $STRICT $LAX);
    
    $VERSION = 0.9912;
    
    #--------------------------------------------------------------------------#
    # Version regexp components
    #--------------------------------------------------------------------------#
    
    # Fraction part of a decimal version number.  This is a common part of
    # both strict and lax decimal versions
    
    my $FRACTION_PART = qr/\.[0-9]+/;
    
    # First part of either decimal or dotted-decimal strict version number.
    # Unsigned integer with no leading zeroes (except for zero itself) to
    # avoid confusion with octal.
    
    my $STRICT_INTEGER_PART = qr/0|[1-9][0-9]*/;
    
    # First part of either decimal or dotted-decimal lax version number.
    # Unsigned integer, but allowing leading zeros.  Always interpreted
    # as decimal.  However, some forms of the resulting syntax give odd
    # results if used as ordinary Perl expressions, due to how perl treats
    # octals.  E.g.
    #   version->new("010" ) == 10
    #   version->new( 010  ) == 8
    #   version->new( 010.2) == 82  # "8" . "2"
    
    my $LAX_INTEGER_PART = qr/[0-9]+/;
    
    # Second and subsequent part of a strict dotted-decimal version number.
    # Leading zeroes are permitted, and the number is always decimal.
    # Limited to three digits to avoid overflow when converting to decimal
    # form and also avoid problematic style with excessive leading zeroes.
    
    my $STRICT_DOTTED_DECIMAL_PART = qr/\.[0-9]{1,3}/;
    
    # Second and subsequent part of a lax dotted-decimal version number.
    # Leading zeroes are permitted, and the number is always decimal.  No
    # limit on the numerical value or number of digits, so there is the
    # possibility of overflow when converting to decimal form.
    
    my $LAX_DOTTED_DECIMAL_PART = qr/\.[0-9]+/;
    
    # Alpha suffix part of lax version number syntax.  Acts like a
    # dotted-decimal part.
    
    my $LAX_ALPHA_PART = qr/_[0-9]+/;
    
    #--------------------------------------------------------------------------#
    # Strict version regexp definitions
    #--------------------------------------------------------------------------#
    
    # Strict decimal version number.
    
    my $STRICT_DECIMAL_VERSION =
        qr/ $STRICT_INTEGER_PART $FRACTION_PART? /x;
    
    # Strict dotted-decimal version number.  Must have both leading "v" and
    # at least three parts, to avoid confusion with decimal syntax.
    
    my $STRICT_DOTTED_DECIMAL_VERSION =
        qr/ v $STRICT_INTEGER_PART $STRICT_DOTTED_DECIMAL_PART{2,} /x;
    
    # Complete strict version number syntax -- should generally be used
    # anchored: qr/ \A $STRICT \z /x
    
    $STRICT =
        qr/ $STRICT_DECIMAL_VERSION | $STRICT_DOTTED_DECIMAL_VERSION /x;
    
    #--------------------------------------------------------------------------#
    # Lax version regexp definitions
    #--------------------------------------------------------------------------#
    
    # Lax decimal version number.  Just like the strict one except for
    # allowing an alpha suffix or allowing a leading or trailing
    # decimal-point
    
    my $LAX_DECIMAL_VERSION =
        qr/ $LAX_INTEGER_PART (?: \. | $FRACTION_PART $LAX_ALPHA_PART? )?
    	|
    	$FRACTION_PART $LAX_ALPHA_PART?
        /x;
    
    # Lax dotted-decimal version number.  Distinguished by having either
    # leading "v" or at least three non-alpha parts.  Alpha part is only
    # permitted if there are at least two non-alpha parts. Strangely
    # enough, without the leading "v", Perl takes .1.2 to mean v0.1.2,
    # so when there is no "v", the leading part is optional
    
    my $LAX_DOTTED_DECIMAL_VERSION =
        qr/
    	v $LAX_INTEGER_PART (?: $LAX_DOTTED_DECIMAL_PART+ $LAX_ALPHA_PART? )?
    	|
    	$LAX_INTEGER_PART? $LAX_DOTTED_DECIMAL_PART{2,} $LAX_ALPHA_PART?
        /x;
    
    # Complete lax version number syntax -- should generally be used
    # anchored: qr/ \A $LAX \z /x
    #
    # The string 'undef' is a special case to make for easier handling
    # of return values from ExtUtils::MM->parse_version
    
    $LAX =
        qr/ undef | $LAX_DECIMAL_VERSION | $LAX_DOTTED_DECIMAL_VERSION /x;
    
    #--------------------------------------------------------------------------#
    
    # Preloaded methods go here.
    sub is_strict	{ defined $_[0] && $_[0] =~ qr/ \A $STRICT \z /x }
    sub is_lax	{ defined $_[0] && $_[0] =~ qr/ \A $LAX \z /x }
    
    1;
  VERSION_REGEX
  
  $fatpacked{"version/vpp.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'VERSION_VPP';
    package charstar;
    # a little helper class to emulate C char* semantics in Perl
    # so that prescan_version can use the same code as in C
    
    use overload (
        '""'	=> \&thischar,
        '0+'	=> \&thischar,
        '++'	=> \&increment,
        '--'	=> \&decrement,
        '+'		=> \&plus,
        '-'		=> \&minus,
        '*'		=> \&multiply,
        'cmp'	=> \&cmp,
        '<=>'	=> \&spaceship,
        'bool'	=> \&thischar,
        '='		=> \&clone,
    );
    
    sub new {
        my ($self, $string) = @_;
        my $class = ref($self) || $self;
    
        my $obj = {
    	string  => [split(//,$string)],
    	current => 0,
        };
        return bless $obj, $class;
    }
    
    sub thischar {
        my ($self) = @_;
        my $last = $#{$self->{string}};
        my $curr = $self->{current};
        if ($curr >= 0 && $curr <= $last) {
    	return $self->{string}->[$curr];
        }
        else {
    	return '';
        }
    }
    
    sub increment {
        my ($self) = @_;
        $self->{current}++;
    }
    
    sub decrement {
        my ($self) = @_;
        $self->{current}--;
    }
    
    sub plus {
        my ($self, $offset) = @_;
        my $rself = $self->clone;
        $rself->{current} += $offset;
        return $rself;
    }
    
    sub minus {
        my ($self, $offset) = @_;
        my $rself = $self->clone;
        $rself->{current} -= $offset;
        return $rself;
    }
    
    sub multiply {
        my ($left, $right, $swapped) = @_;
        my $char = $left->thischar();
        return $char * $right;
    }
    
    sub spaceship {
        my ($left, $right, $swapped) = @_;
        unless (ref($right)) { # not an object already
    	$right = $left->new($right);
        }
        return $left->{current} <=> $right->{current};
    }
    
    sub cmp {
        my ($left, $right, $swapped) = @_;
        unless (ref($right)) { # not an object already
    	if (length($right) == 1) { # comparing single character only
    	    return $left->thischar cmp $right;
    	}
    	$right = $left->new($right);
        }
        return $left->currstr cmp $right->currstr;
    }
    
    sub bool {
        my ($self) = @_;
        my $char = $self->thischar;
        return ($char ne '');
    }
    
    sub clone {
        my ($left, $right, $swapped) = @_;
        $right = {
    	string  => [@{$left->{string}}],
    	current => $left->{current},
        };
        return bless $right, ref($left);
    }
    
    sub currstr {
        my ($self, $s) = @_;
        my $curr = $self->{current};
        my $last = $#{$self->{string}};
        if (defined($s) && $s->{current} < $last) {
    	$last = $s->{current};
        }
    
        my $string = join('', @{$self->{string}}[$curr..$last]);
        return $string;
    }
    
    package version::vpp;
    
    use 5.006002;
    use strict;
    use warnings::register;
    
    use Config;
    use vars qw($VERSION $CLASS @ISA $LAX $STRICT $WARN_CATEGORY);
    $VERSION = 0.9912;
    $CLASS = 'version::vpp';
    if ($] > 5.015) {
        warnings::register_categories(qw/version/);
        $WARN_CATEGORY = 'version';
    } else {
        $WARN_CATEGORY = 'numeric';
    }
    
    require version::regex;
    *version::vpp::is_strict = \&version::regex::is_strict;
    *version::vpp::is_lax = \&version::regex::is_lax;
    *LAX = \$version::regex::LAX;
    *STRICT = \$version::regex::STRICT;
    
    use overload (
        '""'       => \&stringify,
        '0+'       => \&numify,
        'cmp'      => \&vcmp,
        '<=>'      => \&vcmp,
        'bool'     => \&vbool,
        '+'        => \&vnoop,
        '-'        => \&vnoop,
        '*'        => \&vnoop,
        '/'        => \&vnoop,
        '+='        => \&vnoop,
        '-='        => \&vnoop,
        '*='        => \&vnoop,
        '/='        => \&vnoop,
        'abs'      => \&vnoop,
    );
    
    sub import {
        no strict 'refs';
        my ($class) = shift;
    
        # Set up any derived class
        unless ($class eq $CLASS) {
    	local $^W;
    	*{$class.'::declare'} =  \&{$CLASS.'::declare'};
    	*{$class.'::qv'} = \&{$CLASS.'::qv'};
        }
    
        my %args;
        if (@_) { # any remaining terms are arguments
    	map { $args{$_} = 1 } @_
        }
        else { # no parameters at all on use line
    	%args =
    	(
    	    qv => 1,
    	    'UNIVERSAL::VERSION' => 1,
    	);
        }
    
        my $callpkg = caller();
    
        if (exists($args{declare})) {
    	*{$callpkg.'::declare'} =
    	    sub {return $class->declare(shift) }
    	  unless defined(&{$callpkg.'::declare'});
        }
    
        if (exists($args{qv})) {
    	*{$callpkg.'::qv'} =
    	    sub {return $class->qv(shift) }
    	  unless defined(&{$callpkg.'::qv'});
        }
    
        if (exists($args{'UNIVERSAL::VERSION'})) {
    	no warnings qw/redefine/;
    	*UNIVERSAL::VERSION
    		= \&{$CLASS.'::_VERSION'};
        }
    
        if (exists($args{'VERSION'})) {
    	*{$callpkg.'::VERSION'} = \&{$CLASS.'::_VERSION'};
        }
    
        if (exists($args{'is_strict'})) {
    	*{$callpkg.'::is_strict'} = \&{$CLASS.'::is_strict'}
    	  unless defined(&{$callpkg.'::is_strict'});
        }
    
        if (exists($args{'is_lax'})) {
    	*{$callpkg.'::is_lax'} = \&{$CLASS.'::is_lax'}
    	  unless defined(&{$callpkg.'::is_lax'});
        }
    }
    
    my $VERSION_MAX = 0x7FFFFFFF;
    
    # implement prescan_version as closely to the C version as possible
    use constant TRUE  => 1;
    use constant FALSE => 0;
    
    sub isDIGIT {
        my ($char) = shift->thischar();
        return ($char =~ /\d/);
    }
    
    sub isALPHA {
        my ($char) = shift->thischar();
        return ($char =~ /[a-zA-Z]/);
    }
    
    sub isSPACE {
        my ($char) = shift->thischar();
        return ($char =~ /\s/);
    }
    
    sub BADVERSION {
        my ($s, $errstr, $error) = @_;
        if ($errstr) {
    	$$errstr = $error;
        }
        return $s;
    }
    
    sub prescan_version {
        my ($s, $strict, $errstr, $sqv, $ssaw_decimal, $swidth, $salpha) = @_;
        my $qv          = defined $sqv          ? $$sqv          : FALSE;
        my $saw_decimal = defined $ssaw_decimal ? $$ssaw_decimal : 0;
        my $width       = defined $swidth       ? $$swidth       : 3;
        my $alpha       = defined $salpha       ? $$salpha       : FALSE;
    
        my $d = $s;
    
        if ($qv && isDIGIT($d)) {
    	goto dotted_decimal_version;
        }
    
        if ($d eq 'v') { # explicit v-string
    	$d++;
    	if (isDIGIT($d)) {
    	    $qv = TRUE;
    	}
    	else { # degenerate v-string
    	    # requires v1.2.3
    	    return BADVERSION($s,$errstr,"Invalid version format (dotted-decimal versions require at least three parts)");
    	}
    
    dotted_decimal_version:
    	if ($strict && $d eq '0' && isDIGIT($d+1)) {
    	    # no leading zeros allowed
    	    return BADVERSION($s,$errstr,"Invalid version format (no leading zeros)");
    	}
    
    	while (isDIGIT($d)) { 	# integer part
    	    $d++;
    	}
    
    	if ($d eq '.')
    	{
    	    $saw_decimal++;
    	    $d++; 		# decimal point
    	}
    	else
    	{
    	    if ($strict) {
    		# require v1.2.3
    		return BADVERSION($s,$errstr,"Invalid version format (dotted-decimal versions require at least three parts)");
    	    }
    	    else {
    		goto version_prescan_finish;
    	    }
    	}
    
    	{
    	    my $i = 0;
    	    my $j = 0;
    	    while (isDIGIT($d)) {	# just keep reading
    		$i++;
    		while (isDIGIT($d)) {
    		    $d++; $j++;
    		    # maximum 3 digits between decimal
    		    if ($strict && $j > 3) {
    			return BADVERSION($s,$errstr,"Invalid version format (maximum 3 digits between decimals)");
    		    }
    		}
    		if ($d eq '_') {
    		    if ($strict) {
    			return BADVERSION($s,$errstr,"Invalid version format (no underscores)");
    		    }
    		    if ( $alpha ) {
    			return BADVERSION($s,$errstr,"Invalid version format (multiple underscores)");
    		    }
    		    $d++;
    		    $alpha = TRUE;
    		}
    		elsif ($d eq '.') {
    		    if ($alpha) {
    			return BADVERSION($s,$errstr,"Invalid version format (underscores before decimal)");
    		    }
    		    $saw_decimal++;
    		    $d++;
    		}
    		elsif (!isDIGIT($d)) {
    		    last;
    		}
    		$j = 0;
    	    }
    
    	    if ($strict && $i < 2) {
    		# requires v1.2.3
    		return BADVERSION($s,$errstr,"Invalid version format (dotted-decimal versions require at least three parts)");
    	    }
    	}
        } 					# end if dotted-decimal
        else
        {					# decimal versions
    	my $j = 0;
    	# special $strict case for leading '.' or '0'
    	if ($strict) {
    	    if ($d eq '.') {
    		return BADVERSION($s,$errstr,"Invalid version format (0 before decimal required)");
    	    }
    	    if ($d eq '0' && isDIGIT($d+1)) {
    		return BADVERSION($s,$errstr,"Invalid version format (no leading zeros)");
    	    }
    	}
    
    	# and we never support negative version numbers
    	if ($d eq '-') {
    	    return BADVERSION($s,$errstr,"Invalid version format (negative version number)");
    	}
    
    	# consume all of the integer part
    	while (isDIGIT($d)) {
    	    $d++;
    	}
    
    	# look for a fractional part
    	if ($d eq '.') {
    	    # we found it, so consume it
    	    $saw_decimal++;
    	    $d++;
    	}
    	elsif (!$d || $d eq ';' || isSPACE($d) || $d eq '}') {
    	    if ( $d == $s ) {
    		# found nothing
    		return BADVERSION($s,$errstr,"Invalid version format (version required)");
    	    }
    	    # found just an integer
    	    goto version_prescan_finish;
    	}
    	elsif ( $d == $s ) {
    	    # didn't find either integer or period
    	    return BADVERSION($s,$errstr,"Invalid version format (non-numeric data)");
    	}
    	elsif ($d eq '_') {
    	    # underscore can't come after integer part
    	    if ($strict) {
    		return BADVERSION($s,$errstr,"Invalid version format (no underscores)");
    	    }
    	    elsif (isDIGIT($d+1)) {
    		return BADVERSION($s,$errstr,"Invalid version format (alpha without decimal)");
    	    }
    	    else {
    		return BADVERSION($s,$errstr,"Invalid version format (misplaced underscore)");
    	    }
    	}
    	elsif ($d) {
    	    # anything else after integer part is just invalid data
    	    return BADVERSION($s,$errstr,"Invalid version format (non-numeric data)");
    	}
    
    	# scan the fractional part after the decimal point
    	if ($d && !isDIGIT($d) && ($strict || ! ($d eq ';' || isSPACE($d) || $d eq '}') )) {
    		# $strict or lax-but-not-the-end
    		return BADVERSION($s,$errstr,"Invalid version format (fractional part required)");
    	}
    
    	while (isDIGIT($d)) {
    	    $d++; $j++;
    	    if ($d eq '.' && isDIGIT($d-1)) {
    		if ($alpha) {
    		    return BADVERSION($s,$errstr,"Invalid version format (underscores before decimal)");
    		}
    		if ($strict) {
    		    return BADVERSION($s,$errstr,"Invalid version format (dotted-decimal versions must begin with 'v')");
    		}
    		$d = $s; # start all over again
    		$qv = TRUE;
    		goto dotted_decimal_version;
    	    }
    	    if ($d eq '_') {
    		if ($strict) {
    		    return BADVERSION($s,$errstr,"Invalid version format (no underscores)");
    		}
    		if ( $alpha ) {
    		    return BADVERSION($s,$errstr,"Invalid version format (multiple underscores)");
    		}
    		if ( ! isDIGIT($d+1) ) {
    		    return BADVERSION($s,$errstr,"Invalid version format (misplaced underscore)");
    		}
    		$width = $j;
    		$d++;
    		$alpha = TRUE;
    	    }
    	}
        }
    
    version_prescan_finish:
        while (isSPACE($d)) {
    	$d++;
        }
    
        if ($d && !isDIGIT($d) && (! ($d eq ';' || $d eq '}') )) {
    	# trailing non-numeric data
    	return BADVERSION($s,$errstr,"Invalid version format (non-numeric data)");
        }
        if ($saw_decimal > 1 && ($d-1) eq '.') {
    	# no trailing period allowed
    	return BADVERSION($s,$errstr,"Invalid version format (trailing decimal)");
        }
    
        if (defined $sqv) {
    	$$sqv = $qv;
        }
        if (defined $swidth) {
    	$$swidth = $width;
        }
        if (defined $ssaw_decimal) {
    	$$ssaw_decimal = $saw_decimal;
        }
        if (defined $salpha) {
    	$$salpha = $alpha;
        }
        return $d;
    }
    
    sub scan_version {
        my ($s, $rv, $qv) = @_;
        my $start;
        my $pos;
        my $last;
        my $errstr;
        my $saw_decimal = 0;
        my $width = 3;
        my $alpha = FALSE;
        my $vinf = FALSE;
        my @av;
    
        $s = new charstar $s;
    
        while (isSPACE($s)) { # leading whitespace is OK
    	$s++;
        }
    
        $last = prescan_version($s, FALSE, \$errstr, \$qv, \$saw_decimal,
    	\$width, \$alpha);
    
        if ($errstr) {
    	# 'undef' is a special case and not an error
    	if ( $s ne 'undef') {
    	    require Carp;
    	    Carp::croak($errstr);
    	}
        }
    
        $start = $s;
        if ($s eq 'v') {
    	$s++;
        }
        $pos = $s;
    
        if ( $qv ) {
    	$$rv->{qv} = $qv;
        }
        if ( $alpha ) {
    	$$rv->{alpha} = $alpha;
        }
        if ( !$qv && $width < 3 ) {
    	$$rv->{width} = $width;
        }
    
        while (isDIGIT($pos)) {
    	$pos++;
        }
        if (!isALPHA($pos)) {
    	my $rev;
    
    	for (;;) {
    	    $rev = 0;
    	    {
      		# this is atoi() that delimits on underscores
      		my $end = $pos;
      		my $mult = 1;
    		my $orev;
    
    		#  the following if() will only be true after the decimal
    		#  point of a version originally created with a bare
    		#  floating point number, i.e. not quoted in any way
    		#
     		if ( !$qv && $s > $start && $saw_decimal == 1 ) {
    		    $mult *= 100;
     		    while ( $s < $end ) {
    			$orev = $rev;
     			$rev += $s * $mult;
     			$mult /= 10;
    			if (   (abs($orev) > abs($rev))
    			    || (abs($rev) > $VERSION_MAX )) {
    			    warn("Integer overflow in version %d",
    					   $VERSION_MAX);
    			    $s = $end - 1;
    			    $rev = $VERSION_MAX;
    			    $vinf = 1;
    			}
     			$s++;
    			if ( $s eq '_' ) {
    			    $s++;
    			}
     		    }
      		}
     		else {
     		    while (--$end >= $s) {
    			$orev = $rev;
     			$rev += $end * $mult;
     			$mult *= 10;
    			if (   (abs($orev) > abs($rev))
    			    || (abs($rev) > $VERSION_MAX )) {
    			    warn("Integer overflow in version");
    			    $end = $s - 1;
    			    $rev = $VERSION_MAX;
    			    $vinf = 1;
    			}
     		    }
     		}
      	    }
    
      	    # Append revision
    	    push @av, $rev;
    	    if ( $vinf ) {
    		$s = $last;
    		last;
    	    }
    	    elsif ( $pos eq '.' ) {
    		$pos++;
    		if ($qv) {
    		    # skip leading zeros
    		    while ($pos eq '0') {
    			$pos++;
    		    }
    		}
    		$s = $pos;
    	    }
    	    elsif ( $pos eq '_' && isDIGIT($pos+1) ) {
    		$s = ++$pos;
    	    }
    	    elsif ( $pos eq ',' && isDIGIT($pos+1) ) {
    		$s = ++$pos;
    	    }
    	    elsif ( isDIGIT($pos) ) {
    		$s = $pos;
    	    }
    	    else {
    		$s = $pos;
    		last;
    	    }
    	    if ( $qv ) {
    		while ( isDIGIT($pos) ) {
    		    $pos++;
    		}
    	    }
    	    else {
    		my $digits = 0;
    		while ( ( isDIGIT($pos) || $pos eq '_' ) && $digits < 3 ) {
    		    if ( $pos ne '_' ) {
    			$digits++;
    		    }
    		    $pos++;
    		}
    	    }
    	}
        }
        if ( $qv ) { # quoted versions always get at least three terms
    	my $len = $#av;
    	#  This for loop appears to trigger a compiler bug on OS X, as it
    	#  loops infinitely. Yes, len is negative. No, it makes no sense.
    	#  Compiler in question is:
    	#  gcc version 3.3 20030304 (Apple Computer, Inc. build 1640)
    	#  for ( len = 2 - len; len > 0; len-- )
    	#  av_push(MUTABLE_AV(sv), newSViv(0));
    	#
    	$len = 2 - $len;
    	while ($len-- > 0) {
    	    push @av, 0;
    	}
        }
    
        # need to save off the current version string for later
        if ( $vinf ) {
    	$$rv->{original} = "v.Inf";
    	$$rv->{vinf} = 1;
        }
        elsif ( $s > $start ) {
    	$$rv->{original} = $start->currstr($s);
    	if ( $qv && $saw_decimal == 1 && $start ne 'v' ) {
    	    # need to insert a v to be consistent
    	    $$rv->{original} = 'v' . $$rv->{original};
    	}
        }
        else {
    	$$rv->{original} = '0';
    	push(@av, 0);
        }
    
        # And finally, store the AV in the hash
        $$rv->{version} = \@av;
    
        # fix RT#19517 - special case 'undef' as string
        if ($s eq 'undef') {
    	$s += 5;
        }
    
        return $s;
    }
    
    sub new {
        my $class = shift;
        unless (defined $class or $#_ > 1) {
    	require Carp;
    	Carp::croak('Usage: version::new(class, version)');
        }
    
        my $self = bless ({}, ref ($class) || $class);
        my $qv = FALSE;
    
        if ( $#_ == 1 ) { # must be CVS-style
    	$qv = TRUE;
        }
        my $value = pop; # always going to be the last element
    
        if ( ref($value) && eval('$value->isa("version")') ) {
    	# Can copy the elements directly
    	$self->{version} = [ @{$value->{version} } ];
    	$self->{qv} = 1 if $value->{qv};
    	$self->{alpha} = 1 if $value->{alpha};
    	$self->{original} = ''.$value->{original};
    	return $self;
        }
    
        if ( not defined $value or $value =~ /^undef$/ ) {
    	# RT #19517 - special case for undef comparison
    	# or someone forgot to pass a value
    	push @{$self->{version}}, 0;
    	$self->{original} = "0";
    	return ($self);
        }
    
    
        if (ref($value) =~ m/ARRAY|HASH/) {
    	require Carp;
    	Carp::croak("Invalid version format (non-numeric data)");
        }
    
        $value = _un_vstring($value);
    
        if ($Config{d_setlocale}) {
    	use POSIX qw/locale_h/;
    	use if $Config{d_setlocale}, 'locale';
    	my $currlocale = setlocale(LC_ALL);
    
    	# if the current locale uses commas for decimal points, we
    	# just replace commas with decimal places, rather than changing
    	# locales
    	if ( localeconv()->{decimal_point} eq ',' ) {
    	    $value =~ tr/,/./;
    	}
        }
    
        # exponential notation
        if ( $value =~ /\d+.?\d*e[-+]?\d+/ ) {
    	$value = sprintf("%.9f",$value);
    	$value =~ s/(0+)$//; # trim trailing zeros
        }
    
        my $s = scan_version($value, \$self, $qv);
    
        if ($s) { # must be something left over
    	warn("Version string '%s' contains invalid data; "
    		   ."ignoring: '%s'", $value, $s);
        }
    
        return ($self);
    }
    
    *parse = \&new;
    
    sub numify {
        my ($self) = @_;
        unless (_verify($self)) {
    	require Carp;
    	Carp::croak("Invalid version object");
        }
        my $width = $self->{width} || 3;
        my $alpha = $self->{alpha} || "";
        my $len = $#{$self->{version}};
        my $digit = $self->{version}[0];
        my $string = sprintf("%d.", $digit );
    
        if ($alpha and warnings::enabled()) {
    	warnings::warn($WARN_CATEGORY, 'alpha->numify() is lossy');
        }
    
        for ( my $i = 1 ; $i < $len ; $i++ ) {
    	$digit = $self->{version}[$i];
    	if ( $width < 3 ) {
    	    my $denom = 10**(3-$width);
    	    my $quot = int($digit/$denom);
    	    my $rem = $digit - ($quot * $denom);
    	    $string .= sprintf("%0".$width."d_%d", $quot, $rem);
    	}
    	else {
    	    $string .= sprintf("%03d", $digit);
    	}
        }
    
        if ( $len > 0 ) {
    	$digit = $self->{version}[$len];
    	if ( $alpha && $width == 3 ) {
    	    $string .= "_";
    	}
    	$string .= sprintf("%0".$width."d", $digit);
        }
        else # $len = 0
        {
    	$string .= sprintf("000");
        }
    
        return $string;
    }
    
    sub normal {
        my ($self) = @_;
        unless (_verify($self)) {
    	require Carp;
    	Carp::croak("Invalid version object");
        }
        my $alpha = $self->{alpha} || "";
        my $qv = $self->{qv} || "";
    
        my $len = $#{$self->{version}};
        my $digit = $self->{version}[0];
        my $string = sprintf("v%d", $digit );
    
        for ( my $i = 1 ; $i < $len ; $i++ ) {
    	$digit = $self->{version}[$i];
    	$string .= sprintf(".%d", $digit);
        }
    
        if ( $len > 0 ) {
    	$digit = $self->{version}[$len];
    	if ( $alpha ) {
    	    $string .= sprintf("_%0d", $digit);
    	}
    	else {
    	    $string .= sprintf(".%0d", $digit);
    	}
        }
    
        if ( $len <= 2 ) {
    	for ( $len = 2 - $len; $len != 0; $len-- ) {
    	    $string .= sprintf(".%0d", 0);
    	}
        }
    
        return $string;
    }
    
    sub stringify {
        my ($self) = @_;
        unless (_verify($self)) {
    	require Carp;
    	Carp::croak("Invalid version object");
        }
        return exists $self->{original}
        	? $self->{original}
    	: exists $self->{qv}
    	    ? $self->normal
    	    : $self->numify;
    }
    
    sub vcmp {
        require UNIVERSAL;
        my ($left,$right,$swap) = @_;
        my $class = ref($left);
        unless ( UNIVERSAL::isa($right, $class) ) {
    	$right = $class->new($right);
        }
    
        if ( $swap ) {
    	($left, $right) = ($right, $left);
        }
        unless (_verify($left)) {
    	require Carp;
    	Carp::croak("Invalid version object");
        }
        unless (_verify($right)) {
    	require Carp;
    	Carp::croak("Invalid version format");
        }
        my $l = $#{$left->{version}};
        my $r = $#{$right->{version}};
        my $m = $l < $r ? $l : $r;
        my $lalpha = $left->is_alpha;
        my $ralpha = $right->is_alpha;
        my $retval = 0;
        my $i = 0;
        while ( $i <= $m && $retval == 0 ) {
    	$retval = $left->{version}[$i] <=> $right->{version}[$i];
    	$i++;
        }
    
        # tiebreaker for alpha with identical terms
        if ( $retval == 0
    	&& $l == $r
    	&& $left->{version}[$m] == $right->{version}[$m]
    	&& ( $lalpha || $ralpha ) ) {
    
    	if ( $lalpha && !$ralpha ) {
    	    $retval = -1;
    	}
    	elsif ( $ralpha && !$lalpha) {
    	    $retval = +1;
    	}
        }
    
        # possible match except for trailing 0's
        if ( $retval == 0 && $l != $r ) {
    	if ( $l < $r ) {
    	    while ( $i <= $r && $retval == 0 ) {
    		if ( $right->{version}[$i] != 0 ) {
    		    $retval = -1; # not a match after all
    		}
    		$i++;
    	    }
    	}
    	else {
    	    while ( $i <= $l && $retval == 0 ) {
    		if ( $left->{version}[$i] != 0 ) {
    		    $retval = +1; # not a match after all
    		}
    		$i++;
    	    }
    	}
        }
    
        return $retval;
    }
    
    sub vbool {
        my ($self) = @_;
        return vcmp($self,$self->new("0"),1);
    }
    
    sub vnoop {
        require Carp;
        Carp::croak("operation not supported with version object");
    }
    
    sub is_alpha {
        my ($self) = @_;
        return (exists $self->{alpha});
    }
    
    sub qv {
        my $value = shift;
        my $class = $CLASS;
        if (@_) {
    	$class = ref($value) || $value;
    	$value = shift;
        }
    
        $value = _un_vstring($value);
        $value = 'v'.$value unless $value =~ /(^v|\d+\.\d+\.\d)/;
        my $obj = $CLASS->new($value);
        return bless $obj, $class;
    }
    
    *declare = \&qv;
    
    sub is_qv {
        my ($self) = @_;
        return (exists $self->{qv});
    }
    
    
    sub _verify {
        my ($self) = @_;
        if ( ref($self)
    	&& eval { exists $self->{version} }
    	&& ref($self->{version}) eq 'ARRAY'
    	) {
    	return 1;
        }
        else {
    	return 0;
        }
    }
    
    sub _is_non_alphanumeric {
        my $s = shift;
        $s = new charstar $s;
        while ($s) {
    	return 0 if isSPACE($s); # early out
    	return 1 unless (isALPHA($s) || isDIGIT($s) || $s =~ /[.-]/);
    	$s++;
        }
        return 0;
    }
    
    sub _un_vstring {
        my $value = shift;
        # may be a v-string
        if ( length($value) >= 1 && $value !~ /[,._]/
    	&& _is_non_alphanumeric($value)) {
    	my $tvalue;
    	if ( $] >= 5.008_001 ) {
    	    $tvalue = _find_magic_vstring($value);
    	    $value = $tvalue if length $tvalue;
    	}
    	elsif ( $] >= 5.006_000 ) {
    	    $tvalue = sprintf("v%vd",$value);
    	    if ( $tvalue =~ /^v\d+(\.\d+)*$/ ) {
    		# must be a v-string
    		$value = $tvalue;
    	    }
    	}
        }
        return $value;
    }
    
    sub _find_magic_vstring {
        my $value = shift;
        my $tvalue = '';
        require B;
        my $sv = B::svref_2object(\$value);
        my $magic = ref($sv) eq 'B::PVMG' ? $sv->MAGIC : undef;
        while ( $magic ) {
    	if ( $magic->TYPE eq 'V' ) {
    	    $tvalue = $magic->PTR;
    	    $tvalue =~ s/^v?(.+)$/v$1/;
    	    last;
    	}
    	else {
    	    $magic = $magic->MOREMAGIC;
    	}
        }
        return $tvalue;
    }
    
    sub _VERSION {
        my ($obj, $req) = @_;
        my $class = ref($obj) || $obj;
    
        no strict 'refs';
        if ( exists $INC{"$class.pm"} and not %{"$class\::"} and $] >= 5.008) {
    	 # file but no package
    	require Carp;
    	Carp::croak( "$class defines neither package nor VERSION"
    	    ."--version check failed");
        }
    
        my $version = eval "\$$class\::VERSION";
        if ( defined $version ) {
    	local $^W if $] <= 5.008;
    	$version = version::vpp->new($version);
        }
    
        if ( defined $req ) {
    	unless ( defined $version ) {
    	    require Carp;
    	    my $msg =  $] < 5.006
    	    ? "$class version $req required--this is only version "
    	    : "$class does not define \$$class\::VERSION"
    	      ."--version check failed";
    
    	    if ( $ENV{VERSION_DEBUG} ) {
    		Carp::confess($msg);
    	    }
    	    else {
    		Carp::croak($msg);
    	    }
    	}
    
    	$req = version::vpp->new($req);
    
    	if ( $req > $version ) {
    	    require Carp;
    	    if ( $req->is_qv ) {
    		Carp::croak(
    		    sprintf ("%s version %s required--".
    			"this is only version %s", $class,
    			$req->normal, $version->normal)
    		);
    	    }
    	    else {
    		Carp::croak(
    		    sprintf ("%s version %s required--".
    			"this is only version %s", $class,
    			$req->stringify, $version->stringify)
    		);
    	    }
    	}
        }
    
        return defined $version ? $version->stringify : undef;
    }
    
    1; #this line is important and will help the module return a true value
  VERSION_VPP
  
  s/^  //mg for values %fatpacked;
  
  my $class = 'FatPacked::'.(0+\%fatpacked);
  no strict 'refs';
  *{"${class}::files"} = sub { keys %{$_[0]} };
  
  if ($] < 5.008) {
    *{"${class}::INC"} = sub {
       if (my $fat = $_[0]{$_[1]}) {
         return sub {
           return 0 unless length $fat;
           $fat =~ s/^([^\n]*\n?)//;
           $_ = $1;
           return 1;
         };
       }
       return;
    };
  }
  
  else {
    *{"${class}::INC"} = sub {
      if (my $fat = $_[0]{$_[1]}) {
        open my $fh, '<', \$fat
          or die "FatPacker error loading $_[1] (could be a perl installation issue?)";
        return $fh;
      }
      return;
    };
  }
  
  unshift @INC, bless \%fatpacked, $class;
    } # END OF FATPACK CODE
  
  
  
  use strict;
  use App::cpanminus::script;
  
  
  unless (caller) {
      my $app = App::cpanminus::script->new;
      $app->parse_options(@ARGV);
      exit $app->doit;
  }
  
  __END__
  
  =head1 NAME
  
  cpanm - get, unpack build and install modules from CPAN
  
  =head1 SYNOPSIS
  
    cpanm Test::More                                 # install Test::More
    cpanm MIYAGAWA/Plack-0.99_05.tar.gz              # full distribution path
    cpanm http://example.org/LDS/CGI.pm-3.20.tar.gz  # install from URL
    cpanm ~/dists/MyCompany-Enterprise-1.00.tar.gz   # install from a local file
    cpanm --interactive Task::Kensho                 # Configure interactively
    cpanm .                                          # install from local directory
    cpanm --installdeps .                            # install all the deps for the current directory
    cpanm -L extlib Plack                            # install Plack and all non-core deps into extlib
    cpanm --mirror http://cpan.cpantesters.org/ DBI  # use the fast-syncing mirror
    cpanm --from https://cpan.metacpan.org/ Plack    # use only the HTTPS mirror
  
  =head1 COMMANDS
  
  =over 4
  
  =item (arguments)
  
  Command line arguments can be either a module name, distribution file,
  local file path, HTTP URL or git repository URL. Following commands
  will all work as you expect.
  
      cpanm Plack
      cpanm Plack/Request.pm
      cpanm MIYAGAWA/Plack-1.0000.tar.gz
      cpanm /path/to/Plack-1.0000.tar.gz
      cpanm http://cpan.metacpan.org/authors/id/M/MI/MIYAGAWA/Plack-0.9990.tar.gz
      cpanm git://github.com/plack/Plack.git
  
  Additionally, you can use the notation using C<~> and C<@> to specify
  version for a given module. C<~> specifies the version requirement in
  the L<CPAN::Meta::Spec> format, while C<@> pins the exact version, and
  is a shortcut for C<~"== VERSION">.
  
      cpanm Plack~1.0000                 # 1.0000 or later
      cpanm Plack~">= 1.0000, < 2.0000"  # latest of 1.xxxx
      cpanm Plack@0.9990                 # specific version. same as Plack~"== 0.9990"
  
  The version query including specific version or range will be sent to
  L<MetaCPAN> to search for previous releases. The query will search for
  BackPAN archives by default, unless you specify C<--dev> option, in
  which case, archived versions will be filtered out.
  
  For a git repository, you can specify a branch, tag, or commit SHA to
  build. The default is C<master>
  
      cpanm git://github.com/plack/Plack.git@1.0000        # tag
      cpanm git://github.com/plack/Plack.git@devel         # branch
  
  =item -i, --install
  
  Installs the modules. This is a default behavior and this is just a
  compatibility option to make it work like L<cpan> or L<cpanp>.
  
  =item --self-upgrade
  
  Upgrades itself. It's just an alias for:
  
    cpanm App::cpanminus
  
  =item --info
  
  Displays the distribution information in
  C<AUTHOR/Dist-Name-ver.tar.gz> format in the standard out.
  
  =item --installdeps
  
  Installs the dependencies of the target distribution but won't build
  itself. Handy if you want to try the application from a version
  controlled repository such as git.
  
    cpanm --installdeps .
  
  =item --look
  
  Download and unpack the distribution and then open the directory with
  your shell. Handy to poke around the source code or do manual
  testing.
  
  =item -h, --help
  
  Displays the help message.
  
  =item -V, --version
  
  Displays the version number.
  
  =back
  
  =head1 OPTIONS
  
  You can specify the default options in C<PERL_CPANM_OPT> environment variable.
  
  =over 4
  
  =item -f, --force
  
  Force install modules even when testing failed.
  
  =item -n, --notest
  
  Skip the testing of modules. Use this only when you just want to save
  time for installing hundreds of distributions to the same perl and
  architecture you've already tested to make sure it builds fine.
  
  Defaults to false, and you can say C<--no-notest> to override when it
  is set in the default options in C<PERL_CPANM_OPT>.
  
  =item --test-only
  
  Run the tests only, and do not install the specified module or
  distributions. Handy if you want to verify the new (or even old)
  releases pass its unit tests without installing the module.
  
  Note that if you specify this option with a module or distribution
  that has dependencies, these dependencies will be installed if you
  don't currently have them.
  
  =item -S, --sudo
  
  Switch to the root user with C<sudo> when installing modules. Use this
  if you want to install modules to the system perl include path.
  
  Defaults to false, and you can say C<--no-sudo> to override when it is
  set in the default options in C<PERL_CPANM_OPT>.
  
  =item -v, --verbose
  
  Makes the output verbose. It also enables the interactive
  configuration. (See --interactive)
  
  =item -q, --quiet
  
  Makes the output even more quiet than the default. It only shows the
  successful/failed dependencies to the output.
  
  =item -l, --local-lib
  
  Sets the L<local::lib> compatible path to install modules to. You
  don't need to set this if you already configure the shell environment
  variables using L<local::lib>, but this can be used to override that
  as well.
  
  =item -L, --local-lib-contained
  
  Same with C<--local-lib> but with L<--self-contained> set.  All
  non-core dependencies will be installed even if they're already
  installed.
  
  For instance,
  
    cpanm -L extlib Plack
  
  would install Plack and all of its non-core dependencies into the
  directory C<extlib>, which can be loaded from your application with:
  
    use local::lib '/path/to/extlib';
  
  Note that this option does B<NOT> reliably work with perl installations
  supplied by operating system vendors that strips standard modules from perl,
  such as RHEL, Fedora and CentOS, B<UNLESS> you also install packages supplying
  all the modules that have been stripped.  For these systems you will probably
  want to install the C<perl-core> meta-package which does just that.
  
  =item --self-contained
  
  When examining the dependencies, assume no non-core modules are
  installed on the system. Handy if you want to bundle application
  dependencies in one directory so you can distribute to other machines.
  
  =item --exclude-vendor
  
  Don't include modules installed under the 'vendor' paths when searching for
  core modules when the C<--self-contained> flag is in effect.  This restores
  the behaviour from before version 1.7023
  
  =item --mirror
  
  Specifies the base URL for the CPAN mirror to use, such as
  C<http://cpan.cpantesters.org/> (you can omit the trailing slash). You
  can specify multiple mirror URLs by repeating the command line option.
  
  You can use a local directory that has a CPAN mirror structure
  (created by tools such as L<OrePAN> or L<Pinto>) by using a special
  URL scheme C<file://>. If the given URL begins with `/` (without any
  scheme), it is considered as a file scheme as well.
  
    cpanm --mirror file:///path/to/mirror
    cpanm --mirror ~/minicpan      # Because shell expands ~ to /home/user
  
  Defaults to C<http://www.cpan.org/>.
  
  =item --mirror-only
  
  Download the mirror's 02packages.details.txt.gz index file instead of
  querying the CPAN Meta DB. This will also effectively opt out sending
  your local perl versions to backend database servers such as CPAN Meta
  DB and MetaCPAN.
  
  Select this option if you are using a local mirror of CPAN, such as
  minicpan when you're offline, or your own CPAN index (a.k.a darkpan).
  
  =item --from, -M
  
    cpanm -M https://cpan.metacpan.org/
    cpanm --from https://cpan.metacpan.org/
  
  Use the given mirror URL and its index as the I<only> source to search
  and download modules from.
  
  It works similar to C<--mirror> and C<--mirror-only> combined, with a
  small difference: unlike C<--mirror> which I<appends> the URL to the
  list of mirrors, C<--from> (or C<-M> for short) uses the specified URL
  as its I<only> source to download index and modules from. This makes
  the option always override the default mirror, which might have been
  set via global options such as the one set by C<PERL_CPANM_OPT>
  environment variable.
  
  B<Tip:> It might be useful if you name these options with your shell
  aliases, like:
  
    alias minicpanm='cpanm --from ~/minicpan'
    alias darkpan='cpanm --from http://mycompany.example.com/DPAN'
  
  =item --mirror-index
  
  B<EXPERIMENTAL>: Specifies the file path to C<02packages.details.txt>
  for module search index.
  
  =item --cpanmetadb
  
  B<EXPERIMENTAL>: Specifies an alternate URI for CPAN MetaDB index lookups.
  
  =item --cpanfile
  
  B<EXPERIMENTAL>: Specified an alternate path for cpanfile to search for,
  when C<--installdeps> command is in use. Defaults to C<cpanfile>.
  
  =item --prompt
  
  Prompts when a test fails so that you can skip, force install, retry
  or look in the shell to see what's going wrong. It also prompts when
  one of the dependency failed if you want to proceed the installation.
  
  Defaults to false, and you can say C<--no-prompt> to override if it's
  set in the default options in C<PERL_CPANM_OPT>.
  
  =item --dev
  
  B<EXPERIMENTAL>: search for a newer developer release as well. Defaults to false.
  
  =item --reinstall
  
  cpanm, when given a module name in the command line (i.e. C<cpanm
  Plack>), checks the locally installed version first and skips if it is
  already installed. This option makes it skip the check, so:
  
    cpanm --reinstall Plack
  
  would reinstall L<Plack> even if your locally installed version is
  latest, or even newer (which would happen if you install a developer
  release from version control repositories).
  
  Defaults to false.
  
  =item --interactive
  
  Makes the configuration (such as C<Makefile.PL> and C<Build.PL>)
  interactive, so you can answer questions in the distribution that
  requires custom configuration or Task:: distributions.
  
  Defaults to false, and you can say C<--no-interactive> to override
  when it's set in the default options in C<PERL_CPANM_OPT>.
  
  =item --pp, --pureperl
  
  Prefer Pure perl build of modules by setting C<PUREPERL_ONLY=1> for
  MakeMaker and C<--pureperl-only> for Build.PL based
  distributions. Note that not all of the CPAN modules support this
  convention yet.
  
  =item --with-recommends, --with-suggests
  
  B<EXPERIMENTAL>: Installs dependencies declared as C<recommends> and
  C<suggests> respectively, per META spec. When these dependencies fail
  to install, cpanm continues the installation, since they're just
  recommendation/suggestion.
  
  Enabling this could potentially make a circular dependency for a few
  modules on CPAN, when C<recommends> adds a module that C<recommends>
  back the module in return.
  
  There's also C<--without-recommend> and C<--without-suggests> to
  override the default decision made earlier in C<PERL_CPANM_OPT>.
  
  Defaults to false for both.
  
  =item --with-develop
  
  B<EXPERIMENTAL>: Installs develop phase dependencies in META files or
  C<cpanfile> when used with C<--installdeps>. Defaults to false.
  
  =item --with-feature, --without-feature, --with-all-features
  
  B<EXPERIMENTAL>: Specifies the feature to enable, if a module supports
  optional features per META spec 2.0.
  
      cpanm --with-feature=opt_csv Spreadsheet::Read
  
  the features can also be interactively chosen when C<--interactive>
  option is enabled.
  
  C<--with-all-features> enables all the optional features, and
  C<--without-feature> can select a feature to disable.
  
  =item --configure-timeout, --build-timeout, --test-timeout
  
  Specify the timeout length (in seconds) to wait for the configure,
  build and test process. Current default values are: 60 for configure,
  3600 for build and 1800 for test.
  
  =item --configure-args, --build-args, --test-args, --install-args
  
  B<EXPERIMENTAL>: Pass arguments for configure/build/test/install
  commands respectively, for a given module to install.
  
      cpanm DBD::mysql --configure-args="--cflags=... --libs=..."
  
  The argument is only enabled for the module passed as a command line
  argument, not dependencies.
  
  =item --scandeps
  
  B<DEPRECATED>: Scans the depencencies of given modules and output the
  tree in a text format. (See C<--format> below for more options)
  
  Because this command doesn't actually install any distributions, it
  will be useful that by typing:
  
    cpanm --scandeps Catalyst::Runtime
  
  you can make sure what modules will be installed.
  
  This command takes into account which modules you already have
  installed in your system. If you want to see what modules will be
  installed against a vanilla perl installation, you might want to
  combine it with C<-L> option.
  
  =item --format
  
  B<DEPRECATED>: Determines what format to display the scanned
  dependency tree. Available options are C<tree>, C<json>, C<yaml> and
  C<dists>.
  
  =over 8
  
  =item tree
  
  Displays the tree in a plain text format. This is the default value.
  
  =item json, yaml
  
  Outputs the tree in a JSON or YAML format. L<JSON> and L<YAML> modules
  need to be installed respectively. The output tree is represented as a
  recursive tuple of:
  
    [ distribution, dependencies ]
  
  and the container is an array containing the root elements. Note that
  there may be multiple root nodes, since you can give multiple modules
  to the C<--scandeps> command.
  
  =item dists
  
  C<dists> is a special output format, where it prints the distribution
  filename in the I<depth first order> after the dependency resolution,
  like:
  
    GAAS/MIME-Base64-3.13.tar.gz
    GAAS/URI-1.58.tar.gz
    PETDANCE/HTML-Tagset-3.20.tar.gz
    GAAS/HTML-Parser-3.68.tar.gz
    GAAS/libwww-perl-5.837.tar.gz
  
  which means you can install these distributions in this order without
  extra dependencies. When combined with C<-L> option, it will be useful
  to replay installations on other machines.
  
  =back
  
  =item --save-dists
  
  Specifies the optional directory path to copy downloaded tarballs in
  the CPAN mirror compatible directory structure
  i.e. I<authors/id/A/AU/AUTHORS/Foo-Bar-version.tar.gz>
  
  If the distro tarball did not come from CPAN, for example from a local
  file or from GitHub, then it will be saved under
  I<vendor/Foo-Bar-version.tar.gz>.
  
  =item --uninst-shadows
  
  Uninstalls the shadow files of the distribution that you're
  installing. This eliminates the confusion if you're trying to install
  core (dual-life) modules from CPAN against perl 5.10 or older, or
  modules that used to be XS-based but switched to pure perl at some
  version.
  
  If you run cpanm as root and use C<INSTALL_BASE> or equivalent to
  specify custom installation path, you SHOULD disable this option so
  you won't accidentally uninstall dual-life modules from the core
  include path.
  
  Defaults to true if your perl version is smaller than 5.12, and you
  can disable that with C<--no-uninst-shadows>.
  
  B<NOTE>: Since version 1.3000 this flag is turned off by default for
  perl newer than 5.12, since with 5.12 @INC contains site_perl directory
  I<before> the perl core library path, and uninstalling shadows is not
  necessary anymore and does more harm by deleting files from the core
  library path.
  
  =item --uninstall, -U
  
  Uninstalls a module from the library path. It finds a packlist for
  given modules, and removes all the files included in the same
  distribution.
  
  If you enable local::lib, it only removes files from the local::lib
  directory.
  
  If you try to uninstall a module in C<perl> directory (i.e. core
  module), an error will be thrown.
  
  A dialog will be prompted to confirm the files to be deleted. If you pass
  C<-f> option as well, the dialog will be skipped and uninstallation
  will be forced.
  
  =item --cascade-search
  
  B<EXPERIMENTAL>: Specifies whether to cascade search when you specify
  multiple mirrors and a mirror doesn't have a module or has a lower
  version of the module than requested. Defaults to false.
  
  =item --skip-installed
  
  Specifies whether a module given in the command line is skipped if its latest
  version is already installed. Defaults to true.
  
  B<NOTE>: The C<PERL5LIB> environment variable have to be correctly set
  for this to work with modules installed using L<local::lib>, unless
  you always use the C<-l> option.
  
  =item --skip-satisfied
  
  B<EXPERIMENTAL>: Specifies whether a module (and version) given in the
  command line is skipped if it's already installed.
  
  If you run:
  
    cpanm --skip-satisfied CGI DBI~1.2
  
  cpanm won't install them if you already have CGI (for whatever
  versions) or have DBI with version higher than 1.2. It is similar to
  C<--skip-installed> but while C<--skip-installed> checks if the
  I<latest> version of CPAN is installed, C<--skip-satisfied> checks if
  a requested version (or not, which means any version) is installed.
  
  Defaults to false.
  
  =item --verify
  
  Verify the integrity of distribution files retrieved from PAUSE using
  CHECKSUMS and SIGNATURES (if found). Defaults to false.
  
  =item --report-perl-version
  
  Whether it report the locally installed perl version to the various
  web server as part of User-Agent. Defaults to true, and you can disable
  it by using C<--no-report-perl-version>.
  
  =item --auto-cleanup
  
  Specifies the number of days in which cpanm's work directories
  expire. Defaults to 7, which means old work directories will be
  cleaned up in one week.
  
  You can set the value to C<0> to make cpan never cleanup those
  directories.
  
  =item --man-pages
  
  Generates man pages for executables (man1) and libraries (man3).
  
  Defaults to true (man pages generated) unless C<-L|--local-lib-contained>
  option is supplied in which case it's set to false. You can disable
  it with C<--no-man-pages>.
  
  =item --lwp
  
  Uses L<LWP> module to download stuff over HTTP. Defaults to true, and
  you can say C<--no-lwp> to disable using LWP, when you want to upgrade
  LWP from CPAN on some broken perl systems.
  
  =item --wget
  
  Uses GNU Wget (if available) to download stuff. Defaults to true, and
  you can say C<--no-wget> to disable using Wget (versions of Wget older
  than 1.9 don't support the C<--retry-connrefused> option used by cpanm).
  
  =item --curl
  
  Uses cURL (if available) to download stuff. Defaults to true, and
  you can say C<--no-curl> to disable using cURL.
  
  Normally with C<--lwp>, C<--wget> and C<--curl> options set to true
  (which is the default) cpanm tries L<LWP>, Wget, cURL and L<HTTP::Tiny>
  (in that order) and uses the first one available.
  
  =back
  
  =head1 SEE ALSO
  
  L<App::cpanminus>
  
  =head1 COPYRIGHT
  
  Copyright 2010- Tatsuhiko Miyagawa.
  
  =head1 AUTHOR
  
  Tatsuhiko Miyagawa
  
  =cut
APP_CPANMINUS_FATSCRIPT

$fatpacked{"CPAN/Meta.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CPAN_META';
  use 5.006;
  use strict;
  use warnings;
  package CPAN::Meta;
  
  our $VERSION = '2.150005';
  
  #pod =head1 SYNOPSIS
  #pod
  #pod     use v5.10;
  #pod     use strict;
  #pod     use warnings;
  #pod     use CPAN::Meta;
  #pod     use Module::Load;
  #pod
  #pod     my $meta = CPAN::Meta->load_file('META.json');
  #pod
  #pod     printf "testing requirements for %s version %s\n",
  #pod     $meta->name,
  #pod     $meta->version;
  #pod
  #pod     my $prereqs = $meta->effective_prereqs;
  #pod
  #pod     for my $phase ( qw/configure runtime build test/ ) {
  #pod         say "Requirements for $phase:";
  #pod         my $reqs = $prereqs->requirements_for($phase, "requires");
  #pod         for my $module ( sort $reqs->required_modules ) {
  #pod             my $status;
  #pod             if ( eval { load $module unless $module eq 'perl'; 1 } ) {
  #pod                 my $version = $module eq 'perl' ? $] : $module->VERSION;
  #pod                 $status = $reqs->accepts_module($module, $version)
  #pod                         ? "$version ok" : "$version not ok";
  #pod             } else {
  #pod                 $status = "missing"
  #pod             };
  #pod             say "  $module ($status)";
  #pod         }
  #pod     }
  #pod
  #pod =head1 DESCRIPTION
  #pod
  #pod Software distributions released to the CPAN include a F<META.json> or, for
  #pod older distributions, F<META.yml>, which describes the distribution, its
  #pod contents, and the requirements for building and installing the distribution.
  #pod The data structure stored in the F<META.json> file is described in
  #pod L<CPAN::Meta::Spec>.
  #pod
  #pod CPAN::Meta provides a simple class to represent this distribution metadata (or
  #pod I<distmeta>), along with some helpful methods for interrogating that data.
  #pod
  #pod The documentation below is only for the methods of the CPAN::Meta object.  For
  #pod information on the meaning of individual fields, consult the spec.
  #pod
  #pod =cut
  
  use Carp qw(carp croak);
  use CPAN::Meta::Feature;
  use CPAN::Meta::Prereqs;
  use CPAN::Meta::Converter;
  use CPAN::Meta::Validator;
  use Parse::CPAN::Meta 1.4414 ();
  
  BEGIN { *_dclone = \&CPAN::Meta::Converter::_dclone }
  
  #pod =head1 STRING DATA
  #pod
  #pod The following methods return a single value, which is the value for the
  #pod corresponding entry in the distmeta structure.  Values should be either undef
  #pod or strings.
  #pod
  #pod =for :list
  #pod * abstract
  #pod * description
  #pod * dynamic_config
  #pod * generated_by
  #pod * name
  #pod * release_status
  #pod * version
  #pod
  #pod =cut
  
  BEGIN {
    my @STRING_READERS = qw(
      abstract
      description
      dynamic_config
      generated_by
      name
      release_status
      version
    );
  
    no strict 'refs';
    for my $attr (@STRING_READERS) {
      *$attr = sub { $_[0]{ $attr } };
    }
  }
  
  #pod =head1 LIST DATA
  #pod
  #pod These methods return lists of string values, which might be represented in the
  #pod distmeta structure as arrayrefs or scalars:
  #pod
  #pod =for :list
  #pod * authors
  #pod * keywords
  #pod * licenses
  #pod
  #pod The C<authors> and C<licenses> methods may also be called as C<author> and
  #pod C<license>, respectively, to match the field name in the distmeta structure.
  #pod
  #pod =cut
  
  BEGIN {
    my @LIST_READERS = qw(
      author
      keywords
      license
    );
  
    no strict 'refs';
    for my $attr (@LIST_READERS) {
      *$attr = sub {
        my $value = $_[0]{ $attr };
        croak "$attr must be called in list context"
          unless wantarray;
        return @{ _dclone($value) } if ref $value;
        return $value;
      };
    }
  }
  
  sub authors  { $_[0]->author }
  sub licenses { $_[0]->license }
  
  #pod =head1 MAP DATA
  #pod
  #pod These readers return hashrefs of arbitrary unblessed data structures, each
  #pod described more fully in the specification:
  #pod
  #pod =for :list
  #pod * meta_spec
  #pod * resources
  #pod * provides
  #pod * no_index
  #pod * prereqs
  #pod * optional_features
  #pod
  #pod =cut
  
  BEGIN {
    my @MAP_READERS = qw(
      meta-spec
      resources
      provides
      no_index
  
      prereqs
      optional_features
    );
  
    no strict 'refs';
    for my $attr (@MAP_READERS) {
      (my $subname = $attr) =~ s/-/_/;
      *$subname = sub {
        my $value = $_[0]{ $attr };
        return _dclone($value) if $value;
        return {};
      };
    }
  }
  
  #pod =head1 CUSTOM DATA
  #pod
  #pod A list of custom keys are available from the C<custom_keys> method and
  #pod particular keys may be retrieved with the C<custom> method.
  #pod
  #pod   say $meta->custom($_) for $meta->custom_keys;
  #pod
  #pod If a custom key refers to a data structure, a deep clone is returned.
  #pod
  #pod =cut
  
  sub custom_keys {
    return grep { /^x_/i } keys %{$_[0]};
  }
  
  sub custom {
    my ($self, $attr) = @_;
    my $value = $self->{$attr};
    return _dclone($value) if ref $value;
    return $value;
  }
  
  #pod =method new
  #pod
  #pod   my $meta = CPAN::Meta->new($distmeta_struct, \%options);
  #pod
  #pod Returns a valid CPAN::Meta object or dies if the supplied metadata hash
  #pod reference fails to validate.  Older-format metadata will be up-converted to
  #pod version 2 if they validate against the original stated specification.
  #pod
  #pod It takes an optional hashref of options. Valid options include:
  #pod
  #pod =over
  #pod
  #pod =item *
  #pod
  #pod lazy_validation -- if true, new will attempt to convert the given metadata
  #pod to version 2 before attempting to validate it.  This means than any
  #pod fixable errors will be handled by CPAN::Meta::Converter before validation.
  #pod (Note that this might result in invalid optional data being silently
  #pod dropped.)  The default is false.
  #pod
  #pod =back
  #pod
  #pod =cut
  
  sub _new {
    my ($class, $struct, $options) = @_;
    my $self;
  
    if ( $options->{lazy_validation} ) {
      # try to convert to a valid structure; if succeeds, then return it
      my $cmc = CPAN::Meta::Converter->new( $struct );
      $self = $cmc->convert( version => 2 ); # valid or dies
      return bless $self, $class;
    }
    else {
      # validate original struct
      my $cmv = CPAN::Meta::Validator->new( $struct );
      unless ( $cmv->is_valid) {
        die "Invalid metadata structure. Errors: "
          . join(", ", $cmv->errors) . "\n";
      }
    }
  
    # up-convert older spec versions
    my $version = $struct->{'meta-spec'}{version} || '1.0';
    if ( $version == 2 ) {
      $self = $struct;
    }
    else {
      my $cmc = CPAN::Meta::Converter->new( $struct );
      $self = $cmc->convert( version => 2 );
    }
  
    return bless $self, $class;
  }
  
  sub new {
    my ($class, $struct, $options) = @_;
    my $self = eval { $class->_new($struct, $options) };
    croak($@) if $@;
    return $self;
  }
  
  #pod =method create
  #pod
  #pod   my $meta = CPAN::Meta->create($distmeta_struct, \%options);
  #pod
  #pod This is same as C<new()>, except that C<generated_by> and C<meta-spec> fields
  #pod will be generated if not provided.  This means the metadata structure is
  #pod assumed to otherwise follow the latest L<CPAN::Meta::Spec>.
  #pod
  #pod =cut
  
  sub create {
    my ($class, $struct, $options) = @_;
    my $version = __PACKAGE__->VERSION || 2;
    $struct->{generated_by} ||= __PACKAGE__ . " version $version" ;
    $struct->{'meta-spec'}{version} ||= int($version);
    my $self = eval { $class->_new($struct, $options) };
    croak ($@) if $@;
    return $self;
  }
  
  #pod =method load_file
  #pod
  #pod   my $meta = CPAN::Meta->load_file($distmeta_file, \%options);
  #pod
  #pod Given a pathname to a file containing metadata, this deserializes the file
  #pod according to its file suffix and constructs a new C<CPAN::Meta> object, just
  #pod like C<new()>.  It will die if the deserialized version fails to validate
  #pod against its stated specification version.
  #pod
  #pod It takes the same options as C<new()> but C<lazy_validation> defaults to
  #pod true.
  #pod
  #pod =cut
  
  sub load_file {
    my ($class, $file, $options) = @_;
    $options->{lazy_validation} = 1 unless exists $options->{lazy_validation};
  
    croak "load_file() requires a valid, readable filename"
      unless -r $file;
  
    my $self;
    eval {
      my $struct = Parse::CPAN::Meta->load_file( $file );
      $self = $class->_new($struct, $options);
    };
    croak($@) if $@;
    return $self;
  }
  
  #pod =method load_yaml_string
  #pod
  #pod   my $meta = CPAN::Meta->load_yaml_string($yaml, \%options);
  #pod
  #pod This method returns a new CPAN::Meta object using the first document in the
  #pod given YAML string.  In other respects it is identical to C<load_file()>.
  #pod
  #pod =cut
  
  sub load_yaml_string {
    my ($class, $yaml, $options) = @_;
    $options->{lazy_validation} = 1 unless exists $options->{lazy_validation};
  
    my $self;
    eval {
      my ($struct) = Parse::CPAN::Meta->load_yaml_string( $yaml );
      $self = $class->_new($struct, $options);
    };
    croak($@) if $@;
    return $self;
  }
  
  #pod =method load_json_string
  #pod
  #pod   my $meta = CPAN::Meta->load_json_string($json, \%options);
  #pod
  #pod This method returns a new CPAN::Meta object using the structure represented by
  #pod the given JSON string.  In other respects it is identical to C<load_file()>.
  #pod
  #pod =cut
  
  sub load_json_string {
    my ($class, $json, $options) = @_;
    $options->{lazy_validation} = 1 unless exists $options->{lazy_validation};
  
    my $self;
    eval {
      my $struct = Parse::CPAN::Meta->load_json_string( $json );
      $self = $class->_new($struct, $options);
    };
    croak($@) if $@;
    return $self;
  }
  
  #pod =method load_string
  #pod
  #pod   my $meta = CPAN::Meta->load_string($string, \%options);
  #pod
  #pod If you don't know if a string contains YAML or JSON, this method will use
  #pod L<Parse::CPAN::Meta> to guess.  In other respects it is identical to
  #pod C<load_file()>.
  #pod
  #pod =cut
  
  sub load_string {
    my ($class, $string, $options) = @_;
    $options->{lazy_validation} = 1 unless exists $options->{lazy_validation};
  
    my $self;
    eval {
      my $struct = Parse::CPAN::Meta->load_string( $string );
      $self = $class->_new($struct, $options);
    };
    croak($@) if $@;
    return $self;
  }
  
  #pod =method save
  #pod
  #pod   $meta->save($distmeta_file, \%options);
  #pod
  #pod Serializes the object as JSON and writes it to the given file.  The only valid
  #pod option is C<version>, which defaults to '2'. On Perl 5.8.1 or later, the file
  #pod is saved with UTF-8 encoding.
  #pod
  #pod For C<version> 2 (or higher), the filename should end in '.json'.  L<JSON::PP>
  #pod is the default JSON backend. Using another JSON backend requires L<JSON> 2.5 or
  #pod later and you must set the C<$ENV{PERL_JSON_BACKEND}> to a supported alternate
  #pod backend like L<JSON::XS>.
  #pod
  #pod For C<version> less than 2, the filename should end in '.yml'.
  #pod L<CPAN::Meta::Converter> is used to generate an older metadata structure, which
  #pod is serialized to YAML.  CPAN::Meta::YAML is the default YAML backend.  You may
  #pod set the C<$ENV{PERL_YAML_BACKEND}> to a supported alternative backend, though
  #pod this is not recommended due to subtle incompatibilities between YAML parsers on
  #pod CPAN.
  #pod
  #pod =cut
  
  sub save {
    my ($self, $file, $options) = @_;
  
    my $version = $options->{version} || '2';
    my $layer = $] ge '5.008001' ? ':utf8' : '';
  
    if ( $version ge '2' ) {
      carp "'$file' should end in '.json'"
        unless $file =~ m{\.json$};
    }
    else {
      carp "'$file' should end in '.yml'"
        unless $file =~ m{\.yml$};
    }
  
    my $data = $self->as_string( $options );
    open my $fh, ">$layer", $file
      or die "Error opening '$file' for writing: $!\n";
  
    print {$fh} $data;
    close $fh
      or die "Error closing '$file': $!\n";
  
    return 1;
  }
  
  #pod =method meta_spec_version
  #pod
  #pod This method returns the version part of the C<meta_spec> entry in the distmeta
  #pod structure.  It is equivalent to:
  #pod
  #pod   $meta->meta_spec->{version};
  #pod
  #pod =cut
  
  sub meta_spec_version {
    my ($self) = @_;
    return $self->meta_spec->{version};
  }
  
  #pod =method effective_prereqs
  #pod
  #pod   my $prereqs = $meta->effective_prereqs;
  #pod
  #pod   my $prereqs = $meta->effective_prereqs( \@feature_identifiers );
  #pod
  #pod This method returns a L<CPAN::Meta::Prereqs> object describing all the
  #pod prereqs for the distribution.  If an arrayref of feature identifiers is given,
  #pod the prereqs for the identified features are merged together with the
  #pod distribution's core prereqs before the CPAN::Meta::Prereqs object is returned.
  #pod
  #pod =cut
  
  sub effective_prereqs {
    my ($self, $features) = @_;
    $features ||= [];
  
    my $prereq = CPAN::Meta::Prereqs->new($self->prereqs);
  
    return $prereq unless @$features;
  
    my @other = map {; $self->feature($_)->prereqs } @$features;
  
    return $prereq->with_merged_prereqs(\@other);
  }
  
  #pod =method should_index_file
  #pod
  #pod   ... if $meta->should_index_file( $filename );
  #pod
  #pod This method returns true if the given file should be indexed.  It decides this
  #pod by checking the C<file> and C<directory> keys in the C<no_index> property of
  #pod the distmeta structure. Note that neither the version format nor
  #pod C<release_status> are considered.
  #pod
  #pod C<$filename> should be given in unix format.
  #pod
  #pod =cut
  
  sub should_index_file {
    my ($self, $filename) = @_;
  
    for my $no_index_file (@{ $self->no_index->{file} || [] }) {
      return if $filename eq $no_index_file;
    }
  
    for my $no_index_dir (@{ $self->no_index->{directory} }) {
      $no_index_dir =~ s{$}{/} unless $no_index_dir =~ m{/\z};
      return if index($filename, $no_index_dir) == 0;
    }
  
    return 1;
  }
  
  #pod =method should_index_package
  #pod
  #pod   ... if $meta->should_index_package( $package );
  #pod
  #pod This method returns true if the given package should be indexed.  It decides
  #pod this by checking the C<package> and C<namespace> keys in the C<no_index>
  #pod property of the distmeta structure. Note that neither the version format nor
  #pod C<release_status> are considered.
  #pod
  #pod =cut
  
  sub should_index_package {
    my ($self, $package) = @_;
  
    for my $no_index_pkg (@{ $self->no_index->{package} || [] }) {
      return if $package eq $no_index_pkg;
    }
  
    for my $no_index_ns (@{ $self->no_index->{namespace} }) {
      return if index($package, "${no_index_ns}::") == 0;
    }
  
    return 1;
  }
  
  #pod =method features
  #pod
  #pod   my @feature_objects = $meta->features;
  #pod
  #pod This method returns a list of L<CPAN::Meta::Feature> objects, one for each
  #pod optional feature described by the distribution's metadata.
  #pod
  #pod =cut
  
  sub features {
    my ($self) = @_;
  
    my $opt_f = $self->optional_features;
    my @features = map {; CPAN::Meta::Feature->new($_ => $opt_f->{ $_ }) }
                   keys %$opt_f;
  
    return @features;
  }
  
  #pod =method feature
  #pod
  #pod   my $feature_object = $meta->feature( $identifier );
  #pod
  #pod This method returns a L<CPAN::Meta::Feature> object for the optional feature
  #pod with the given identifier.  If no feature with that identifier exists, an
  #pod exception will be raised.
  #pod
  #pod =cut
  
  sub feature {
    my ($self, $ident) = @_;
  
    croak "no feature named $ident"
      unless my $f = $self->optional_features->{ $ident };
  
    return CPAN::Meta::Feature->new($ident, $f);
  }
  
  #pod =method as_struct
  #pod
  #pod   my $copy = $meta->as_struct( \%options );
  #pod
  #pod This method returns a deep copy of the object's metadata as an unblessed hash
  #pod reference.  It takes an optional hashref of options.  If the hashref contains
  #pod a C<version> argument, the copied metadata will be converted to the version
  #pod of the specification and returned.  For example:
  #pod
  #pod   my $old_spec = $meta->as_struct( {version => "1.4"} );
  #pod
  #pod =cut
  
  sub as_struct {
    my ($self, $options) = @_;
    my $struct = _dclone($self);
    if ( $options->{version} ) {
      my $cmc = CPAN::Meta::Converter->new( $struct );
      $struct = $cmc->convert( version => $options->{version} );
    }
    return $struct;
  }
  
  #pod =method as_string
  #pod
  #pod   my $string = $meta->as_string( \%options );
  #pod
  #pod This method returns a serialized copy of the object's metadata as a character
  #pod string.  (The strings are B<not> UTF-8 encoded.)  It takes an optional hashref
  #pod of options.  If the hashref contains a C<version> argument, the copied metadata
  #pod will be converted to the version of the specification and returned.  For
  #pod example:
  #pod
  #pod   my $string = $meta->as_string( {version => "1.4"} );
  #pod
  #pod For C<version> greater than or equal to 2, the string will be serialized as
  #pod JSON.  For C<version> less than 2, the string will be serialized as YAML.  In
  #pod both cases, the same rules are followed as in the C<save()> method for choosing
  #pod a serialization backend.
  #pod
  #pod The serialized structure will include a C<x_serialization_backend> entry giving
  #pod the package and version used to serialize.  Any existing key in the given
  #pod C<$meta> object will be clobbered.
  #pod
  #pod =cut
  
  sub as_string {
    my ($self, $options) = @_;
  
    my $version = $options->{version} || '2';
  
    my $struct;
    if ( $self->meta_spec_version ne $version ) {
      my $cmc = CPAN::Meta::Converter->new( $self->as_struct );
      $struct = $cmc->convert( version => $version );
    }
    else {
      $struct = $self->as_struct;
    }
  
    my ($data, $backend);
    if ( $version ge '2' ) {
      $backend = Parse::CPAN::Meta->json_backend();
      local $struct->{x_serialization_backend} = sprintf '%s version %s',
        $backend, $backend->VERSION;
      $data = $backend->new->pretty->canonical->encode($struct);
    }
    else {
      $backend = Parse::CPAN::Meta->yaml_backend();
      local $struct->{x_serialization_backend} = sprintf '%s version %s',
        $backend, $backend->VERSION;
      $data = eval { no strict 'refs'; &{"$backend\::Dump"}($struct) };
      if ( $@ ) {
        croak $backend->can('errstr') ? $backend->errstr : $@
      }
    }
  
    return $data;
  }
  
  # Used by JSON::PP, etc. for "convert_blessed"
  sub TO_JSON {
    return { %{ $_[0] } };
  }
  
  1;
  
  # ABSTRACT: the distribution metadata for a CPAN dist
  
  =pod
  
  =encoding UTF-8
  
  =head1 NAME
  
  CPAN::Meta - the distribution metadata for a CPAN dist
  
  =head1 VERSION
  
  version 2.150005
  
  =head1 SYNOPSIS
  
      use v5.10;
      use strict;
      use warnings;
      use CPAN::Meta;
      use Module::Load;
  
      my $meta = CPAN::Meta->load_file('META.json');
  
      printf "testing requirements for %s version %s\n",
      $meta->name,
      $meta->version;
  
      my $prereqs = $meta->effective_prereqs;
  
      for my $phase ( qw/configure runtime build test/ ) {
          say "Requirements for $phase:";
          my $reqs = $prereqs->requirements_for($phase, "requires");
          for my $module ( sort $reqs->required_modules ) {
              my $status;
              if ( eval { load $module unless $module eq 'perl'; 1 } ) {
                  my $version = $module eq 'perl' ? $] : $module->VERSION;
                  $status = $reqs->accepts_module($module, $version)
                          ? "$version ok" : "$version not ok";
              } else {
                  $status = "missing"
              };
              say "  $module ($status)";
          }
      }
  
  =head1 DESCRIPTION
  
  Software distributions released to the CPAN include a F<META.json> or, for
  older distributions, F<META.yml>, which describes the distribution, its
  contents, and the requirements for building and installing the distribution.
  The data structure stored in the F<META.json> file is described in
  L<CPAN::Meta::Spec>.
  
  CPAN::Meta provides a simple class to represent this distribution metadata (or
  I<distmeta>), along with some helpful methods for interrogating that data.
  
  The documentation below is only for the methods of the CPAN::Meta object.  For
  information on the meaning of individual fields, consult the spec.
  
  =head1 METHODS
  
  =head2 new
  
    my $meta = CPAN::Meta->new($distmeta_struct, \%options);
  
  Returns a valid CPAN::Meta object or dies if the supplied metadata hash
  reference fails to validate.  Older-format metadata will be up-converted to
  version 2 if they validate against the original stated specification.
  
  It takes an optional hashref of options. Valid options include:
  
  =over
  
  =item *
  
  lazy_validation -- if true, new will attempt to convert the given metadata
  to version 2 before attempting to validate it.  This means than any
  fixable errors will be handled by CPAN::Meta::Converter before validation.
  (Note that this might result in invalid optional data being silently
  dropped.)  The default is false.
  
  =back
  
  =head2 create
  
    my $meta = CPAN::Meta->create($distmeta_struct, \%options);
  
  This is same as C<new()>, except that C<generated_by> and C<meta-spec> fields
  will be generated if not provided.  This means the metadata structure is
  assumed to otherwise follow the latest L<CPAN::Meta::Spec>.
  
  =head2 load_file
  
    my $meta = CPAN::Meta->load_file($distmeta_file, \%options);
  
  Given a pathname to a file containing metadata, this deserializes the file
  according to its file suffix and constructs a new C<CPAN::Meta> object, just
  like C<new()>.  It will die if the deserialized version fails to validate
  against its stated specification version.
  
  It takes the same options as C<new()> but C<lazy_validation> defaults to
  true.
  
  =head2 load_yaml_string
  
    my $meta = CPAN::Meta->load_yaml_string($yaml, \%options);
  
  This method returns a new CPAN::Meta object using the first document in the
  given YAML string.  In other respects it is identical to C<load_file()>.
  
  =head2 load_json_string
  
    my $meta = CPAN::Meta->load_json_string($json, \%options);
  
  This method returns a new CPAN::Meta object using the structure represented by
  the given JSON string.  In other respects it is identical to C<load_file()>.
  
  =head2 load_string
  
    my $meta = CPAN::Meta->load_string($string, \%options);
  
  If you don't know if a string contains YAML or JSON, this method will use
  L<Parse::CPAN::Meta> to guess.  In other respects it is identical to
  C<load_file()>.
  
  =head2 save
  
    $meta->save($distmeta_file, \%options);
  
  Serializes the object as JSON and writes it to the given file.  The only valid
  option is C<version>, which defaults to '2'. On Perl 5.8.1 or later, the file
  is saved with UTF-8 encoding.
  
  For C<version> 2 (or higher), the filename should end in '.json'.  L<JSON::PP>
  is the default JSON backend. Using another JSON backend requires L<JSON> 2.5 or
  later and you must set the C<$ENV{PERL_JSON_BACKEND}> to a supported alternate
  backend like L<JSON::XS>.
  
  For C<version> less than 2, the filename should end in '.yml'.
  L<CPAN::Meta::Converter> is used to generate an older metadata structure, which
  is serialized to YAML.  CPAN::Meta::YAML is the default YAML backend.  You may
  set the C<$ENV{PERL_YAML_BACKEND}> to a supported alternative backend, though
  this is not recommended due to subtle incompatibilities between YAML parsers on
  CPAN.
  
  =head2 meta_spec_version
  
  This method returns the version part of the C<meta_spec> entry in the distmeta
  structure.  It is equivalent to:
  
    $meta->meta_spec->{version};
  
  =head2 effective_prereqs
  
    my $prereqs = $meta->effective_prereqs;
  
    my $prereqs = $meta->effective_prereqs( \@feature_identifiers );
  
  This method returns a L<CPAN::Meta::Prereqs> object describing all the
  prereqs for the distribution.  If an arrayref of feature identifiers is given,
  the prereqs for the identified features are merged together with the
  distribution's core prereqs before the CPAN::Meta::Prereqs object is returned.
  
  =head2 should_index_file
  
    ... if $meta->should_index_file( $filename );
  
  This method returns true if the given file should be indexed.  It decides this
  by checking the C<file> and C<directory> keys in the C<no_index> property of
  the distmeta structure. Note that neither the version format nor
  C<release_status> are considered.
  
  C<$filename> should be given in unix format.
  
  =head2 should_index_package
  
    ... if $meta->should_index_package( $package );
  
  This method returns true if the given package should be indexed.  It decides
  this by checking the C<package> and C<namespace> keys in the C<no_index>
  property of the distmeta structure. Note that neither the version format nor
  C<release_status> are considered.
  
  =head2 features
  
    my @feature_objects = $meta->features;
  
  This method returns a list of L<CPAN::Meta::Feature> objects, one for each
  optional feature described by the distribution's metadata.
  
  =head2 feature
  
    my $feature_object = $meta->feature( $identifier );
  
  This method returns a L<CPAN::Meta::Feature> object for the optional feature
  with the given identifier.  If no feature with that identifier exists, an
  exception will be raised.
  
  =head2 as_struct
  
    my $copy = $meta->as_struct( \%options );
  
  This method returns a deep copy of the object's metadata as an unblessed hash
  reference.  It takes an optional hashref of options.  If the hashref contains
  a C<version> argument, the copied metadata will be converted to the version
  of the specification and returned.  For example:
  
    my $old_spec = $meta->as_struct( {version => "1.4"} );
  
  =head2 as_string
  
    my $string = $meta->as_string( \%options );
  
  This method returns a serialized copy of the object's metadata as a character
  string.  (The strings are B<not> UTF-8 encoded.)  It takes an optional hashref
  of options.  If the hashref contains a C<version> argument, the copied metadata
  will be converted to the version of the specification and returned.  For
  example:
  
    my $string = $meta->as_string( {version => "1.4"} );
  
  For C<version> greater than or equal to 2, the string will be serialized as
  JSON.  For C<version> less than 2, the string will be serialized as YAML.  In
  both cases, the same rules are followed as in the C<save()> method for choosing
  a serialization backend.
  
  The serialized structure will include a C<x_serialization_backend> entry giving
  the package and version used to serialize.  Any existing key in the given
  C<$meta> object will be clobbered.
  
  =head1 STRING DATA
  
  The following methods return a single value, which is the value for the
  corresponding entry in the distmeta structure.  Values should be either undef
  or strings.
  
  =over 4
  
  =item *
  
  abstract
  
  =item *
  
  description
  
  =item *
  
  dynamic_config
  
  =item *
  
  generated_by
  
  =item *
  
  name
  
  =item *
  
  release_status
  
  =item *
  
  version
  
  =back
  
  =head1 LIST DATA
  
  These methods return lists of string values, which might be represented in the
  distmeta structure as arrayrefs or scalars:
  
  =over 4
  
  =item *
  
  authors
  
  =item *
  
  keywords
  
  =item *
  
  licenses
  
  =back
  
  The C<authors> and C<licenses> methods may also be called as C<author> and
  C<license>, respectively, to match the field name in the distmeta structure.
  
  =head1 MAP DATA
  
  These readers return hashrefs of arbitrary unblessed data structures, each
  described more fully in the specification:
  
  =over 4
  
  =item *
  
  meta_spec
  
  =item *
  
  resources
  
  =item *
  
  provides
  
  =item *
  
  no_index
  
  =item *
  
  prereqs
  
  =item *
  
  optional_features
  
  =back
  
  =head1 CUSTOM DATA
  
  A list of custom keys are available from the C<custom_keys> method and
  particular keys may be retrieved with the C<custom> method.
  
    say $meta->custom($_) for $meta->custom_keys;
  
  If a custom key refers to a data structure, a deep clone is returned.
  
  =for Pod::Coverage TO_JSON abstract author authors custom custom_keys description dynamic_config
  generated_by keywords license licenses meta_spec name no_index
  optional_features prereqs provides release_status resources version
  
  =head1 BUGS
  
  Please report any bugs or feature using the CPAN Request Tracker.
  Bugs can be submitted through the web interface at
  L<http://rt.cpan.org/Dist/Display.html?Queue=CPAN-Meta>
  
  When submitting a bug or request, please include a test-file or a patch to an
  existing test-file that illustrates the bug or desired feature.
  
  =head1 SEE ALSO
  
  =over 4
  
  =item *
  
  L<CPAN::Meta::Converter>
  
  =item *
  
  L<CPAN::Meta::Validator>
  
  =back
  
  =for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan
  
  =head1 SUPPORT
  
  =head2 Bugs / Feature Requests
  
  Please report any bugs or feature requests through the issue tracker
  at L<https://github.com/Perl-Toolchain-Gang/CPAN-Meta/issues>.
  You will be notified automatically of any progress on your issue.
  
  =head2 Source Code
  
  This is open source software.  The code repository is available for
  public review and contribution under the terms of the license.
  
  L<https://github.com/Perl-Toolchain-Gang/CPAN-Meta>
  
    git clone https://github.com/Perl-Toolchain-Gang/CPAN-Meta.git
  
  =head1 AUTHORS
  
  =over 4
  
  =item *
  
  David Golden <dagolden@cpan.org>
  
  =item *
  
  Ricardo Signes <rjbs@cpan.org>
  
  =back
  
  =head1 CONTRIBUTORS
  
  =for stopwords Ansgar Burchardt Avar Arnfjord Bjarmason Christopher J. Madsen Chuck Adams Cory G Watson Damyan Ivanov Eric Wilhelm Graham Knop Gregor Hermann Karen Etheridge Kenichi Ishigaki Ken Williams Lars Dieckow Leon Timmermans majensen Mark Fowler Matt S Trout Michael G. Schwern mohawk2 moznion Niko Tyni Olaf Alders Olivier Mengué Randy Sims Tomohiro Hosaka
  
  =over 4
  
  =item *
  
  Ansgar Burchardt <ansgar@cpan.org>
  
  =item *
  
  Avar Arnfjord Bjarmason <avar@cpan.org>
  
  =item *
  
  Christopher J. Madsen <cjm@cpan.org>
  
  =item *
  
  Chuck Adams <cja987@gmail.com>
  
  =item *
  
  Cory G Watson <gphat@cpan.org>
  
  =item *
  
  Damyan Ivanov <dam@cpan.org>
  
  =item *
  
  Eric Wilhelm <ewilhelm@cpan.org>
  
  =item *
  
  Graham Knop <haarg@haarg.org>
  
  =item *
  
  Gregor Hermann <gregoa@debian.org>
  
  =item *
  
  Karen Etheridge <ether@cpan.org>
  
  =item *
  
  Kenichi Ishigaki <ishigaki@cpan.org>
  
  =item *
  
  Ken Williams <kwilliams@cpan.org>
  
  =item *
  
  Lars Dieckow <daxim@cpan.org>
  
  =item *
  
  Leon Timmermans <leont@cpan.org>
  
  =item *
  
  majensen <maj@fortinbras.us>
  
  =item *
  
  Mark Fowler <markf@cpan.org>
  
  =item *
  
  Matt S Trout <mst@shadowcat.co.uk>
  
  =item *
  
  Michael G. Schwern <mschwern@cpan.org>
  
  =item *
  
  mohawk2 <mohawk2@users.noreply.github.com>
  
  =item *
  
  moznion <moznion@gmail.com>
  
  =item *
  
  Niko Tyni <ntyni@debian.org>
  
  =item *
  
  Olaf Alders <olaf@wundersolutions.com>
  
  =item *
  
  Olivier Mengué <dolmen@cpan.org>
  
  =item *
  
  Randy Sims <randys@thepierianspring.org>
  
  =item *
  
  Tomohiro Hosaka <bokutin@bokut.in>
  
  =back
  
  =head1 COPYRIGHT AND LICENSE
  
  This software is copyright (c) 2010 by David Golden and Ricardo Signes.
  
  This is free software; you can redistribute it and/or modify it under
  the same terms as the Perl 5 programming language system itself.
  
  =cut
  
  __END__
  
  
  # vim: ts=2 sts=2 sw=2 et :
CPAN_META

$fatpacked{"CPAN/Meta/Converter.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CPAN_META_CONVERTER';
  use 5.006;
  use strict;
  use warnings;
  package CPAN::Meta::Converter;
  
  our $VERSION = '2.150005';
  
  #pod =head1 SYNOPSIS
  #pod
  #pod   my $struct = decode_json_file('META.json');
  #pod
  #pod   my $cmc = CPAN::Meta::Converter->new( $struct );
  #pod
  #pod   my $new_struct = $cmc->convert( version => "2" );
  #pod
  #pod =head1 DESCRIPTION
  #pod
  #pod This module converts CPAN Meta structures from one form to another.  The
  #pod primary use is to convert older structures to the most modern version of
  #pod the specification, but other transformations may be implemented in the
  #pod future as needed.  (E.g. stripping all custom fields or stripping all
  #pod optional fields.)
  #pod
  #pod =cut
  
  use CPAN::Meta::Validator;
  use CPAN::Meta::Requirements;
  use Parse::CPAN::Meta 1.4400 ();
  
  # To help ExtUtils::MakeMaker bootstrap CPAN::Meta::Requirements on perls
  # before 5.10, we fall back to the EUMM bundled compatibility version module if
  # that's the only thing available.  This shouldn't ever happen in a normal CPAN
  # install of CPAN::Meta::Requirements, as version.pm will be picked up from
  # prereqs and be available at runtime.
  
  BEGIN {
    eval "use version ()"; ## no critic
    if ( my $err = $@ ) {
      eval "use ExtUtils::MakeMaker::version" or die $err; ## no critic
    }
  }
  
  # Perl 5.10.0 didn't have "is_qv" in version.pm
  *_is_qv = version->can('is_qv') ? sub { $_[0]->is_qv } : sub { exists $_[0]->{qv} };
  
  sub _dclone {
    my $ref = shift;
  
    # if an object is in the data structure and doesn't specify how to
    # turn itself into JSON, we just stringify the object.  That does the
    # right thing for typical things that might be there, like version objects,
    # Path::Class objects, etc.
    no warnings 'once';
    no warnings 'redefine';
    local *UNIVERSAL::TO_JSON = sub { "$_[0]" };
  
    my $json = Parse::CPAN::Meta->json_backend()->new
        ->utf8
        ->allow_blessed
        ->convert_blessed;
    $json->decode($json->encode($ref))
  }
  
  my %known_specs = (
      '2'   => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec',
      '1.4' => 'http://module-build.sourceforge.net/META-spec-v1.4.html',
      '1.3' => 'http://module-build.sourceforge.net/META-spec-v1.3.html',
      '1.2' => 'http://module-build.sourceforge.net/META-spec-v1.2.html',
      '1.1' => 'http://module-build.sourceforge.net/META-spec-v1.1.html',
      '1.0' => 'http://module-build.sourceforge.net/META-spec-v1.0.html'
  );
  
  my @spec_list = sort { $a <=> $b } keys %known_specs;
  my ($LOWEST, $HIGHEST) = @spec_list[0,-1];
  
  #--------------------------------------------------------------------------#
  # converters
  #
  # called as $converter->($element, $field_name, $full_meta, $to_version)
  #
  # defined return value used for field
  # undef return value means field is skipped
  #--------------------------------------------------------------------------#
  
  sub _keep { $_[0] }
  
  sub _keep_or_one { defined($_[0]) ? $_[0] : 1 }
  
  sub _keep_or_zero { defined($_[0]) ? $_[0] : 0 }
  
  sub _keep_or_unknown { defined($_[0]) && length($_[0]) ? $_[0] : "unknown" }
  
  sub _generated_by {
    my $gen = shift;
    my $sig = __PACKAGE__ . " version " . (__PACKAGE__->VERSION || "<dev>");
  
    return $sig unless defined $gen and length $gen;
    return $gen if $gen =~ /\Q$sig/;
    return "$gen, $sig";
  }
  
  sub _listify { ! defined $_[0] ? undef : ref $_[0] eq 'ARRAY' ? $_[0] : [$_[0]] }
  
  sub _prefix_custom {
    my $key = shift;
    $key =~ s/^(?!x_)   # Unless it already starts with x_
               (?:x-?)? # Remove leading x- or x (if present)
             /x_/ix;    # and prepend x_
    return $key;
  }
  
  sub _ucfirst_custom {
    my $key = shift;
    $key = ucfirst $key unless $key =~ /[A-Z]/;
    return $key;
  }
  
  sub _no_prefix_ucfirst_custom {
    my $key = shift;
    $key =~ s/^x_//;
    return _ucfirst_custom($key);
  }
  
  sub _change_meta_spec {
    my ($element, undef, undef, $version) = @_;
    return {
      version => $version,
      url => $known_specs{$version},
    };
  }
  
  my @open_source = (
    'perl',
    'gpl',
    'apache',
    'artistic',
    'artistic_2',
    'lgpl',
    'bsd',
    'gpl',
    'mit',
    'mozilla',
    'open_source',
  );
  
  my %is_open_source = map {; $_ => 1 } @open_source;
  
  my @valid_licenses_1 = (
    @open_source,
    'unrestricted',
    'restrictive',
    'unknown',
  );
  
  my %license_map_1 = (
    ( map { $_ => $_ } @valid_licenses_1 ),
    artistic2 => 'artistic_2',
  );
  
  sub _license_1 {
    my ($element) = @_;
    return 'unknown' unless defined $element;
    if ( $license_map_1{lc $element} ) {
      return $license_map_1{lc $element};
    }
    else {
      return 'unknown';
    }
  }
  
  my @valid_licenses_2 = qw(
    agpl_3
    apache_1_1
    apache_2_0
    artistic_1
    artistic_2
    bsd
    freebsd
    gfdl_1_2
    gfdl_1_3
    gpl_1
    gpl_2
    gpl_3
    lgpl_2_1
    lgpl_3_0
    mit
    mozilla_1_0
    mozilla_1_1
    openssl
    perl_5
    qpl_1_0
    ssleay
    sun
    zlib
    open_source
    restricted
    unrestricted
    unknown
  );
  
  # The "old" values were defined by Module::Build, and were often vague.  I have
  # made the decisions below based on reading Module::Build::API and how clearly
  # it specifies the version of the license.
  my %license_map_2 = (
    (map { $_ => $_ } @valid_licenses_2),
    apache      => 'apache_2_0',  # clearly stated as 2.0
    artistic    => 'artistic_1',  # clearly stated as 1
    artistic2   => 'artistic_2',  # clearly stated as 2
    gpl         => 'open_source', # we don't know which GPL; punt
    lgpl        => 'open_source', # we don't know which LGPL; punt
    mozilla     => 'open_source', # we don't know which MPL; punt
    perl        => 'perl_5',      # clearly Perl 5
    restrictive => 'restricted',
  );
  
  sub _license_2 {
    my ($element) = @_;
    return [ 'unknown' ] unless defined $element;
    $element = [ $element ] unless ref $element eq 'ARRAY';
    my @new_list;
    for my $lic ( @$element ) {
      next unless defined $lic;
      if ( my $new = $license_map_2{lc $lic} ) {
        push @new_list, $new;
      }
    }
    return @new_list ? \@new_list : [ 'unknown' ];
  }
  
  my %license_downgrade_map = qw(
    agpl_3            open_source
    apache_1_1        apache
    apache_2_0        apache
    artistic_1        artistic
    artistic_2        artistic_2
    bsd               bsd
    freebsd           open_source
    gfdl_1_2          open_source
    gfdl_1_3          open_source
    gpl_1             gpl
    gpl_2             gpl
    gpl_3             gpl
    lgpl_2_1          lgpl
    lgpl_3_0          lgpl
    mit               mit
    mozilla_1_0       mozilla
    mozilla_1_1       mozilla
    openssl           open_source
    perl_5            perl
    qpl_1_0           open_source
    ssleay            open_source
    sun               open_source
    zlib              open_source
    open_source       open_source
    restricted        restrictive
    unrestricted      unrestricted
    unknown           unknown
  );
  
  sub _downgrade_license {
    my ($element) = @_;
    if ( ! defined $element ) {
      return "unknown";
    }
    elsif( ref $element eq 'ARRAY' ) {
      if ( @$element > 1) {
        if (grep { !$is_open_source{ $license_downgrade_map{lc $_} || 'unknown' } } @$element) {
          return 'unknown';
        }
        else {
          return 'open_source';
        }
      }
      elsif ( @$element == 1 ) {
        return $license_downgrade_map{lc $element->[0]} || "unknown";
      }
    }
    elsif ( ! ref $element ) {
      return $license_downgrade_map{lc $element} || "unknown";
    }
    return "unknown";
  }
  
  my $no_index_spec_1_2 = {
    'file' => \&_listify,
    'dir' => \&_listify,
    'package' => \&_listify,
    'namespace' => \&_listify,
  };
  
  my $no_index_spec_1_3 = {
    'file' => \&_listify,
    'directory' => \&_listify,
    'package' => \&_listify,
    'namespace' => \&_listify,
  };
  
  my $no_index_spec_2 = {
    'file' => \&_listify,
    'directory' => \&_listify,
    'package' => \&_listify,
    'namespace' => \&_listify,
    ':custom'  => \&_prefix_custom,
  };
  
  sub _no_index_1_2 {
    my (undef, undef, $meta) = @_;
    my $no_index = $meta->{no_index} || $meta->{private};
    return unless $no_index;
  
    # cleanup wrong format
    if ( ! ref $no_index ) {
      my $item = $no_index;
      $no_index = { dir => [ $item ], file => [ $item ] };
    }
    elsif ( ref $no_index eq 'ARRAY' ) {
      my $list = $no_index;
      $no_index = { dir => [ @$list ], file => [ @$list ] };
    }
  
    # common mistake: files -> file
    if ( exists $no_index->{files} ) {
      $no_index->{file} = delete $no_index->{files};
    }
    # common mistake: modules -> module
    if ( exists $no_index->{modules} ) {
      $no_index->{module} = delete $no_index->{modules};
    }
    return _convert($no_index, $no_index_spec_1_2);
  }
  
  sub _no_index_directory {
    my ($element, $key, $meta, $version) = @_;
    return unless $element;
  
    # cleanup wrong format
    if ( ! ref $element ) {
      my $item = $element;
      $element = { directory => [ $item ], file => [ $item ] };
    }
    elsif ( ref $element eq 'ARRAY' ) {
      my $list = $element;
      $element = { directory => [ @$list ], file => [ @$list ] };
    }
  
    if ( exists $element->{dir} ) {
      $element->{directory} = delete $element->{dir};
    }
    # common mistake: files -> file
    if ( exists $element->{files} ) {
      $element->{file} = delete $element->{files};
    }
    # common mistake: modules -> module
    if ( exists $element->{modules} ) {
      $element->{module} = delete $element->{modules};
    }
    my $spec = $version == 2 ? $no_index_spec_2 : $no_index_spec_1_3;
    return _convert($element, $spec);
  }
  
  sub _is_module_name {
    my $mod = shift;
    return unless defined $mod && length $mod;
    return $mod =~ m{^[A-Za-z][A-Za-z0-9_]*(?:::[A-Za-z0-9_]+)*$};
  }
  
  sub _clean_version {
    my ($element) = @_;
    return 0 if ! defined $element;
  
    $element =~ s{^\s*}{};
    $element =~ s{\s*$}{};
    $element =~ s{^\.}{0.};
  
    return 0 if ! length $element;
    return 0 if ( $element eq 'undef' || $element eq '<undef>' );
  
    my $v = eval { version->new($element) };
    # XXX check defined $v and not just $v because version objects leak memory
    # in boolean context -- dagolden, 2012-02-03
    if ( defined $v ) {
      return _is_qv($v) ? $v->normal : $element;
    }
    else {
      return 0;
    }
  }
  
  sub _bad_version_hook {
    my ($v) = @_;
    $v =~ s{^\s*}{};
    $v =~ s{\s*$}{};
    $v =~ s{[a-z]+$}{}; # strip trailing alphabetics
    my $vobj = eval { version->new($v) };
    return defined($vobj) ? $vobj : version->new(0); # or give up
  }
  
  sub _version_map {
    my ($element) = @_;
    return unless defined $element;
    if ( ref $element eq 'HASH' ) {
      # XXX turn this into CPAN::Meta::Requirements with bad version hook
      # and then turn it back into a hash
      my $new_map = CPAN::Meta::Requirements->new(
        { bad_version_hook => \&_bad_version_hook } # punt
      );
      while ( my ($k,$v) = each %$element ) {
        next unless _is_module_name($k);
        if ( !defined($v) || !length($v) || $v eq 'undef' || $v eq '<undef>'  ) {
          $v = 0;
        }
        # some weird, old META have bad yml with module => module
        # so check if value is like a module name and not like a version
        if ( _is_module_name($v) && ! version::is_lax($v) ) {
          $new_map->add_minimum($k => 0);
          $new_map->add_minimum($v => 0);
        }
        $new_map->add_string_requirement($k => $v);
      }
      return $new_map->as_string_hash;
    }
    elsif ( ref $element eq 'ARRAY' ) {
      my $hashref = { map { $_ => 0 } @$element };
      return _version_map($hashref); # cleanup any weird stuff
    }
    elsif ( ref $element eq '' && length $element ) {
      return { $element => 0 }
    }
    return;
  }
  
  sub _prereqs_from_1 {
    my (undef, undef, $meta) = @_;
    my $prereqs = {};
    for my $phase ( qw/build configure/ ) {
      my $key = "${phase}_requires";
      $prereqs->{$phase}{requires} = _version_map($meta->{$key})
        if $meta->{$key};
    }
    for my $rel ( qw/requires recommends conflicts/ ) {
      $prereqs->{runtime}{$rel} = _version_map($meta->{$rel})
        if $meta->{$rel};
    }
    return $prereqs;
  }
  
  my $prereqs_spec = {
    configure => \&_prereqs_rel,
    build     => \&_prereqs_rel,
    test      => \&_prereqs_rel,
    runtime   => \&_prereqs_rel,
    develop   => \&_prereqs_rel,
    ':custom'  => \&_prefix_custom,
  };
  
  my $relation_spec = {
    requires   => \&_version_map,
    recommends => \&_version_map,
    suggests   => \&_version_map,
    conflicts  => \&_version_map,
    ':custom'  => \&_prefix_custom,
  };
  
  sub _cleanup_prereqs {
    my ($prereqs, $key, $meta, $to_version) = @_;
    return unless $prereqs && ref $prereqs eq 'HASH';
    return _convert( $prereqs, $prereqs_spec, $to_version );
  }
  
  sub _prereqs_rel {
    my ($relation, $key, $meta, $to_version) = @_;
    return unless $relation && ref $relation eq 'HASH';
    return _convert( $relation, $relation_spec, $to_version );
  }
  
  
  BEGIN {
    my @old_prereqs = qw(
      requires
      configure_requires
      recommends
      conflicts
    );
  
    for ( @old_prereqs ) {
      my $sub = "_get_$_";
      my ($phase,$type) = split qr/_/, $_;
      if ( ! defined $type ) {
        $type = $phase;
        $phase = 'runtime';
      }
      no strict 'refs';
      *{$sub} = sub { _extract_prereqs($_[2]->{prereqs},$phase,$type) };
    }
  }
  
  sub _get_build_requires {
    my ($data, $key, $meta) = @_;
  
    my $test_h  = _extract_prereqs($_[2]->{prereqs}, qw(test  requires)) || {};
    my $build_h = _extract_prereqs($_[2]->{prereqs}, qw(build requires)) || {};
  
    my $test_req  = CPAN::Meta::Requirements->from_string_hash($test_h);
    my $build_req = CPAN::Meta::Requirements->from_string_hash($build_h);
  
    $test_req->add_requirements($build_req)->as_string_hash;
  }
  
  sub _extract_prereqs {
    my ($prereqs, $phase, $type) = @_;
    return unless ref $prereqs eq 'HASH';
    return scalar _version_map($prereqs->{$phase}{$type});
  }
  
  sub _downgrade_optional_features {
    my (undef, undef, $meta) = @_;
    return unless exists $meta->{optional_features};
    my $origin = $meta->{optional_features};
    my $features = {};
    for my $name ( keys %$origin ) {
      $features->{$name} = {
        description => $origin->{$name}{description},
        requires => _extract_prereqs($origin->{$name}{prereqs},'runtime','requires'),
        configure_requires => _extract_prereqs($origin->{$name}{prereqs},'runtime','configure_requires'),
        build_requires => _extract_prereqs($origin->{$name}{prereqs},'runtime','build_requires'),
        recommends => _extract_prereqs($origin->{$name}{prereqs},'runtime','recommends'),
        conflicts => _extract_prereqs($origin->{$name}{prereqs},'runtime','conflicts'),
      };
      for my $k (keys %{$features->{$name}} ) {
        delete $features->{$name}{$k} unless defined $features->{$name}{$k};
      }
    }
    return $features;
  }
  
  sub _upgrade_optional_features {
    my (undef, undef, $meta) = @_;
    return unless exists $meta->{optional_features};
    my $origin = $meta->{optional_features};
    my $features = {};
    for my $name ( keys %$origin ) {
      $features->{$name} = {
        description => $origin->{$name}{description},
        prereqs => _prereqs_from_1(undef, undef, $origin->{$name}),
      };
      delete $features->{$name}{prereqs}{configure};
    }
    return $features;
  }
  
  my $optional_features_2_spec = {
    description => \&_keep,
    prereqs => \&_cleanup_prereqs,
    ':custom'  => \&_prefix_custom,
  };
  
  sub _feature_2 {
    my ($element, $key, $meta, $to_version) = @_;
    return unless $element && ref $element eq 'HASH';
    _convert( $element, $optional_features_2_spec, $to_version );
  }
  
  sub _cleanup_optional_features_2 {
    my ($element, $key, $meta, $to_version) = @_;
    return unless $element && ref $element eq 'HASH';
    my $new_data = {};
    for my $k ( keys %$element ) {
      $new_data->{$k} = _feature_2( $element->{$k}, $k, $meta, $to_version );
    }
    return unless keys %$new_data;
    return $new_data;
  }
  
  sub _optional_features_1_4 {
    my ($element) = @_;
    return unless $element;
    $element = _optional_features_as_map($element);
    for my $name ( keys %$element ) {
      for my $drop ( qw/requires_packages requires_os excluded_os/ ) {
        delete $element->{$name}{$drop};
      }
    }
    return $element;
  }
  
  sub _optional_features_as_map {
    my ($element) = @_;
    return unless $element;
    if ( ref $element eq 'ARRAY' ) {
      my %map;
      for my $feature ( @$element ) {
        my (@parts) = %$feature;
        $map{$parts[0]} = $parts[1];
      }
      $element = \%map;
    }
    return $element;
  }
  
  sub _is_urlish { defined $_[0] && $_[0] =~ m{\A[-+.a-z0-9]+:.+}i }
  
  sub _url_or_drop {
    my ($element) = @_;
    return $element if _is_urlish($element);
    return;
  }
  
  sub _url_list {
    my ($element) = @_;
    return unless $element;
    $element = _listify( $element );
    $element = [ grep { _is_urlish($_) } @$element ];
    return unless @$element;
    return $element;
  }
  
  sub _author_list {
    my ($element) = @_;
    return [ 'unknown' ] unless $element;
    $element = _listify( $element );
    $element = [ map { defined $_ && length $_ ? $_ : 'unknown' } @$element ];
    return [ 'unknown' ] unless @$element;
    return $element;
  }
  
  my $resource2_upgrade = {
    license    => sub { return _is_urlish($_[0]) ? _listify( $_[0] ) : undef },
    homepage   => \&_url_or_drop,
    bugtracker => sub {
      my ($item) = @_;
      return unless $item;
      if ( $item =~ m{^mailto:(.*)$} ) { return { mailto => $1 } }
      elsif( _is_urlish($item) ) { return { web => $item } }
      else { return }
    },
    repository => sub { return _is_urlish($_[0]) ? { url => $_[0] } : undef },
    ':custom'  => \&_prefix_custom,
  };
  
  sub _upgrade_resources_2 {
    my (undef, undef, $meta, $version) = @_;
    return unless exists $meta->{resources};
    return _convert($meta->{resources}, $resource2_upgrade);
  }
  
  my $bugtracker2_spec = {
    web => \&_url_or_drop,
    mailto => \&_keep,
    ':custom'  => \&_prefix_custom,
  };
  
  sub _repo_type {
    my ($element, $key, $meta, $to_version) = @_;
    return $element if defined $element;
    return unless exists $meta->{url};
    my $repo_url = $meta->{url};
    for my $type ( qw/git svn/ ) {
      return $type if $repo_url =~ m{\A$type};
    }
    return;
  }
  
  my $repository2_spec = {
    web => \&_url_or_drop,
    url => \&_url_or_drop,
    type => \&_repo_type,
    ':custom'  => \&_prefix_custom,
  };
  
  my $resources2_cleanup = {
    license    => \&_url_list,
    homepage   => \&_url_or_drop,
    bugtracker => sub { ref $_[0] ? _convert( $_[0], $bugtracker2_spec ) : undef },
    repository => sub { my $data = shift; ref $data ? _convert( $data, $repository2_spec ) : undef },
    ':custom'  => \&_prefix_custom,
  };
  
  sub _cleanup_resources_2 {
    my ($resources, $key, $meta, $to_version) = @_;
    return unless $resources && ref $resources eq 'HASH';
    return _convert($resources, $resources2_cleanup, $to_version);
  }
  
  my $resource1_spec = {
    license    => \&_url_or_drop,
    homepage   => \&_url_or_drop,
    bugtracker => \&_url_or_drop,
    repository => \&_url_or_drop,
    ':custom'  => \&_keep,
  };
  
  sub _resources_1_3 {
    my (undef, undef, $meta, $version) = @_;
    return unless exists $meta->{resources};
    return _convert($meta->{resources}, $resource1_spec);
  }
  
  *_resources_1_4 = *_resources_1_3;
  
  sub _resources_1_2 {
    my (undef, undef, $meta) = @_;
    my $resources = $meta->{resources} || {};
    if ( $meta->{license_url} && ! $resources->{license} ) {
      $resources->{license} = $meta->{license_url}
        if _is_urlish($meta->{license_url});
    }
    return unless keys %$resources;
    return _convert($resources, $resource1_spec);
  }
  
  my $resource_downgrade_spec = {
    license    => sub { return ref $_[0] ? $_[0]->[0] : $_[0] },
    homepage   => \&_url_or_drop,
    bugtracker => sub { return $_[0]->{web} },
    repository => sub { return $_[0]->{url} || $_[0]->{web} },
    ':custom'  => \&_no_prefix_ucfirst_custom,
  };
  
  sub _downgrade_resources {
    my (undef, undef, $meta, $version) = @_;
    return unless exists $meta->{resources};
    return _convert($meta->{resources}, $resource_downgrade_spec);
  }
  
  sub _release_status {
    my ($element, undef, $meta) = @_;
    return $element if $element && $element =~ m{\A(?:stable|testing|unstable)\z};
    return _release_status_from_version(undef, undef, $meta);
  }
  
  sub _release_status_from_version {
    my (undef, undef, $meta) = @_;
    my $version = $meta->{version} || '';
    return ( $version =~ /_/ ) ? 'testing' : 'stable';
  }
  
  my $provides_spec = {
    file => \&_keep,
    version => \&_keep,
  };
  
  my $provides_spec_2 = {
    file => \&_keep,
    version => \&_keep,
    ':custom'  => \&_prefix_custom,
  };
  
  sub _provides {
    my ($element, $key, $meta, $to_version) = @_;
    return unless defined $element && ref $element eq 'HASH';
    my $spec = $to_version == 2 ? $provides_spec_2 : $provides_spec;
    my $new_data = {};
    for my $k ( keys %$element ) {
      $new_data->{$k} = _convert($element->{$k}, $spec, $to_version);
      $new_data->{$k}{version} = _clean_version($element->{$k}{version})
        if exists $element->{$k}{version};
    }
    return $new_data;
  }
  
  sub _convert {
    my ($data, $spec, $to_version, $is_fragment) = @_;
  
    my $new_data = {};
    for my $key ( keys %$spec ) {
      next if $key eq ':custom' || $key eq ':drop';
      next unless my $fcn = $spec->{$key};
      if ( $is_fragment && $key eq 'generated_by' ) {
        $fcn = \&_keep;
      }
      die "spec for '$key' is not a coderef"
        unless ref $fcn && ref $fcn eq 'CODE';
      my $new_value = $fcn->($data->{$key}, $key, $data, $to_version);
      $new_data->{$key} = $new_value if defined $new_value;
    }
  
    my $drop_list   = $spec->{':drop'};
    my $customizer  = $spec->{':custom'} || \&_keep;
  
    for my $key ( keys %$data ) {
      next if $drop_list && grep { $key eq $_ } @$drop_list;
      next if exists $spec->{$key}; # we handled it
      $new_data->{ $customizer->($key) } = $data->{$key};
    }
  
    return $new_data;
  }
  
  #--------------------------------------------------------------------------#
  # define converters for each conversion
  #--------------------------------------------------------------------------#
  
  # each converts from prior version
  # special ":custom" field is used for keys not recognized in spec
  my %up_convert = (
    '2-from-1.4' => {
      # PRIOR MANDATORY
      'abstract'            => \&_keep_or_unknown,
      'author'              => \&_author_list,
      'generated_by'        => \&_generated_by,
      'license'             => \&_license_2,
      'meta-spec'           => \&_change_meta_spec,
      'name'                => \&_keep,
      'version'             => \&_keep,
      # CHANGED TO MANDATORY
      'dynamic_config'      => \&_keep_or_one,
      # ADDED MANDATORY
      'release_status'      => \&_release_status,
      # PRIOR OPTIONAL
      'keywords'            => \&_keep,
      'no_index'            => \&_no_index_directory,
      'optional_features'   => \&_upgrade_optional_features,
      'provides'            => \&_provides,
      'resources'           => \&_upgrade_resources_2,
      # ADDED OPTIONAL
      'description'         => \&_keep,
      'prereqs'             => \&_prereqs_from_1,
  
      # drop these deprecated fields, but only after we convert
      ':drop' => [ qw(
          build_requires
          configure_requires
          conflicts
          distribution_type
          license_url
          private
          recommends
          requires
      ) ],
  
      # other random keys need x_ prefixing
      ':custom'              => \&_prefix_custom,
    },
    '1.4-from-1.3' => {
      # PRIOR MANDATORY
      'abstract'            => \&_keep_or_unknown,
      'author'              => \&_author_list,
      'generated_by'        => \&_generated_by,
      'license'             => \&_license_1,
      'meta-spec'           => \&_change_meta_spec,
      'name'                => \&_keep,
      'version'             => \&_keep,
      # PRIOR OPTIONAL
      'build_requires'      => \&_version_map,
      'conflicts'           => \&_version_map,
      'distribution_type'   => \&_keep,
      'dynamic_config'      => \&_keep_or_one,
      'keywords'            => \&_keep,
      'no_index'            => \&_no_index_directory,
      'optional_features'   => \&_optional_features_1_4,
      'provides'            => \&_provides,
      'recommends'          => \&_version_map,
      'requires'            => \&_version_map,
      'resources'           => \&_resources_1_4,
      # ADDED OPTIONAL
      'configure_requires'  => \&_keep,
  
      # drop these deprecated fields, but only after we convert
      ':drop' => [ qw(
        license_url
        private
      )],
  
      # other random keys are OK if already valid
      ':custom'              => \&_keep
    },
    '1.3-from-1.2' => {
      # PRIOR MANDATORY
      'abstract'            => \&_keep_or_unknown,
      'author'              => \&_author_list,
      'generated_by'        => \&_generated_by,
      'license'             => \&_license_1,
      'meta-spec'           => \&_change_meta_spec,
      'name'                => \&_keep,
      'version'             => \&_keep,
      # PRIOR OPTIONAL
      'build_requires'      => \&_version_map,
      'conflicts'           => \&_version_map,
      'distribution_type'   => \&_keep,
      'dynamic_config'      => \&_keep_or_one,
      'keywords'            => \&_keep,
      'no_index'            => \&_no_index_directory,
      'optional_features'   => \&_optional_features_as_map,
      'provides'            => \&_provides,
      'recommends'          => \&_version_map,
      'requires'            => \&_version_map,
      'resources'           => \&_resources_1_3,
  
      # drop these deprecated fields, but only after we convert
      ':drop' => [ qw(
        license_url
        private
      )],
  
      # other random keys are OK if already valid
      ':custom'              => \&_keep
    },
    '1.2-from-1.1' => {
      # PRIOR MANDATORY
      'version'             => \&_keep,
      # CHANGED TO MANDATORY
      'license'             => \&_license_1,
      'name'                => \&_keep,
      'generated_by'        => \&_generated_by,
      # ADDED MANDATORY
      'abstract'            => \&_keep_or_unknown,
      'author'              => \&_author_list,
      'meta-spec'           => \&_change_meta_spec,
      # PRIOR OPTIONAL
      'build_requires'      => \&_version_map,
      'conflicts'           => \&_version_map,
      'distribution_type'   => \&_keep,
      'dynamic_config'      => \&_keep_or_one,
      'recommends'          => \&_version_map,
      'requires'            => \&_version_map,
      # ADDED OPTIONAL
      'keywords'            => \&_keep,
      'no_index'            => \&_no_index_1_2,
      'optional_features'   => \&_optional_features_as_map,
      'provides'            => \&_provides,
      'resources'           => \&_resources_1_2,
  
      # drop these deprecated fields, but only after we convert
      ':drop' => [ qw(
        license_url
        private
      )],
  
      # other random keys are OK if already valid
      ':custom'              => \&_keep
    },
    '1.1-from-1.0' => {
      # CHANGED TO MANDATORY
      'version'             => \&_keep,
      # IMPLIED MANDATORY
      'name'                => \&_keep,
      # PRIOR OPTIONAL
      'build_requires'      => \&_version_map,
      'conflicts'           => \&_version_map,
      'distribution_type'   => \&_keep,
      'dynamic_config'      => \&_keep_or_one,
      'generated_by'        => \&_generated_by,
      'license'             => \&_license_1,
      'recommends'          => \&_version_map,
      'requires'            => \&_version_map,
      # ADDED OPTIONAL
      'license_url'         => \&_url_or_drop,
      'private'             => \&_keep,
  
      # other random keys are OK if already valid
      ':custom'              => \&_keep
    },
  );
  
  my %down_convert = (
    '1.4-from-2' => {
      # MANDATORY
      'abstract'            => \&_keep_or_unknown,
      'author'              => \&_author_list,
      'generated_by'        => \&_generated_by,
      'license'             => \&_downgrade_license,
      'meta-spec'           => \&_change_meta_spec,
      'name'                => \&_keep,
      'version'             => \&_keep,
      # OPTIONAL
      'build_requires'      => \&_get_build_requires,
      'configure_requires'  => \&_get_configure_requires,
      'conflicts'           => \&_get_conflicts,
      'distribution_type'   => \&_keep,
      'dynamic_config'      => \&_keep_or_one,
      'keywords'            => \&_keep,
      'no_index'            => \&_no_index_directory,
      'optional_features'   => \&_downgrade_optional_features,
      'provides'            => \&_provides,
      'recommends'          => \&_get_recommends,
      'requires'            => \&_get_requires,
      'resources'           => \&_downgrade_resources,
  
      # drop these unsupported fields (after conversion)
      ':drop' => [ qw(
        description
        prereqs
        release_status
      )],
  
      # custom keys will be left unchanged
      ':custom'              => \&_keep
    },
    '1.3-from-1.4' => {
      # MANDATORY
      'abstract'            => \&_keep_or_unknown,
      'author'              => \&_author_list,
      'generated_by'        => \&_generated_by,
      'license'             => \&_license_1,
      'meta-spec'           => \&_change_meta_spec,
      'name'                => \&_keep,
      'version'             => \&_keep,
      # OPTIONAL
      'build_requires'      => \&_version_map,
      'conflicts'           => \&_version_map,
      'distribution_type'   => \&_keep,
      'dynamic_config'      => \&_keep_or_one,
      'keywords'            => \&_keep,
      'no_index'            => \&_no_index_directory,
      'optional_features'   => \&_optional_features_as_map,
      'provides'            => \&_provides,
      'recommends'          => \&_version_map,
      'requires'            => \&_version_map,
      'resources'           => \&_resources_1_3,
  
      # drop these unsupported fields, but only after we convert
      ':drop' => [ qw(
        configure_requires
      )],
  
      # other random keys are OK if already valid
      ':custom'              => \&_keep,
    },
    '1.2-from-1.3' => {
      # MANDATORY
      'abstract'            => \&_keep_or_unknown,
      'author'              => \&_author_list,
      'generated_by'        => \&_generated_by,
      'license'             => \&_license_1,
      'meta-spec'           => \&_change_meta_spec,
      'name'                => \&_keep,
      'version'             => \&_keep,
      # OPTIONAL
      'build_requires'      => \&_version_map,
      'conflicts'           => \&_version_map,
      'distribution_type'   => \&_keep,
      'dynamic_config'      => \&_keep_or_one,
      'keywords'            => \&_keep,
      'no_index'            => \&_no_index_1_2,
      'optional_features'   => \&_optional_features_as_map,
      'provides'            => \&_provides,
      'recommends'          => \&_version_map,
      'requires'            => \&_version_map,
      'resources'           => \&_resources_1_3,
  
      # other random keys are OK if already valid
      ':custom'              => \&_keep,
    },
    '1.1-from-1.2' => {
      # MANDATORY
      'version'             => \&_keep,
      # IMPLIED MANDATORY
      'name'                => \&_keep,
      'meta-spec'           => \&_change_meta_spec,
      # OPTIONAL
      'build_requires'      => \&_version_map,
      'conflicts'           => \&_version_map,
      'distribution_type'   => \&_keep,
      'dynamic_config'      => \&_keep_or_one,
      'generated_by'        => \&_generated_by,
      'license'             => \&_license_1,
      'private'             => \&_keep,
      'recommends'          => \&_version_map,
      'requires'            => \&_version_map,
  
      # drop unsupported fields
      ':drop' => [ qw(
        abstract
        author
        provides
        no_index
        keywords
        resources
      )],
  
      # other random keys are OK if already valid
      ':custom'              => \&_keep,
    },
    '1.0-from-1.1' => {
      # IMPLIED MANDATORY
      'name'                => \&_keep,
      'meta-spec'           => \&_change_meta_spec,
      'version'             => \&_keep,
      # PRIOR OPTIONAL
      'build_requires'      => \&_version_map,
      'conflicts'           => \&_version_map,
      'distribution_type'   => \&_keep,
      'dynamic_config'      => \&_keep_or_one,
      'generated_by'        => \&_generated_by,
      'license'             => \&_license_1,
      'recommends'          => \&_version_map,
      'requires'            => \&_version_map,
  
      # other random keys are OK if already valid
      ':custom'              => \&_keep,
    },
  );
  
  my %cleanup = (
    '2' => {
      # PRIOR MANDATORY
      'abstract'            => \&_keep_or_unknown,
      'author'              => \&_author_list,
      'generated_by'        => \&_generated_by,
      'license'             => \&_license_2,
      'meta-spec'           => \&_change_meta_spec,
      'name'                => \&_keep,
      'version'             => \&_keep,
      # CHANGED TO MANDATORY
      'dynamic_config'      => \&_keep_or_one,
      # ADDED MANDATORY
      'release_status'      => \&_release_status,
      # PRIOR OPTIONAL
      'keywords'            => \&_keep,
      'no_index'            => \&_no_index_directory,
      'optional_features'   => \&_cleanup_optional_features_2,
      'provides'            => \&_provides,
      'resources'           => \&_cleanup_resources_2,
      # ADDED OPTIONAL
      'description'         => \&_keep,
      'prereqs'             => \&_cleanup_prereqs,
  
      # drop these deprecated fields, but only after we convert
      ':drop' => [ qw(
          build_requires
          configure_requires
          conflicts
          distribution_type
          license_url
          private
          recommends
          requires
      ) ],
  
      # other random keys need x_ prefixing
      ':custom'              => \&_prefix_custom,
    },
    '1.4' => {
      # PRIOR MANDATORY
      'abstract'            => \&_keep_or_unknown,
      'author'              => \&_author_list,
      'generated_by'        => \&_generated_by,
      'license'             => \&_license_1,
      'meta-spec'           => \&_change_meta_spec,
      'name'                => \&_keep,
      'version'             => \&_keep,
      # PRIOR OPTIONAL
      'build_requires'      => \&_version_map,
      'conflicts'           => \&_version_map,
      'distribution_type'   => \&_keep,
      'dynamic_config'      => \&_keep_or_one,
      'keywords'            => \&_keep,
      'no_index'            => \&_no_index_directory,
      'optional_features'   => \&_optional_features_1_4,
      'provides'            => \&_provides,
      'recommends'          => \&_version_map,
      'requires'            => \&_version_map,
      'resources'           => \&_resources_1_4,
      # ADDED OPTIONAL
      'configure_requires'  => \&_keep,
  
      # other random keys are OK if already valid
      ':custom'             => \&_keep
    },
    '1.3' => {
      # PRIOR MANDATORY
      'abstract'            => \&_keep_or_unknown,
      'author'              => \&_author_list,
      'generated_by'        => \&_generated_by,
      'license'             => \&_license_1,
      'meta-spec'           => \&_change_meta_spec,
      'name'                => \&_keep,
      'version'             => \&_keep,
      # PRIOR OPTIONAL
      'build_requires'      => \&_version_map,
      'conflicts'           => \&_version_map,
      'distribution_type'   => \&_keep,
      'dynamic_config'      => \&_keep_or_one,
      'keywords'            => \&_keep,
      'no_index'            => \&_no_index_directory,
      'optional_features'   => \&_optional_features_as_map,
      'provides'            => \&_provides,
      'recommends'          => \&_version_map,
      'requires'            => \&_version_map,
      'resources'           => \&_resources_1_3,
  
      # other random keys are OK if already valid
      ':custom'             => \&_keep
    },
    '1.2' => {
      # PRIOR MANDATORY
      'version'             => \&_keep,
      # CHANGED TO MANDATORY
      'license'             => \&_license_1,
      'name'                => \&_keep,
      'generated_by'        => \&_generated_by,
      # ADDED MANDATORY
      'abstract'            => \&_keep_or_unknown,
      'author'              => \&_author_list,
      'meta-spec'           => \&_change_meta_spec,
      # PRIOR OPTIONAL
      'build_requires'      => \&_version_map,
      'conflicts'           => \&_version_map,
      'distribution_type'   => \&_keep,
      'dynamic_config'      => \&_keep_or_one,
      'recommends'          => \&_version_map,
      'requires'            => \&_version_map,
      # ADDED OPTIONAL
      'keywords'            => \&_keep,
      'no_index'            => \&_no_index_1_2,
      'optional_features'   => \&_optional_features_as_map,
      'provides'            => \&_provides,
      'resources'           => \&_resources_1_2,
  
      # other random keys are OK if already valid
      ':custom'             => \&_keep
    },
    '1.1' => {
      # CHANGED TO MANDATORY
      'version'             => \&_keep,
      # IMPLIED MANDATORY
      'name'                => \&_keep,
      'meta-spec'           => \&_change_meta_spec,
      # PRIOR OPTIONAL
      'build_requires'      => \&_version_map,
      'conflicts'           => \&_version_map,
      'distribution_type'   => \&_keep,
      'dynamic_config'      => \&_keep_or_one,
      'generated_by'        => \&_generated_by,
      'license'             => \&_license_1,
      'recommends'          => \&_version_map,
      'requires'            => \&_version_map,
      # ADDED OPTIONAL
      'license_url'         => \&_url_or_drop,
      'private'             => \&_keep,
  
      # other random keys are OK if already valid
      ':custom'             => \&_keep
    },
    '1.0' => {
      # IMPLIED MANDATORY
      'name'                => \&_keep,
      'meta-spec'           => \&_change_meta_spec,
      'version'             => \&_keep,
      # IMPLIED OPTIONAL
      'build_requires'      => \&_version_map,
      'conflicts'           => \&_version_map,
      'distribution_type'   => \&_keep,
      'dynamic_config'      => \&_keep_or_one,
      'generated_by'        => \&_generated_by,
      'license'             => \&_license_1,
      'recommends'          => \&_version_map,
      'requires'            => \&_version_map,
  
      # other random keys are OK if already valid
      ':custom'             => \&_keep,
    },
  );
  
  # for a given field in a spec version, what fields will it feed
  # into in the *latest* spec (i.e. v2); meta-spec omitted because
  # we always expect a meta-spec to be generated
  my %fragments_generate = (
    '2' => {
      'abstract'            =>   'abstract',
      'author'              =>   'author',
      'generated_by'        =>   'generated_by',
      'license'             =>   'license',
      'name'                =>   'name',
      'version'             =>   'version',
      'dynamic_config'      =>   'dynamic_config',
      'release_status'      =>   'release_status',
      'keywords'            =>   'keywords',
      'no_index'            =>   'no_index',
      'optional_features'   =>   'optional_features',
      'provides'            =>   'provides',
      'resources'           =>   'resources',
      'description'         =>   'description',
      'prereqs'             =>   'prereqs',
    },
    '1.4' => {
      'abstract'            => 'abstract',
      'author'              => 'author',
      'generated_by'        => 'generated_by',
      'license'             => 'license',
      'name'                => 'name',
      'version'             => 'version',
      'build_requires'      => 'prereqs',
      'conflicts'           => 'prereqs',
      'distribution_type'   => 'distribution_type',
      'dynamic_config'      => 'dynamic_config',
      'keywords'            => 'keywords',
      'no_index'            => 'no_index',
      'optional_features'   => 'optional_features',
      'provides'            => 'provides',
      'recommends'          => 'prereqs',
      'requires'            => 'prereqs',
      'resources'           => 'resources',
      'configure_requires'  => 'prereqs',
    },
  );
  # this is not quite true but will work well enough
  # as 1.4 is a superset of earlier ones
  $fragments_generate{$_} = $fragments_generate{'1.4'} for qw/1.3 1.2 1.1 1.0/;
  
  #--------------------------------------------------------------------------#
  # Code
  #--------------------------------------------------------------------------#
  
  #pod =method new
  #pod
  #pod   my $cmc = CPAN::Meta::Converter->new( $struct );
  #pod
  #pod The constructor should be passed a valid metadata structure but invalid
  #pod structures are accepted.  If no meta-spec version is provided, version 1.0 will
  #pod be assumed.
  #pod
  #pod Optionally, you can provide a C<default_version> argument after C<$struct>:
  #pod
  #pod   my $cmc = CPAN::Meta::Converter->new( $struct, default_version => "1.4" );
  #pod
  #pod This is only needed when converting a metadata fragment that does not include a
  #pod C<meta-spec> field.
  #pod
  #pod =cut
  
  sub new {
    my ($class,$data,%args) = @_;
  
    # create an attributes hash
    my $self = {
      'data'    => $data,
      'spec'    => _extract_spec_version($data, $args{default_version}),
    };
  
    # create the object
    return bless $self, $class;
  }
  
  sub _extract_spec_version {
      my ($data, $default) = @_;
      my $spec = $data->{'meta-spec'};
  
      # is meta-spec there and valid?
      return( $default || "1.0" ) unless defined $spec && ref $spec eq 'HASH'; # before meta-spec?
  
      # does the version key look like a valid version?
      my $v = $spec->{version};
      if ( defined $v && $v =~ /^\d+(?:\.\d+)?$/ ) {
          return $v if defined $v && grep { $v eq $_ } keys %known_specs; # known spec
          return $v+0 if defined $v && grep { $v == $_ } keys %known_specs; # 2.0 => 2
      }
  
      # otherwise, use heuristics: look for 1.x vs 2.0 fields
      return "2" if exists $data->{prereqs};
      return "1.4" if exists $data->{configure_requires};
      return( $default || "1.2" ); # when meta-spec was first defined
  }
  
  #pod =method convert
  #pod
  #pod   my $new_struct = $cmc->convert( version => "2" );
  #pod
  #pod Returns a new hash reference with the metadata converted to a different form.
  #pod C<convert> will die if any conversion/standardization still results in an
  #pod invalid structure.
  #pod
  #pod Valid parameters include:
  #pod
  #pod =over
  #pod
  #pod =item *
  #pod
  #pod C<version> -- Indicates the desired specification version (e.g. "1.0", "1.1" ... "1.4", "2").
  #pod Defaults to the latest version of the CPAN Meta Spec.
  #pod
  #pod =back
  #pod
  #pod Conversion proceeds through each version in turn.  For example, a version 1.2
  #pod structure might be converted to 1.3 then 1.4 then finally to version 2. The
  #pod conversion process attempts to clean-up simple errors and standardize data.
  #pod For example, if C<author> is given as a scalar, it will converted to an array
  #pod reference containing the item. (Converting a structure to its own version will
  #pod also clean-up and standardize.)
  #pod
  #pod When data are cleaned and standardized, missing or invalid fields will be
  #pod replaced with sensible defaults when possible.  This may be lossy or imprecise.
  #pod For example, some badly structured META.yml files on CPAN have prerequisite
  #pod modules listed as both keys and values:
  #pod
  #pod   requires => { 'Foo::Bar' => 'Bam::Baz' }
  #pod
  #pod These would be split and each converted to a prerequisite with a minimum
  #pod version of zero.
  #pod
  #pod When some mandatory fields are missing or invalid, the conversion will attempt
  #pod to provide a sensible default or will fill them with a value of 'unknown'.  For
  #pod example a missing or unrecognized C<license> field will result in a C<license>
  #pod field of 'unknown'.  Fields that may get an 'unknown' include:
  #pod
  #pod =for :list
  #pod * abstract
  #pod * author
  #pod * license
  #pod
  #pod =cut
  
  sub convert {
    my ($self, %args) = @_;
    my $args = { %args };
  
    my $new_version = $args->{version} || $HIGHEST;
    my $is_fragment = $args->{is_fragment};
  
    my ($old_version) = $self->{spec};
    my $converted = _dclone($self->{data});
  
    if ( $old_version == $new_version ) {
      $converted = _convert( $converted, $cleanup{$old_version}, $old_version, $is_fragment );
      unless ( $args->{is_fragment} ) {
        my $cmv = CPAN::Meta::Validator->new( $converted );
        unless ( $cmv->is_valid ) {
          my $errs = join("\n", $cmv->errors);
          die "Failed to clean-up $old_version metadata. Errors:\n$errs\n";
        }
      }
      return $converted;
    }
    elsif ( $old_version > $new_version )  {
      my @vers = sort { $b <=> $a } keys %known_specs;
      for my $i ( 0 .. $#vers-1 ) {
        next if $vers[$i] > $old_version;
        last if $vers[$i+1] < $new_version;
        my $spec_string = "$vers[$i+1]-from-$vers[$i]";
        $converted = _convert( $converted, $down_convert{$spec_string}, $vers[$i+1], $is_fragment );
        unless ( $args->{is_fragment} ) {
          my $cmv = CPAN::Meta::Validator->new( $converted );
          unless ( $cmv->is_valid ) {
            my $errs = join("\n", $cmv->errors);
            die "Failed to downconvert metadata to $vers[$i+1]. Errors:\n$errs\n";
          }
        }
      }
      return $converted;
    }
    else {
      my @vers = sort { $a <=> $b } keys %known_specs;
      for my $i ( 0 .. $#vers-1 ) {
        next if $vers[$i] < $old_version;
        last if $vers[$i+1] > $new_version;
        my $spec_string = "$vers[$i+1]-from-$vers[$i]";
        $converted = _convert( $converted, $up_convert{$spec_string}, $vers[$i+1], $is_fragment );
        unless ( $args->{is_fragment} ) {
          my $cmv = CPAN::Meta::Validator->new( $converted );
          unless ( $cmv->is_valid ) {
            my $errs = join("\n", $cmv->errors);
            die "Failed to upconvert metadata to $vers[$i+1]. Errors:\n$errs\n";
          }
        }
      }
      return $converted;
    }
  }
  
  #pod =method upgrade_fragment
  #pod
  #pod   my $new_struct = $cmc->upgrade_fragment;
  #pod
  #pod Returns a new hash reference with the metadata converted to the latest version
  #pod of the CPAN Meta Spec.  No validation is done on the result -- you must
  #pod validate after merging fragments into a complete metadata document.
  #pod
  #pod Available since version 2.141170.
  #pod
  #pod =cut
  
  sub upgrade_fragment {
    my ($self) = @_;
    my ($old_version) = $self->{spec};
    my %expected =
      map {; $_ => 1 }
      grep { defined }
      map { $fragments_generate{$old_version}{$_} }
      keys %{ $self->{data} };
    my $converted = $self->convert( version => $HIGHEST, is_fragment => 1 );
    for my $key ( keys %$converted ) {
      next if $key =~ /^x_/i || $key eq 'meta-spec';
      delete $converted->{$key} unless $expected{$key};
    }
    return $converted;
  }
  
  1;
  
  # ABSTRACT: Convert CPAN distribution metadata structures
  
  =pod
  
  =encoding UTF-8
  
  =head1 NAME
  
  CPAN::Meta::Converter - Convert CPAN distribution metadata structures
  
  =head1 VERSION
  
  version 2.150005
  
  =head1 SYNOPSIS
  
    my $struct = decode_json_file('META.json');
  
    my $cmc = CPAN::Meta::Converter->new( $struct );
  
    my $new_struct = $cmc->convert( version => "2" );
  
  =head1 DESCRIPTION
  
  This module converts CPAN Meta structures from one form to another.  The
  primary use is to convert older structures to the most modern version of
  the specification, but other transformations may be implemented in the
  future as needed.  (E.g. stripping all custom fields or stripping all
  optional fields.)
  
  =head1 METHODS
  
  =head2 new
  
    my $cmc = CPAN::Meta::Converter->new( $struct );
  
  The constructor should be passed a valid metadata structure but invalid
  structures are accepted.  If no meta-spec version is provided, version 1.0 will
  be assumed.
  
  Optionally, you can provide a C<default_version> argument after C<$struct>:
  
    my $cmc = CPAN::Meta::Converter->new( $struct, default_version => "1.4" );
  
  This is only needed when converting a metadata fragment that does not include a
  C<meta-spec> field.
  
  =head2 convert
  
    my $new_struct = $cmc->convert( version => "2" );
  
  Returns a new hash reference with the metadata converted to a different form.
  C<convert> will die if any conversion/standardization still results in an
  invalid structure.
  
  Valid parameters include:
  
  =over
  
  =item *
  
  C<version> -- Indicates the desired specification version (e.g. "1.0", "1.1" ... "1.4", "2").
  Defaults to the latest version of the CPAN Meta Spec.
  
  =back
  
  Conversion proceeds through each version in turn.  For example, a version 1.2
  structure might be converted to 1.3 then 1.4 then finally to version 2. The
  conversion process attempts to clean-up simple errors and standardize data.
  For example, if C<author> is given as a scalar, it will converted to an array
  reference containing the item. (Converting a structure to its own version will
  also clean-up and standardize.)
  
  When data are cleaned and standardized, missing or invalid fields will be
  replaced with sensible defaults when possible.  This may be lossy or imprecise.
  For example, some badly structured META.yml files on CPAN have prerequisite
  modules listed as both keys and values:
  
    requires => { 'Foo::Bar' => 'Bam::Baz' }
  
  These would be split and each converted to a prerequisite with a minimum
  version of zero.
  
  When some mandatory fields are missing or invalid, the conversion will attempt
  to provide a sensible default or will fill them with a value of 'unknown'.  For
  example a missing or unrecognized C<license> field will result in a C<license>
  field of 'unknown'.  Fields that may get an 'unknown' include:
  
  =over 4
  
  =item *
  
  abstract
  
  =item *
  
  author
  
  =item *
  
  license
  
  =back
  
  =head2 upgrade_fragment
  
    my $new_struct = $cmc->upgrade_fragment;
  
  Returns a new hash reference with the metadata converted to the latest version
  of the CPAN Meta Spec.  No validation is done on the result -- you must
  validate after merging fragments into a complete metadata document.
  
  Available since version 2.141170.
  
  =head1 BUGS
  
  Please report any bugs or feature using the CPAN Request Tracker.
  Bugs can be submitted through the web interface at
  L<http://rt.cpan.org/Dist/Display.html?Queue=CPAN-Meta>
  
  When submitting a bug or request, please include a test-file or a patch to an
  existing test-file that illustrates the bug or desired feature.
  
  =head1 AUTHORS
  
  =over 4
  
  =item *
  
  David Golden <dagolden@cpan.org>
  
  =item *
  
  Ricardo Signes <rjbs@cpan.org>
  
  =back
  
  =head1 COPYRIGHT AND LICENSE
  
  This software is copyright (c) 2010 by David Golden and Ricardo Signes.
  
  This is free software; you can redistribute it and/or modify it under
  the same terms as the Perl 5 programming language system itself.
  
  =cut
  
  __END__
  
  
  # vim: ts=2 sts=2 sw=2 et :
CPAN_META_CONVERTER

$fatpacked{"CPAN/Meta/Feature.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CPAN_META_FEATURE';
  use 5.006;
  use strict;
  use warnings;
  package CPAN::Meta::Feature;
  
  our $VERSION = '2.150005';
  
  use CPAN::Meta::Prereqs;
  
  #pod =head1 DESCRIPTION
  #pod
  #pod A CPAN::Meta::Feature object describes an optional feature offered by a CPAN
  #pod distribution and specified in the distribution's F<META.json> (or F<META.yml>)
  #pod file.
  #pod
  #pod For the most part, this class will only be used when operating on the result of
  #pod the C<feature> or C<features> methods on a L<CPAN::Meta> object.
  #pod
  #pod =method new
  #pod
  #pod   my $feature = CPAN::Meta::Feature->new( $identifier => \%spec );
  #pod
  #pod This returns a new Feature object.  The C<%spec> argument to the constructor
  #pod should be the same as the value of the C<optional_feature> entry in the
  #pod distmeta.  It must contain entries for C<description> and C<prereqs>.
  #pod
  #pod =cut
  
  sub new {
    my ($class, $identifier, $spec) = @_;
  
    my %guts = (
      identifier  => $identifier,
      description => $spec->{description},
      prereqs     => CPAN::Meta::Prereqs->new($spec->{prereqs}),
    );
  
    bless \%guts => $class;
  }
  
  #pod =method identifier
  #pod
  #pod This method returns the feature's identifier.
  #pod
  #pod =cut
  
  sub identifier  { $_[0]{identifier}  }
  
  #pod =method description
  #pod
  #pod This method returns the feature's long description.
  #pod
  #pod =cut
  
  sub description { $_[0]{description} }
  
  #pod =method prereqs
  #pod
  #pod This method returns the feature's prerequisites as a L<CPAN::Meta::Prereqs>
  #pod object.
  #pod
  #pod =cut
  
  sub prereqs     { $_[0]{prereqs} }
  
  1;
  
  # ABSTRACT: an optional feature provided by a CPAN distribution
  
  =pod
  
  =encoding UTF-8
  
  =head1 NAME
  
  CPAN::Meta::Feature - an optional feature provided by a CPAN distribution
  
  =head1 VERSION
  
  version 2.150005
  
  =head1 DESCRIPTION
  
  A CPAN::Meta::Feature object describes an optional feature offered by a CPAN
  distribution and specified in the distribution's F<META.json> (or F<META.yml>)
  file.
  
  For the most part, this class will only be used when operating on the result of
  the C<feature> or C<features> methods on a L<CPAN::Meta> object.
  
  =head1 METHODS
  
  =head2 new
  
    my $feature = CPAN::Meta::Feature->new( $identifier => \%spec );
  
  This returns a new Feature object.  The C<%spec> argument to the constructor
  should be the same as the value of the C<optional_feature> entry in the
  distmeta.  It must contain entries for C<description> and C<prereqs>.
  
  =head2 identifier
  
  This method returns the feature's identifier.
  
  =head2 description
  
  This method returns the feature's long description.
  
  =head2 prereqs
  
  This method returns the feature's prerequisites as a L<CPAN::Meta::Prereqs>
  object.
  
  =head1 BUGS
  
  Please report any bugs or feature using the CPAN Request Tracker.
  Bugs can be submitted through the web interface at
  L<http://rt.cpan.org/Dist/Display.html?Queue=CPAN-Meta>
  
  When submitting a bug or request, please include a test-file or a patch to an
  existing test-file that illustrates the bug or desired feature.
  
  =head1 AUTHORS
  
  =over 4
  
  =item *
  
  David Golden <dagolden@cpan.org>
  
  =item *
  
  Ricardo Signes <rjbs@cpan.org>
  
  =back
  
  =head1 COPYRIGHT AND LICENSE
  
  This software is copyright (c) 2010 by David Golden and Ricardo Signes.
  
  This is free software; you can redistribute it and/or modify it under
  the same terms as the Perl 5 programming language system itself.
  
  =cut
  
  __END__
  
  
  # vim: ts=2 sts=2 sw=2 et :
CPAN_META_FEATURE

$fatpacked{"CPAN/Meta/History.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CPAN_META_HISTORY';
  # vi:tw=72
  use 5.006;
  use strict;
  use warnings;
  package CPAN::Meta::History;
  
  our $VERSION = '2.150005';
  
  1;
  
  # ABSTRACT: history of CPAN Meta Spec changes
  
  __END__
  
  =pod
  
  =encoding UTF-8
  
  =head1 NAME
  
  CPAN::Meta::History - history of CPAN Meta Spec changes
  
  =head1 VERSION
  
  version 2.150005
  
  =head1 DESCRIPTION
  
  The CPAN Meta Spec has gone through several iterations.  It was
  originally written in HTML and later revised into POD (though published
  in HTML generated from the POD).  Fields were added, removed or changed,
  sometimes by design and sometimes to reflect real-world usage after the
  fact.
  
  This document reconstructs the history of the CPAN Meta Spec based on
  change logs, repository commit messages and the published HTML files.
  In some cases, particularly prior to version 1.2, the exact version
  when certain fields were introduced or changed is inconsistent between
  sources.  When in doubt, the published HTML files for versions 1.0 to
  1.4 as they existed when version 2 was developed are used as the
  definitive source.
  
  Starting with version 2, the specification document is part of the
  CPAN-Meta distribution and will be published on CPAN as
  L<CPAN::Meta::Spec>.
  
  Going forward, specification version numbers will be integers and
  decimal portions will correspond to a release date for the CPAN::Meta
  library.
  
  =head1 HISTORY
  
  =head2 Version 2
  
  April 2010
  
  =over
  
  =item *
  
  Revised spec examples as perl data structures rather than YAML
  
  =item *
  
  Switched to JSON serialization from YAML
  
  =item *
  
  Specified allowed version number formats
  
  =item *
  
  Replaced 'requires', 'build_requires', 'configure_requires',
  'recommends' and 'conflicts' with new 'prereqs' data structure divided
  by I<phase> (configure, build, test, runtime, etc.) and I<relationship>
  (requires, recommends, suggests, conflicts)
  
  =item *
  
  Added support for 'develop' phase for requirements for maintaining
  a list of authoring tools
  
  =item *
  
  Changed 'license' to a list and revised the set of valid licenses
  
  =item *
  
  Made 'dynamic_config' mandatory to reduce confusion
  
  =item *
  
  Changed 'resources' subkey 'repository' to a hash that clarifies
  repository type, url for browsing and url for checkout
  
  =item *
  
  Changed 'resources' subkey 'bugtracker' to a hash for either web
  or mailto resource
  
  =item *
  
  Changed specification of 'optional_features':
  
  =over
  
  =item *
  
  Added formal specification and usage guide instead of just example
  
  =item *
  
  Changed to use new prereqs data structure instead of individual keys
  
  =back
  
  =item *
  
  Clarified intended use of 'author' as generalized contact list
  
  =item *
  
  Added 'release_status' field to indicate stable, testing or unstable
  status to provide hints to indexers
  
  =item *
  
  Added 'description' field for a longer description of the distribution
  
  =item *
  
  Formalized use of "x_" or "X_" for all custom keys not listed in the
  official spec
  
  =back
  
  =head2 Version 1.4
  
  June 2008
  
  =over
  
  =item *
  
  Noted explicit support for 'perl' in prerequisites
  
  =item *
  
  Added 'configure_requires' prerequisite type
  
  =item *
  
  Changed 'optional_features'
  
  =over
  
  =item *
  
  Example corrected to show map of maps instead of list of maps
  (though descriptive text said 'map' even in v1.3)
  
  =item *
  
  Removed 'requires_packages', 'requires_os' and 'excluded_os'
  as valid subkeys
  
  =back
  
  =back
  
  =head2 Version 1.3
  
  November 2006
  
  =over
  
  =item *
  
  Added 'no_index' subkey 'directory' and removed 'dir' to match actual
  usage in the wild
  
  =item *
  
  Added a 'repository' subkey to 'resources'
  
  =back
  
  =head2 Version 1.2
  
  August 2005
  
  =over
  
  =item *
  
  Re-wrote and restructured spec in POD syntax
  
  =item *
  
  Changed 'name' to be mandatory
  
  =item *
  
  Changed 'generated_by' to be mandatory
  
  =item *
  
  Changed 'license' to be mandatory
  
  =item *
  
  Added version range specifications for prerequisites
  
  =item *
  
  Added required 'abstract' field
  
  =item *
  
  Added required 'author' field
  
  =item *
  
  Added required 'meta-spec' field to define 'version' (and 'url') of the
  CPAN Meta Spec used for metadata
  
  =item *
  
  Added 'provides' field
  
  =item *
  
  Added 'no_index' field and deprecated 'private' field.  'no_index'
  subkeys include 'file', 'dir', 'package' and 'namespace'
  
  =item *
  
  Added 'keywords' field
  
  =item *
  
  Added 'resources' field with subkeys 'homepage', 'license', and
  'bugtracker'
  
  =item *
  
  Added 'optional_features' field as an alternate under 'recommends'.
  Includes 'description', 'requires', 'build_requires', 'conflicts',
  'requires_packages', 'requires_os' and 'excluded_os' as valid subkeys
  
  =item *
  
  Removed 'license_uri' field
  
  =back
  
  =head2 Version 1.1
  
  May 2003
  
  =over
  
  =item *
  
  Changed 'version' to be mandatory
  
  =item *
  
  Added 'private' field
  
  =item *
  
  Added 'license_uri' field
  
  =back
  
  =head2 Version 1.0
  
  March 2003
  
  =over
  
  =item *
  
  Original release (in HTML format only)
  
  =item *
  
  Included 'name', 'version', 'license', 'distribution_type', 'requires',
  'recommends', 'build_requires', 'conflicts', 'dynamic_config',
  'generated_by'
  
  =back
  
  =head1 AUTHORS
  
  =over 4
  
  =item *
  
  David Golden <dagolden@cpan.org>
  
  =item *
  
  Ricardo Signes <rjbs@cpan.org>
  
  =back
  
  =head1 COPYRIGHT AND LICENSE
  
  This software is copyright (c) 2010 by David Golden and Ricardo Signes.
  
  This is free software; you can redistribute it and/or modify it under
  the same terms as the Perl 5 programming language system itself.
  
  =cut
CPAN_META_HISTORY

$fatpacked{"CPAN/Meta/Merge.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CPAN_META_MERGE';
  use strict;
  use warnings;
  
  package CPAN::Meta::Merge;
  
  our $VERSION = '2.150005';
  
  use Carp qw/croak/;
  use Scalar::Util qw/blessed/;
  use CPAN::Meta::Converter 2.141170;
  
  sub _is_identical {
    my ($left, $right) = @_;
    return
      (not defined $left and not defined $right)
      # if either of these are references, we compare the serialized value
      || (defined $left and defined $right and $left eq $right);
  }
  
  sub _identical {
    my ($left, $right, $path) = @_;
    croak sprintf "Can't merge attribute %s: '%s' does not equal '%s'", join('.', @{$path}), $left, $right
      unless _is_identical($left, $right);
    return $left;
  }
  
  sub _merge {
    my ($current, $next, $mergers, $path) = @_;
    for my $key (keys %{$next}) {
      if (not exists $current->{$key}) {
        $current->{$key} = $next->{$key};
      }
      elsif (my $merger = $mergers->{$key}) {
        $current->{$key} = $merger->($current->{$key}, $next->{$key}, [ @{$path}, $key ]);
      }
      elsif ($merger = $mergers->{':default'}) {
        $current->{$key} = $merger->($current->{$key}, $next->{$key}, [ @{$path}, $key ]);
      }
      else {
        croak sprintf "Can't merge unknown attribute '%s'", join '.', @{$path}, $key;
      }
    }
    return $current;
  }
  
  sub _uniq {
    my %seen = ();
    return grep { not $seen{$_}++ } @_;
  }
  
  sub _set_addition {
    my ($left, $right) = @_;
    return [ +_uniq(@{$left}, @{$right}) ];
  }
  
  sub _uniq_map {
    my ($left, $right, $path) = @_;
    for my $key (keys %{$right}) {
      if (not exists $left->{$key}) {
        $left->{$key} = $right->{$key};
      }
      # identical strings or references are merged identically
      elsif (_is_identical($left->{$key}, $right->{$key})) {
        1; # do nothing - keep left
      }
      elsif (ref $left->{$key} eq 'HASH' and ref $right->{$key} eq 'HASH') {
        $left->{$key} = _uniq_map($left->{$key}, $right->{$key}, [ @{$path}, $key ]);
      }
      else {
        croak 'Duplication of element ' . join '.', @{$path}, $key;
      }
    }
    return $left;
  }
  
  sub _improvize {
    my ($left, $right, $path) = @_;
    my ($name) = reverse @{$path};
    if ($name =~ /^x_/) {
      if (ref($left) eq 'ARRAY') {
        return _set_addition($left, $right, $path);
      }
      elsif (ref($left) eq 'HASH') {
        return _uniq_map($left, $right, $path);
      }
      else {
        return _identical($left, $right, $path);
      }
    }
    croak sprintf "Can't merge '%s'", join '.', @{$path};
  }
  
  sub _optional_features {
    my ($left, $right, $path) = @_;
  
    for my $key (keys %{$right}) {
      if (not exists $left->{$key}) {
        $left->{$key} = $right->{$key};
      }
      else {
        for my $subkey (keys %{ $right->{$key} }) {
          next if $subkey eq 'prereqs';
          if (not exists $left->{$key}{$subkey}) {
            $left->{$key}{$subkey} = $right->{$key}{$subkey};
          }
          else {
            Carp::croak "Cannot merge two optional_features named '$key' with different '$subkey' values"
              if do { no warnings 'uninitialized'; $left->{$key}{$subkey} ne $right->{$key}{$subkey} };
          }
        }
  
        require CPAN::Meta::Prereqs;
        $left->{$key}{prereqs} =
          CPAN::Meta::Prereqs->new($left->{$key}{prereqs})
            ->with_merged_prereqs(CPAN::Meta::Prereqs->new($right->{$key}{prereqs}))
            ->as_string_hash;
      }
    }
    return $left;
  }
  
  
  my %default = (
    abstract       => \&_identical,
    author         => \&_set_addition,
    dynamic_config => sub {
      my ($left, $right) = @_;
      return $left || $right;
    },
    generated_by => sub {
      my ($left, $right) = @_;
      return join ', ', _uniq(split(/, /, $left), split(/, /, $right));
    },
    license     => \&_set_addition,
    'meta-spec' => {
      version => \&_identical,
      url     => \&_identical
    },
    name              => \&_identical,
    release_status    => \&_identical,
    version           => \&_identical,
    description       => \&_identical,
    keywords          => \&_set_addition,
    no_index          => { map { ($_ => \&_set_addition) } qw/file directory package namespace/ },
    optional_features => \&_optional_features,
    prereqs           => sub {
      require CPAN::Meta::Prereqs;
      my ($left, $right) = map { CPAN::Meta::Prereqs->new($_) } @_[0,1];
      return $left->with_merged_prereqs($right)->as_string_hash;
    },
    provides  => \&_uniq_map,
    resources => {
      license    => \&_set_addition,
      homepage   => \&_identical,
      bugtracker => \&_uniq_map,
      repository => \&_uniq_map,
      ':default' => \&_improvize,
    },
    ':default' => \&_improvize,
  );
  
  sub new {
    my ($class, %arguments) = @_;
    croak 'default version required' if not exists $arguments{default_version};
    my %mapping = %default;
    my %extra = %{ $arguments{extra_mappings} || {} };
    for my $key (keys %extra) {
      if (ref($mapping{$key}) eq 'HASH') {
        $mapping{$key} = { %{ $mapping{$key} }, %{ $extra{$key} } };
      }
      else {
        $mapping{$key} = $extra{$key};
      }
    }
    return bless {
      default_version => $arguments{default_version},
      mapping => _coerce_mapping(\%mapping, []),
    }, $class;
  }
  
  my %coderef_for = (
    set_addition => \&_set_addition,
    uniq_map     => \&_uniq_map,
    identical    => \&_identical,
    improvize    => \&_improvize,
  );
  
  sub _coerce_mapping {
    my ($orig, $map_path) = @_;
    my %ret;
    for my $key (keys %{$orig}) {
      my $value = $orig->{$key};
      if (ref($orig->{$key}) eq 'CODE') {
        $ret{$key} = $value;
      }
      elsif (ref($value) eq 'HASH') {
        my $mapping = _coerce_mapping($value, [ @{$map_path}, $key ]);
        $ret{$key} = sub {
          my ($left, $right, $path) = @_;
          return _merge($left, $right, $mapping, [ @{$path} ]);
        };
      }
      elsif ($coderef_for{$value}) {
        $ret{$key} = $coderef_for{$value};
      }
      else {
        croak "Don't know what to do with " . join '.', @{$map_path}, $key;
      }
    }
    return \%ret;
  }
  
  sub merge {
    my ($self, @items) = @_;
    my $current = {};
    for my $next (@items) {
      if ( blessed($next) && $next->isa('CPAN::Meta') ) {
        $next = $next->as_struct;
      }
      elsif ( ref($next) eq 'HASH' ) {
        my $cmc = CPAN::Meta::Converter->new(
          $next, default_version => $self->{default_version}
        );
        $next = $cmc->upgrade_fragment;
      }
      else {
        croak "Don't know how to merge '$next'";
      }
      $current = _merge($current, $next, $self->{mapping}, []);
    }
    return $current;
  }
  
  1;
  
  # ABSTRACT: Merging CPAN Meta fragments
  
  
  # vim: ts=2 sts=2 sw=2 et :
  
  __END__
  
  =pod
  
  =encoding UTF-8
  
  =head1 NAME
  
  CPAN::Meta::Merge - Merging CPAN Meta fragments
  
  =head1 VERSION
  
  version 2.150005
  
  =head1 SYNOPSIS
  
   my $merger = CPAN::Meta::Merge->new(default_version => "2");
   my $meta = $merger->merge($base, @additional);
  
  =head1 DESCRIPTION
  
  =head1 METHODS
  
  =head2 new
  
  This creates a CPAN::Meta::Merge object. It takes one mandatory named
  argument, C<version>, declaring the version of the meta-spec that must be
  used for the merge. It can optionally take an C<extra_mappings> argument
  that allows one to add additional merging functions for specific elements.
  
  =head2 merge(@fragments)
  
  Merge all C<@fragments> together. It will accept both CPAN::Meta objects and
  (possibly incomplete) hashrefs of metadata.
  
  =head1 AUTHORS
  
  =over 4
  
  =item *
  
  David Golden <dagolden@cpan.org>
  
  =item *
  
  Ricardo Signes <rjbs@cpan.org>
  
  =back
  
  =head1 COPYRIGHT AND LICENSE
  
  This software is copyright (c) 2010 by David Golden and Ricardo Signes.
  
  This is free software; you can redistribute it and/or modify it under
  the same terms as the Perl 5 programming language system itself.
  
  =cut
CPAN_META_MERGE

$fatpacked{"CPAN/Meta/Prereqs.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CPAN_META_PREREQS';
  use 5.006;
  use strict;
  use warnings;
  package CPAN::Meta::Prereqs;
  
  our $VERSION = '2.150005';
  
  #pod =head1 DESCRIPTION
  #pod
  #pod A CPAN::Meta::Prereqs object represents the prerequisites for a CPAN
  #pod distribution or one of its optional features.  Each set of prereqs is
  #pod organized by phase and type, as described in L<CPAN::Meta::Prereqs>.
  #pod
  #pod =cut
  
  use Carp qw(confess);
  use Scalar::Util qw(blessed);
  use CPAN::Meta::Requirements 2.121;
  
  #pod =method new
  #pod
  #pod   my $prereq = CPAN::Meta::Prereqs->new( \%prereq_spec );
  #pod
  #pod This method returns a new set of Prereqs.  The input should look like the
  #pod contents of the C<prereqs> field described in L<CPAN::Meta::Spec>, meaning
  #pod something more or less like this:
  #pod
  #pod   my $prereq = CPAN::Meta::Prereqs->new({
  #pod     runtime => {
  #pod       requires => {
  #pod         'Some::Module' => '1.234',
  #pod         ...,
  #pod       },
  #pod       ...,
  #pod     },
  #pod     ...,
  #pod   });
  #pod
  #pod You can also construct an empty set of prereqs with:
  #pod
  #pod   my $prereqs = CPAN::Meta::Prereqs->new;
  #pod
  #pod This empty set of prereqs is useful for accumulating new prereqs before finally
  #pod dumping the whole set into a structure or string.
  #pod
  #pod =cut
  
  sub __legal_phases { qw(configure build test runtime develop)   }
  sub __legal_types  { qw(requires recommends suggests conflicts) }
  
  # expect a prereq spec from META.json -- rjbs, 2010-04-11
  sub new {
    my ($class, $prereq_spec) = @_;
    $prereq_spec ||= {};
  
    my %is_legal_phase = map {; $_ => 1 } $class->__legal_phases;
    my %is_legal_type  = map {; $_ => 1 } $class->__legal_types;
  
    my %guts;
    PHASE: for my $phase (keys %$prereq_spec) {
      next PHASE unless $phase =~ /\Ax_/i or $is_legal_phase{$phase};
  
      my $phase_spec = $prereq_spec->{ $phase };
      next PHASE unless keys %$phase_spec;
  
      TYPE: for my $type (keys %$phase_spec) {
        next TYPE unless $type =~ /\Ax_/i or $is_legal_type{$type};
  
        my $spec = $phase_spec->{ $type };
  
        next TYPE unless keys %$spec;
  
        $guts{prereqs}{$phase}{$type} = CPAN::Meta::Requirements->from_string_hash(
          $spec
        );
      }
    }
  
    return bless \%guts => $class;
  }
  
  #pod =method requirements_for
  #pod
  #pod   my $requirements = $prereqs->requirements_for( $phase, $type );
  #pod
  #pod This method returns a L<CPAN::Meta::Requirements> object for the given
  #pod phase/type combination.  If no prerequisites are registered for that
  #pod combination, a new CPAN::Meta::Requirements object will be returned, and it may
  #pod be added to as needed.
  #pod
  #pod If C<$phase> or C<$type> are undefined or otherwise invalid, an exception will
  #pod be raised.
  #pod
  #pod =cut
  
  sub requirements_for {
    my ($self, $phase, $type) = @_;
  
    confess "requirements_for called without phase" unless defined $phase;
    confess "requirements_for called without type"  unless defined $type;
  
    unless ($phase =~ /\Ax_/i or grep { $phase eq $_ } $self->__legal_phases) {
      confess "requested requirements for unknown phase: $phase";
    }
  
    unless ($type =~ /\Ax_/i or grep { $type eq $_ } $self->__legal_types) {
      confess "requested requirements for unknown type: $type";
    }
  
    my $req = ($self->{prereqs}{$phase}{$type} ||= CPAN::Meta::Requirements->new);
  
    $req->finalize if $self->is_finalized;
  
    return $req;
  }
  
  #pod =method with_merged_prereqs
  #pod
  #pod   my $new_prereqs = $prereqs->with_merged_prereqs( $other_prereqs );
  #pod
  #pod   my $new_prereqs = $prereqs->with_merged_prereqs( \@other_prereqs );
  #pod
  #pod This method returns a new CPAN::Meta::Prereqs objects in which all the
  #pod other prerequisites given are merged into the current set.  This is primarily
  #pod provided for combining a distribution's core prereqs with the prereqs of one of
  #pod its optional features.
  #pod
  #pod The new prereqs object has no ties to the originals, and altering it further
  #pod will not alter them.
  #pod
  #pod =cut
  
  sub with_merged_prereqs {
    my ($self, $other) = @_;
  
    my @other = blessed($other) ? $other : @$other;
  
    my @prereq_objs = ($self, @other);
  
    my %new_arg;
  
    for my $phase ($self->__legal_phases) {
      for my $type ($self->__legal_types) {
        my $req = CPAN::Meta::Requirements->new;
  
        for my $prereq (@prereq_objs) {
          my $this_req = $prereq->requirements_for($phase, $type);
          next unless $this_req->required_modules;
  
          $req->add_requirements($this_req);
        }
  
        next unless $req->required_modules;
  
        $new_arg{ $phase }{ $type } = $req->as_string_hash;
      }
    }
  
    return (ref $self)->new(\%new_arg);
  }
  
  #pod =method merged_requirements
  #pod
  #pod     my $new_reqs = $prereqs->merged_requirements( \@phases, \@types );
  #pod     my $new_reqs = $prereqs->merged_requirements( \@phases );
  #pod     my $new_reqs = $prereqs->merged_requirements();
  #pod
  #pod This method joins together all requirements across a number of phases
  #pod and types into a new L<CPAN::Meta::Requirements> object.  If arguments
  #pod are omitted, it defaults to "runtime", "build" and "test" for phases
  #pod and "requires" and "recommends" for types.
  #pod
  #pod =cut
  
  sub merged_requirements {
    my ($self, $phases, $types) = @_;
    $phases = [qw/runtime build test/] unless defined $phases;
    $types = [qw/requires recommends/] unless defined $types;
  
    confess "merged_requirements phases argument must be an arrayref"
      unless ref $phases eq 'ARRAY';
    confess "merged_requirements types argument must be an arrayref"
      unless ref $types eq 'ARRAY';
  
    my $req = CPAN::Meta::Requirements->new;
  
    for my $phase ( @$phases ) {
      unless ($phase =~ /\Ax_/i or grep { $phase eq $_ } $self->__legal_phases) {
          confess "requested requirements for unknown phase: $phase";
      }
      for my $type ( @$types ) {
        unless ($type =~ /\Ax_/i or grep { $type eq $_ } $self->__legal_types) {
            confess "requested requirements for unknown type: $type";
        }
        $req->add_requirements( $self->requirements_for($phase, $type) );
      }
    }
  
    $req->finalize if $self->is_finalized;
  
    return $req;
  }
  
  
  #pod =method as_string_hash
  #pod
  #pod This method returns a hashref containing structures suitable for dumping into a
  #pod distmeta data structure.  It is made up of hashes and strings, only; there will
  #pod be no Prereqs, CPAN::Meta::Requirements, or C<version> objects inside it.
  #pod
  #pod =cut
  
  sub as_string_hash {
    my ($self) = @_;
  
    my %hash;
  
    for my $phase ($self->__legal_phases) {
      for my $type ($self->__legal_types) {
        my $req = $self->requirements_for($phase, $type);
        next unless $req->required_modules;
  
        $hash{ $phase }{ $type } = $req->as_string_hash;
      }
    }
  
    return \%hash;
  }
  
  #pod =method is_finalized
  #pod
  #pod This method returns true if the set of prereqs has been marked "finalized," and
  #pod cannot be altered.
  #pod
  #pod =cut
  
  sub is_finalized { $_[0]{finalized} }
  
  #pod =method finalize
  #pod
  #pod Calling C<finalize> on a Prereqs object will close it for further modification.
  #pod Attempting to make any changes that would actually alter the prereqs will
  #pod result in an exception being thrown.
  #pod
  #pod =cut
  
  sub finalize {
    my ($self) = @_;
  
    $self->{finalized} = 1;
  
    for my $phase (keys %{ $self->{prereqs} }) {
      $_->finalize for values %{ $self->{prereqs}{$phase} };
    }
  }
  
  #pod =method clone
  #pod
  #pod   my $cloned_prereqs = $prereqs->clone;
  #pod
  #pod This method returns a Prereqs object that is identical to the original object,
  #pod but can be altered without affecting the original object.  Finalization does
  #pod not survive cloning, meaning that you may clone a finalized set of prereqs and
  #pod then modify the clone.
  #pod
  #pod =cut
  
  sub clone {
    my ($self) = @_;
  
    my $clone = (ref $self)->new( $self->as_string_hash );
  }
  
  1;
  
  # ABSTRACT: a set of distribution prerequisites by phase and type
  
  =pod
  
  =encoding UTF-8
  
  =head1 NAME
  
  CPAN::Meta::Prereqs - a set of distribution prerequisites by phase and type
  
  =head1 VERSION
  
  version 2.150005
  
  =head1 DESCRIPTION
  
  A CPAN::Meta::Prereqs object represents the prerequisites for a CPAN
  distribution or one of its optional features.  Each set of prereqs is
  organized by phase and type, as described in L<CPAN::Meta::Prereqs>.
  
  =head1 METHODS
  
  =head2 new
  
    my $prereq = CPAN::Meta::Prereqs->new( \%prereq_spec );
  
  This method returns a new set of Prereqs.  The input should look like the
  contents of the C<prereqs> field described in L<CPAN::Meta::Spec>, meaning
  something more or less like this:
  
    my $prereq = CPAN::Meta::Prereqs->new({
      runtime => {
        requires => {
          'Some::Module' => '1.234',
          ...,
        },
        ...,
      },
      ...,
    });
  
  You can also construct an empty set of prereqs with:
  
    my $prereqs = CPAN::Meta::Prereqs->new;
  
  This empty set of prereqs is useful for accumulating new prereqs before finally
  dumping the whole set into a structure or string.
  
  =head2 requirements_for
  
    my $requirements = $prereqs->requirements_for( $phase, $type );
  
  This method returns a L<CPAN::Meta::Requirements> object for the given
  phase/type combination.  If no prerequisites are registered for that
  combination, a new CPAN::Meta::Requirements object will be returned, and it may
  be added to as needed.
  
  If C<$phase> or C<$type> are undefined or otherwise invalid, an exception will
  be raised.
  
  =head2 with_merged_prereqs
  
    my $new_prereqs = $prereqs->with_merged_prereqs( $other_prereqs );
  
    my $new_prereqs = $prereqs->with_merged_prereqs( \@other_prereqs );
  
  This method returns a new CPAN::Meta::Prereqs objects in which all the
  other prerequisites given are merged into the current set.  This is primarily
  provided for combining a distribution's core prereqs with the prereqs of one of
  its optional features.
  
  The new prereqs object has no ties to the originals, and altering it further
  will not alter them.
  
  =head2 merged_requirements
  
      my $new_reqs = $prereqs->merged_requirements( \@phases, \@types );
      my $new_reqs = $prereqs->merged_requirements( \@phases );
      my $new_reqs = $prereqs->merged_requirements();
  
  This method joins together all requirements across a number of phases
  and types into a new L<CPAN::Meta::Requirements> object.  If arguments
  are omitted, it defaults to "runtime", "build" and "test" for phases
  and "requires" and "recommends" for types.
  
  =head2 as_string_hash
  
  This method returns a hashref containing structures suitable for dumping into a
  distmeta data structure.  It is made up of hashes and strings, only; there will
  be no Prereqs, CPAN::Meta::Requirements, or C<version> objects inside it.
  
  =head2 is_finalized
  
  This method returns true if the set of prereqs has been marked "finalized," and
  cannot be altered.
  
  =head2 finalize
  
  Calling C<finalize> on a Prereqs object will close it for further modification.
  Attempting to make any changes that would actually alter the prereqs will
  result in an exception being thrown.
  
  =head2 clone
  
    my $cloned_prereqs = $prereqs->clone;
  
  This method returns a Prereqs object that is identical to the original object,
  but can be altered without affecting the original object.  Finalization does
  not survive cloning, meaning that you may clone a finalized set of prereqs and
  then modify the clone.
  
  =head1 BUGS
  
  Please report any bugs or feature using the CPAN Request Tracker.
  Bugs can be submitted through the web interface at
  L<http://rt.cpan.org/Dist/Display.html?Queue=CPAN-Meta>
  
  When submitting a bug or request, please include a test-file or a patch to an
  existing test-file that illustrates the bug or desired feature.
  
  =head1 AUTHORS
  
  =over 4
  
  =item *
  
  David Golden <dagolden@cpan.org>
  
  =item *
  
  Ricardo Signes <rjbs@cpan.org>
  
  =back
  
  =head1 COPYRIGHT AND LICENSE
  
  This software is copyright (c) 2010 by David Golden and Ricardo Signes.
  
  This is free software; you can redistribute it and/or modify it under
  the same terms as the Perl 5 programming language system itself.
  
  =cut
  
  __END__
  
  
  # vim: ts=2 sts=2 sw=2 et :
CPAN_META_PREREQS

$fatpacked{"CPAN/Meta/Spec.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CPAN_META_SPEC';
  # XXX RULES FOR PATCHING THIS FILE XXX
  # Patches that fix typos or formatting are acceptable.  Patches
  # that change semantics are not acceptable without prior approval
  # by David Golden or Ricardo Signes.
  
  use 5.006;
  use strict;
  use warnings;
  package CPAN::Meta::Spec;
  
  our $VERSION = '2.150005';
  
  1;
  
  # ABSTRACT: specification for CPAN distribution metadata
  
  
  # vi:tw=72
  
  __END__
  
  =pod
  
  =encoding UTF-8
  
  =head1 NAME
  
  CPAN::Meta::Spec - specification for CPAN distribution metadata
  
  =head1 VERSION
  
  version 2.150005
  
  =head1 SYNOPSIS
  
    my $distmeta = {
      name => 'Module-Build',
      abstract => 'Build and install Perl modules',
      description =>  "Module::Build is a system for "
        . "building, testing, and installing Perl modules. "
        . "It is meant to ... blah blah blah ...",
      version  => '0.36',
      release_status => 'stable',
      author   => [
        'Ken Williams <kwilliams@cpan.org>',
        'Module-Build List <module-build@perl.org>', # additional contact
      ],
      license  => [ 'perl_5' ],
      prereqs => {
        runtime => {
          requires => {
            'perl'   => '5.006',
            'ExtUtils::Install' => '0',
            'File::Basename' => '0',
            'File::Compare'  => '0',
            'IO::File'   => '0',
          },
          recommends => {
            'Archive::Tar' => '1.00',
            'ExtUtils::Install' => '0.3',
            'ExtUtils::ParseXS' => '2.02',
          },
        },
        build => {
          requires => {
            'Test::More' => '0',
          },
        }
      },
      resources => {
        license => ['http://dev.perl.org/licenses/'],
      },
      optional_features => {
        domination => {
          description => 'Take over the world',
          prereqs     => {
            develop => { requires => { 'Genius::Evil'     => '1.234' } },
            runtime => { requires => { 'Machine::Weather' => '2.0'   } },
          },
        },
      },
      dynamic_config => 1,
      keywords => [ qw/ toolchain cpan dual-life / ],
      'meta-spec' => {
        version => '2',
        url     => 'https://metacpan.org/pod/CPAN::Meta::Spec',
      },
      generated_by => 'Module::Build version 0.36',
    };
  
  =head1 DESCRIPTION
  
  This document describes version 2 of the CPAN distribution metadata
  specification, also known as the "CPAN Meta Spec".
  
  Revisions of this specification for typo corrections and prose
  clarifications may be issued as CPAN::Meta::Spec 2.I<x>.  These
  revisions will never change semantics or add or remove specified
  behavior.
  
  Distribution metadata describe important properties of Perl
  distributions. Distribution building tools like Module::Build,
  Module::Install, ExtUtils::MakeMaker or Dist::Zilla should create a
  metadata file in accordance with this specification and include it with
  the distribution for use by automated tools that index, examine, package
  or install Perl distributions.
  
  =head1 TERMINOLOGY
  
  =over 4
  
  =item distribution
  
  This is the primary object described by the metadata. In the context of
  this document it usually refers to a collection of modules, scripts,
  and/or documents that are distributed together for other developers to
  use.  Examples of distributions are C<Class-Container>, C<libwww-perl>,
  or C<DBI>.
  
  =item module
  
  This refers to a reusable library of code contained in a single file.
  Modules usually contain one or more packages and are often referred
  to by the name of a primary package that can be mapped to the file
  name. For example, one might refer to C<File::Spec> instead of
  F<File/Spec.pm>
  
  =item package
  
  This refers to a namespace declared with the Perl C<package> statement.
  In Perl, packages often have a version number property given by the
  C<$VERSION> variable in the namespace.
  
  =item consumer
  
  This refers to code that reads a metadata file, deserializes it into a
  data structure in memory, or interprets a data structure of metadata
  elements.
  
  =item producer
  
  This refers to code that constructs a metadata data structure,
  serializes into a bytestream and/or writes it to disk.
  
  =item must, should, may, etc.
  
  These terms are interpreted as described in IETF RFC 2119.
  
  =back
  
  =head1 DATA TYPES
  
  Fields in the L</STRUCTURE> section describe data elements, each of
  which has an associated data type as described herein.  There are four
  primitive types: Boolean, String, List and Map.  Other types are
  subtypes of primitives and define compound data structures or define
  constraints on the values of a data element.
  
  =head2 Boolean
  
  A I<Boolean> is used to provide a true or false value.  It B<must> be
  represented as a defined value.
  
  =head2 String
  
  A I<String> is data element containing a non-zero length sequence of
  Unicode characters, such as an ordinary Perl scalar that is not a
  reference.
  
  =head2 List
  
  A I<List> is an ordered collection of zero or more data elements.
  Elements of a List may be of mixed types.
  
  Producers B<must> represent List elements using a data structure which
  unambiguously indicates that multiple values are possible, such as a
  reference to a Perl array (an "arrayref").
  
  Consumers expecting a List B<must> consider a String as equivalent to a
  List of length 1.
  
  =head2 Map
  
  A I<Map> is an unordered collection of zero or more data elements
  ("values"), indexed by associated String elements ("keys").  The Map's
  value elements may be of mixed types.
  
  =head2 License String
  
  A I<License String> is a subtype of String with a restricted set of
  values.  Valid values are described in detail in the description of
  the L</license> field.
  
  =head2 URL
  
  I<URL> is a subtype of String containing a Uniform Resource Locator or
  Identifier.  [ This type is called URL and not URI for historical reasons. ]
  
  =head2 Version
  
  A I<Version> is a subtype of String containing a value that describes
  the version number of packages or distributions.  Restrictions on format
  are described in detail in the L</Version Formats> section.
  
  =head2 Version Range
  
  The I<Version Range> type is a subtype of String.  It describes a range
  of Versions that may be present or installed to fulfill prerequisites.
  It is specified in detail in the L</Version Ranges> section.
  
  =head1 STRUCTURE
  
  The metadata structure is a data element of type Map.  This section
  describes valid keys within the Map.
  
  Any keys not described in this specification document (whether top-level
  or within compound data structures described herein) are considered
  I<custom keys> and B<must> begin with an "x" or "X" and be followed by an
  underscore; i.e. they must match the pattern: C<< qr{\Ax_}i >>.  If a
  custom key refers to a compound data structure, subkeys within it do not
  need an "x_" or "X_" prefix.
  
  Consumers of metadata may ignore any or all custom keys.  All other keys
  not described herein are invalid and should be ignored by consumers.
  Producers must not generate or output invalid keys.
  
  For each key, an example is provided followed by a description.  The
  description begins with the version of spec in which the key was added
  or in which the definition was modified, whether the key is I<required>
  or I<optional> and the data type of the corresponding data element.
  These items are in parentheses, brackets and braces, respectively.
  
  If a data type is a Map or Map subtype, valid subkeys will be described
  as well.
  
  Some fields are marked I<Deprecated>.  These are shown for historical
  context and must not be produced in or consumed from any metadata structure
  of version 2 or higher.
  
  =head2 REQUIRED FIELDS
  
  =head3 abstract
  
  Example:
  
    abstract => 'Build and install Perl modules'
  
  (Spec 1.2) [required] {String}
  
  This is a short description of the purpose of the distribution.
  
  =head3 author
  
  Example:
  
    author => [ 'Ken Williams <kwilliams@cpan.org>' ]
  
  (Spec 1.2) [required] {List of one or more Strings}
  
  This List indicates the person(s) to contact concerning the
  distribution. The preferred form of the contact string is:
  
    contact-name <email-address>
  
  This field provides a general contact list independent of other
  structured fields provided within the L</resources> field, such as
  C<bugtracker>.  The addressee(s) can be contacted for any purpose
  including but not limited to (security) problems with the distribution,
  questions about the distribution or bugs in the distribution.
  
  A distribution's original author is usually the contact listed within
  this field.  Co-maintainers, successor maintainers or mailing lists
  devoted to the distribution may also be listed in addition to or instead
  of the original author.
  
  =head3 dynamic_config
  
  Example:
  
    dynamic_config => 1
  
  (Spec 2) [required] {Boolean}
  
  A boolean flag indicating whether a F<Build.PL> or F<Makefile.PL> (or
  similar) must be executed to determine prerequisites.
  
  This field should be set to a true value if the distribution performs
  some dynamic configuration (asking questions, sensing the environment,
  etc.) as part of its configuration.  This field should be set to a false
  value to indicate that prerequisites included in metadata may be
  considered final and valid for static analysis.
  
  Note: when this field is true, post-configuration prerequisites are not
  guaranteed to bear any relation whatsoever to those stated in the metadata,
  and relying on them doing so is an error. See also
  L</Prerequisites for dynamically configured distributions> in the implementors'
  notes.
  
  This field explicitly B<does not> indicate whether installation may be
  safely performed without using a Makefile or Build file, as there may be
  special files to install or custom installation targets (e.g. for
  dual-life modules that exist on CPAN as well as in the Perl core).  This
  field only defines whether or not prerequisites are exactly as given in the
  metadata.
  
  =head3 generated_by
  
  Example:
  
    generated_by => 'Module::Build version 0.36'
  
  (Spec 1.0) [required] {String}
  
  This field indicates the tool that was used to create this metadata.
  There are no defined semantics for this field, but it is traditional to
  use a string in the form "Generating::Package version 1.23" or the
  author's name, if the file was generated by hand.
  
  =head3 license
  
  Example:
  
    license => [ 'perl_5' ]
  
    license => [ 'apache_2_0', 'mozilla_1_0' ]
  
  (Spec 2) [required] {List of one or more License Strings}
  
  One or more licenses that apply to some or all of the files in the
  distribution.  If multiple licenses are listed, the distribution
  documentation should be consulted to clarify the interpretation of
  multiple licenses.
  
  The following list of license strings are valid:
  
   string          description
   -------------   -----------------------------------------------
   agpl_3          GNU Affero General Public License, Version 3
   apache_1_1      Apache Software License, Version 1.1
   apache_2_0      Apache License, Version 2.0
   artistic_1      Artistic License, (Version 1)
   artistic_2      Artistic License, Version 2.0
   bsd             BSD License (three-clause)
   freebsd         FreeBSD License (two-clause)
   gfdl_1_2        GNU Free Documentation License, Version 1.2
   gfdl_1_3        GNU Free Documentation License, Version 1.3
   gpl_1           GNU General Public License, Version 1
   gpl_2           GNU General Public License, Version 2
   gpl_3           GNU General Public License, Version 3
   lgpl_2_1        GNU Lesser General Public License, Version 2.1
   lgpl_3_0        GNU Lesser General Public License, Version 3.0
   mit             MIT (aka X11) License
   mozilla_1_0     Mozilla Public License, Version 1.0
   mozilla_1_1     Mozilla Public License, Version 1.1
   openssl         OpenSSL License
   perl_5          The Perl 5 License (Artistic 1 & GPL 1 or later)
   qpl_1_0         Q Public License, Version 1.0
   ssleay          Original SSLeay License
   sun             Sun Internet Standards Source License (SISSL)
   zlib            zlib License
  
  The following license strings are also valid and indicate other
  licensing not described above:
  
   string          description
   -------------   -----------------------------------------------
   open_source     Other Open Source Initiative (OSI) approved license
   restricted      Requires special permission from copyright holder
   unrestricted    Not an OSI approved license, but not restricted
   unknown         License not provided in metadata
  
  All other strings are invalid in the license field.
  
  =head3 meta-spec
  
  Example:
  
    'meta-spec' => {
      version => '2',
      url     => 'http://search.cpan.org/perldoc?CPAN::Meta::Spec',
    }
  
  (Spec 1.2) [required] {Map}
  
  This field indicates the version of the CPAN Meta Spec that should be
  used to interpret the metadata.  Consumers must check this key as soon
  as possible and abort further metadata processing if the meta-spec
  version is not supported by the consumer.
  
  The following keys are valid, but only C<version> is required.
  
  =over
  
  =item version
  
  This subkey gives the integer I<Version> of the CPAN Meta Spec against
  which the document was generated.
  
  =item url
  
  This is a I<URL> of the metadata specification document corresponding to
  the given version.  This is strictly for human-consumption and should
  not impact the interpretation of the document.
  
  For the version 2 spec, either of these are recommended:
  
  =over 4
  
  =item *
  
  C<https://metacpan.org/pod/CPAN::Meta::Spec>
  
  =item *
  
  C<http://search.cpan.org/perldoc?CPAN::Meta::Spec>
  
  =back
  
  =back
  
  =head3 name
  
  Example:
  
    name => 'Module-Build'
  
  (Spec 1.0) [required] {String}
  
  This field is the name of the distribution.  This is often created by
  taking the "main package" in the distribution and changing C<::> to
  C<->, but the name may be completely unrelated to the packages within
  the distribution.  For example, L<LWP::UserAgent> is distributed as part
  of the distribution name "libwww-perl".
  
  =head3 release_status
  
  Example:
  
    release_status => 'stable'
  
  (Spec 2) [required] {String}
  
  This field provides the  release status of this distribution.  If the
  C<version> field contains an underscore character, then
  C<release_status> B<must not> be "stable."
  
  The C<release_status> field B<must> have one of the following values:
  
  =over
  
  =item stable
  
  This indicates an ordinary, "final" release that should be indexed by PAUSE
  or other indexers.
  
  =item testing
  
  This indicates a "beta" release that is substantially complete, but has an
  elevated risk of bugs and requires additional testing.  The distribution
  should not be installed over a stable release without an explicit request
  or other confirmation from a user.  This release status may also be used
  for "release candidate" versions of a distribution.
  
  =item unstable
  
  This indicates an "alpha" release that is under active development, but has
  been released for early feedback or testing and may be missing features or
  may have serious bugs.  The distribution should not be installed over a
  stable release without an explicit request or other confirmation from a
  user.
  
  =back
  
  Consumers B<may> use this field to determine how to index the
  distribution for CPAN or other repositories in addition to or in
  replacement of heuristics based on version number or file name.
  
  =head3 version
  
  Example:
  
    version => '0.36'
  
  (Spec 1.0) [required] {Version}
  
  This field gives the version of the distribution to which the metadata
  structure refers.
  
  =head2 OPTIONAL FIELDS
  
  =head3 description
  
  Example:
  
      description =>  "Module::Build is a system for "
        . "building, testing, and installing Perl modules. "
        . "It is meant to ... blah blah blah ...",
  
  (Spec 2) [optional] {String}
  
  A longer, more complete description of the purpose or intended use of
  the distribution than the one provided by the C<abstract> key.
  
  =head3 keywords
  
  Example:
  
    keywords => [ qw/ toolchain cpan dual-life / ]
  
  (Spec 1.1) [optional] {List of zero or more Strings}
  
  A List of keywords that describe this distribution.  Keywords
  B<must not> include whitespace.
  
  =head3 no_index
  
  Example:
  
    no_index => {
      file      => [ 'My/Module.pm' ],
      directory => [ 'My/Private' ],
      package   => [ 'My::Module::Secret' ],
      namespace => [ 'My::Module::Sample' ],
    }
  
  (Spec 1.2) [optional] {Map}
  
  This Map describes any files, directories, packages, and namespaces that
  are private to the packaging or implementation of the distribution and
  should be ignored by indexing or search tools. Note that this is a list of
  exclusions, and the spec does not define what to I<include> - see
  L</Indexing distributions a la PAUSE> in the implementors notes for more
  information.
  
  Valid subkeys are as follows:
  
  =over
  
  =item file
  
  A I<List> of relative paths to files.  Paths B<must be> specified with
  unix conventions.
  
  =item directory
  
  A I<List> of relative paths to directories.  Paths B<must be> specified
  with unix conventions.
  
  [ Note: previous editions of the spec had C<dir> instead of C<directory> ]
  
  =item package
  
  A I<List> of package names.
  
  =item namespace
  
  A I<List> of package namespaces, where anything below the namespace
  must be ignored, but I<not> the namespace itself.
  
  In the example above for C<no_index>, C<My::Module::Sample::Foo> would
  be ignored, but C<My::Module::Sample> would not.
  
  =back
  
  =head3 optional_features
  
  Example:
  
    optional_features => {
      sqlite => {
        description => 'Provides SQLite support',
        prereqs => {
          runtime => {
            requires => {
              'DBD::SQLite' => '1.25'
            }
          }
        }
      }
    }
  
  (Spec 2) [optional] {Map}
  
  This Map describes optional features with incremental prerequisites.
  Each key of the C<optional_features> Map is a String used to identify
  the feature and each value is a Map with additional information about
  the feature.  Valid subkeys include:
  
  =over
  
  =item description
  
  This is a String describing the feature.  Every optional feature
  should provide a description
  
  =item prereqs
  
  This entry is required and has the same structure as that of the
  C<L</prereqs>> key.  It provides a list of package requirements
  that must be satisfied for the feature to be supported or enabled.
  
  There is one crucial restriction:  the prereqs of an optional feature
  B<must not> include C<configure> phase prereqs.
  
  =back
  
  Consumers B<must not> include optional features as prerequisites without
  explicit instruction from users (whether via interactive prompting,
  a function parameter or a configuration value, etc. ).
  
  If an optional feature is used by a consumer to add additional
  prerequisites, the consumer should merge the optional feature
  prerequisites into those given by the C<prereqs> key using the same
  semantics.  See L</Merging and Resolving Prerequisites> for details on
  merging prerequisites.
  
  I<Suggestion for disuse:> Because there is currently no way for a
  distribution to specify a dependency on an optional feature of another
  dependency, the use of C<optional_feature> is discouraged.  Instead,
  create a separate, installable distribution that ensures the desired
  feature is available.  For example, if C<Foo::Bar> has a C<Baz> feature,
  release a separate C<Foo-Bar-Baz> distribution that satisfies
  requirements for the feature.
  
  =head3 prereqs
  
  Example:
  
    prereqs => {
      runtime => {
        requires => {
          'perl'          => '5.006',
          'File::Spec'    => '0.86',
          'JSON'          => '2.16',
        },
        recommends => {
          'JSON::XS'      => '2.26',
        },
        suggests => {
          'Archive::Tar'  => '0',
        },
      },
      build => {
        requires => {
          'Alien::SDL'    => '1.00',
        },
      },
      test => {
        recommends => {
          'Test::Deep'    => '0.10',
        },
      }
    }
  
  (Spec 2) [optional] {Map}
  
  This is a Map that describes all the prerequisites of the distribution.
  The keys are phases of activity, such as C<configure>, C<build>, C<test>
  or C<runtime>.  Values are Maps in which the keys name the type of
  prerequisite relationship such as C<requires>, C<recommends>, or
  C<suggests> and the value provides a set of prerequisite relations.  The
  set of relations B<must> be specified as a Map of package names to
  version ranges.
  
  The full definition for this field is given in the L</Prereq Spec>
  section.
  
  =head3 provides
  
  Example:
  
    provides => {
      'Foo::Bar' => {
        file    => 'lib/Foo/Bar.pm',
        version => '0.27_02',
      },
      'Foo::Bar::Blah' => {
        file    => 'lib/Foo/Bar/Blah.pm',
      },
      'Foo::Bar::Baz' => {
        file    => 'lib/Foo/Bar/Baz.pm',
        version => '0.3',
      },
    }
  
  (Spec 1.2) [optional] {Map}
  
  This describes all packages provided by this distribution.  This
  information is used by distribution and automation mechanisms like
  PAUSE, CPAN, metacpan.org and search.cpan.org to build indexes saying in
  which distribution various packages can be found.
  
  The keys of C<provides> are package names that can be found within
  the distribution.  If a package name key is provided, it must
  have a Map with the following valid subkeys:
  
  =over
  
  =item file
  
  This field is required.  It must contain a Unix-style relative file path
  from the root of the distribution directory to a file that contains or
  generates the package.  It may be given as C<META.yml> or C<META.json>
  to claim a package for indexing without needing a C<*.pm>.
  
  =item version
  
  If it exists, this field must contains a I<Version> String for the
  package.  If the package does not have a C<$VERSION>, this field must
  be omitted.
  
  =back
  
  =head3 resources
  
  Example:
  
    resources => {
      license     => [ 'http://dev.perl.org/licenses/' ],
      homepage    => 'http://sourceforge.net/projects/module-build',
      bugtracker  => {
        web    => 'http://rt.cpan.org/Public/Dist/Display.html?Name=CPAN-Meta',
        mailto => 'meta-bugs@example.com',
      },
      repository  => {
        url  => 'git://github.com/dagolden/cpan-meta.git',
        web  => 'http://github.com/dagolden/cpan-meta',
        type => 'git',
      },
      x_twitter   => 'http://twitter.com/cpan_linked/',
    }
  
  (Spec 2) [optional] {Map}
  
  This field describes resources related to this distribution.
  
  Valid subkeys include:
  
  =over
  
  =item homepage
  
  The official home of this project on the web.
  
  =item license
  
  A List of I<URL>'s that relate to this distribution's license.  As with the
  top-level C<license> field, distribution documentation should be consulted
  to clarify the interpretation of multiple licenses provided here.
  
  =item bugtracker
  
  This entry describes the bug tracking system for this distribution.  It
  is a Map with the following valid keys:
  
    web    - a URL pointing to a web front-end for the bug tracker
    mailto - an email address to which bugs can be sent
  
  =item repository
  
  This entry describes the source control repository for this distribution.  It
  is a Map with the following valid keys:
  
    url  - a URL pointing to the repository itself
    web  - a URL pointing to a web front-end for the repository
    type - a lowercase string indicating the VCS used
  
  Because a url like C<http://myrepo.example.com/> is ambiguous as to
  type, producers should provide a C<type> whenever a C<url> key is given.
  The C<type> field should be the name of the most common program used
  to work with the repository, e.g. C<git>, C<svn>, C<cvs>, C<darcs>,
  C<bzr> or C<hg>.
  
  =back
  
  =head2 DEPRECATED FIELDS
  
  =head3 build_requires
  
  I<(Deprecated in Spec 2)> [optional] {String}
  
  Replaced by C<prereqs>
  
  =head3 configure_requires
  
  I<(Deprecated in Spec 2)> [optional] {String}
  
  Replaced by C<prereqs>
  
  =head3 conflicts
  
  I<(Deprecated in Spec 2)> [optional] {String}
  
  Replaced by C<prereqs>
  
  =head3 distribution_type
  
  I<(Deprecated in Spec 2)> [optional] {String}
  
  This field indicated 'module' or 'script' but was considered
  meaningless, since many distributions are hybrids of several kinds of
  things.
  
  =head3 license_uri
  
  I<(Deprecated in Spec 1.2)> [optional] {URL}
  
  Replaced by C<license> in C<resources>
  
  =head3 private
  
  I<(Deprecated in Spec 1.2)> [optional] {Map}
  
  This field has been renamed to L</"no_index">.
  
  =head3 recommends
  
  I<(Deprecated in Spec 2)> [optional] {String}
  
  Replaced by C<prereqs>
  
  =head3 requires
  
  I<(Deprecated in Spec 2)> [optional] {String}
  
  Replaced by C<prereqs>
  
  =head1 VERSION NUMBERS
  
  =head2 Version Formats
  
  This section defines the Version type, used by several fields in the
  CPAN Meta Spec.
  
  Version numbers must be treated as strings, not numbers.  For
  example, C<1.200> B<must not> be serialized as C<1.2>.  Version
  comparison should be delegated to the Perl L<version> module, version
  0.80 or newer.
  
  Unless otherwise specified, version numbers B<must> appear in one of two
  formats:
  
  =over
  
  =item Decimal versions
  
  Decimal versions are regular "decimal numbers", with some limitations.
  They B<must> be non-negative and B<must> begin and end with a digit.  A
  single underscore B<may> be included, but B<must> be between two digits.
  They B<must not> use exponential notation ("1.23e-2").
  
     version => '1.234'       # OK
     version => '1.23_04'     # OK
  
     version => '1.23_04_05'  # Illegal
     version => '1.'          # Illegal
     version => '.1'          # Illegal
  
  =item Dotted-integer versions
  
  Dotted-integer (also known as dotted-decimal) versions consist of
  positive integers separated by full stop characters (i.e. "dots",
  "periods" or "decimal points").  This are equivalent in format to Perl
  "v-strings", with some additional restrictions on form.  They must be
  given in "normal" form, which has a leading "v" character and at least
  three integer components.  To retain a one-to-one mapping with decimal
  versions, all components after the first B<should> be restricted to the
  range 0 to 999.  The final component B<may> be separated by an
  underscore character instead of a period.
  
     version => 'v1.2.3'      # OK
     version => 'v1.2_3'      # OK
     version => 'v1.2.3.4'    # OK
     version => 'v1.2.3_4'    # OK
     version => 'v2009.10.31' # OK
  
     version => 'v1.2'          # Illegal
     version => '1.2.3'         # Illegal
     version => 'v1.2_3_4'      # Illegal
     version => 'v1.2009.10.31' # Not recommended
  
  =back
  
  =head2 Version Ranges
  
  Some fields (prereq, optional_features) indicate the particular
  version(s) of some other module that may be required as a prerequisite.
  This section details the Version Range type used to provide this
  information.
  
  The simplest format for a Version Range is just the version
  number itself, e.g. C<2.4>.  This means that B<at least> version 2.4
  must be present.  To indicate that B<any> version of a prerequisite is
  okay, even if the prerequisite doesn't define a version at all, use
  the version C<0>.
  
  Alternatively, a version range B<may> use the operators E<lt> (less than),
  E<lt>= (less than or equal), E<gt> (greater than), E<gt>= (greater than
  or equal), == (equal), and != (not equal).  For example, the
  specification C<E<lt> 2.0> means that any version of the prerequisite
  less than 2.0 is suitable.
  
  For more complicated situations, version specifications B<may> be AND-ed
  together using commas.  The specification C<E<gt>= 1.2, != 1.5, E<lt>
  2.0> indicates a version that must be B<at least> 1.2, B<less than> 2.0,
  and B<not equal to> 1.5.
  
  =head1 PREREQUISITES
  
  =head2 Prereq Spec
  
  The C<prereqs> key in the top-level metadata and within
  C<optional_features> define the relationship between a distribution and
  other packages.  The prereq spec structure is a hierarchical data
  structure which divides prerequisites into I<Phases> of activity in the
  installation process and I<Relationships> that indicate how
  prerequisites should be resolved.
  
  For example, to specify that C<Data::Dumper> is C<required> during the
  C<test> phase, this entry would appear in the distribution metadata:
  
    prereqs => {
      test => {
        requires => {
          'Data::Dumper' => '2.00'
        }
      }
    }
  
  =head3 Phases
  
  Requirements for regular use must be listed in the C<runtime> phase.
  Other requirements should be listed in the earliest stage in which they
  are required and consumers must accumulate and satisfy requirements
  across phases before executing the activity. For example, C<build>
  requirements must also be available during the C<test> phase.
  
    before action       requirements that must be met
    ----------------    --------------------------------
    perl Build.PL       configure
    perl Makefile.PL
  
    make                configure, runtime, build
    Build
  
    make test           configure, runtime, build, test
    Build test
  
  Consumers that install the distribution must ensure that
  I<runtime> requirements are also installed and may install
  dependencies from other phases.
  
    after action        requirements that must be met
    ----------------    --------------------------------
    make install        runtime
    Build install
  
  =over
  
  =item configure
  
  The configure phase occurs before any dynamic configuration has been
  attempted.  Libraries required by the configure phase B<must> be
  available for use before the distribution building tool has been
  executed.
  
  =item build
  
  The build phase is when the distribution's source code is compiled (if
  necessary) and otherwise made ready for installation.
  
  =item test
  
  The test phase is when the distribution's automated test suite is run.
  Any library that is needed only for testing and not for subsequent use
  should be listed here.
  
  =item runtime
  
  The runtime phase refers not only to when the distribution's contents
  are installed, but also to its continued use.  Any library that is a
  prerequisite for regular use of this distribution should be indicated
  here.
  
  =item develop
  
  The develop phase's prereqs are libraries needed to work on the
  distribution's source code as its author does.  These tools might be
  needed to build a release tarball, to run author-only tests, or to
  perform other tasks related to developing new versions of the
  distribution.
  
  =back
  
  =head3 Relationships
  
  =over
  
  =item requires
  
  These dependencies B<must> be installed for proper completion of the
  phase.
  
  =item recommends
  
  Recommended dependencies are I<strongly> encouraged and should be
  satisfied except in resource constrained environments.
  
  =item suggests
  
  These dependencies are optional, but are suggested for enhanced operation
  of the described distribution.
  
  =item conflicts
  
  These libraries cannot be installed when the phase is in operation.
  This is a very rare situation, and the C<conflicts> relationship should
  be used with great caution, or not at all.
  
  =back
  
  =head2 Merging and Resolving Prerequisites
  
  Whenever metadata consumers merge prerequisites, either from different
  phases or from C<optional_features>, they should merged in a way which
  preserves the intended semantics of the prerequisite structure.  Generally,
  this means concatenating the version specifications using commas, as
  described in the L<Version Ranges> section.
  
  Another subtle error that can occur in resolving prerequisites comes from
  the way that modules in prerequisites are indexed to distribution files on
  CPAN.  When a module is deleted from a distribution, prerequisites calling
  for that module could indicate an older distribution should be installed,
  potentially overwriting files from a newer distribution.
  
  For example, as of Oct 31, 2009, the CPAN index file contained these
  module-distribution mappings:
  
    Class::MOP                   0.94  D/DR/DROLSKY/Class-MOP-0.94.tar.gz
    Class::MOP::Class            0.94  D/DR/DROLSKY/Class-MOP-0.94.tar.gz
    Class::MOP::Class::Immutable 0.04  S/ST/STEVAN/Class-MOP-0.36.tar.gz
  
  Consider the case where "Class::MOP" 0.94 is installed.  If a
  distribution specified "Class::MOP::Class::Immutable" as a prerequisite,
  it could result in Class-MOP-0.36.tar.gz being installed, overwriting
  any files from Class-MOP-0.94.tar.gz.
  
  Consumers of metadata B<should> test whether prerequisites would result
  in installed module files being "downgraded" to an older version and
  B<may> warn users or ignore the prerequisite that would cause such a
  result.
  
  =head1 SERIALIZATION
  
  Distribution metadata should be serialized (as a hashref) as
  JSON-encoded data and packaged with distributions as the file
  F<META.json>.
  
  In the past, the distribution metadata structure had been packed with
  distributions as F<META.yml>, a file in the YAML Tiny format (for which,
  see L<YAML::Tiny>).  Tools that consume distribution metadata from disk
  should be capable of loading F<META.yml>, but should prefer F<META.json>
  if both are found.
  
  =head1 NOTES FOR IMPLEMENTORS
  
  =head2 Extracting Version Numbers from Perl Modules
  
  To get the version number from a Perl module, consumers should use the
  C<< MM->parse_version($file) >> method provided by
  L<ExtUtils::MakeMaker> or L<Module::Metadata>.  For example, for the
  module given by C<$mod>, the version may be retrieved in one of the
  following ways:
  
    # via ExtUtils::MakeMaker
    my $file = MM->_installed_file_for_module($mod);
    my $version = MM->parse_version($file)
  
  The private C<_installed_file_for_module> method may be replaced with
  other methods for locating a module in C<@INC>.
  
    # via Module::Metadata
    my $info = Module::Metadata->new_from_module($mod);
    my $version = $info->version;
  
  If only a filename is available, the following approach may be used:
  
    # via Module::Build
    my $info = Module::Metadata->new_from_file($file);
    my $version = $info->version;
  
  =head2 Comparing Version Numbers
  
  The L<version> module provides the most reliable way to compare version
  numbers in all the various ways they might be provided or might exist
  within modules.  Given two strings containing version numbers, C<$v1> and
  C<$v2>, they should be converted to C<version> objects before using
  ordinary comparison operators.  For example:
  
    use version;
    if ( version->new($v1) <=> version->new($v2) ) {
      print "Versions are not equal\n";
    }
  
  If the only comparison needed is whether an installed module is of a
  sufficiently high version, a direct test may be done using the string
  form of C<eval> and the C<use> function.  For example, for module C<$mod>
  and version prerequisite C<$prereq>:
  
    if ( eval "use $mod $prereq (); 1" ) {
      print "Module $mod version is OK.\n";
    }
  
  If the values of C<$mod> and C<$prereq> have not been scrubbed, however,
  this presents security implications.
  
  =head2 Prerequisites for dynamically configured distributions
  
  When C<dynamic_config> is true, it is an error to presume that the
  prerequisites given in distribution metadata will have any relationship
  whatsoever to the actual prerequisites of the distribution.
  
  In practice, however, one can generally expect such prerequisites to be
  one of two things:
  
  =over 4
  
  =item *
  
  The minimum prerequisites for the distribution, to which dynamic configuration will only add items
  
  =item *
  
  Whatever the distribution configured with on the releaser's machine at release time
  
  =back
  
  The second case often turns out to have identical results to the first case,
  albeit only by accident.
  
  As such, consumers may use this data for informational analysis, but
  presenting it to the user as canonical or relying on it as such is
  invariably the height of folly.
  
  =head2 Indexing distributions a la PAUSE
  
  While no_index tells you what must be ignored when indexing, this spec holds
  no opinion on how you should get your initial candidate list of things to
  possibly index. For "normal" distributions you might consider simply indexing
  the contents of lib/, but there are many fascinating oddities on CPAN and
  many dists from the days when it was normal to put the main .pm file in the
  root of the distribution archive - so PAUSE currently indexes all .pm and .PL
  files that are not either (a) specifically excluded by no_index (b) in
  C<inc>, C<xt>, or C<t> directories, or common 'mistake' directories such as
  C<perl5>.
  
  Or: If you're trying to be PAUSE-like, make sure you skip C<inc>, C<xt> and
  C<t> as well as anything marked as no_index.
  
  Also remember: If the META file contains a provides field, you shouldn't be
  indexing anything in the first place - just use that.
  
  =head1 SEE ALSO
  
  =over 4
  
  =item *
  
  CPAN, L<http://www.cpan.org/>
  
  =item *
  
  JSON, L<http://json.org/>
  
  =item *
  
  YAML, L<http://www.yaml.org/>
  
  =item *
  
  L<CPAN>
  
  =item *
  
  L<CPANPLUS>
  
  =item *
  
  L<ExtUtils::MakeMaker>
  
  =item *
  
  L<Module::Build>
  
  =item *
  
  L<Module::Install>
  
  =back
  
  =head1 HISTORY
  
  Ken Williams wrote the original CPAN Meta Spec (also known as the
  "META.yml spec") in 2003 and maintained it through several revisions
  with input from various members of the community.  In 2005, Randy
  Sims redrafted it from HTML to POD for the version 1.2 release.  Ken
  continued to maintain the spec through version 1.4.
  
  In late 2009, David Golden organized the version 2 proposal review
  process.  David and Ricardo Signes drafted the final version 2 spec
  in April 2010 based on the version 1.4 spec and patches contributed
  during the proposal process.
  
  =head1 AUTHORS
  
  =over 4
  
  =item *
  
  David Golden <dagolden@cpan.org>
  
  =item *
  
  Ricardo Signes <rjbs@cpan.org>
  
  =back
  
  =head1 COPYRIGHT AND LICENSE
  
  This software is copyright (c) 2010 by David Golden and Ricardo Signes.
  
  This is free software; you can redistribute it and/or modify it under
  the same terms as the Perl 5 programming language system itself.
  
  =cut
CPAN_META_SPEC

$fatpacked{"CPAN/Meta/Validator.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CPAN_META_VALIDATOR';
  use 5.006;
  use strict;
  use warnings;
  package CPAN::Meta::Validator;
  
  our $VERSION = '2.150005';
  
  #pod =head1 SYNOPSIS
  #pod
  #pod   my $struct = decode_json_file('META.json');
  #pod
  #pod   my $cmv = CPAN::Meta::Validator->new( $struct );
  #pod
  #pod   unless ( $cmv->is_valid ) {
  #pod     my $msg = "Invalid META structure.  Errors found:\n";
  #pod     $msg .= join( "\n", $cmv->errors );
  #pod     die $msg;
  #pod   }
  #pod
  #pod =head1 DESCRIPTION
  #pod
  #pod This module validates a CPAN Meta structure against the version of the
  #pod the specification claimed in the C<meta-spec> field of the structure.
  #pod
  #pod =cut
  
  #--------------------------------------------------------------------------#
  # This code copied and adapted from Test::CPAN::Meta
  # by Barbie, <barbie@cpan.org> for Miss Barbell Productions,
  # L<http://www.missbarbell.co.uk>
  #--------------------------------------------------------------------------#
  
  #--------------------------------------------------------------------------#
  # Specification Definitions
  #--------------------------------------------------------------------------#
  
  my %known_specs = (
      '1.4' => 'http://module-build.sourceforge.net/META-spec-v1.4.html',
      '1.3' => 'http://module-build.sourceforge.net/META-spec-v1.3.html',
      '1.2' => 'http://module-build.sourceforge.net/META-spec-v1.2.html',
      '1.1' => 'http://module-build.sourceforge.net/META-spec-v1.1.html',
      '1.0' => 'http://module-build.sourceforge.net/META-spec-v1.0.html'
  );
  my %known_urls = map {$known_specs{$_} => $_} keys %known_specs;
  
  my $module_map1 = { 'map' => { ':key' => { name => \&module, value => \&exversion } } };
  
  my $module_map2 = { 'map' => { ':key' => { name => \&module, value => \&version   } } };
  
  my $no_index_2 = {
      'map'       => { file       => { list => { value => \&string } },
                       directory  => { list => { value => \&string } },
                       'package'  => { list => { value => \&string } },
                       namespace  => { list => { value => \&string } },
                      ':key'      => { name => \&custom_2, value => \&anything },
      }
  };
  
  my $no_index_1_3 = {
      'map'       => { file       => { list => { value => \&string } },
                       directory  => { list => { value => \&string } },
                       'package'  => { list => { value => \&string } },
                       namespace  => { list => { value => \&string } },
                       ':key'     => { name => \&string, value => \&anything },
      }
  };
  
  my $no_index_1_2 = {
      'map'       => { file       => { list => { value => \&string } },
                       dir        => { list => { value => \&string } },
                       'package'  => { list => { value => \&string } },
                       namespace  => { list => { value => \&string } },
                       ':key'     => { name => \&string, value => \&anything },
      }
  };
  
  my $no_index_1_1 = {
      'map'       => { ':key'     => { name => \&string, list => { value => \&string } },
      }
  };
  
  my $prereq_map = {
    map => {
      ':key' => {
        name => \&phase,
        'map' => {
          ':key'  => {
            name => \&relation,
            %$module_map1,
          },
        },
      }
    },
  };
  
  my %definitions = (
    '2' => {
      # REQUIRED
      'abstract'            => { mandatory => 1, value => \&string  },
      'author'              => { mandatory => 1, list => { value => \&string } },
      'dynamic_config'      => { mandatory => 1, value => \&boolean },
      'generated_by'        => { mandatory => 1, value => \&string  },
      'license'             => { mandatory => 1, list => { value => \&license } },
      'meta-spec' => {
        mandatory => 1,
        'map' => {
          version => { mandatory => 1, value => \&version},
          url     => { value => \&url },
          ':key' => { name => \&custom_2, value => \&anything },
        }
      },
      'name'                => { mandatory => 1, value => \&string  },
      'release_status'      => { mandatory => 1, value => \&release_status },
      'version'             => { mandatory => 1, value => \&version },
  
      # OPTIONAL
      'description' => { value => \&string },
      'keywords'    => { list => { value => \&string } },
      'no_index'    => $no_index_2,
      'optional_features'   => {
        'map'       => {
          ':key'  => {
            name => \&string,
            'map'   => {
              description        => { value => \&string },
              prereqs => $prereq_map,
              ':key' => { name => \&custom_2, value => \&anything },
            }
          }
        }
      },
      'prereqs' => $prereq_map,
      'provides'    => {
        'map'       => {
          ':key' => {
            name  => \&module,
            'map' => {
              file    => { mandatory => 1, value => \&file },
              version => { value => \&version },
              ':key' => { name => \&custom_2, value => \&anything },
            }
          }
        }
      },
      'resources'   => {
        'map'       => {
          license    => { list => { value => \&url } },
          homepage   => { value => \&url },
          bugtracker => {
            'map' => {
              web => { value => \&url },
              mailto => { value => \&string},
              ':key' => { name => \&custom_2, value => \&anything },
            }
          },
          repository => {
            'map' => {
              web => { value => \&url },
              url => { value => \&url },
              type => { value => \&string },
              ':key' => { name => \&custom_2, value => \&anything },
            }
          },
          ':key'     => { value => \&string, name => \&custom_2 },
        }
      },
  
      # CUSTOM -- additional user defined key/value pairs
      # note we can only validate the key name, as the structure is user defined
      ':key'        => { name => \&custom_2, value => \&anything },
    },
  
  '1.4' => {
    'meta-spec'           => {
      mandatory => 1,
      'map' => {
        version => { mandatory => 1, value => \&version},
        url     => { mandatory => 1, value => \&urlspec },
        ':key'  => { name => \&string, value => \&anything },
      },
    },
  
    'name'                => { mandatory => 1, value => \&string  },
    'version'             => { mandatory => 1, value => \&version },
    'abstract'            => { mandatory => 1, value => \&string  },
    'author'              => { mandatory => 1, list  => { value => \&string } },
    'license'             => { mandatory => 1, value => \&license },
    'generated_by'        => { mandatory => 1, value => \&string  },
  
    'distribution_type'   => { value => \&string  },
    'dynamic_config'      => { value => \&boolean },
  
    'requires'            => $module_map1,
    'recommends'          => $module_map1,
    'build_requires'      => $module_map1,
    'configure_requires'  => $module_map1,
    'conflicts'           => $module_map2,
  
    'optional_features'   => {
      'map'       => {
          ':key'  => { name => \&string,
              'map'   => { description        => { value => \&string },
                           requires           => $module_map1,
                           recommends         => $module_map1,
                           build_requires     => $module_map1,
                           conflicts          => $module_map2,
                           ':key'  => { name => \&string, value => \&anything },
              }
          }
       }
    },
  
    'provides'    => {
      'map'       => {
        ':key' => { name  => \&module,
          'map' => {
            file    => { mandatory => 1, value => \&file },
            version => { value => \&version },
            ':key'  => { name => \&string, value => \&anything },
          }
        }
      }
    },
  
    'no_index'    => $no_index_1_3,
    'private'     => $no_index_1_3,
  
    'keywords'    => { list => { value => \&string } },
  
    'resources'   => {
      'map'       => { license    => { value => \&url },
                       homepage   => { value => \&url },
                       bugtracker => { value => \&url },
                       repository => { value => \&url },
                       ':key'     => { value => \&string, name => \&custom_1 },
      }
    },
  
    # additional user defined key/value pairs
    # note we can only validate the key name, as the structure is user defined
    ':key'        => { name => \&string, value => \&anything },
  },
  
  '1.3' => {
    'meta-spec'           => {
      mandatory => 1,
      'map' => {
        version => { mandatory => 1, value => \&version},
        url     => { mandatory => 1, value => \&urlspec },
        ':key'  => { name => \&string, value => \&anything },
      },
    },
  
    'name'                => { mandatory => 1, value => \&string  },
    'version'             => { mandatory => 1, value => \&version },
    'abstract'            => { mandatory => 1, value => \&string  },
    'author'              => { mandatory => 1, list  => { value => \&string } },
    'license'             => { mandatory => 1, value => \&license },
    'generated_by'        => { mandatory => 1, value => \&string  },
  
    'distribution_type'   => { value => \&string  },
    'dynamic_config'      => { value => \&boolean },
  
    'requires'            => $module_map1,
    'recommends'          => $module_map1,
    'build_requires'      => $module_map1,
    'conflicts'           => $module_map2,
  
    'optional_features'   => {
      'map'       => {
          ':key'  => { name => \&string,
              'map'   => { description        => { value => \&string },
                           requires           => $module_map1,
                           recommends         => $module_map1,
                           build_requires     => $module_map1,
                           conflicts          => $module_map2,
                           ':key'  => { name => \&string, value => \&anything },
              }
          }
       }
    },
  
    'provides'    => {
      'map'       => {
        ':key' => { name  => \&module,
          'map' => {
            file    => { mandatory => 1, value => \&file },
            version => { value => \&version },
            ':key'  => { name => \&string, value => \&anything },
          }
        }
      }
    },
  
  
    'no_index'    => $no_index_1_3,
    'private'     => $no_index_1_3,
  
    'keywords'    => { list => { value => \&string } },
  
    'resources'   => {
      'map'       => { license    => { value => \&url },
                       homepage   => { value => \&url },
                       bugtracker => { value => \&url },
                       repository => { value => \&url },
                       ':key'     => { value => \&string, name => \&custom_1 },
      }
    },
  
    # additional user defined key/value pairs
    # note we can only validate the key name, as the structure is user defined
    ':key'        => { name => \&string, value => \&anything },
  },
  
  # v1.2 is misleading, it seems to assume that a number of fields where created
  # within v1.1, when they were created within v1.2. This may have been an
  # original mistake, and that a v1.1 was retro fitted into the timeline, when
  # v1.2 was originally slated as v1.1. But I could be wrong ;)
  '1.2' => {
    'meta-spec'           => {
      mandatory => 1,
      'map' => {
        version => { mandatory => 1, value => \&version},
        url     => { mandatory => 1, value => \&urlspec },
        ':key'  => { name => \&string, value => \&anything },
      },
    },
  
  
    'name'                => { mandatory => 1, value => \&string  },
    'version'             => { mandatory => 1, value => \&version },
    'license'             => { mandatory => 1, value => \&license },
    'generated_by'        => { mandatory => 1, value => \&string  },
    'author'              => { mandatory => 1, list => { value => \&string } },
    'abstract'            => { mandatory => 1, value => \&string  },
  
    'distribution_type'   => { value => \&string  },
    'dynamic_config'      => { value => \&boolean },
  
    'keywords'            => { list => { value => \&string } },
  
    'private'             => $no_index_1_2,
    '$no_index'           => $no_index_1_2,
  
    'requires'            => $module_map1,
    'recommends'          => $module_map1,
    'build_requires'      => $module_map1,
    'conflicts'           => $module_map2,
  
    'optional_features'   => {
      'map'       => {
          ':key'  => { name => \&string,
              'map'   => { description        => { value => \&string },
                           requires           => $module_map1,
                           recommends         => $module_map1,
                           build_requires     => $module_map1,
                           conflicts          => $module_map2,
                           ':key'  => { name => \&string, value => \&anything },
              }
          }
       }
    },
  
    'provides'    => {
      'map'       => {
        ':key' => { name  => \&module,
          'map' => {
            file    => { mandatory => 1, value => \&file },
            version => { value => \&version },
            ':key'  => { name => \&string, value => \&anything },
          }
        }
      }
    },
  
    'resources'   => {
      'map'       => { license    => { value => \&url },
                       homepage   => { value => \&url },
                       bugtracker => { value => \&url },
                       repository => { value => \&url },
                       ':key'     => { value => \&string, name => \&custom_1 },
      }
    },
  
    # additional user defined key/value pairs
    # note we can only validate the key name, as the structure is user defined
    ':key'        => { name => \&string, value => \&anything },
  },
  
  # note that the 1.1 spec only specifies 'version' as mandatory
  '1.1' => {
    'name'                => { value => \&string  },
    'version'             => { mandatory => 1, value => \&version },
    'license'             => { value => \&license },
    'generated_by'        => { value => \&string  },
  
    'license_uri'         => { value => \&url },
    'distribution_type'   => { value => \&string  },
    'dynamic_config'      => { value => \&boolean },
  
    'private'             => $no_index_1_1,
  
    'requires'            => $module_map1,
    'recommends'          => $module_map1,
    'build_requires'      => $module_map1,
    'conflicts'           => $module_map2,
  
    # additional user defined key/value pairs
    # note we can only validate the key name, as the structure is user defined
    ':key'        => { name => \&string, value => \&anything },
  },
  
  # note that the 1.0 spec doesn't specify optional or mandatory fields
  # but we will treat version as mandatory since otherwise META 1.0 is
  # completely arbitrary and pointless
  '1.0' => {
    'name'                => { value => \&string  },
    'version'             => { mandatory => 1, value => \&version },
    'license'             => { value => \&license },
    'generated_by'        => { value => \&string  },
  
    'license_uri'         => { value => \&url },
    'distribution_type'   => { value => \&string  },
    'dynamic_config'      => { value => \&boolean },
  
    'requires'            => $module_map1,
    'recommends'          => $module_map1,
    'build_requires'      => $module_map1,
    'conflicts'           => $module_map2,
  
    # additional user defined key/value pairs
    # note we can only validate the key name, as the structure is user defined
    ':key'        => { name => \&string, value => \&anything },
  },
  );
  
  #--------------------------------------------------------------------------#
  # Code
  #--------------------------------------------------------------------------#
  
  #pod =method new
  #pod
  #pod   my $cmv = CPAN::Meta::Validator->new( $struct )
  #pod
  #pod The constructor must be passed a metadata structure.
  #pod
  #pod =cut
  
  sub new {
    my ($class,$data) = @_;
  
    # create an attributes hash
    my $self = {
      'data'    => $data,
      'spec'    => eval { $data->{'meta-spec'}{'version'} } || "1.0",
      'errors'  => undef,
    };
  
    # create the object
    return bless $self, $class;
  }
  
  #pod =method is_valid
  #pod
  #pod   if ( $cmv->is_valid ) {
  #pod     ...
  #pod   }
  #pod
  #pod Returns a boolean value indicating whether the metadata provided
  #pod is valid.
  #pod
  #pod =cut
  
  sub is_valid {
      my $self = shift;
      my $data = $self->{data};
      my $spec_version = $self->{spec};
      $self->check_map($definitions{$spec_version},$data);
      return ! $self->errors;
  }
  
  #pod =method errors
  #pod
  #pod   warn( join "\n", $cmv->errors );
  #pod
  #pod Returns a list of errors seen during validation.
  #pod
  #pod =cut
  
  sub errors {
      my $self = shift;
      return ()   unless(defined $self->{errors});
      return @{$self->{errors}};
  }
  
  #pod =begin :internals
  #pod
  #pod =head2 Check Methods
  #pod
  #pod =over
  #pod
  #pod =item *
  #pod
  #pod check_map($spec,$data)
  #pod
  #pod Checks whether a map (or hash) part of the data structure conforms to the
  #pod appropriate specification definition.
  #pod
  #pod =item *
  #pod
  #pod check_list($spec,$data)
  #pod
  #pod Checks whether a list (or array) part of the data structure conforms to
  #pod the appropriate specification definition.
  #pod
  #pod =item *
  #pod
  #pod =back
  #pod
  #pod =cut
  
  my $spec_error = "Missing validation action in specification. "
    . "Must be one of 'map', 'list', or 'value'";
  
  sub check_map {
      my ($self,$spec,$data) = @_;
  
      if(ref($spec) ne 'HASH') {
          $self->_error( "Unknown META specification, cannot validate." );
          return;
      }
  
      if(ref($data) ne 'HASH') {
          $self->_error( "Expected a map structure from string or file." );
          return;
      }
  
      for my $key (keys %$spec) {
          next    unless($spec->{$key}->{mandatory});
          next    if(defined $data->{$key});
          push @{$self->{stack}}, $key;
          $self->_error( "Missing mandatory field, '$key'" );
          pop @{$self->{stack}};
      }
  
      for my $key (keys %$data) {
          push @{$self->{stack}}, $key;
          if($spec->{$key}) {
              if($spec->{$key}{value}) {
                  $spec->{$key}{value}->($self,$key,$data->{$key});
              } elsif($spec->{$key}{'map'}) {
                  $self->check_map($spec->{$key}{'map'},$data->{$key});
              } elsif($spec->{$key}{'list'}) {
                  $self->check_list($spec->{$key}{'list'},$data->{$key});
              } else {
                  $self->_error( "$spec_error for '$key'" );
              }
  
          } elsif ($spec->{':key'}) {
              $spec->{':key'}{name}->($self,$key,$key);
              if($spec->{':key'}{value}) {
                  $spec->{':key'}{value}->($self,$key,$data->{$key});
              } elsif($spec->{':key'}{'map'}) {
                  $self->check_map($spec->{':key'}{'map'},$data->{$key});
              } elsif($spec->{':key'}{'list'}) {
                  $self->check_list($spec->{':key'}{'list'},$data->{$key});
              } else {
                  $self->_error( "$spec_error for ':key'" );
              }
  
  
          } else {
              $self->_error( "Unknown key, '$key', found in map structure" );
          }
          pop @{$self->{stack}};
      }
  }
  
  sub check_list {
      my ($self,$spec,$data) = @_;
  
      if(ref($data) ne 'ARRAY') {
          $self->_error( "Expected a list structure" );
          return;
      }
  
      if(defined $spec->{mandatory}) {
          if(!defined $data->[0]) {
              $self->_error( "Missing entries from mandatory list" );
          }
      }
  
      for my $value (@$data) {
          push @{$self->{stack}}, $value || "<undef>";
          if(defined $spec->{value}) {
              $spec->{value}->($self,'list',$value);
          } elsif(defined $spec->{'map'}) {
              $self->check_map($spec->{'map'},$value);
          } elsif(defined $spec->{'list'}) {
              $self->check_list($spec->{'list'},$value);
          } elsif ($spec->{':key'}) {
              $self->check_map($spec,$value);
          } else {
            $self->_error( "$spec_error associated with '$self->{stack}[-2]'" );
          }
          pop @{$self->{stack}};
      }
  }
  
  #pod =head2 Validator Methods
  #pod
  #pod =over
  #pod
  #pod =item *
  #pod
  #pod header($self,$key,$value)
  #pod
  #pod Validates that the header is valid.
  #pod
  #pod Note: No longer used as we now read the data structure, not the file.
  #pod
  #pod =item *
  #pod
  #pod url($self,$key,$value)
  #pod
  #pod Validates that a given value is in an acceptable URL format
  #pod
  #pod =item *
  #pod
  #pod urlspec($self,$key,$value)
  #pod
  #pod Validates that the URL to a META specification is a known one.
  #pod
  #pod =item *
  #pod
  #pod string_or_undef($self,$key,$value)
  #pod
  #pod Validates that the value is either a string or an undef value. Bit of a
  #pod catchall function for parts of the data structure that are completely user
  #pod defined.
  #pod
  #pod =item *
  #pod
  #pod string($self,$key,$value)
  #pod
  #pod Validates that a string exists for the given key.
  #pod
  #pod =item *
  #pod
  #pod file($self,$key,$value)
  #pod
  #pod Validate that a file is passed for the given key. This may be made more
  #pod thorough in the future. For now it acts like \&string.
  #pod
  #pod =item *
  #pod
  #pod exversion($self,$key,$value)
  #pod
  #pod Validates a list of versions, e.g. '<= 5, >=2, ==3, !=4, >1, <6, 0'.
  #pod
  #pod =item *
  #pod
  #pod version($self,$key,$value)
  #pod
  #pod Validates a single version string. Versions of the type '5.8.8' and '0.00_00'
  #pod are both valid. A leading 'v' like 'v1.2.3' is also valid.
  #pod
  #pod =item *
  #pod
  #pod boolean($self,$key,$value)
  #pod
  #pod Validates for a boolean value. Currently these values are '1', '0', 'true',
  #pod 'false', however the latter 2 may be removed.
  #pod
  #pod =item *
  #pod
  #pod license($self,$key,$value)
  #pod
  #pod Validates that a value is given for the license. Returns 1 if an known license
  #pod type, or 2 if a value is given but the license type is not a recommended one.
  #pod
  #pod =item *
  #pod
  #pod custom_1($self,$key,$value)
  #pod
  #pod Validates that the given key is in CamelCase, to indicate a user defined
  #pod keyword and only has characters in the class [-_a-zA-Z].  In version 1.X
  #pod of the spec, this was only explicitly stated for 'resources'.
  #pod
  #pod =item *
  #pod
  #pod custom_2($self,$key,$value)
  #pod
  #pod Validates that the given key begins with 'x_' or 'X_', to indicate a user
  #pod defined keyword and only has characters in the class [-_a-zA-Z]
  #pod
  #pod =item *
  #pod
  #pod identifier($self,$key,$value)
  #pod
  #pod Validates that key is in an acceptable format for the META specification,
  #pod for an identifier, i.e. any that matches the regular expression
  #pod qr/[a-z][a-z_]/i.
  #pod
  #pod =item *
  #pod
  #pod module($self,$key,$value)
  #pod
  #pod Validates that a given key is in an acceptable module name format, e.g.
  #pod 'Test::CPAN::Meta::Version'.
  #pod
  #pod =back
  #pod
  #pod =end :internals
  #pod
  #pod =cut
  
  sub header {
      my ($self,$key,$value) = @_;
      if(defined $value) {
          return 1    if($value && $value =~ /^--- #YAML:1.0/);
      }
      $self->_error( "file does not have a valid YAML header." );
      return 0;
  }
  
  sub release_status {
    my ($self,$key,$value) = @_;
    if(defined $value) {
      my $version = $self->{data}{version} || '';
      if ( $version =~ /_/ ) {
        return 1 if ( $value =~ /\A(?:testing|unstable)\z/ );
        $self->_error( "'$value' for '$key' is invalid for version '$version'" );
      }
      else {
        return 1 if ( $value =~ /\A(?:stable|testing|unstable)\z/ );
        $self->_error( "'$value' for '$key' is invalid" );
      }
    }
    else {
      $self->_error( "'$key' is not defined" );
    }
    return 0;
  }
  
  # _uri_split taken from URI::Split by Gisle Aas, Copyright 2003
  sub _uri_split {
       return $_[0] =~ m,(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?,;
  }
  
  sub url {
      my ($self,$key,$value) = @_;
      if(defined $value) {
        my ($scheme, $auth, $path, $query, $frag) = _uri_split($value);
        unless ( defined $scheme && length $scheme ) {
          $self->_error( "'$value' for '$key' does not have a URL scheme" );
          return 0;
        }
        unless ( defined $auth && length $auth ) {
          $self->_error( "'$value' for '$key' does not have a URL authority" );
          return 0;
        }
        return 1;
      }
      $value ||= '';
      $self->_error( "'$value' for '$key' is not a valid URL." );
      return 0;
  }
  
  sub urlspec {
      my ($self,$key,$value) = @_;
      if(defined $value) {
          return 1    if($value && $known_specs{$self->{spec}} eq $value);
          if($value && $known_urls{$value}) {
              $self->_error( 'META specification URL does not match version' );
              return 0;
          }
      }
      $self->_error( 'Unknown META specification' );
      return 0;
  }
  
  sub anything { return 1 }
  
  sub string {
      my ($self,$key,$value) = @_;
      if(defined $value) {
          return 1    if($value || $value =~ /^0$/);
      }
      $self->_error( "value is an undefined string" );
      return 0;
  }
  
  sub string_or_undef {
      my ($self,$key,$value) = @_;
      return 1    unless(defined $value);
      return 1    if($value || $value =~ /^0$/);
      $self->_error( "No string defined for '$key'" );
      return 0;
  }
  
  sub file {
      my ($self,$key,$value) = @_;
      return 1    if(defined $value);
      $self->_error( "No file defined for '$key'" );
      return 0;
  }
  
  sub exversion {
      my ($self,$key,$value) = @_;
      if(defined $value && ($value || $value =~ /0/)) {
          my $pass = 1;
          for(split(",",$value)) { $self->version($key,$_) or ($pass = 0); }
          return $pass;
      }
      $value = '<undef>'  unless(defined $value);
      $self->_error( "'$value' for '$key' is not a valid version." );
      return 0;
  }
  
  sub version {
      my ($self,$key,$value) = @_;
      if(defined $value) {
          return 0    unless($value || $value =~ /0/);
          return 1    if($value =~ /^\s*((<|<=|>=|>|!=|==)\s*)?v?\d+((\.\d+((_|\.)\d+)?)?)/);
      } else {
          $value = '<undef>';
      }
      $self->_error( "'$value' for '$key' is not a valid version." );
      return 0;
  }
  
  sub boolean {
      my ($self,$key,$value) = @_;
      if(defined $value) {
          return 1    if($value =~ /^(0|1|true|false)$/);
      } else {
          $value = '<undef>';
      }
      $self->_error( "'$value' for '$key' is not a boolean value." );
      return 0;
  }
  
  my %v1_licenses = (
      'perl'         => 'http://dev.perl.org/licenses/',
      'gpl'          => 'http://www.opensource.org/licenses/gpl-license.php',
      'apache'       => 'http://apache.org/licenses/LICENSE-2.0',
      'artistic'     => 'http://opensource.org/licenses/artistic-license.php',
      'artistic_2'   => 'http://opensource.org/licenses/artistic-license-2.0.php',
      'lgpl'         => 'http://www.opensource.org/licenses/lgpl-license.php',
      'bsd'          => 'http://www.opensource.org/licenses/bsd-license.php',
      'gpl'          => 'http://www.opensource.org/licenses/gpl-license.php',
      'mit'          => 'http://opensource.org/licenses/mit-license.php',
      'mozilla'      => 'http://opensource.org/licenses/mozilla1.1.php',
      'open_source'  => undef,
      'unrestricted' => undef,
      'restrictive'  => undef,
      'unknown'      => undef,
  );
  
  my %v2_licenses = map { $_ => 1 } qw(
    agpl_3
    apache_1_1
    apache_2_0
    artistic_1
    artistic_2
    bsd
    freebsd
    gfdl_1_2
    gfdl_1_3
    gpl_1
    gpl_2
    gpl_3
    lgpl_2_1
    lgpl_3_0
    mit
    mozilla_1_0
    mozilla_1_1
    openssl
    perl_5
    qpl_1_0
    ssleay
    sun
    zlib
    open_source
    restricted
    unrestricted
    unknown
  );
  
  sub license {
      my ($self,$key,$value) = @_;
      my $licenses = $self->{spec} < 2 ? \%v1_licenses : \%v2_licenses;
      if(defined $value) {
          return 1    if($value && exists $licenses->{$value});
      } else {
          $value = '<undef>';
      }
      $self->_error( "License '$value' is invalid" );
      return 0;
  }
  
  sub custom_1 {
      my ($self,$key) = @_;
      if(defined $key) {
          # a valid user defined key should be alphabetic
          # and contain at least one capital case letter.
          return 1    if($key && $key =~ /^[_a-z]+$/i && $key =~ /[A-Z]/);
      } else {
          $key = '<undef>';
      }
      $self->_error( "Custom resource '$key' must be in CamelCase." );
      return 0;
  }
  
  sub custom_2 {
      my ($self,$key) = @_;
      if(defined $key) {
          return 1    if($key && $key =~ /^x_/i);  # user defined
      } else {
          $key = '<undef>';
      }
      $self->_error( "Custom key '$key' must begin with 'x_' or 'X_'." );
      return 0;
  }
  
  sub identifier {
      my ($self,$key) = @_;
      if(defined $key) {
          return 1    if($key && $key =~ /^([a-z][_a-z]+)$/i);    # spec 2.0 defined
      } else {
          $key = '<undef>';
      }
      $self->_error( "Key '$key' is not a legal identifier." );
      return 0;
  }
  
  sub module {
      my ($self,$key) = @_;
      if(defined $key) {
          return 1    if($key && $key =~ /^[A-Za-z0-9_]+(::[A-Za-z0-9_]+)*$/);
      } else {
          $key = '<undef>';
      }
      $self->_error( "Key '$key' is not a legal module name." );
      return 0;
  }
  
  my @valid_phases = qw/ configure build test runtime develop /;
  sub phase {
      my ($self,$key) = @_;
      if(defined $key) {
          return 1 if( length $key && grep { $key eq $_ } @valid_phases );
          return 1 if $key =~ /x_/i;
      } else {
          $key = '<undef>';
      }
      $self->_error( "Key '$key' is not a legal phase." );
      return 0;
  }
  
  my @valid_relations = qw/ requires recommends suggests conflicts /;
  sub relation {
      my ($self,$key) = @_;
      if(defined $key) {
          return 1 if( length $key && grep { $key eq $_ } @valid_relations );
          return 1 if $key =~ /x_/i;
      } else {
          $key = '<undef>';
      }
      $self->_error( "Key '$key' is not a legal prereq relationship." );
      return 0;
  }
  
  sub _error {
      my $self = shift;
      my $mess = shift;
  
      $mess .= ' ('.join(' -> ',@{$self->{stack}}).')'  if($self->{stack});
      $mess .= " [Validation: $self->{spec}]";
  
      push @{$self->{errors}}, $mess;
  }
  
  1;
  
  # ABSTRACT: validate CPAN distribution metadata structures
  
  =pod
  
  =encoding UTF-8
  
  =head1 NAME
  
  CPAN::Meta::Validator - validate CPAN distribution metadata structures
  
  =head1 VERSION
  
  version 2.150005
  
  =head1 SYNOPSIS
  
    my $struct = decode_json_file('META.json');
  
    my $cmv = CPAN::Meta::Validator->new( $struct );
  
    unless ( $cmv->is_valid ) {
      my $msg = "Invalid META structure.  Errors found:\n";
      $msg .= join( "\n", $cmv->errors );
      die $msg;
    }
  
  =head1 DESCRIPTION
  
  This module validates a CPAN Meta structure against the version of the
  the specification claimed in the C<meta-spec> field of the structure.
  
  =head1 METHODS
  
  =head2 new
  
    my $cmv = CPAN::Meta::Validator->new( $struct )
  
  The constructor must be passed a metadata structure.
  
  =head2 is_valid
  
    if ( $cmv->is_valid ) {
      ...
    }
  
  Returns a boolean value indicating whether the metadata provided
  is valid.
  
  =head2 errors
  
    warn( join "\n", $cmv->errors );
  
  Returns a list of errors seen during validation.
  
  =begin :internals
  
  =head2 Check Methods
  
  =over
  
  =item *
  
  check_map($spec,$data)
  
  Checks whether a map (or hash) part of the data structure conforms to the
  appropriate specification definition.
  
  =item *
  
  check_list($spec,$data)
  
  Checks whether a list (or array) part of the data structure conforms to
  the appropriate specification definition.
  
  =item *
  
  =back
  
  =head2 Validator Methods
  
  =over
  
  =item *
  
  header($self,$key,$value)
  
  Validates that the header is valid.
  
  Note: No longer used as we now read the data structure, not the file.
  
  =item *
  
  url($self,$key,$value)
  
  Validates that a given value is in an acceptable URL format
  
  =item *
  
  urlspec($self,$key,$value)
  
  Validates that the URL to a META specification is a known one.
  
  =item *
  
  string_or_undef($self,$key,$value)
  
  Validates that the value is either a string or an undef value. Bit of a
  catchall function for parts of the data structure that are completely user
  defined.
  
  =item *
  
  string($self,$key,$value)
  
  Validates that a string exists for the given key.
  
  =item *
  
  file($self,$key,$value)
  
  Validate that a file is passed for the given key. This may be made more
  thorough in the future. For now it acts like \&string.
  
  =item *
  
  exversion($self,$key,$value)
  
  Validates a list of versions, e.g. '<= 5, >=2, ==3, !=4, >1, <6, 0'.
  
  =item *
  
  version($self,$key,$value)
  
  Validates a single version string. Versions of the type '5.8.8' and '0.00_00'
  are both valid. A leading 'v' like 'v1.2.3' is also valid.
  
  =item *
  
  boolean($self,$key,$value)
  
  Validates for a boolean value. Currently these values are '1', '0', 'true',
  'false', however the latter 2 may be removed.
  
  =item *
  
  license($self,$key,$value)
  
  Validates that a value is given for the license. Returns 1 if an known license
  type, or 2 if a value is given but the license type is not a recommended one.
  
  =item *
  
  custom_1($self,$key,$value)
  
  Validates that the given key is in CamelCase, to indicate a user defined
  keyword and only has characters in the class [-_a-zA-Z].  In version 1.X
  of the spec, this was only explicitly stated for 'resources'.
  
  =item *
  
  custom_2($self,$key,$value)
  
  Validates that the given key begins with 'x_' or 'X_', to indicate a user
  defined keyword and only has characters in the class [-_a-zA-Z]
  
  =item *
  
  identifier($self,$key,$value)
  
  Validates that key is in an acceptable format for the META specification,
  for an identifier, i.e. any that matches the regular expression
  qr/[a-z][a-z_]/i.
  
  =item *
  
  module($self,$key,$value)
  
  Validates that a given key is in an acceptable module name format, e.g.
  'Test::CPAN::Meta::Version'.
  
  =back
  
  =end :internals
  
  =for Pod::Coverage anything boolean check_list custom_1 custom_2 exversion file
  identifier license module phase relation release_status string string_or_undef
  url urlspec version header check_map
  
  =head1 BUGS
  
  Please report any bugs or feature using the CPAN Request Tracker.
  Bugs can be submitted through the web interface at
  L<http://rt.cpan.org/Dist/Display.html?Queue=CPAN-Meta>
  
  When submitting a bug or request, please include a test-file or a patch to an
  existing test-file that illustrates the bug or desired feature.
  
  =head1 AUTHORS
  
  =over 4
  
  =item *
  
  David Golden <dagolden@cpan.org>
  
  =item *
  
  Ricardo Signes <rjbs@cpan.org>
  
  =back
  
  =head1 COPYRIGHT AND LICENSE
  
  This software is copyright (c) 2010 by David Golden and Ricardo Signes.
  
  This is free software; you can redistribute it and/or modify it under
  the same terms as the Perl 5 programming language system itself.
  
  =cut
  
  __END__
  
  
  # vim: ts=2 sts=2 sw=2 et :
CPAN_META_VALIDATOR

$fatpacked{"Carton.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CARTON';
  package Carton;
  use strict;
  use 5.008_005;
  use version; our $VERSION = version->declare("v1.0.12");
  
  1;
  __END__
  
  =head1 NAME
  
  Carton - Perl module dependency manager (aka Bundler for Perl)
  
  =head1 SYNOPSIS
  
    # On your development environment
    > cat cpanfile
    requires 'Plack', '0.9980';
    requires 'Starman', '0.2000';
  
    > carton install
    > git add cpanfile cpanfile.snapshot
    > git commit -m "add Plack and Starman"
  
    # Other developer's machine, or on a deployment box
    > carton install
    > carton exec starman -p 8080 myapp.psgi
  
  =head1 AVAILABILITY
  
  Carton only works with perl installation with the complete set of core
  modules. If you use perl installed by a vendor package with modules
  stripped from core, Carton is not expected to work correctly.
  
  Also, Carton requires you to run your command/application with
  C<carton exec> command, which means it's difficult or impossible to
  run in an embedded perl use case such as mod_perl.
  
  =head1 DESCRIPTION
  
  carton is a command line tool to track the Perl module dependencies
  for your Perl application. Dependencies are declared using L<cpanfile>
  format, and the managed dependencies are tracked in a
  I<cpanfile.snapshot> file, which is meant to be version controlled,
  and the snapshot file allows other developers of your application will
  have the exact same versions of the modules.
  
  For C<cpanfile> syntax, see L<cpanfile> documentation.
  
  =head1 TUTORIAL
  
  =head2 Initializing the environment
  
  carton will use the I<local> directory to install modules into. You're
  recommended to exclude these directories from the version control
  system.
  
    > echo local/ >> .gitignore
    > git add cpanfile cpanfile.snapshot
    > git commit -m "Start using carton"
  
  =head2 Tracking the dependencies
  
  You can manage the dependencies of your application via C<cpanfile>.
  
    # cpanfile
    requires 'Plack', '0.9980';
    requires 'Starman', '0.2000';
  
  And then you can install these dependencies via:
  
    > carton install
  
  The modules are installed into your I<local> directory, and the
  dependencies tree and version information are analyzed and saved into
  I<cpanfile.snapshot> in your directory.
  
  Make sure you add I<cpanfile> and I<cpanfile.snapshot> to your version
  controlled repository and commit changes as you update
  dependencies. This will ensure that other developers on your app, as
  well as your deployment environment, use exactly the same versions of
  the modules you just installed.
  
    > git add cpanfile cpanfile.snapshot
    > git commit -m "Added Plack and Starman"
  
  =head2 Deploying your application
  
  Once you've done installing all the dependencies, you can push your
  application directory to a remote machine (excluding I<local> and
  I<.carton>) and run the following command:
  
    > carton install --deployment
  
  This will look at the I<cpanfile.snapshot> and install the exact same
  versions of the dependencies into I<local>, and now your application
  is ready to run.
  
  The C<--deployment> flag makes sure that carton will only install
  modules and versions available in your snapshot, and won't fallback to
  query for CPAN Meta DB for missing modules.
  
  =head2 Bundling modules
  
  carton can bundle all the tarballs for your dependencies into a
  directory so that you can even install dependencies that are not
  available on CPAN, such as internal distribution aka DarkPAN.
  
    > carton bundle
  
  will bundle these tarballs into I<vendor/cache> directory, and
  
    > carton install --cached
  
  will install modules using this local cache. Combined with
  C<--deployment> option, you can avoid querying for a database like
  CPAN Meta DB or downloading files from CPAN mirrors upon deployment
  time.
  
  =head1 PERL VERSIONS
  
  When you take a snapshot in one perl version and deploy on another
  (different) version, you might have troubles with core modules.
  
  The simplest solution, which might not work for everybody, is to use
  the same version of perl in the development and deployment.
  
  To enforce that, you're recommended to use L<plenv> and
  C<.perl-version> to lock perl versions in development.
  
  You can also specify the minimum perl required in C<cpanfile>:
  
    requires 'perl', '5.16.3';
  
  and carton (and cpanm) will give you errors when deployed on hosts
  with perl lower than the specified version.
  
  =head1 COMMUNITY
  
  =over 4
  
  =item L<https://github.com/miyagawa/carton>
  
  Code repository, Wiki and Issue Tracker
  
  =item L<irc://irc.perl.org/#carton>
  
  IRC chat room
  
  =back
  
  =head1 AUTHOR
  
  Tatsuhiko Miyagawa
  
  =head1 COPYRIGHT
  
  Tatsuhiko Miyagawa 2011-
  
  =head1 LICENSE
  
  This software is licensed under the same terms as Perl itself.
  
  =head1 SEE ALSO
  
  L<cpanm>
  
  L<cpanfile>
  
  L<Bundler|http://gembundler.com/>
  
  L<pip|http://pypi.python.org/pypi/pip>
  
  L<npm|http://npmjs.org/>
  
  L<perlrocks|https://github.com/gugod/perlrocks>
  
  L<only>
  
  =cut
CARTON

$fatpacked{"Carton/Builder.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CARTON_BUILDER';
  package Carton::Builder;
  use Moo;
  use warnings NONFATAL => 'all';
  no warnings 'once';
  
  has mirror  => (is => 'rw');
  has index   => (is => 'rw');
  has cascade => (is => 'rw', default => sub { 1 });
  has without => (is => 'rw', default => sub { [] });
  has cpanfile => (is => 'rw');
  has fatscript => (is => 'lazy');
  
  sub effective_mirrors {
      my $self = shift;
  
      # push default CPAN mirror always, as a fallback
      # TODO don't pass fallback if --cached is set?
  
      my @mirrors = ($self->mirror);
      push @mirrors, Carton::Mirror->default if $self->custom_mirror;
      push @mirrors, Carton::Mirror->new('http://backpan.perl.org/');
  
      @mirrors;
  }
  
  sub custom_mirror {
      my $self = shift;
      ! $self->mirror->is_default;
  }
  
  sub bundle {
      my($self, $path, $cache_path, $snapshot) = @_;
  
      for my $dist ($snapshot->distributions) {
          my $source = $path->child("cache/authors/id/" . $dist->pathname);
          my $target = $cache_path->child("authors/id/" . $dist->pathname);
  
          if ($source->exists) {
              warn "Copying ", $dist->pathname, "\n";
              $target->parent->mkpath;
              $source->copy($target) or warn "$target: $!";
          } else {
              warn "Couldn't find @{[ $dist->pathname ]}\n";
          }
      }
  }
  
  sub install {
      my($self, $path) = @_;
  
      $self->run_cpanm(
          "-L", $path,
          (map { ("--mirror", $_->url) } $self->effective_mirrors),
          ( $self->index ? ("--mirror-index", $self->index) : () ),
          ( $self->cascade ? "--cascade-search" : () ),
          ( $self->custom_mirror ? "--mirror-only" : () ),
          "--save-dists", "$path/cache",
          $self->groups,
          "--cpanfile", $self->cpanfile,
          "--installdeps", $self->cpanfile->dirname,
      ) or die "Installing modules failed\n";
  }
  
  sub groups {
      my $self = shift;
  
      # TODO support --without test (don't need test on deployment)
      my @options = ('--with-all-features', '--with-develop');
  
      for my $group (@{$self->without}) {
          push @options, '--without-develop' if $group eq 'develop';
          push @options, "--without-feature=$group";
      }
  
      return @options;
  }
  
  sub update {
      my($self, $path, @modules) = @_;
  
      $self->run_cpanm(
          "-L", $path,
          (map { ("--mirror", $_->url) } $self->effective_mirrors),
          ( $self->custom_mirror ? "--mirror-only" : () ),
          "--save-dists", "$path/cache",
          @modules
      ) or die "Updating modules failed\n";
  }
  
  sub _build_fatscript {
      my $self = shift;
  
      my $fatscript;
      if ($Carton::Fatpacked) {
          require Module::Reader;
          my $content = Module::Reader::module_content('App::cpanminus::fatscript')
              or die "Can't locate App::cpanminus::fatscript";
          $fatscript = Path::Tiny->tempfile;
          $fatscript->spew($content);
      } else {
          require Module::Metadata;
          $fatscript = Module::Metadata->find_module_by_name("App::cpanminus::fatscript")
              or die "Can't locate App::cpanminus::fatscript";
      }
  
      return $fatscript;
  }
  
  sub run_cpanm {
      my($self, @args) = @_;
      local $ENV{PERL_CPANM_OPT};
      !system $^X, $self->fatscript, "--quiet", "--notest", @args;
  }
  
  1;
CARTON_BUILDER

$fatpacked{"Carton/CLI.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CARTON_CLI';
  package Carton::CLI;
  use Moo;
  use warnings NONFATAL => 'all';
  
  use Config;
  use Getopt::Long;
  use Path::Tiny;
  use Try::Tiny;
  use Module::CoreList;
  use Scalar::Util qw(blessed);
  
  use Carton;
  use Carton::Builder;
  use Carton::Mirror;
  use Carton::Snapshot;
  use Carton::Util;
  use Carton::Environment;
  use Carton::Error;
  
  use constant { SUCCESS => 0, INFO => 1, WARN => 2, ERROR => 3 };
  
  our $UseSystem = 0; # 1 for unit testing
  
  has verbose => (is => 'rw');
  has carton  => (is => 'lazy');
  has mirror  => (is => 'rw', builder => 1,
                  coerce => sub { Carton::Mirror->new($_[0]) });
  
  sub _build_mirror {
      my $self = shift;
      $ENV{PERL_CARTON_MIRROR} || $Carton::Mirror::DefaultMirror;
  }
  
  sub run {
      my($self, @args) = @_;
  
      my @commands;
      my $p = Getopt::Long::Parser->new(
          config => [ "no_ignore_case", "pass_through" ],
      );
      $p->getoptionsfromarray(
          \@args,
          "h|help"    => sub { unshift @commands, 'help' },
          "v|version" => sub { unshift @commands, 'version' },
          "verbose!"  => sub { $self->verbose($_[1]) },
      );
  
      push @commands, @args;
  
      my $cmd = shift @commands || 'install';
  
      my $code = try {
          my $call = $self->can("cmd_$cmd")
              or Carton::Error::CommandNotFound->throw(error => "Could not find command '$cmd'");
          $self->$call(@commands);
          return 0;
      } catch {
          die $_ unless blessed $_ && $_->can('rethrow');
  
          if ($_->isa('Carton::Error::CommandExit')) {
              return $_->code || 255;
          } elsif ($_->isa('Carton::Error::CommandNotFound')) {
              warn $_->error, "\n\n";
              $self->cmd_usage;
              return 255;
          } elsif ($_->isa('Carton::Error')) {
              warn $_->error, "\n";
              return 255;
          }
      };
  
      return $code;
  }
  
  sub commands {
      my $self = shift;
  
      no strict 'refs';
      map { s/^cmd_//; $_ }
          grep { /^cmd_.*/ && $self->can($_) } sort keys %{__PACKAGE__."::"};
  }
  
  sub cmd_usage {
      my $self = shift;
      $self->print(<<HELP);
  Usage: carton <command>
  
  where <command> is one of:
    @{[ join ", ", $self->commands ]}
  
  Run carton -h <command> for help.
  HELP
  }
  
  sub parse_options {
      my($self, $args, @spec) = @_;
      my $p = Getopt::Long::Parser->new(
          config => [ "no_auto_abbrev", "no_ignore_case" ],
      );
      $p->getoptionsfromarray($args, @spec);
  }
  
  sub parse_options_pass_through {
      my($self, $args, @spec) = @_;
  
      my $p = Getopt::Long::Parser->new(
          config => [ "no_auto_abbrev", "no_ignore_case", "pass_through" ],
      );
      $p->getoptionsfromarray($args, @spec);
  
      # with pass_through keeps -- in args
      shift @$args if $args->[0] && $args->[0] eq '--';
  }
  
  sub printf {
      my $self = shift;
      my $type = pop;
      my($temp, @args) = @_;
      $self->print(sprintf($temp, @args), $type);
  }
  
  sub print {
      my($self, $msg, $type) = @_;
      my $fh = $type && $type >= WARN ? *STDERR : *STDOUT;
      print {$fh} $msg;
  }
  
  sub error {
      my($self, $msg) = @_;
      $self->print($msg, ERROR);
      Carton::Error::CommandExit->throw;
  }
  
  sub cmd_help {
      my $self = shift;
      my $module = $_[0] ? ("Carton::Doc::" . ucfirst $_[0]) : "Carton.pm";
      system "perldoc", $module;
  }
  
  sub cmd_version {
      my $self = shift;
      $self->print("carton $Carton::VERSION\n");
  }
  
  sub cmd_bundle {
      my($self, @args) = @_;
  
      my $fatpack = 1;
      $self->parse_options(
          \@args,
          "fatpack!" => \$fatpack,
      );
  
      my $env = Carton::Environment->build;
      $env->snapshot->load;
  
      $self->print("Bundling modules using @{[$env->cpanfile]}\n");
  
      my $builder = Carton::Builder->new(
          mirror => $self->mirror,
          cpanfile => $env->cpanfile,
      );
      $builder->bundle($env->install_path, $env->vendor_cache, $env->snapshot);
  
      if ($fatpack) {
          require Carton::Packer;
          Carton::Packer->new->fatpack_carton($env->vendor_bin);
      }
  
      $self->printf("Complete! Modules were bundled into %s\n", $env->vendor_cache, SUCCESS);
  }
  
  sub cmd_install {
      my($self, @args) = @_;
  
      my($install_path, $cpanfile_path, @without);
  
      $self->parse_options(
          \@args,
          "p|path=s"    => \$install_path,
          "cpanfile=s"  => \$cpanfile_path,
          "without=s"   => sub { push @without, split /,/, $_[1] },
          "deployment!" => \my $deployment,
          "cached!"     => \my $cached,
      );
  
      my $env = Carton::Environment->build($cpanfile_path, $install_path);
      $env->snapshot->load_if_exists;
  
      if ($deployment && !$env->snapshot->loaded) {
          $self->error("--deployment requires cpanfile.snapshot: Run `carton install` and make sure cpanfile.snapshot is checked into your version control.\n");
      }
  
      my $builder = Carton::Builder->new(
          cascade => 1,
          mirror  => $self->mirror,
          without => \@without,
          cpanfile => $env->cpanfile,
      );
  
      # TODO: --without with no .lock won't fetch the groups, resulting in insufficient requirements
  
      if ($deployment) {
          $self->print("Installing modules using @{[$env->cpanfile]} (deployment mode)\n");
          $builder->cascade(0);
      } else {
          $self->print("Installing modules using @{[$env->cpanfile]}\n");
      }
  
      # TODO merge CPANfile git to mirror even if lock doesn't exist
      if ($env->snapshot->loaded) {
          my $index_file = $env->install_path->child("cache/modules/02packages.details.txt");
             $index_file->parent->mkpath;
  
          $env->snapshot->write_index($index_file);
          $builder->index($index_file);
      }
  
      if ($cached) {
          $builder->mirror(Carton::Mirror->new($env->vendor_cache));
      }
  
      $builder->install($env->install_path);
  
      unless ($deployment) {
          $env->cpanfile->load;
          $env->snapshot->find_installs($env->install_path, $env->cpanfile->requirements);
          $env->snapshot->save;
      }
  
      $self->print("Complete! Modules were installed into @{[$env->install_path]}\n", SUCCESS);
  }
  
  sub cmd_show {
      my($self, @args) = @_;
  
      my $env = Carton::Environment->build;
      $env->snapshot->load;
  
      for my $module (@args) {
          my $dist = $env->snapshot->find($module)
              or $self->error("Couldn't locate $module in cpanfile.snapshot\n");
          $self->print( $dist->name . "\n" );
      }
  }
  
  sub cmd_list {
      my($self, @args) = @_;
  
      my $format = 'name';
  
      $self->parse_options(
          \@args,
          "distfile" => sub { $format = 'distfile' },
      );
  
      my $env = Carton::Environment->build;
      $env->snapshot->load;
  
      for my $dist ($env->snapshot->distributions) {
          $self->print($dist->$format . "\n");
      }
  }
  
  sub cmd_tree {
      my($self, @args) = @_;
  
      my $env = Carton::Environment->build;
      $env->snapshot->load;
      $env->cpanfile->load;
  
      my %seen;
      my $dumper = sub {
          my($dependency, $reqs, $level) = @_;
          return if $level == 0;
          return Carton::Tree::STOP if $dependency->dist->is_core;
          return Carton::Tree::STOP if $seen{$dependency->distname}++;
          $self->printf( "%s%s (%s)\n", " " x ($level - 1), $dependency->module, $dependency->distname, INFO );
      };
  
      $env->tree->walk_down($dumper);
  }
  
  sub cmd_check {
      my($self, @args) = @_;
  
      my $cpanfile_path;
      $self->parse_options(
          \@args,
          "cpanfile=s"  => \$cpanfile_path,
      );
  
      my $env = Carton::Environment->build($cpanfile_path);
      $env->snapshot->load;
      $env->cpanfile->load;
  
      # TODO remove snapshot
      # TODO pass git spec to Requirements?
      my $merged_reqs = $env->tree->merged_requirements;
  
      my @missing;
      for my $module ($merged_reqs->required_modules) {
          my $install = $env->snapshot->find_or_core($module);
          if ($install) {
              unless ($merged_reqs->accepts_module($module => $install->version_for($module))) {
                  push @missing, [ $module, 1, $install->version_for($module) ];
              }
          } else {
              push @missing, [ $module, 0 ];
          }
      }
  
      if (@missing) {
          $self->print("Following dependencies are not satisfied.\n", INFO);
          for my $missing (@missing) {
              my($module, $unsatisfied, $version) = @$missing;
              if ($unsatisfied) {
                  $self->printf("  %s has version %s. Needs %s\n",
                                $module, $version, $merged_reqs->requirements_for_module($module), INFO);
              } else {
                  $self->printf("  %s is not installed. Needs %s\n",
                                $module, $merged_reqs->requirements_for_module($module), INFO);
              }
          }
          $self->printf("Run `carton install` to install them.\n", INFO);
          Carton::Error::CommandExit->throw;
      } else {
          $self->print("cpanfile's dependencies are satisfied.\n", INFO);
      }
  }
  
  sub cmd_update {
      my($self, @args) = @_;
  
      my $env = Carton::Environment->build;
      $env->cpanfile->load;
  
  
      my $cpanfile = Module::CPANfile->load($env->cpanfile);
      @args = grep { $_ ne 'perl' } $env->cpanfile->required_modules unless @args;
  
      $env->snapshot->load;
  
      my @modules;
      for my $module (@args) {
          my $dist = $env->snapshot->find_or_core($module)
              or $self->error("Could not find module $module.\n");
          next if $dist->is_core;
          push @modules, "$module~" . $env->cpanfile->requirements_for_module($module);
      }
  
      my $builder = Carton::Builder->new(
          mirror => $self->mirror,
          cpanfile => $env->cpanfile,
      );
      $builder->update($env->install_path, @modules);
  
      $env->snapshot->find_installs($env->install_path, $env->cpanfile->requirements);
      $env->snapshot->save;
  }
  
  sub cmd_exec {
      my($self, @args) = @_;
  
      my $env = Carton::Environment->build;
      $env->snapshot->load;
  
      # allows -Ilib
      @args = map { /^(-[I])(.+)/ ? ($1,$2) : $_ } @args;
  
      while (@args) {
          if ($args[0] eq '-I') {
              warn "exec -Ilib is deprecated. You might want to run: carton exec perl -Ilib ...\n";
              splice(@args, 0, 2);
          } else {
              last;
          }
      }
  
      $self->parse_options_pass_through(\@args); # to handle --
  
      unless (@args) {
          $self->error("carton exec needs a command to run.\n");
      }
  
      # PERL5LIB takes care of arch
      my $path = $env->install_path;
      local $ENV{PERL5LIB} = "$path/lib/perl5";
      local $ENV{PATH} = "$path/bin:$ENV{PATH}";
  
      $UseSystem ? system(@args) : exec(@args);
  }
  
  1;
CARTON_CLI

$fatpacked{"Carton/CPANfile.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CARTON_CPANFILE';
  package Carton::CPANfile;
  use Moo;
  use warnings NONFATAL => 'all';
  use Path::Tiny ();
  use Module::CPANfile;
  
  use overload q{""} => sub { $_[0]->stringify }, fallback => 1;
  
  has path => (is => 'rw', coerce => sub { Path::Tiny->new($_[0]) }, handles => [ qw(stringify dirname) ]);
  has _cpanfile => (is => 'rw', handles => [ qw(prereqs) ]);
  has requirements => (is => 'rw', lazy => 1, builder => 1, handles => [ qw(required_modules requirements_for_module) ]);
  
  sub load {
      my $self = shift;
      $self->_cpanfile( Module::CPANfile->load($self->path) );
  }
  
  sub _build_requirements {
      my $self = shift;
      my $reqs = CPAN::Meta::Requirements->new;
      $reqs->add_requirements($self->prereqs->requirements_for($_, 'requires'))
          for qw( configure build runtime test develop );
      $reqs->clear_requirement('perl');
      $reqs;
  }
  
  1;
CARTON_CPANFILE

$fatpacked{"Carton/Dependency.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CARTON_DEPENDENCY';
  package Carton::Dependency;
  use Moo;
  use warnings NONFATAL => 'all';
  
  has module => (is => 'rw');
  has requirement => (is => 'rw');
  has dist => (is => 'rw', handles => [ qw(requirements) ]);
  
  sub distname {
      my $self = shift;
      $self->dist->name;
  }
  
  sub version {
      my $self = shift;
      $self->dist->version_for($self->module);
  }
  
  1;
CARTON_DEPENDENCY

$fatpacked{"Carton/Dist.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CARTON_DIST';
  package Carton::Dist;
  use Moo;
  use warnings NONFATAL => 'all';
  use CPAN::Meta;
  
  has name     => (is => 'ro');
  has pathname => (is => 'rw');
  has provides => (is => 'rw', default => sub { +{} });
  has requirements => (is => 'rw', lazy => 1, builder => 1,
                       handles => [ qw(add_string_requirement required_modules requirements_for_module) ]);
  
  sub is_core { 0 }
  
  sub distfile {
      my $self = shift;
      $self->pathname;
  }
  
  sub _build_requirements {
      CPAN::Meta::Requirements->new;
  }
  
  sub provides_module {
      my($self, $module) = @_;
      exists $self->provides->{$module};
  }
  
  sub version_for {
      my($self, $module) = @_;
      $self->provides->{$module}{version};
  }
  
  1;
CARTON_DIST

$fatpacked{"Carton/Dist/Core.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CARTON_DIST_CORE';
  package Carton::Dist::Core;
  use Moo;
  use warnings NONFATAL => 'all';
  extends 'Carton::Dist';
  
  has module_version => (is => 'ro');
  
  sub BUILDARGS {
      my($class, %args) = @_;
  
      # TODO represent dual-life
      $args{name} =~ s/::/-/g;
  
      \%args;
  }
  
  sub is_core { 1 }
  
  sub version_for {
      my($self, $module) = @_;
      $self->module_version;
  }
  
  1;
CARTON_DIST_CORE

$fatpacked{"Carton/Environment.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CARTON_ENVIRONMENT';
  package Carton::Environment;
  use Moo;
  use warnings NONFATAL => 'all';
  
  use Carton::CPANfile;
  use Carton::Snapshot;
  use Carton::Error;
  use Carton::Tree;
  use Path::Tiny;
  
  has cpanfile => (is => 'rw');
  has snapshot => (is => 'lazy');
  has install_path => (is => 'rw', lazy => 1, builder => 1, coerce => sub { Path::Tiny->new($_[0])->absolute });
  has vendor_cache  => (is => 'lazy');
  has tree => (is => 'rw', lazy => 1, builder => 1);
  
  sub _build_snapshot {
      my $self = shift;
      Carton::Snapshot->new(path => $self->cpanfile->stringify . ".snapshot");
  }
  
  sub _build_install_path {
      my $self = shift;
      if ($ENV{PERL_CARTON_PATH}) {
          return $ENV{PERL_CARTON_PATH};
      } else {
          return $self->cpanfile->dirname . "/local";
      }
  }
  
  sub _build_vendor_cache {
      my $self = shift;
      Path::Tiny->new($self->install_path->dirname . "/vendor/cache");
  }
  
  sub _build_tree {
      my $self = shift;
      Carton::Tree->new(cpanfile => $self->cpanfile, snapshot => $self->snapshot);
  }
  
  sub vendor_bin {
      my $self = shift;
      $self->vendor_cache->parent->child('bin');
  }
  
  sub build_with {
      my($class, $cpanfile) = @_;
  
      $cpanfile = Path::Tiny->new($cpanfile)->absolute;
      if ($cpanfile->is_file) {
          return $class->new(cpanfile => Carton::CPANfile->new(path => $cpanfile));
      } else {
          Carton::Error::CPANfileNotFound->throw(error => "Can't locate cpanfile: $cpanfile");
      }
  }
  
  sub build {
      my($class, $cpanfile_path, $install_path) = @_;
  
      my $self = $class->new;
  
      $cpanfile_path &&= Path::Tiny->new($cpanfile_path)->absolute;
  
      my $cpanfile = $self->locate_cpanfile($cpanfile_path || $ENV{PERL_CARTON_CPANFILE});
      if ($cpanfile && $cpanfile->is_file) {
          $self->cpanfile( Carton::CPANfile->new(path => $cpanfile) );
      } else {
          Carton::Error::CPANfileNotFound->throw(error => "Can't locate cpanfile: (@{[ $cpanfile_path || 'cpanfile' ]})");
      }
  
      $self->install_path($install_path) if $install_path;
  
      $self;
  }
  
  sub locate_cpanfile {
      my($self, $path) = @_;
  
      if ($path) {
          return Path::Tiny->new($path)->absolute;
      }
  
      my $current  = Path::Tiny->cwd;
      my $previous = '';
  
      until ($current eq '/' or $current eq $previous) {
          # TODO support PERL_CARTON_CPANFILE
          my $try = $current->child('cpanfile');
          if ($try->is_file) {
              return $try->absolute;
          }
  
          ($previous, $current) = ($current, $current->parent);
      }
  
      return;
  }
  
  1;
  
CARTON_ENVIRONMENT

$fatpacked{"Carton/Error.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CARTON_ERROR';
  package Carton::Error;
  use strict;
  use Exception::Class (
      'Carton::Error',
      'Carton::Error::CommandNotFound' => { isa => 'Carton::Error' },
      'Carton::Error::CommandExit' => { isa => 'Carton::Error', fields => [ 'code' ] },
      'Carton::Error::CPANfileNotFound' => { isa => 'Carton::Error' },
      'Carton::Error::SnapshotParseError' => { isa => 'Carton::Error', fields => [ 'path' ] },
      'Carton::Error::SnapshotNotFound' => { isa => 'Carton::Error', fields => [ 'path' ] },
  );
  
  1;
CARTON_ERROR

$fatpacked{"Carton/Index.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CARTON_INDEX';
  package Carton::Index;
  use Moo;
  use warnings NONFATAL => 'all';
  
  has _packages => (is => 'rw', default => sub { +{} });
  
  sub add_package {
      my($self, $package) = @_;
      $self->_packages->{$package->name} = $package; # XXX ||=
  }
  
  sub count {
      my $self = shift;
      scalar keys %{$self->_packages};
  }
  
  sub packages {
      my $self = shift;
      sort { $a->name cmp $b->name } values %{$self->_packages};
  }
  
  sub write {
      my($self, $fh) = @_;
  
      print $fh <<EOF;
  File:         02packages.details.txt
  URL:          http://www.perl.com/CPAN/modules/02packages.details.txt
  Description:  Package names found in cpanfile.snapshot
  Columns:      package name, version, path
  Intended-For: Automated fetch routines, namespace documentation.
  Written-By:   Carton $Carton::VERSION
  Line-Count:   @{[ $self->count ]}
  Last-Updated: @{[ scalar localtime ]}
  
  EOF
      for my $p ($self->packages) {
          print $fh sprintf "%s %s  %s\n", pad($p->name, 32), pad($p->version || 'undef', 10, 1), $p->pathname;
      }
  }
  
  sub pad {
      my($str, $len, $left) = @_;
  
      my $howmany = $len - length($str);
      return $str if $howmany <= 0;
  
      my $pad = " " x $howmany;
      return $left ? "$pad$str" : "$str$pad";
  }
  
  
  1;
CARTON_INDEX

$fatpacked{"Carton/Mirror.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CARTON_MIRROR';
  package Carton::Mirror;
  use Moo;
  use warnings NONFATAL => 'all';
  
  our $DefaultMirror = 'http://cpan.metacpan.org/';
  
  has url => (is => 'ro');
  
  sub BUILDARGS {
      my($class, $url) = @_;
      return { url => $url };
  }
  
  sub default {
      my $class = shift;
      $class->new($DefaultMirror);
  }
  
  sub is_default {
      my $self = shift;
      $self->url eq $DefaultMirror;
  }
  
  1;
  
CARTON_MIRROR

$fatpacked{"Carton/Package.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CARTON_PACKAGE';
  package Carton::Package;
  use Moo;
  use warnings NONFATAL => 'all';
  
  has name     => (is => 'ro');
  has version  => (is => 'ro');
  has pathname => (is => 'ro');
  
  sub BUILDARGS {
      my($class, @args) = @_;
      return { name => $args[0], version => $args[1], pathname => $args[2] };
  }
  
  1;
  
  
CARTON_PACKAGE

$fatpacked{"Carton/Packer.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CARTON_PACKER';
  package Carton::Packer;
  use Moo;
  use warnings NONFATAL => 'all';
  use App::FatPacker;
  use File::pushd ();
  use Path::Tiny ();
  use CPAN::Meta ();
  use File::Find ();
  
  sub fatpack_carton {
      my($self, $dir) = @_;
  
      my $temp = Path::Tiny->tempdir;
      my $pushd = File::pushd::pushd $temp;
  
      my $file = $temp->child('carton.pre.pl');
  
      $file->spew(<<'EOF');
  #!/usr/bin/env perl
  use strict;
  use 5.008001;
  use Carton::CLI;
  $Carton::Fatpacked = 1;
  exit Carton::CLI->new->run(@ARGV);
  EOF
  
      my $fatpacked = $self->do_fatpack($file);
  
      my $executable = $dir->child('carton');
      warn "Bundling $executable\n";
  
      $dir->mkpath;
      $executable->spew($fatpacked);
      chmod 0755, $executable;
  }
  
  sub do_fatpack {
      my($self, $file) = @_;
  
      my $packer = App::FatPacker->new;
  
      my @modules = split /\r?\n/, $packer->trace(args => [$file], use => $self->required_modules);
      my @packlists = $packer->packlists_containing(\@modules);
      $packer->packlists_to_tree(Path::Tiny->new('fatlib')->absolute, \@packlists);
  
      my $fatpacked = do {
          local $SIG{__WARN__} = sub {};
          $packer->fatpack_file($file);
      };
  
      # HACK: File::Spec bundled into arch in < 5.16, but is loadable as pure-perl
      use Config;
      $fatpacked =~ s/\$fatpacked{"$Config{archname}\/(Cwd|File)/\$fatpacked{"$1/g;
  
      $fatpacked;
  }
  
  sub required_modules {
      my($self, $packer) = @_;
  
      my $meta = $self->installed_meta('Carton')
          or die "Couldn't find install metadata for Carton";
  
      my %excludes = (
          perl => 1,
          'ExtUtils::MakeMaker' => 1,
          'Module::Build' => 1,
      );
  
      my @requirements = grep !$excludes{$_},
          $meta->effective_prereqs->requirements_for('runtime', 'requires')->required_modules;
  
      return \@requirements;
  }
  
  sub installed_meta {
      my($self, $dist) = @_;
  
      my @meta;
      my $finder = sub {
          if (m!\b$dist-.*[\\/]MYMETA.json!) {
              my $meta = CPAN::Meta->load_file($_);
              push @meta, $meta if $meta->name eq $dist;
          }
      };
  
      File::Find::find({ wanted => $finder, no_chdir => 1 }, grep -d, map "$_/.meta", @INC);
  
      # return the latest version
      @meta = sort { version->new($b->version) cmp version->new($a->version) } @meta;
  
      return $meta[0];
  }
  
  1;
CARTON_PACKER

$fatpacked{"Carton/Snapshot.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CARTON_SNAPSHOT';
  package Carton::Snapshot;
  use Moo;
  use warnings NONFATAL => 'all';
  use Config;
  use Carton::Dist;
  use Carton::Dist::Core;
  use Carton::Error;
  use Carton::Package;
  use Carton::Index;
  use Carton::Util;
  use Carton::Snapshot::Emitter;
  use Carton::Snapshot::Parser;
  use CPAN::Meta;
  use CPAN::Meta::Requirements;
  use File::Find ();
  use Try::Tiny;
  use Path::Tiny ();
  use Module::CoreList;
  
  use constant CARTON_SNAPSHOT_VERSION => '1.0';
  
  has path    => (is => 'rw', coerce => sub { Path::Tiny->new($_[0]) });
  has version => (is => 'rw', default => sub { CARTON_SNAPSHOT_VERSION });
  has loaded  => (is => 'rw');
  has _distributions => (is => 'rw', default => sub { +[] });
  
  sub load_if_exists {
      my $self = shift;
      $self->load if $self->path->is_file;
  }
  
  sub load {
      my $self = shift;
  
      return 1 if $self->loaded;
  
      if ($self->path->is_file) {
          my $parser = Carton::Snapshot::Parser->new;
          $parser->parse($self->path->slurp_utf8, $self);
          $self->loaded(1);
  
          return 1;
      } else {
          Carton::Error::SnapshotNotFound->throw(
              error => "Can't find cpanfile.snapshot: Run `carton install` to build the snapshot file.",
              path => $self->path,
          );
      }
  }
  
  sub save {
      my $self = shift;
      $self->path->spew_utf8( Carton::Snapshot::Emitter->new->emit($self) );
  }
  
  sub find {
      my($self, $module) = @_;
      (grep $_->provides_module($module), $self->distributions)[0];
  }
  
  sub find_or_core {
      my($self, $module) = @_;
      $self->find($module) || $self->find_in_core($module);
  }
  
  sub find_in_core {
      my($self, $module) = @_;
  
      if (exists $Module::CoreList::version{$]}{$module}) {
          my $version = $Module::CoreList::version{$]}{$module}; # maybe undef
          return Carton::Dist::Core->new(name => $module, module_version => $version);
      }
  
      return;
  }
  
  sub index {
      my $self = shift;
  
      my $index = Carton::Index->new;
      for my $package ($self->packages) {
          $index->add_package($package);
      }
  
      return $index;
  }
  
  sub distributions {
      @{$_[0]->_distributions};
  }
  
  sub add_distribution {
      my($self, $dist) = @_;
      push @{$self->_distributions}, $dist;
  }
  
  sub packages {
      my $self = shift;
  
      my @packages;
      for my $dist ($self->distributions) {
          while (my($package, $provides) = each %{$dist->provides}) {
              # TODO what if duplicates?
              push @packages, Carton::Package->new($package, $provides->{version}, $dist->pathname);
          }
      }
  
      return @packages;
  }
  
  sub write_index {
      my($self, $file) = @_;
  
      open my $fh, ">", $file or die $!;
      $self->index->write($fh);
  }
  
  sub find_installs {
      my($self, $path, $reqs) = @_;
  
      my $libdir = "$path/lib/perl5/$Config{archname}/.meta";
      return {} unless -e $libdir;
  
      my @installs;
      my $wanted = sub {
          if ($_ eq 'install.json') {
              push @installs, [ $File::Find::name, "$File::Find::dir/MYMETA.json" ];
          }
      };
      File::Find::find($wanted, $libdir);
  
      my %installs;
  
      my $accepts = sub {
          my $module = shift;
  
          return 0 unless $reqs->accepts_module($module->{name}, $module->{provides}{$module->{name}}{version});
  
          if (my $exist = $installs{$module->{name}}) {
              my $old_ver = version->new($exist->{provides}{$module->{name}}{version});
              my $new_ver = version->new($module->{provides}{$module->{name}}{version});
              return $new_ver >= $old_ver;
          } else {
              return 1;
          }
      };
  
      for my $file (@installs) {
          my $module = Carton::Util::load_json($file->[0]);
          my $prereqs = -f $file->[1] ? CPAN::Meta->load_file($file->[1])->effective_prereqs : CPAN::Meta::Prereqs->new;
  
          my $reqs = CPAN::Meta::Requirements->new;
          $reqs->add_requirements($prereqs->requirements_for($_, 'requires'))
            for qw( configure build runtime );
  
          if ($accepts->($module)) {
              $installs{$module->{name}} = Carton::Dist->new(
                  name => $module->{dist},
                  pathname => $module->{pathname},
                  provides => $module->{provides},
                  version => $module->{version},
                  requirements => $reqs,
              );
          }
      }
  
      my @new_dists;
      for my $module (sort keys %installs) {
          push @new_dists, $installs{$module};
      }
  
      $self->_distributions(\@new_dists);
  }
  
  1;
CARTON_SNAPSHOT

$fatpacked{"Carton/Snapshot/Emitter.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CARTON_SNAPSHOT_EMITTER';
  package Carton::Snapshot::Emitter;
  use Moo;
  use warnings NONFATAL => 'all';
  
  sub emit {
      my($self, $snapshot) = @_;
  
      my $data = '';
      $data .= "# carton snapshot format: version @{[$snapshot->version]}\n";
      $data .= "DISTRIBUTIONS\n";
  
      for my $dist (sort { $a->name cmp $b->name } $snapshot->distributions) {
          $data .= "  @{[$dist->name]}\n";
          $data .= "    pathname: @{[$dist->pathname]}\n";
  
          $data .= "    provides:\n";
          for my $package (sort keys %{$dist->provides}) {
              $data .= "      $package @{[$dist->provides->{$package}{version} || 'undef' ]}\n";
          }
  
          $data .= "    requirements:\n";
          for my $module (sort $dist->required_modules) {
              $data .= "      $module @{[ $dist->requirements_for_module($module) || '0' ]}\n";
          }
      }
  
      $data;
  }
  
  1;
CARTON_SNAPSHOT_EMITTER

$fatpacked{"Carton/Snapshot/Parser.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CARTON_SNAPSHOT_PARSER';
  package Carton::Snapshot::Parser;
  use Moo;
  use warnings NONFATAL => 'all';
  use Carton::Dist;
  use Carton::Error;
  
  my $machine = {
      init => [
          {
              re => qr/^\# carton snapshot format: version (1\.0)/,
              code => sub {
                  my($stash, $snapshot, $ver) = @_;
                  $snapshot->version($ver);
              },
              goto => 'section',
          },
          # TODO support pasing error and version mismatch etc.
      ],
      section => [
          {
              re => qr/^DISTRIBUTIONS$/,
              goto => 'dists',
          },
          {
              re => qr/^__EOF__$/,
              done => 1,
          },
      ],
      dists => [
          {
              re => qr/^  (\S+)$/,
              code => sub { $_[0]->{dist} = Carton::Dist->new(name => $1) },
              goto => 'distmeta',
          },
          {
              re => qr/^\S/,
              goto => 'section',
              redo => 1,
          },
      ],
      distmeta => [
          {
              re => qr/^    pathname: (.*)$/,
              code => sub { $_[0]->{dist}->pathname($1) },
          },
          {
              re => qr/^\s{4}provides:$/,
              code => sub { $_[0]->{property} = 'provides' },
              goto => 'properties',
          },
          {
              re => qr/^\s{4}requirements:$/,
              code => sub {
                  $_[0]->{property} = 'requirements';
              },
              goto => 'properties',
          },
          {
              re => qr/^\s{0,2}\S/,
              code => sub {
                  my($stash, $snapshot) = @_;
                  $snapshot->add_distribution($stash->{dist});
                  %$stash = (); # clear
              },
              goto => 'dists',
              redo => 1,
          },
      ],
      properties => [
          {
              re => qr/^\s{6}([0-9A-Za-z_:]+) ([v0-9\._,=\!<>\s]+|undef)/,
              code => sub {
                  my($stash, $snapshot, $module, $version) = @_;
  
                  if ($stash->{property} eq 'provides') {
                      $stash->{dist}->provides->{$module} = { version => $version };
                  } else {
                      $stash->{dist}->add_string_requirement($module, $version);
                  }
              },
          },
          {
              re => qr/^\s{0,4}\S/,
              goto => 'distmeta',
              redo => 1,
          },
      ],
  };
  
  sub parse {
      my($self, $data, $snapshot) = @_;
  
      my @lines = split /\r?\n/, $data;
  
      my $state = $machine->{init};
      my $stash = {};
  
      LINE:
      for my $line (@lines, '__EOF__') {
          last LINE unless @$state;
  
      STATE: {
              for my $trans (@{$state}) {
                  if (my @match = $line =~ $trans->{re}) {
                      if (my $code = $trans->{code}) {
                          $code->($stash, $snapshot, @match);
                      }
                      if (my $goto = $trans->{goto}) {
                          $state = $machine->{$goto};
                          if ($trans->{redo}) {
                              redo STATE;
                          } else {
                              next LINE;
                          }
                      }
  
                      last STATE;
                  }
              }
  
              Carton::Error::SnapshotParseError->throw(error => "Could not parse snapshot file.");
          }
      }
  }
  
  1;
CARTON_SNAPSHOT_PARSER

$fatpacked{"Carton/Tree.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CARTON_TREE';
  package Carton::Tree;
  use Moo;
  use warnings NONFATAL => 'all';
  use Carton::Dependency;
  
  has cpanfile => (is => 'ro');
  has snapshot => (is => 'ro');
  
  use constant STOP => -1;
  
  sub walk_down {
      my($self, $cb) = @_;
  
      my $dumper; $dumper = sub {
          my($dependency, $reqs, $level, $parent) = @_;
  
          my $ret = $cb->($dependency, $reqs, $level);
          return if $ret && $ret == STOP;
  
          local $parent->{$dependency->distname} = 1 if $dependency;
  
          for my $module (sort $reqs->required_modules) {
              my $dependency = $self->dependency_for($module, $reqs);
              if ($dependency->dist) {
                  next if $parent->{$dependency->distname};
                  $dumper->($dependency, $dependency->requirements, $level + 1, $parent);
              } else {
                  # no dist found in lock
              }
          }
      };
  
      $dumper->(undef, $self->cpanfile->requirements, 0, {});
      undef $dumper;
  }
  
  sub dependency_for {
      my($self, $module, $reqs) = @_;
  
      my $requirement = $reqs->requirements_for_module($module);
  
      my $dep = Carton::Dependency->new;
      $dep->module($module);
      $dep->requirement($requirement);
  
      if (my $dist = $self->snapshot->find_or_core($module)) {
          $dep->dist($dist);
      }
  
      return $dep;
  }
  
  sub merged_requirements {
      my $self = shift;
  
      my $merged_reqs = CPAN::Meta::Requirements->new;
  
      my %seen;
      $self->walk_down(sub {
          my($dependency, $reqs, $level) = @_;
          return Carton::Tree::STOP if $dependency && $seen{$dependency->distname}++;
          $merged_reqs->add_requirements($reqs);
      });
  
      $merged_reqs->clear_requirement('perl');
      $merged_reqs->finalize;
  
      $merged_reqs;
  }
  
  1;
CARTON_TREE

$fatpacked{"Carton/Util.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CARTON_UTIL';
  package Carton::Util;
  use strict;
  use warnings;
  
  sub load_json {
      my $file = shift;
  
      open my $fh, "<", $file or die "$file: $!";
      from_json(join '', <$fh>);
  }
  
  sub dump_json {
      my($data, $file) = @_;
  
      open my $fh, ">", $file or die "$file: $!";
      binmode $fh;
      print $fh to_json($data);
  }
  
  sub from_json {
      require JSON;
      JSON::decode_json(@_);
  }
  
  sub to_json {
      my($data) = @_;
      require JSON;
      JSON->new->utf8->pretty->canonical->encode($data);
  }
  
  1;
CARTON_UTIL

$fatpacked{"Class/Data/Inheritable.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'CLASS_DATA_INHERITABLE';
  package Class::Data::Inheritable;
  
  use strict qw(vars subs);
  use vars qw($VERSION);
  $VERSION = '0.08';
  
  sub mk_classdata {
      my ($declaredclass, $attribute, $data) = @_;
  
      if( ref $declaredclass ) {
          require Carp;
          Carp::croak("mk_classdata() is a class method, not an object method");
      }
  
      my $accessor = sub {
          my $wantclass = ref($_[0]) || $_[0];
  
          return $wantclass->mk_classdata($attribute)->(@_)
            if @_>1 && $wantclass ne $declaredclass;
  
          $data = $_[1] if @_>1;
          return $data;
      };
  
      my $alias = "_${attribute}_accessor";
      *{$declaredclass.'::'.$attribute} = $accessor;
      *{$declaredclass.'::'.$alias}     = $accessor;
  }
  
  1;
  
  __END__
  
  =head1 NAME
  
  Class::Data::Inheritable - Inheritable, overridable class data
  
  =head1 SYNOPSIS
  
    package Stuff;
    use base qw(Class::Data::Inheritable);
  
    # Set up DataFile as inheritable class data.
    Stuff->mk_classdata('DataFile');
  
    # Declare the location of the data file for this class.
    Stuff->DataFile('/etc/stuff/data');
  
    # Or, all in one shot:
    Stuff->mk_classdata(DataFile => '/etc/stuff/data');
  
  =head1 DESCRIPTION
  
  Class::Data::Inheritable is for creating accessor/mutators to class
  data.  That is, if you want to store something about your class as a
  whole (instead of about a single object).  This data is then inherited
  by your subclasses and can be overriden.
  
  For example:
  
    Pere::Ubu->mk_classdata('Suitcase');
  
  will generate the method Suitcase() in the class Pere::Ubu.
  
  This new method can be used to get and set a piece of class data.
  
    Pere::Ubu->Suitcase('Red');
    $suitcase = Pere::Ubu->Suitcase;
  
  The interesting part happens when a class inherits from Pere::Ubu:
  
    package Raygun;
    use base qw(Pere::Ubu);
    
    # Raygun's suitcase is Red.
    $suitcase = Raygun->Suitcase;
  
  Raygun inherits its Suitcase class data from Pere::Ubu.
  
  Inheritance of class data works analogous to method inheritance.  As
  long as Raygun does not "override" its inherited class data (by using
  Suitcase() to set a new value) it will continue to use whatever is set
  in Pere::Ubu and inherit further changes:
  
    # Both Raygun's and Pere::Ubu's suitcases are now Blue
    Pere::Ubu->Suitcase('Blue');
  
  However, should Raygun decide to set its own Suitcase() it has now
  "overridden" Pere::Ubu and is on its own, just like if it had
  overriden a method:
  
    # Raygun has an orange suitcase, Pere::Ubu's is still Blue.
    Raygun->Suitcase('Orange');
  
  Now that Raygun has overridden Pere::Ubu futher changes by Pere::Ubu
  no longer effect Raygun.
  
    # Raygun still has an orange suitcase, but Pere::Ubu is using Samsonite.
    Pere::Ubu->Suitcase('Samsonite');
  
  =head1 Methods
  
  =head2 mk_classdata
  
    Class->mk_classdata($data_accessor_name);
    Class->mk_classdata($data_accessor_name => $value);
  
  This is a class method used to declare new class data accessors.
  A new accessor will be created in the Class using the name from
  $data_accessor_name, and optionally initially setting it to the given
  value.
  
  To facilitate overriding, mk_classdata creates an alias to the
  accessor, _field_accessor().  So Suitcase() would have an alias
  _Suitcase_accessor() that does the exact same thing as Suitcase().
  This is useful if you want to alter the behavior of a single accessor
  yet still get the benefits of inheritable class data.  For example.
  
    sub Suitcase {
        my($self) = shift;
        warn "Fashion tragedy" if @_ and $_[0] eq 'Plaid';
  
        $self->_Suitcase_accessor(@_);
    }
  
  =head1 AUTHOR
  
  Original code by Damian Conway.
  
  Maintained by Michael G Schwern until September 2005.
  
  Now maintained by Tony Bowden.
  
  =head1 BUGS and QUERIES
  
  Please direct all correspondence regarding this module to:
    bug-Class-Data-Inheritable@rt.cpan.org
  
  =head1 COPYRIGHT and LICENSE
  
  Copyright (c) 2000-2005, Damian Conway and Michael G Schwern. 
  All Rights Reserved.  
  
  This module is free software. It may be used, redistributed and/or
  modified under the same terms as Perl itself.
  
  =head1 SEE ALSO
  
  L<perltooc> has a very elaborate discussion of class data in Perl.
  
CLASS_DATA_INHERITABLE

$fatpacked{"Devel/GlobalDestruction.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'DEVEL_GLOBALDESTRUCTION';
  package Devel::GlobalDestruction;
  
  use strict;
  use warnings;
  
  our $VERSION = '0.11';
  
  use Sub::Exporter::Progressive -setup => {
    exports => [ qw(in_global_destruction) ],
    groups  => { default => [ -all ] },
  };
  
  # we run 5.14+ - everything is in core
  #
  if (defined ${^GLOBAL_PHASE}) {
    eval 'sub in_global_destruction () { ${^GLOBAL_PHASE} eq q[DESTRUCT] }; 1'
      or die $@;
  }
  # try to load the xs version if it was compiled
  #
  elsif (eval {
    require Devel::GlobalDestruction::XS;
    no warnings 'once';
    *in_global_destruction = \&Devel::GlobalDestruction::XS::in_global_destruction;
    1;
  }) {
    # the eval already installed everything, nothing to do
  }
  else {
    # internally, PL_main_start is nulled immediately before entering global destruction
    # and we can use B to detect that.  It will also be null before the main runloop starts,
    # so we check install a CHECK if needed to detect that.
    require B;
    my $started = !B::main_start()->isa(q[B::NULL]);
    unless ($started) {
      # work around 5.6 eval bug
      eval '0 && $started; CHECK { $started = 1 }; 1'
        or die $@;
    }
    eval '0 && $started; sub in_global_destruction () { $started && B::main_start()->isa(q[B::NULL]) }; 1'
      or die $@;
  }
  
  1;  # keep require happy
  
  
  __END__
  
  =head1 NAME
  
  Devel::GlobalDestruction - Provides function returning the equivalent of
  C<${^GLOBAL_PHASE} eq 'DESTRUCT'> for older perls.
  
  =head1 SYNOPSIS
  
      package Foo;
      use Devel::GlobalDestruction;
  
      use namespace::clean; # to avoid having an "in_global_destruction" method
  
      sub DESTROY {
          return if in_global_destruction;
  
          do_something_a_little_tricky();
      }
  
  =head1 DESCRIPTION
  
  Perl's global destruction is a little tricky to deal with WRT finalizers
  because it's not ordered and objects can sometimes disappear.
  
  Writing defensive destructors is hard and annoying, and usually if global
  destruction is happenning you only need the destructors that free up non
  process local resources to actually execute.
  
  For these constructors you can avoid the mess by simply bailing out if global
  destruction is in effect.
  
  =head1 EXPORTS
  
  This module uses L<Sub::Exporter::Progressive> so the exports may be renamed,
  aliased, etc. if L<Sub::Exporter> is present.
  
  =over 4
  
  =item in_global_destruction
  
  Returns true if the interpreter is in global destruction. In perl 5.14+, this
  returns C<${^GLOBAL_PHASE} eq 'DESTRUCT'>, and on earlier perls, detects it using
  the value of C<PL_main_start> or C<PL_dirty>.
  
  =back
  
  =head1 AUTHORS
  
  Yuval Kogman E<lt>nothingmuch@woobling.orgE<gt>
  
  Florian Ragwitz E<lt>rafl@debian.orgE<gt>
  
  Jesse Luehrs E<lt>doy@tozt.netE<gt>
  
  Peter Rabbitson E<lt>ribasushi@cpan.orgE<gt>
  
  Arthur Axel 'fREW' Schmidt E<lt>frioux@gmail.comE<gt>
  
  Elizabeth Mattijsen E<lt>liz@dijkmat.nlE<gt>
  
  Greham Knop E<lt>haarg@haarg.orgE<gt>
  
  =head1 COPYRIGHT
  
      Copyright (c) 2008 Yuval Kogman. All rights reserved
      This program is free software; you can redistribute
      it and/or modify it under the same terms as Perl itself.
  
  =cut
DEVEL_GLOBALDESTRUCTION

$fatpacked{"Devel/StackTrace.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'DEVEL_STACKTRACE';
  package Devel::StackTrace;
  # git description: v1.34-10-g810fd3f
  
  $Devel::StackTrace::VERSION = '2.00';
  use 5.006;
  
  use strict;
  use warnings;
  
  use Devel::StackTrace::Frame;
  use File::Spec;
  use Scalar::Util qw( blessed );
  
  use overload
      '""'     => \&as_string,
      fallback => 1;
  
  sub new {
      my $class = shift;
      my %p     = @_;
  
      $p{unsafe_ref_capture} = !delete $p{no_refs}
          if exists $p{no_refs};
  
      my $self = bless {
          index  => undef,
          frames => [],
          raw    => [],
          %p,
      }, $class;
  
      $self->_record_caller_data();
  
      return $self;
  }
  
  sub _record_caller_data {
      my $self = shift;
  
      my $filter = $self->{filter_frames_early} && $self->_make_frame_filter();
  
      # We exclude this method by starting at least one frame back.
      my $x = 1 + ( $self->{skip_frames} || 0 );
  
      while (
          my @c
          = $self->{no_args}
          ? caller( $x++ )
          : do {
              package    # the newline keeps dzil from adding a version here
                  DB;
              @DB::args = ();
              caller( $x++ );
          }
          ) {
  
          my @args;
  
          @args = $self->{no_args} ? () : @DB::args;
  
          my $raw = {
              caller => \@c,
              args   => \@args,
          };
  
          next if $filter && !$filter->($raw);
  
          unless ( $self->{unsafe_ref_capture} ) {
              $raw->{args} = [ map { ref $_ ? $self->_ref_to_string($_) : $_ }
                      @{ $raw->{args} } ];
          }
  
          push @{ $self->{raw} }, $raw;
      }
  }
  
  sub _ref_to_string {
      my $self = shift;
      my $ref  = shift;
  
      return overload::AddrRef($ref)
          if blessed $ref && $ref->isa('Exception::Class::Base');
  
      return overload::AddrRef($ref) unless $self->{respect_overload};
  
      local $@;
      local $SIG{__DIE__};
  
      my $str = eval { $ref . '' };
  
      return $@ ? overload::AddrRef($ref) : $str;
  }
  
  sub _make_frames {
      my $self = shift;
  
      my $filter = !$self->{filter_frames_early} && $self->_make_frame_filter();
  
      my $raw = delete $self->{raw};
      for my $r ( @{$raw} ) {
          next if $filter && !$filter->($r);
  
          $self->_add_frame( $r->{caller}, $r->{args} );
      }
  }
  
  my $default_filter = sub { 1 };
  
  sub _make_frame_filter {
      my $self = shift;
  
      my ( @i_pack_re, %i_class );
      if ( $self->{ignore_package} ) {
          local $@;
          local $SIG{__DIE__};
  
          $self->{ignore_package} = [ $self->{ignore_package} ]
              unless eval { @{ $self->{ignore_package} } };
  
          @i_pack_re
              = map { ref $_ ? $_ : qr/^\Q$_\E$/ } @{ $self->{ignore_package} };
      }
  
      my $p = __PACKAGE__;
      push @i_pack_re, qr/^\Q$p\E$/;
  
      if ( $self->{ignore_class} ) {
          $self->{ignore_class} = [ $self->{ignore_class} ]
              unless ref $self->{ignore_class};
          %i_class = map { $_ => 1 } @{ $self->{ignore_class} };
      }
  
      my $user_filter = $self->{frame_filter};
  
      return sub {
          return 0 if grep { $_[0]{caller}[0] =~ /$_/ } @i_pack_re;
          return 0 if grep { $_[0]{caller}[0]->isa($_) } keys %i_class;
  
          if ($user_filter) {
              return $user_filter->( $_[0] );
          }
  
          return 1;
      };
  }
  
  sub _add_frame {
      my $self = shift;
      my $c    = shift;
      my $p    = shift;
  
      # eval and is_require are only returned when applicable under 5.00503.
      push @$c, ( undef, undef ) if scalar @$c == 6;
  
      push @{ $self->{frames} },
          Devel::StackTrace::Frame->new(
          $c,
          $p,
          $self->{respect_overload},
          $self->{max_arg_length},
          $self->{message},
          $self->{indent}
          );
  }
  
  sub next_frame {
      my $self = shift;
  
      # reset to top if necessary.
      $self->{index} = -1 unless defined $self->{index};
  
      my @f = $self->frames();
      if ( defined $f[ $self->{index} + 1 ] ) {
          return $f[ ++$self->{index} ];
      }
      else {
          $self->{index} = undef;
          return undef;
      }
  }
  
  sub prev_frame {
      my $self = shift;
  
      my @f = $self->frames();
  
      # reset to top if necessary.
      $self->{index} = scalar @f unless defined $self->{index};
  
      if ( defined $f[ $self->{index} - 1 ] && $self->{index} >= 1 ) {
          return $f[ --$self->{index} ];
      }
      else {
          $self->{index} = undef;
          return undef;
      }
  }
  
  sub reset_pointer {
      my $self = shift;
  
      $self->{index} = undef;
  }
  
  sub frames {
      my $self = shift;
  
      if (@_) {
          die
              "Devel::StackTrace->frames() can only take Devel::StackTrace::Frame args\n"
              if grep { !$_->isa('Devel::StackTrace::Frame') } @_;
  
          $self->{frames} = \@_;
      }
      else {
          $self->_make_frames() if $self->{raw};
      }
  
      return @{ $self->{frames} };
  }
  
  sub frame {
      my $self = shift;
      my $i    = shift;
  
      return unless defined $i;
  
      return ( $self->frames() )[$i];
  }
  
  sub frame_count {
      my $self = shift;
  
      return scalar( $self->frames() );
  }
  
  sub as_string {
      my $self = shift;
      my $p    = shift;
  
      my $st    = '';
      my $first = 1;
      foreach my $f ( $self->frames() ) {
          $st .= $f->as_string( $first, $p ) . "\n";
          $first = 0;
      }
  
      return $st;
  }
  
  {
      package    # hide from PAUSE
          Devel::StackTraceFrame;
  
      our @ISA = 'Devel::StackTrace::Frame';
  }
  
  1;
  
  # ABSTRACT: An object representing a stack trace
  
  __END__
  
  =pod
  
  =head1 NAME
  
  Devel::StackTrace - An object representing a stack trace
  
  =head1 VERSION
  
  version 2.00
  
  =head1 SYNOPSIS
  
    use Devel::StackTrace;
  
    my $trace = Devel::StackTrace->new();
  
    print $trace->as_string(); # like carp
  
    # from top (most recent) of stack to bottom.
    while ( my $frame = $trace->next_frame() ) {
        print "Has args\n" if $frame->hasargs();
    }
  
    # from bottom (least recent) of stack to top.
    while ( my $frame = $trace->prev_frame() ) {
        print "Sub: ", $frame->subroutine(), "\n";
    }
  
  =head1 DESCRIPTION
  
  The C<Devel::StackTrace> module contains two classes, C,Devel::StackTrace> and
  L<Devel::StackTrace::Frame>. These objects encapsulate the information that
  can retrieved via Perl's C<caller()> function, as well as providing a simple
  interface to this data.
  
  The C<Devel::StackTrace> object contains a set of C<Devel::StackTrace::Frame>
  objects, one for each level of the stack. The frames contain all the data
  available from C<caller()>.
  
  This code was created to support my L<Exception::Class::Base> class (part of
  L<Exception::Class>) but may be useful in other contexts.
  
  =encoding UTF-8
  
  =head1 'TOP' AND 'BOTTOM' OF THE STACK
  
  When describing the methods of the trace object, I use the words 'top' and
  'bottom'. In this context, the 'top' frame on the stack is the most recent
  frame and the 'bottom' is the least recent.
  
  Here's an example:
  
    foo();  # bottom frame is here
  
    sub foo {
       bar();
    }
  
    sub bar {
       Devel::StackTrace->new();  # top frame is here.
    }
  
  =head1 METHODS
  
  This class provide the following methods:
  
  =head2 Devel::StackTrace->new(%named_params)
  
  Returns a new Devel::StackTrace object.
  
  Takes the following parameters:
  
  =over 4
  
  =item * frame_filter => $sub
  
  By default, Devel::StackTrace will include all stack frames before the
  call to its constructor.
  
  However, you may want to filter out some frames with more granularity
  than 'ignore_package' or 'ignore_class' allow.
  
  You can provide a subroutine which is called with the raw frame data
  for each frame. This is a hash reference with two keys, "caller", and
  "args", both of which are array references. The "caller" key is the
  raw data as returned by Perl's C<caller()> function, and the "args"
  key are the subroutine arguments found in C<@DB::args>.
  
  The filter should return true if the frame should be included, or
  false if it should be skipped.
  
  =item * filter_frames_early => $boolean
  
  If this parameter is true, C<frame_filter> will be called as soon as the
  stacktrace is created, and before refs are stringified (if
  C<unsafe_ref_capture> is not set), rather than being filtered lazily when
  L<Devel::StackTrace::Frame> objects are first needed.
  
  This is useful if you want to filter based on the frame's arguments and want
  to be able to examine object properties, for example.
  
  =item * ignore_package => $package_name OR \@package_names
  
  Any frames where the package is one of these packages will not be on
  the stack.
  
  =item * ignore_class => $package_name OR \@package_names
  
  Any frames where the package is a subclass of one of these packages
  (or is the same package) will not be on the stack.
  
  Devel::StackTrace internally adds itself to the 'ignore_package'
  parameter, meaning that the Devel::StackTrace package is B<ALWAYS>
  ignored. However, if you create a subclass of Devel::StackTrace it
  will not be ignored.
  
  =item * skip_frames => $integer
  
  This will cause this number of stack frames to be excluded from top of the
  stack trace. This prevents the frames from being captured at all, and applies
  before the C<frame_filter>, C<ignore_package>, or C<ignore_class> options,
  even with C<filter_frames_early>.
  
  =item * unsafe_ref_capture => $boolean
  
  If this parameter is true, then Devel::StackTrace will store
  references internally when generating stacktrace frames.
  
  B<This option is very dangerous, and should never be used with exception
  objects>. Using this option will keep any objects or references alive past
  their normal lifetime, until the stack trace object goes out of scope. It can
  keep objects alive even after their C<DESTROY> sub is called, resulting it it
  being called multiple times on the same object.
  
  If not set, Devel::StackTrace replaces any references with their stringified
  representation.
  
  =item * no_args => $boolean
  
  If this parameter is true, then Devel::StackTrace will not store caller
  arguments in stack trace frames at all.
  
  =item * respect_overload => $boolean
  
  By default, Devel::StackTrace will call C<overload::AddrRef()> to get
  the underlying string representation of an object, instead of
  respecting the object's stringification overloading. If you would
  prefer to see the overloaded representation of objects in stack
  traces, then set this parameter to true.
  
  =item * max_arg_length => $integer
  
  By default, Devel::StackTrace will display the entire argument for each
  subroutine call. Setting this parameter causes truncates each subroutine
  argument's string representation if it is longer than this number of
  characters.
  
  =item * message => $string
  
  By default, Devel::StackTrace will use 'Trace begun' as the message for the
  first stack frame when you call C<as_string>. You can supply an alternative
  message using this option.
  
  =item * indent => $boolean
  
  If this parameter is true, each stack frame after the first will start with a
  tab character, just like C<Carp::confess()>.
  
  =back
  
  =head2 $trace->next_frame()
  
  Returns the next L<Devel::StackTrace::Frame> object on the stack, going
  down. If this method hasn't been called before it returns the first frame. It
  returns C<undef> when it reaches the bottom of the stack and then resets its
  pointer so the next call to C<< $trace->next_frame() >> or C<<
  $trace->prev_frame() >> will work properly.
  
  =head2 $trace->prev_frame()
  
  Returns the next L<Devel::StackTrace::Frame> object on the stack, going up. If
  this method hasn't been called before it returns the last frame. It returns
  undef when it reaches the top of the stack and then resets its pointer so the
  next call to C<< $trace->next_frame() >> or C<< $trace->prev_frame() >> will
  work properly.
  
  =head2 $trace->reset_pointer
  
  Resets the pointer so that the next call to C<< $trace->next_frame() >> or C<<
  $trace->prev_frame() >> will start at the top or bottom of the stack, as
  appropriate.
  
  =head2 $trace->frames()
  
  When this method is called with no arguments, it returns a list of
  L<Devel::StackTrace::Frame> objects. They are returned in order from top (most
  recent) to bottom.
  
  This method can also be used to set the object's frames if you pass it a list
  of L<Devel::StackTrace::Frame> objects.
  
  This is useful if you want to filter the list of frames in ways that are more
  complex than can be handled by the C<< $trace->filter_frames() >> method:
  
    $stacktrace->frames( my_filter( $stacktrace->frames() ) );
  
  =head2 $trace->frame($index)
  
  Given an index, this method returns the relevant frame, or undef if there is
  no frame at that index. The index is exactly like a Perl array. The first
  frame is 0 and negative indexes are allowed.
  
  =head2 $trace->frame_count()
  
  Returns the number of frames in the trace object.
  
  =head2 $trace->as_string(\%p)
  
  Calls C<< $frame->as_string() >> on each frame from top to bottom, producing
  output quite similar to the Carp module's cluck/confess methods.
  
  The optional C<\%p> parameter only has one option. The C<max_arg_length>
  parameter truncates each subroutine argument's string representation if it is
  longer than this number of characters.
  
  =head1 SUPPORT
  
  Please submit bugs to the CPAN RT system at
  http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Devel%3A%3AStackTrace
  or via email at bug-devel-stacktrace@rt.cpan.org.
  
  =head1 AUTHOR
  
  Dave Rolsky <autarch@urth.org>
  
  =head1 CONTRIBUTORS
  
  =for stopwords Dagfinn Ilmari Mannsåker David Cantrell Graham Knop Ricardo Signes
  
  =over 4
  
  =item *
  
  Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
  
  =item *
  
  David Cantrell <david@cantrell.org.uk>
  
  =item *
  
  Graham Knop <haarg@haarg.org>
  
  =item *
  
  Ricardo Signes <rjbs@cpan.org>
  
  =back
  
  =head1 COPYRIGHT AND LICENSE
  
  This software is Copyright (c) 2000 - 2014 by David Rolsky.
  
  This is free software, licensed under:
  
    The Artistic License 2.0 (GPL Compatible)
  
  =cut
DEVEL_STACKTRACE

$fatpacked{"Devel/StackTrace/Frame.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'DEVEL_STACKTRACE_FRAME';
  package Devel::StackTrace::Frame;
  $Devel::StackTrace::Frame::VERSION = '2.00';
  use strict;
  use warnings;
  
  # Create accessor routines
  BEGIN {
      no strict 'refs';
      foreach my $f (
          qw( package filename line subroutine hasargs
          wantarray evaltext is_require hints bitmask args )
          ) {
          next if $f eq 'args';
          *{$f} = sub { my $s = shift; return $s->{$f} };
      }
  }
  
  {
      my @fields = (
          qw( package filename line subroutine hasargs wantarray
              evaltext is_require hints bitmask )
      );
  
      sub new {
          my $proto = shift;
          my $class = ref $proto || $proto;
  
          my $self = bless {}, $class;
  
          @{$self}{@fields} = @{ shift() };
  
          # fixup unix-style paths on win32
          $self->{filename} = File::Spec->canonpath( $self->{filename} );
  
          $self->{args} = shift;
  
          $self->{respect_overload} = shift;
  
          $self->{max_arg_length} = shift;
  
          $self->{message} = shift;
  
          $self->{indent} = shift;
  
          return $self;
      }
  }
  
  sub args {
      my $self = shift;
  
      return @{ $self->{args} };
  }
  
  sub as_string {
      my $self  = shift;
      my $first = shift;
      my $p     = shift;
  
      my $sub = $self->subroutine;
  
      # This code stolen straight from Carp.pm and then tweaked.  All
      # errors are probably my fault  -dave
      if ($first) {
          $sub
              = defined $self->{message}
              ? $self->{message}
              : 'Trace begun';
      }
      else {
  
          # Build a string, $sub, which names the sub-routine called.
          # This may also be "require ...", "eval '...' or "eval {...}"
          if ( my $eval = $self->evaltext ) {
              if ( $self->is_require ) {
                  $sub = "require $eval";
              }
              else {
                  $eval =~ s/([\\\'])/\\$1/g;
                  $sub = "eval '$eval'";
              }
          }
          elsif ( $sub eq '(eval)' ) {
              $sub = 'eval {...}';
          }
  
          # if there are any arguments in the sub-routine call, format
          # them according to the format variables defined earlier in
          # this file and join them onto the $sub sub-routine string
          #
          # We copy them because they're going to be modified.
          #
          if ( my @a = $self->args ) {
              for (@a) {
  
                  # set args to the string "undef" if undefined
                  $_ = "undef", next unless defined $_;
  
                  # hack!
                  $_ = $self->Devel::StackTrace::_ref_to_string($_)
                      if ref $_;
  
                  local $SIG{__DIE__};
                  local $@;
  
                  eval {
                      my $max_arg_length
                          = exists $p->{max_arg_length}
                          ? $p->{max_arg_length}
                          : $self->{max_arg_length};
  
                      if ( $max_arg_length
                          && length $_ > $max_arg_length ) {
                          substr( $_, $max_arg_length ) = '...';
                      }
  
                      s/'/\\'/g;
  
                      # 'quote' arg unless it looks like a number
                      $_ = "'$_'" unless /^-?[\d.]+$/;
  
                      # print control/high ASCII chars as 'M-<char>' or '^<char>'
                      s/([\200-\377])/sprintf("M-%c",ord($1)&0177)/eg;
                      s/([\0-\37\177])/sprintf("^%c",ord($1)^64)/eg;
                  };
  
                  if ( my $e = $@ ) {
                      $_ = $e =~ /malformed utf-8/i ? '(bad utf-8)' : '?';
                  }
              }
  
              # append ('all', 'the', 'arguments') to the $sub string
              $sub .= '(' . join( ', ', @a ) . ')';
              $sub .= ' called';
          }
      }
  
      # If the user opted into indentation (a la Carp::confess), pre-add a tab
      my $tab = $self->{indent} && !$first ? "\t" : q{};
  
      return "${tab}$sub at " . $self->filename . ' line ' . $self->line;
  }
  
  1;
  
  # ABSTRACT: A single frame in a stack trace
  
  __END__
  
  =pod
  
  =head1 NAME
  
  Devel::StackTrace::Frame - A single frame in a stack trace
  
  =head1 VERSION
  
  version 2.00
  
  =head1 DESCRIPTION
  
  See L<Devel::StackTrace> for details.
  
  =for Pod::Coverage new
  
  =head1 METHODS
  
  See Perl's C<caller()> documentation for more information on what these
  methods return.
  
  =head2 $frame->package()
  
  =head2 $frame->filename()
  
  =head2 $frame->line()
  
  =head2 $frame->subroutine()
  
  =head2 $frame->hasargs()
  
  =head2 $frame->wantarray()
  
  =head2 $frame->evaltext()
  
  Returns undef if the frame was not part of an eval.
  
  =head2 $frame->is_require()
  
  Returns undef if the frame was not part of a require.
  
  =head2 $frame->args()
  
  Returns the arguments passed to the frame.  Note that any arguments that are
  references are returned as references, not copies.
  
  =head2 $frame->hints()
  
  =head2 $frame->bitmask()
  
  =head2 $frame->as_string()
  
  Returns a string containing a description of the frame.
  
  =head1 AUTHOR
  
  Dave Rolsky <autarch@urth.org>
  
  =head1 COPYRIGHT AND LICENSE
  
  This software is Copyright (c) 2000 - 2014 by David Rolsky.
  
  This is free software, licensed under:
  
    The Artistic License 2.0 (GPL Compatible)
  
  =cut
DEVEL_STACKTRACE_FRAME

$fatpacked{"Exception/Class.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'EXCEPTION_CLASS';
  package Exception::Class;
  {
    $Exception::Class::VERSION = '1.37';
  }
  
  use 5.008001;
  
  use strict;
  
  use Exception::Class::Base;
  use Scalar::Util qw(blessed);
  
  our $BASE_EXC_CLASS;
  BEGIN { $BASE_EXC_CLASS ||= 'Exception::Class::Base'; }
  
  our %CLASSES;
  
  sub import {
      my $class = shift;
  
      local $Exception::Class::Caller = caller();
  
      my %c;
  
      my %needs_parent;
      while ( my $subclass = shift ) {
          my $def = ref $_[0] ? shift : {};
          $def->{isa}
              = $def->{isa}
              ? ( ref $def->{isa} ? $def->{isa} : [ $def->{isa} ] )
              : [];
  
          $c{$subclass} = $def;
      }
  
      # We need to sort by length because if we check for keys in the
      # Foo::Bar:: stash, this creates a "Bar::" key in the Foo:: stash!
  MAKE_CLASSES:
      foreach my $subclass ( sort { length $a <=> length $b } keys %c ) {
          my $def = $c{$subclass};
  
          # We already made this one.
          next if $CLASSES{$subclass};
  
          {
              no strict 'refs';
              foreach my $parent ( @{ $def->{isa} } ) {
                  unless ( keys %{"$parent\::"} ) {
                      $needs_parent{$subclass} = {
                          parents => $def->{isa},
                          def     => $def
                      };
                      next MAKE_CLASSES;
                  }
              }
          }
  
          $class->_make_subclass(
              subclass => $subclass,
              def      => $def || {},
          );
      }
  
      foreach my $subclass ( keys %needs_parent ) {
  
          # This will be used to spot circular references.
          my %seen;
          $class->_make_parents( \%needs_parent, $subclass, \%seen );
      }
  }
  
  sub _make_parents {
      my $class    = shift;
      my $needs    = shift;
      my $subclass = shift;
      my $seen     = shift;
      my $child    = shift;    # Just for error messages.
  
      no strict 'refs';
  
      # What if someone makes a typo in specifying their 'isa' param?
      # This should catch it.  Either it's been made because it didn't
      # have missing parents OR it's in our hash as needing a parent.
      # If neither of these is true then the _only_ place it is
      # mentioned is in the 'isa' param for some other class, which is
      # not a good enough reason to make a new class.
      die
          "Class $subclass appears to be a typo as it is only specified in the 'isa' param for $child\n"
          unless exists $needs->{$subclass}
          || $CLASSES{$subclass}
          || keys %{"$subclass\::"};
  
      foreach my $c ( @{ $needs->{$subclass}{parents} } ) {
  
          # It's been made
          next if $CLASSES{$c} || keys %{"$c\::"};
  
          die "There appears to be some circularity involving $subclass\n"
              if $seen->{$subclass};
  
          $seen->{$subclass} = 1;
  
          $class->_make_parents( $needs, $c, $seen, $subclass );
      }
  
      return if $CLASSES{$subclass} || keys %{"$subclass\::"};
  
      $class->_make_subclass(
          subclass => $subclass,
          def      => $needs->{$subclass}{def}
      );
  }
  
  sub _make_subclass {
      my $class = shift;
      my %p     = @_;
  
      my $subclass = $p{subclass};
      my $def      = $p{def};
  
      my $isa;
      if ( $def->{isa} ) {
          $isa = ref $def->{isa} ? join ' ', @{ $def->{isa} } : $def->{isa};
      }
      $isa ||= $BASE_EXC_CLASS;
  
      my $version_name = 'VERSION';
  
      my $code = <<"EOPERL";
  package $subclass;
  
  use base qw($isa);
  
  our \$$version_name = '1.1';
  
  1;
  
  EOPERL
  
      if ( $def->{description} ) {
          ( my $desc = $def->{description} ) =~ s/([\\\'])/\\$1/g;
          $code .= <<"EOPERL";
  sub description
  {
      return '$desc';
  }
  EOPERL
      }
  
      my @fields;
      if ( my $fields = $def->{fields} ) {
          @fields = UNIVERSAL::isa( $fields, 'ARRAY' ) ? @$fields : $fields;
  
          $code
              .= "sub Fields { return (\$_[0]->SUPER::Fields, "
              . join( ", ", map { "'$_'" } @fields )
              . ") }\n\n";
  
          foreach my $field (@fields) {
              $code .= sprintf( "sub %s { \$_[0]->{%s} }\n", $field, $field );
          }
      }
  
      if ( my $alias = $def->{alias} ) {
          die "Cannot make alias without caller"
              unless defined $Exception::Class::Caller;
  
          no strict 'refs';
          *{"$Exception::Class::Caller\::$alias"}
              = sub { $subclass->throw(@_) };
      }
  
      if ( my $defaults = $def->{defaults} ) {
          $code
              .= "sub _defaults { return shift->SUPER::_defaults, our \%_DEFAULTS }\n";
          no strict 'refs';
          *{"$subclass\::_DEFAULTS"} = {%$defaults};
      }
  
      eval $code;
  
      die $@ if $@;
  
      $CLASSES{$subclass} = 1;
  }
  
  sub caught {
      my $e = $@;
  
      return $e unless $_[1];
  
      return unless blessed($e) && $e->isa( $_[1] );
      return $e;
  }
  
  sub Classes { sort keys %Exception::Class::CLASSES }
  
  1;
  
  # ABSTRACT: A module that allows you to declare real exception classes in Perl
  
  __END__
  
  =pod
  
  =head1 NAME
  
  Exception::Class - A module that allows you to declare real exception classes in Perl
  
  =head1 VERSION
  
  version 1.37
  
  =head1 SYNOPSIS
  
    use Exception::Class (
        'MyException',
  
        'AnotherException' => { isa => 'MyException' },
  
        'YetAnotherException' => {
            isa         => 'AnotherException',
            description => 'These exceptions are related to IPC'
        },
  
        'ExceptionWithFields' => {
            isa    => 'YetAnotherException',
            fields => [ 'grandiosity', 'quixotic' ],
            alias  => 'throw_fields',
        },
    );
    use Scalar::Util qw( blessed );
    use Try::Tiny;
  
    try {
        MyException->throw( error => 'I feel funny.' );
    }
    catch {
        die $_ unless blessed $_ && $_->can('rethrow');
  
        if ( $_->isa('Exception::Class') ) {
            warn $_->error, "\n", $_->trace->as_string, "\n";
            warn join ' ', $_->euid, $_->egid, $_->uid, $_->gid, $_->pid, $_->time;
  
            exit;
        }
        elsif ( $_->isa('ExceptionWithFields') ) {
            if ( $_->quixotic ) {
                handle_quixotic_exception();
            }
            else {
                handle_non_quixotic_exception();
            }
        }
        else {
            $_->rethrow;
        }
    };
  
    # without Try::Tiny
  
    eval { ... };
    if ( my $e = Exception::Class->caught() ) { ... }
  
    # use an alias - without parens subroutine name is checked at
    # compile time
    throw_fields error => "No strawberry", grandiosity => "quite a bit";
  
  =head1 DESCRIPTION
  
  B<RECOMMENDATION 1>: If you are writing modern Perl code with L<Moose> or
  L<Moo> I highly recommend using L<Throwable> instead of this module.
  
  B<RECOMMENDATION 2>: Whether or not you use L<Throwable>, you should use
  L<Try::Tiny>.
  
  Exception::Class allows you to declare exception hierarchies in your
  modules in a "Java-esque" manner.
  
  It features a simple interface allowing programmers to 'declare'
  exception classes at compile time.  It also has a base exception
  class, L<Exception::Class::Base>, that can be easily extended.
  
  It is designed to make structured exception handling simpler and
  better by encouraging people to use hierarchies of exceptions in their
  applications, as opposed to a single catch-all exception class.
  
  This module does not implement any try/catch syntax.  Please see the
  "OTHER EXCEPTION MODULES (try/catch syntax)" section for more
  information on how to get this syntax.
  
  You will also want to look at the documentation for
  L<Exception::Class::Base>, which is the default base class for all
  exception objects created by this module.
  
  =head1 DECLARING EXCEPTION CLASSES
  
  Importing C<Exception::Class> allows you to automagically create
  L<Exception::Class::Base> subclasses.  You can also create subclasses
  via the traditional means of defining your own subclass with C<@ISA>.
  These two methods may be easily combined, so that you could subclass
  an exception class defined via the automagic import, if you desired
  this.
  
  The syntax for the magic declarations is as follows:
  
  'MANDATORY CLASS NAME' => \%optional_hashref
  
  The hashref may contain the following options:
  
  =over 4
  
  =item * isa
  
  This is the class's parent class.  If this isn't provided then the
  class name in C<$Exception::Class::BASE_EXC_CLASS> is assumed to be
  the parent (see below).
  
  This parameter lets you create arbitrarily deep class hierarchies.
  This can be any other L<Exception::Class::Base> subclass in your
  declaration I<or> a subclass loaded from a module.
  
  To change the default exception class you will need to change the
  value of C<$Exception::Class::BASE_EXC_CLASS> I<before> calling
  C<import()>.  To do this simply do something like this:
  
    BEGIN { $Exception::Class::BASE_EXC_CLASS = 'SomeExceptionClass'; }
  
  If anyone can come up with a more elegant way to do this please let me
  know.
  
  CAVEAT: If you want to automagically subclass an
  L<Exception::Class::Base> subclass loaded from a file, then you
  I<must> compile the class (via use or require or some other magic)
  I<before> you import C<Exception::Class> or you'll get a compile time
  error.
  
  =item * fields
  
  This allows you to define additional attributes for your exception
  class.  Any field you define can be passed to the C<throw()> or
  C<new()> methods as additional parameters for the constructor.  In
  addition, your exception object will have an accessor method for the
  fields you define.
  
  This parameter can be either a scalar (for a single field) or an array
  reference if you need to define multiple fields.
  
  Fields will be inherited by subclasses.
  
  =item * alias
  
  Specifying an alias causes this class to create a subroutine of the
  specified name in the I<caller's> namespace.  Calling this subroutine
  is equivalent to calling C<< <class>->throw(@_) >> for the given
  exception class.
  
  Besides convenience, using aliases also allows for additional compile
  time checking.  If the alias is called I<without parentheses>, as in
  C<throw_fields "an error occurred">, then Perl checks for the
  existence of the C<throw_fields()> subroutine at compile time.  If
  instead you do C<< ExceptionWithFields->throw(...) >>, then Perl
  checks the class name at runtime, meaning that typos may sneak
  through.
  
  =item * description
  
  Each exception class has a description method that returns a fixed
  string.  This should describe the exception I<class> (as opposed to
  any particular exception object).  This may be useful for debugging if
  you start catching exceptions you weren't expecting (particularly if
  someone forgot to document them) and you don't understand the error
  messages.
  
  =back
  
  The C<Exception::Class> magic attempts to detect circular class
  hierarchies and will die if it finds one.  It also detects missing
  links in a chain, for example if you declare Bar to be a subclass of
  Foo and never declare Foo.
  
  =head1 L<Try::Tiny>
  
  If you are interested in adding try/catch/finally syntactic sugar to your code
  then I recommend you check out L<Try::Tiny>. This is a great module that helps
  you ignore some of the weirdness with C<eval> and C<$@>. Here's an example of
  how the two modules work together:
  
    use Exception::Class ( 'My::Exception' );
    use Scalar::Util qw( blessed );
    use Try::Tiny;
  
    try {
        might_throw();
    }
    catch {
        if ( blessed $_ && $_->isa('My::Exception') ) {
            handle_it();
        }
        else {
            die $_;
        }
    };
  
  Note that you B<cannot> use C<< Exception::Class->caught() >> with
  L<Try::Tiny>.
  
  =head1 Catching Exceptions Without L<Try::Tiny>
  
  C<Exception::Class> provides some syntactic sugar for catching
  exceptions in a safe manner:
  
    eval {...};
  
    if ( my $e = Exception::Class->caught('My::Error') ) {
        cleanup();
        do_something_with_exception($e);
    }
  
  The C<caught()> method takes a class name and returns an exception
  object if the last thrown exception is of the given class, or a
  subclass of that class.  If it is not given any arguments, it simply
  returns C<$@>.
  
  You should B<always> make a copy of the exception object, rather than
  using C<$@> directly.  This is necessary because if your C<cleanup()>
  function uses C<eval>, or calls something which uses it, then C<$@> is
  overwritten.  Copying the exception preserves it for the call to
  C<do_something_with_exception()>.
  
  Exception objects also provide a caught method so you can write:
  
    if ( my $e = My::Error->caught() ) {
        cleanup();
        do_something_with_exception($e);
    }
  
  =head2 Uncatchable Exceptions
  
  Internally, the C<caught()> method will call C<isa()> on the exception
  object.  You could make an exception "uncatchable" by overriding
  C<isa()> in that class like this:
  
   package Exception::Uncatchable;
  
   sub isa { shift->rethrow }
  
  Of course, this only works if you always call C<< Exception::Class->caught()
  >> after an C<eval>.
  
  =head1 USAGE RECOMMENDATION
  
  If you're creating a complex system that throws lots of different
  types of exceptions, consider putting all the exception declarations
  in one place.  For an app called Foo you might make a
  C<Foo::Exceptions> module and use that in all your code.  This module
  could just contain the code to make C<Exception::Class> do its
  automagic class creation.  Doing this allows you to more easily see
  what exceptions you have, and makes it easier to keep track of them.
  
  This might look something like this:
  
    package Foo::Bar::Exceptions;
  
    use Exception::Class (
        Foo::Bar::Exception::Senses =>
            { description => 'sense-related exception' },
  
        Foo::Bar::Exception::Smell => {
            isa         => 'Foo::Bar::Exception::Senses',
            fields      => 'odor',
            description => 'stinky!'
        },
  
        Foo::Bar::Exception::Taste => {
            isa         => 'Foo::Bar::Exception::Senses',
            fields      => [ 'taste', 'bitterness' ],
            description => 'like, gag me with a spoon!'
        },
  
        ...
    );
  
  You may want to create a real module to subclass
  L<Exception::Class::Base> as well, particularly if you want your
  exceptions to have more methods.
  
  =head2 Subclassing Exception::Class::Base
  
  As part of your usage of C<Exception::Class>, you may want to create
  your own base exception class which subclasses
  L<Exception::Class::Base>.  You should feel free to subclass any of
  the methods documented above.  For example, you may want to subclass
  C<new()> to add additional information to your exception objects.
  
  =head1 Exception::Class FUNCTIONS
  
  The C<Exception::Class> method offers one function, C<Classes()>,
  which is not exported.  This method returns a list of the classes that
  have been created by calling the C<Exception::Class> import() method.
  Note that this is I<all> the subclasses that have been created, so it
  may include subclasses created by things like CPAN modules, etc.  Also
  note that if you simply define a subclass via the normal Perl method
  of setting C<@ISA> or C<use base>, then your subclass will not be
  included.
  
  =head1 SUPPORT
  
  Please submit bugs to the CPAN RT system at
  http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Exception%3A%3AClass or
  via email at bug-exception-class@rt.cpan.org.
  
  =head1 DONATIONS
  
  If you'd like to thank me for the work I've done on this module,
  please consider making a "donation" to me via PayPal. I spend a lot of
  free time creating free software, and would appreciate any support
  you'd care to offer.
  
  Please note that B<I am not suggesting that you must do this> in order
  for me to continue working on this particular software. I will
  continue to do so, inasmuch as I have in the past, for as long as it
  interests me.
  
  Similarly, a donation made in this way will probably not make me work
  on this software much more, unless I get so many donations that I can
  consider working on free software full time, which seems unlikely at
  best.
  
  To donate, log into PayPal and send money to autarch@urth.org or use
  the button on this page:
  L<http://www.urth.org/~autarch/fs-donation.html>
  
  =head1 AUTHOR
  
  Dave Rolsky <autarch@urth.org>
  
  =head1 COPYRIGHT AND LICENSE
  
  This software is copyright (c) 2013 by Dave Rolsky.
  
  This is free software; you can redistribute it and/or modify it under
  the same terms as the Perl 5 programming language system itself.
  
  =cut
EXCEPTION_CLASS

$fatpacked{"Exception/Class/Base.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'EXCEPTION_CLASS_BASE';
  package Exception::Class::Base;
  {
    $Exception::Class::Base::VERSION = '1.37';
  }
  
  use strict;
  use warnings;
  
  use Class::Data::Inheritable 0.02;
  use Devel::StackTrace 1.20;
  use Scalar::Util qw( blessed );
  
  use base qw(Class::Data::Inheritable);
  
  BEGIN {
      __PACKAGE__->mk_classdata('Trace');
      __PACKAGE__->mk_classdata('NoRefs');
      __PACKAGE__->NoRefs(1);
  
      __PACKAGE__->mk_classdata('NoContextInfo');
      __PACKAGE__->NoContextInfo(0);
  
      __PACKAGE__->mk_classdata('RespectOverload');
      __PACKAGE__->RespectOverload(0);
  
      __PACKAGE__->mk_classdata('MaxArgLength');
      __PACKAGE__->MaxArgLength(0);
  
      sub Fields { () }
  }
  
  use overload
  
      # an exception is always true
      bool => sub { 1 }, '""' => 'as_string', fallback => 1;
  
  # Create accessor routines
  BEGIN {
      my @fields = qw( message pid uid euid gid egid time trace );
  
      foreach my $f (@fields) {
          my $sub = sub { my $s = shift; return $s->{$f}; };
  
          no strict 'refs';
          *{$f} = $sub;
      }
      *error = \&message;
  
      my %trace_fields = (
          package => 'package',
          file    => 'filename',
          line    => 'line',
      );
  
      while ( my ( $f, $m ) = each %trace_fields ) {
          my $sub = sub {
              my $s = shift;
              return $s->{$f} if exists $s->{$f};
  
              my $frame = $s->trace->frame(0);
  
              return $s->{$f} = $frame ? $frame->$m() : undef;
          };
          no strict 'refs';
          *{$f} = $sub;
      }
  }
  
  1;
  
  sub Classes { Exception::Class::Classes() }
  
  sub throw {
      my $proto = shift;
  
      $proto->rethrow if ref $proto;
  
      die $proto->new(@_);
  }
  
  sub rethrow {
      my $self = shift;
  
      die $self;
  }
  
  sub new {
      my $proto = shift;
      my $class = ref $proto || $proto;
  
      my $self = bless {}, $class;
  
      $self->_initialize(@_);
  
      return $self;
  }
  
  sub _initialize {
      my $self = shift;
      my %p = @_ == 1 ? ( error => $_[0] ) : @_;
  
      $self->{message} = $p{message} || $p{error} || '';
  
      $self->{show_trace} = $p{show_trace} if exists $p{show_trace};
  
      if ( $self->NoContextInfo() ) {
          $self->{show_trace} = 0;
          $self->{package} = $self->{file} = $self->{line} = undef;
      }
      else {
          # CORE::time is important to fix an error with some versions of
          # Perl
          $self->{time} = CORE::time();
          $self->{pid}  = $$;
          $self->{uid}  = $<;
          $self->{euid} = $>;
          $self->{gid}  = $(;
          $self->{egid} = $);
  
          my @ignore_class   = (__PACKAGE__);
          my @ignore_package = 'Exception::Class';
  
          if ( my $i = delete $p{ignore_class} ) {
              push @ignore_class, ( ref($i) eq 'ARRAY' ? @$i : $i );
          }
  
          if ( my $i = delete $p{ignore_package} ) {
              push @ignore_package, ( ref($i) eq 'ARRAY' ? @$i : $i );
          }
  
          $self->{trace} = Devel::StackTrace->new(
              ignore_class     => \@ignore_class,
              ignore_package   => \@ignore_package,
              no_refs          => $self->NoRefs,
              respect_overload => $self->RespectOverload,
              max_arg_length   => $self->MaxArgLength,
          );
      }
  
      my %fields = map { $_ => 1 } $self->Fields;
      while ( my ( $key, $value ) = each %p ) {
          next if $key =~ /^(?:error|message|show_trace)$/;
  
          if ( $fields{$key} ) {
              $self->{$key} = $value;
          }
          else {
              Exception::Class::Base->throw(
                  error => "unknown field $key passed to constructor for class "
                      . ref $self );
          }
      }
  }
  
  sub description {
      return 'Generic exception';
  }
  
  sub show_trace {
      my $self = shift;
  
      return 0 unless $self->{trace};
  
      if (@_) {
          $self->{show_trace} = shift;
      }
  
      return exists $self->{show_trace} ? $self->{show_trace} : $self->Trace;
  }
  
  sub as_string {
      my $self = shift;
  
      my $str = $self->full_message;
      $str .= "\n\n" . $self->trace->as_string
          if $self->show_trace;
  
      return $str;
  }
  
  sub full_message { $_[0]->{message} }
  
  #
  # The %seen bit protects against circular inheritance.
  #
  eval <<'EOF' if $] == 5.006;
  sub isa {
      my ( $inheritor, $base ) = @_;
      $inheritor = ref($inheritor) if ref($inheritor);
  
      my %seen;
  
      no strict 'refs';
      my @parents = ( $inheritor, @{"$inheritor\::ISA"} );
      while ( my $class = shift @parents ) {
          return 1 if $class eq $base;
  
          push @parents, grep { !$seen{$_}++ } @{"$class\::ISA"};
      }
      return 0;
  }
  EOF
  
  sub caught {
      my $class = shift;
  
      my $e = $@;
  
      return unless defined $e && blessed($e) && $e->isa($class);
      return $e;
  }
  
  1;
  
  # ABSTRACT: A base class for exception objects
  
  __END__
  
  =pod
  
  =head1 NAME
  
  Exception::Class::Base - A base class for exception objects
  
  =head1 VERSION
  
  version 1.37
  
  =head1 SYNOPSIS
  
    use Exception::Class 'MyException';
  
    eval { MyException->throw( error => 'I feel funny.' ) };
  
    print $@->error();
  
  =head1 DESCRIPTION
  
  This class is the base class for all exceptions created by
  L<Exception::Class>. It provides a number of methods for getting
  information about the exception.
  
  =head1 METHODS
  
  =head2 MyException->Trace($boolean)
  
  Each C<Exception::Class::Base> subclass can be set individually to
  include a stacktrace when the C<as_string> method is called.  The
  default is to not include a stacktrace.  Calling this method with a
  value changes this behavior.  It always returns the current value
  (after any change is applied).
  
  This value is inherited by any subclasses.  However, if this value is
  set for a subclass, it will thereafter be independent of the value in
  C<Exception::Class::Base>.
  
  Do not call this on the C<Exception::Class::Base> class directly or
  you'll change it for all exception classes that use
  L<Exception::Class>, including ones created in modules you don't
  control.
  
  This is a class method, not an object method.
  
  =head2 MyException->NoRefs($boolean)
  
  When a C<Devel::StackTrace> object is created, it walks through the
  stack and stores the arguments which were passed to each subroutine on
  the stack.  If any of these arguments are references, then that means
  that the C<Devel::StackTrace> ends up increasing the refcount of these
  references, delaying their destruction.
  
  Since C<Exception::Class::Base> uses C<Devel::StackTrace> internally,
  this method provides a way to tell C<Devel::StackTrace> not to store
  these references.  Instead, C<Devel::StackTrace> replaces references
  with their stringified representation.
  
  This method defaults to true.  As with C<Trace()>, it is inherited by
  subclasses but setting it in a subclass makes it independent
  thereafter.
  
  Do not call this on the C<Exception::Class::Base> class directly or
  you'll change it for all exception classes that use
  L<Exception::Class>, including ones created in modules you don't
  control.
  
  =head2 MyException->RespectOverload($boolean)
  
  When a C<Devel::StackTrace> object stringifies, by default it ignores
  stringification overloading on any objects being dealt with.
  
  Since C<Exception::Class::Base> uses C<Devel::StackTrace> internally,
  this method provides a way to tell C<Devel::StackTrace> to respect
  overloading.
  
  This method defaults to false.  As with C<Trace()>, it is inherited by
  subclasses but setting it in a subclass makes it independent
  thereafter.
  
  Do not call this on the C<Exception::Class::Base> class directly or
  you'll change it for all exception classes that use
  L<Exception::Class>, including ones created in modules you don't
  control.
  
  =head2 MyException->MaxArgLength($boolean)
  
  When a C<Devel::StackTrace> object stringifies, by default it displays
  the full argument for each function. This parameter can be used to
  limit the maximum length of each argument.
  
  Since C<Exception::Class::Base> uses C<Devel::StackTrace> internally,
  this method provides a way to tell C<Devel::StackTrace> to limit the
  length of arguments.
  
  This method defaults to 0. As with C<Trace()>, it is inherited by
  subclasses but setting it in a subclass makes it independent
  thereafter.
  
  Do not call this on the C<Exception::Class::Base> class directly or
  you'll change it for all exception classes that use
  L<Exception::Class>, including ones created in modules you don't
  control.
  
  =head2 MyException->Fields
  
  This method returns the extra fields defined for the given class, as
  an array.
  
  Do not call this on the C<Exception::Class::Base> class directly or
  you'll change it for all exception classes that use
  L<Exception::Class>, including ones created in modules you don't
  control.
  
  =head2 MyException->throw( $message )
  
  =head2 MyException->throw( message => $message )
  
  =head2 MyException->throw( error => $error )
  
  This method creates a new object with the given error message.  If no
  error message is given, this will be an empty string.  It then dies
  with this object as its argument.
  
  This method also takes a C<show_trace> parameter which indicates
  whether or not the particular exception object being created should
  show a stacktrace when its C<as_string()> method is called.  This
  overrides the value of C<Trace()> for this class if it is given.
  
  The frames included in the trace can be controlled by the C<ignore_class>
  and C<ignore_package> parameters. These are passed directly to
  Devel::Stacktrace's constructor. See C<Devel::Stacktrace> for more details.
  
  If only a single value is given to the constructor it is assumed to be
  the message parameter.
  
  Additional keys corresponding to the fields defined for the particular
  exception subclass will also be accepted.
  
  =head2 MyException->new(...)
  
  This method takes the same parameters as C<throw()>, but instead of
  dying simply returns a new exception object.
  
  This method is always called when constructing a new exception object
  via the C<throw()> method.
  
  =head2 MyException->description()
  
  Returns the description for the given C<Exception::Class::Base>
  subclass.  The C<Exception::Class::Base> class's description is
  "Generic exception" (this may change in the future).  This is also an
  object method.
  
  =head2 $exception->rethrow()
  
  Simply dies with the object as its sole argument.  It's just syntactic
  sugar.  This does not change any of the object's attribute values.
  However, it will cause C<caller()> to report the die as coming from
  within the C<Exception::Class::Base> class rather than where rethrow
  was called.
  
  Of course, you always have access to the original stacktrace for the
  exception object.
  
  =head2 $exception->message()
  
  =head2 $exception->error()
  
  Returns the error/message associated with the exception.
  
  =head2 $exception->pid()
  
  Returns the pid at the time the exception was thrown.
  
  =head2 $exception->uid()
  
  Returns the real user id at the time the exception was thrown.
  
  =head2 $exception->gid()
  
  Returns the real group id at the time the exception was thrown.
  
  =head2 $exception->euid()
  
  Returns the effective user id at the time the exception was thrown.
  
  =head2 $exception->egid()
  
  Returns the effective group id at the time the exception was thrown.
  
  =head2 $exception->time()
  
  Returns the time in seconds since the epoch at the time the exception
  was thrown.
  
  =head2 $exception->package()
  
  Returns the package from which the exception was thrown.
  
  =head2 $exception->file()
  
  Returns the file within which the exception was thrown.
  
  =head2 $exception->line()
  
  Returns the line where the exception was thrown.
  
  =head2 $exception->trace()
  
  Returns the trace object associated with the object.
  
  =head2 $exception->show_trace($boolean)
  
  This method can be used to set whether or not a stack trace is
  included when the as_string method is called or the object is
  stringified.
  
  =head2 $exception->as_string()
  
  Returns a string form of the error message (something like what you'd
  expect from die).  If the class or object is set to show traces then
  then the full trace is also included.  The result looks like
  C<Carp::confess()>.
  
  =head2 $exception->full_message()
  
  Called by the C<as_string()> method to get the message.  By default,
  this is the same as calling the C<message()> method, but may be
  overridden by a subclass.  See below for details.
  
  =head1 LIGHTWEIGHT EXCEPTIONS
  
  A lightweight exception is one which records no information about its context
  when it is created. This can be achieved by setting C<<
  $class->NoContextInfo() >> to a true value.
  
  You can make this the default for a class of exceptions by setting it after
  creating the class:
  
    use Exception::Class (
        'LightWeight',
        'HeavyWeight',
    );
  
    LightWeight->NoContextInfo(1);
  
  A lightweight exception does have a stack trace object, nor does it record the
  time, pid, uid, euid, gid, or egid. It only has a message.
  
  =head1 OVERLOADING
  
  C<Exception::Class::Base> objects are overloaded so that
  stringification produces a normal error message.  This just calls the
  C<< $exception->as_string() >> method described above.  This means
  that you can just C<print $@> after an C<eval> and not worry about
  whether or not its an actual object.  It also means an application or
  module could do this:
  
   $SIG{__DIE__} = sub { Exception::Class::Base->throw( error => join '', @_ ); };
  
  and this would probably not break anything (unless someone was
  expecting a different type of exception object from C<die()>).
  
  =head1 OVERRIDING THE as_string METHOD
  
  By default, the C<as_string()> method simply returns the value
  C<message> or C<error> param plus a stack trace, if the class's
  C<Trace()> method returns a true value or C<show_trace> was set when
  creating the exception.
  
  However, once you add new fields to a subclass, you may want to
  include those fields in the stringified error.
  
  Inside the C<as_string()> method, the message (non-stack trace)
  portion of the error is generated by calling the C<full_message()>
  method.  This can be easily overridden.  For example:
  
    sub full_message {
        my $self = shift;
  
        my $msg = $self->message;
  
        $msg .= " and foo was " . $self->foo;
  
        return $msg;
    }
  
  =head1 AUTHOR
  
  Dave Rolsky <autarch@urth.org>
  
  =head1 COPYRIGHT AND LICENSE
  
  This software is copyright (c) 2013 by Dave Rolsky.
  
  This is free software; you can redistribute it and/or modify it under
  the same terms as the Perl 5 programming language system itself.
  
  =cut
EXCEPTION_CLASS_BASE

$fatpacked{"File/pushd.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'FILE_PUSHD';
  use strict;
  use warnings;
  package File::pushd;
  # ABSTRACT: change directory temporarily for a limited scope
  our $VERSION = '1.005'; # VERSION
  
  our @EXPORT  = qw( pushd tempd );
  our @ISA     = qw( Exporter );
  
  use Exporter;
  use Carp;
  use Cwd         qw( getcwd abs_path );
  use File::Path  qw( rmtree );
  use File::Temp  qw();
  use File::Spec;
  
  use overload
      q{""} => sub { File::Spec->canonpath( $_[0]->{_pushd} ) },
      fallback => 1;
  
  #--------------------------------------------------------------------------#
  # pushd()
  #--------------------------------------------------------------------------#
  
  sub pushd {
      my ($target_dir, $options) = @_;
      $options->{untaint_pattern} ||= qr{^([-+@\w./]+)$};
  
      $target_dir = "." unless defined $target_dir;
      croak "Can't locate directory $target_dir" unless -d $target_dir;
  
      my $tainted_orig = getcwd;
      my $orig;
      if ( $tainted_orig =~ $options->{untaint_pattern} ) {
        $orig = $1;
      }
      else {
        $orig = $tainted_orig;
      }
  
      my $tainted_dest;
      eval { $tainted_dest   = $target_dir ? abs_path( $target_dir ) : $orig };
      croak "Can't locate absolute path for $target_dir: $@" if $@;
  
      my $dest;
      if ( $tainted_dest =~ $options->{untaint_pattern} ) {
        $dest = $1;
      }
      else {
        $dest = $tainted_dest;
      }
  
      if ($dest ne $orig) {
          chdir $dest or croak "Can't chdir to $dest\: $!";
      }
  
      my $self = bless {
          _pushd => $dest,
          _original => $orig
      }, __PACKAGE__;
  
      return $self;
  }
  
  #--------------------------------------------------------------------------#
  # tempd()
  #--------------------------------------------------------------------------#
  
  sub tempd {
      my ($options) = @_;
      my $dir;
      eval { $dir = pushd( File::Temp::tempdir( CLEANUP => 0 ), $options ) };
      croak $@ if $@;
      $dir->{_tempd} = 1;
      return $dir;
  }
  
  #--------------------------------------------------------------------------#
  # preserve()
  #--------------------------------------------------------------------------#
  
  sub preserve {
      my $self = shift;
      return 1 if ! $self->{"_tempd"};
      if ( @_ == 0 ) {
          return $self->{_preserve} = 1;
      }
      else {
          return $self->{_preserve} = $_[0] ? 1 : 0;
      }
  }
  
  #--------------------------------------------------------------------------#
  # DESTROY()
  # Revert to original directory as object is destroyed and cleanup
  # if necessary
  #--------------------------------------------------------------------------#
  
  sub DESTROY {
      my ($self) = @_;
      my $orig = $self->{_original};
      chdir $orig if $orig; # should always be so, but just in case...
      if ( $self->{_tempd} &&
          !$self->{_preserve} ) {
          # don't destroy existing $@ if there is no error.
          my $err = do {
              local $@;
              eval { rmtree( $self->{_pushd} ) };
              $@;
          };
          carp $err if $err;
      }
  }
  
  1;
  
  __END__
  
  =pod
  
  =head1 NAME
  
  File::pushd - change directory temporarily for a limited scope
  
  =head1 VERSION
  
  version 1.005
  
  =head1 SYNOPSIS
  
    use File::pushd;
   
    chdir $ENV{HOME};
   
    # change directory again for a limited scope
    {
        my $dir = pushd( '/tmp' );
        # working directory changed to /tmp
    }
    # working directory has reverted to $ENV{HOME}
   
    # tempd() is equivalent to pushd( File::Temp::tempdir )
    {
        my $dir = tempd();
    }
   
    # object stringifies naturally as an absolute path
    {
       my $dir = pushd( '/tmp' );
       my $filename = File::Spec->catfile( $dir, "somefile.txt" );
       # gives /tmp/somefile.txt
    }
  
  =head1 DESCRIPTION
  
  File::pushd does a temporary C<<< chdir >>> that is easily and automatically
  reverted, similar to C<<< pushd >>> in some Unix command shells.  It works by
  creating an object that caches the original working directory.  When the object
  is destroyed, the destructor calls C<<< chdir >>> to revert to the original working
  directory.  By storing the object in a lexical variable with a limited scope,
  this happens automatically at the end of the scope.
  
  This is very handy when working with temporary directories for tasks like
  testing; a function is provided to streamline getting a temporary
  directory from L<File::Temp>.
  
  For convenience, the object stringifies as the canonical form of the absolute
  pathname of the directory entered.
  
  =head1 USAGE
  
    use File::pushd;
  
  Using File::pushd automatically imports the C<<< pushd >>> and C<<< tempd >>> functions.
  
  =head2 pushd
  
    {
        my $dir = pushd( $target_directory );
    }
  
  Caches the current working directory, calls C<<< chdir >>> to change to the target
  directory, and returns a File::pushd object.  When the object is
  destroyed, the working directory reverts to the original directory.
  
  The provided target directory can be a relative or absolute path. If
  called with no arguments, it uses the current directory as its target and
  returns to the current directory when the object is destroyed.
  
  If the target directory does not exist or if the directory change fails
  for some reason, C<<< pushd >>> will die with an error message.
  
  Can be given a hashref as an optional second argument.  The only supported
  option is C<<< untaint_pattern >>>, which is used to untaint file paths involved.
  It defaults to C<<< qr{^([-+@\w./]+)$} >>>, which is reasonably restrictive (e.g.
  it does not even allow spaces in the path).  Change this to suit your
  circumstances and security needs if running under taint mode. B<Note>: you
  must include the parentheses in the pattern to capture the untainted
  portion of the path.
  
  =head2 tempd
  
    {
        my $dir = tempd();
    }
  
  This function is like C<<< pushd >>> but automatically creates and calls C<<< chdir >>> to
  a temporary directory created by L<File::Temp>. Unlike normal L<File::Temp>
  cleanup which happens at the end of the program, this temporary directory is
  removed when the object is destroyed. (But also see C<<< preserve >>>.)  A warning
  will be issued if the directory cannot be removed.
  
  As with C<<< pushd >>>, C<<< tempd >>> will die if C<<< chdir >>> fails.
  
  It may be given a single options hash that will be passed internally
  to CE<lt>pushdE<gt>.
  
  =head2 preserve
  
    {
        my $dir = tempd();
        $dir->preserve;      # mark to preserve at end of scope
        $dir->preserve(0);   # mark to delete at end of scope
    }
  
  Controls whether a temporary directory will be cleaned up when the object is
  destroyed.  With no arguments, C<<< preserve >>> sets the directory to be preserved.
  With an argument, the directory will be preserved if the argument is true, or
  marked for cleanup if the argument is false.  Only C<<< tempd >>> objects may be
  marked for cleanup.  (Target directories to C<<< pushd >>> are always preserved.)
  C<<< preserve >>> returns true if the directory will be preserved, and false
  otherwise.
  
  =head1 SEE ALSO
  
  =over
  
  =item *
  
  L<File::chdir>
  
  =back
  
  =for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan
  
  =head1 SUPPORT
  
  =head2 Bugs / Feature Requests
  
  Please report any bugs or feature requests through the issue tracker
  at L<https://github.com/dagolden/file-pushd/issues>.
  You will be notified automatically of any progress on your issue.
  
  =head2 Source Code
  
  This is open source software.  The code repository is available for
  public review and contribution under the terms of the license.
  
  L<https://github.com/dagolden/file-pushd>
  
    git clone git://github.com/dagolden/file-pushd.git
  
  =head1 AUTHOR
  
  David Golden <dagolden@cpan.org>
  
  =head1 CONTRIBUTOR
  
  Diab Jerius <djerius@cfa.harvard.edu>
  
  =head1 COPYRIGHT AND LICENSE
  
  This software is Copyright (c) 2013 by David A Golden.
  
  This is free software, licensed under:
  
    The Apache License, Version 2.0, January 2004
  
  =cut
FILE_PUSHD

$fatpacked{"Import/Into.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'IMPORT_INTO';
  package Import::Into;
  
  use strict;
  use warnings FATAL => 'all';
  use Module::Runtime;
  
  our $VERSION = '1.002004';
  
  sub _prelude {
    my $target = shift;
    my ($package, $file, $line, $level)
      = ref $target         ? @{$target}{qw(package filename line)}
      : $target =~ /[^0-9]/ ? ($target)
                            : (undef, undef, undef, $target);
    if (defined $level) {
      my ($p, $fn, $ln) = caller($level + 2);
      $package ||= $p;
      $file    ||= $fn;
      $line    ||= $ln;
    }
    qq{package $package;\n}
      . ($file ? "#line $line \"$file\"\n" : '')
  }
  
  sub _make_action {
    my ($action, $target) = @_;
    my $version = ref $target && $target->{version};
    my $ver_check = $version ? ', $version' : '';
    eval _prelude($target)
      . qq{sub { Module::Runtime::use_module( shift$ver_check )->$action(\@_) }}
      or die "Failed to build action sub to ${action} for ${target}: $@";
  }
  
  sub import::into {
    my ($class, $target, @args) = @_;
    _make_action(import => $target)->($class, @args);
  }
  
  sub unimport::out_of {
    my ($class, $target, @args) = @_;
    _make_action(unimport => $target)->($class, @args);
  }
  
  1;
  
  __END__
  
  =head1 NAME
  
  Import::Into - Import packages into other packages
  
  =head1 SYNOPSIS
  
    package My::MultiExporter;
  
    use Import::Into;
  
    # simple
    sub import {
      Thing1->import::into(scalar caller);
    }
  
    # multiple
    sub import {
      my $target = caller;
      Thing1->import::into($target);
      Thing2->import::into($target, qw(import arguments));
    }
  
    # by level
    sub import {
      Thing1->import::into(1);
    }
  
    # with exporter
    use base qw(Exporter);
    sub import {
      shift->export_to_level(1);
      Thing1->import::into(1);
    }
  
    # no My::MultiExporter == no Thing1
    sub unimport {
      Thing1->unimport::out_of(scalar caller);
    }
  
  People wanting to re-export your module should also be using L<Import::Into>.
  Any exporter or pragma will work seamlessly.
  
  Note: You do B<not> need to make any changes to Thing1 to be able to call
  C<import::into> on it. This is a global method, and is callable on any
  package (and in fact on any object as well, although it's rarer that you'd
  want to do that).
  
  =head1 DESCRIPTION
  
  Writing exporters is a pain. Some use L<Exporter>, some use L<Sub::Exporter>,
  some use L<Moose::Exporter>, some use L<Exporter::Declare> ... and some things
  are pragmas.
  
  Exporting on someone else's behalf is harder.  The exporters don't provide a
  consistent API for this, and pragmas need to have their import method called
  directly, since they effect the current unit of compilation.
  
  C<Import::Into> provides global methods to make this painless.
  
  =head1 METHODS
  
  =head2 $package->import::into( $target, @arguments );
  
  A global method, callable on any package.  Loads and imports the given package
  into C<$target>.  C<@arguments> are passed along to the package's import method.
  
  C<$target> can be an package name to export to, an integer for the
  caller level to export to, or a hashref with the following options:
  
  =over 4
  
  =item package
  
  The target package to export to.
  
  =item filename
  
  The apparent filename to export to.  Some exporting modules, such as
  L<autodie> or L<strictures>, care about the filename they are being imported
  to.
  
  =item line
  
  The apparent line number to export to.  To be combined with the C<filename>
  option.
  
  =item level
  
  The caller level to export to.  This will automatically populate the
  C<package>, C<filename>, and C<line> options, making it the easiest most
  constent option.
  
  =item version
  
  A version number to check for the module.  The equivalent of specifying the
  version number on a C<use> line.
  
  =back
  
  =head2 $package->unimport::out_of( $target, @arguments );
  
  Equivalent to C<import::into>, but dispatches to C<$package>'s C<unimport>
  method instead of C<import>.
  
  =head1 WHY USE THIS MODULE
  
  The APIs for exporting modules aren't consistent.  L<Exporter> subclasses
  provide export_to_level, but if they overrode their import method all bets
  are off.  L<Sub::Exporter> provides an into parameter but figuring out
  something used it isn't trivial. Pragmas need to have their C<import> method
  called directly since they affect the current unit of compilation.
  
  It's ... annoying.
  
  However, there is an approach that actually works for all of these types.
  
    eval "package $target; use $thing;"
  
  will work for anything checking caller, which is everything except pragmas.
  But it doesn't work for pragmas - pragmas need:
  
    $thing->import;
  
  because they're designed to affect the code currently being compiled - so
  within an eval, that's the scope of the eval itself, not the module that
  just C<use>d you - so
  
    sub import {
      eval "use strict;"
    }
  
  doesn't do what you wanted, but
  
    sub import {
      strict->import;
    }
  
  will apply L<strict> to the calling file correctly.
  
  Of course, now you have two new problems - first, that you still need to
  know if something's a pragma, and second that you can't use either of
  these approaches alone on something like L<Moose> or L<Moo> that's both
  an exporter and a pragma.
  
  So, a solution for that is:
  
    use Module::Runtime;
    my $sub = eval "package $target; sub { use_module(shift)->import(\@_) }";
    $sub->($thing, @import_args);
  
  which means that import is called from the right place for pragmas to take
  effect, and from the right package for caller checking to work - and so
  behaves correctly for all types of exporter, for pragmas, and for hybrids.
  
  Additionally, some import routines check the filename they are being imported
  to.  This can be dealt with by generating a L<#line directive|perlsyn/Plain
  Old Comments (Not!)> in the eval, which will change what C<caller> reports for
  the filename when called in the importer. The filename and line number to use
  in the directive then need to be fetched using C<caller>:
  
    my ($target, $file, $line) = caller(1);
    my $sub = eval qq{
      package $target;
    #line $line "$file"
      sub { use_module(shift)->import(\@_) }
    };
    $sub->($thing, @import_args);
  
  And you need to switch between these implementations depending on if you are
  targeting a specific package, or something in your call stack.
  
  Remembering all this, however, is excessively irritating. So I wrote a module
  so I didn't have to anymore. Loading L<Import::Into> creates a global method
  C<import::into> which you can call on any package to import it into another
  package. So now you can simply write:
  
    use Import::Into;
  
    $thing->import::into($target, @import_args);
  
  This works because of how perl resolves method calls - a call to a simple
  method name is resolved against the package of the class or object, so
  
    $thing->method_name(@args);
  
  is roughly equivalent to:
  
    my $code_ref = $thing->can('method_name');
    $code_ref->($thing, @args);
  
  while if a C<::> is found, the lookup is made relative to the package name
  (i.e. everything before the last C<::>) so
  
    $thing->Package::Name::method_name(@args);
  
  is roughly equivalent to:
  
    my $code_ref = Package::Name->can('method_name');
    $code_ref->($thing, @args);
  
  So since L<Import::Into> defines a method C<into> in package C<import>
  the syntax reliably calls that.
  
  For more craziness of this order, have a look at the article I wrote at
  L<http://shadow.cat/blog/matt-s-trout/madness-with-methods> which covers
  coderef abuse and the C<${\...}> syntax.
  
  And that's it.
  
  =head1 SEE ALSO
  
  I gave a lightning talk on this module (and L<curry> and L<Safe::Isa>) at
  L<YAPC::NA 2013|https://www.youtube.com/watch?v=wFXWV2yY7gE&t=46m05s>.
  
  =head1 ACKNOWLEDGEMENTS
  
  Thanks to Getty for asking "how can I get C<< use strict; use warnings; >>
  turned on for all consumers of my code?" and then "why is this not a
  module?!".
  
  =head1 AUTHOR
  
  mst - Matt S. Trout (cpan:MSTROUT) <mst@shadowcat.co.uk>
  
  =head1 CONTRIBUTORS
  
  haarg - Graham Knop (cpan:HAARG) <haarg@haarg.org>
  
  Mithaldu - Christian Walde (cpan:MITHALDU) <walde.christian@gmail.com>
  
  =head1 COPYRIGHT
  
  Copyright (c) 2012 the Import::Into L</AUTHOR> and L</CONTRIBUTORS>
  as listed above.
  
  =head1 LICENSE
  
  This library is free software and may be distributed under the same terms
  as perl itself.
  
  =cut
IMPORT_INTO

$fatpacked{"JSON.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'JSON';
  package JSON;
  
  
  use strict;
  use Carp ();
  use base qw(Exporter);
  @JSON::EXPORT = qw(from_json to_json jsonToObj objToJson encode_json decode_json);
  
  BEGIN {
      $JSON::VERSION = '2.59';
      $JSON::DEBUG   = 0 unless (defined $JSON::DEBUG);
      $JSON::DEBUG   = $ENV{ PERL_JSON_DEBUG } if exists $ENV{ PERL_JSON_DEBUG };
  }
  
  my $Module_XS  = 'JSON::XS';
  my $Module_PP  = 'JSON::PP';
  my $Module_bp  = 'JSON::backportPP'; # included in JSON distribution
  my $PP_Version = '2.27200';
  my $XS_Version = '2.34';
  
  
  # XS and PP common methods
  
  my @PublicMethods = qw/
      ascii latin1 utf8 pretty indent space_before space_after relaxed canonical allow_nonref 
      allow_blessed convert_blessed filter_json_object filter_json_single_key_object 
      shrink max_depth max_size encode decode decode_prefix allow_unknown
  /;
  
  my @Properties = qw/
      ascii latin1 utf8 indent space_before space_after relaxed canonical allow_nonref
      allow_blessed convert_blessed shrink max_depth max_size allow_unknown
  /;
  
  my @XSOnlyMethods = qw//; # Currently nothing
  
  my @PPOnlyMethods = qw/
      indent_length sort_by
      allow_singlequote allow_bignum loose allow_barekey escape_slash as_nonblessed
  /; # JSON::PP specific
  
  
  # used in _load_xs and _load_pp ($INSTALL_ONLY is not used currently)
  my $_INSTALL_DONT_DIE  = 1; # When _load_xs fails to load XS, don't die.
  my $_INSTALL_ONLY      = 2; # Don't call _set_methods()
  my $_ALLOW_UNSUPPORTED = 0;
  my $_UNIV_CONV_BLESSED = 0;
  my $_USSING_bpPP       = 0;
  
  
  # Check the environment variable to decide worker module. 
  
  unless ($JSON::Backend) {
      $JSON::DEBUG and  Carp::carp("Check used worker module...");
  
      my $backend = exists $ENV{PERL_JSON_BACKEND} ? $ENV{PERL_JSON_BACKEND} : 1;
  
      if ($backend eq '1' or $backend =~ /JSON::XS\s*,\s*JSON::PP/) {
          _load_xs($_INSTALL_DONT_DIE) or _load_pp();
      }
      elsif ($backend eq '0' or $backend eq 'JSON::PP') {
          _load_pp();
      }
      elsif ($backend eq '2' or $backend eq 'JSON::XS') {
          _load_xs();
      }
      elsif ($backend eq 'JSON::backportPP') {
          $_USSING_bpPP = 1;
          _load_pp();
      }
      else {
          Carp::croak "The value of environmental variable 'PERL_JSON_BACKEND' is invalid.";
      }
  }
  
  
  sub import {
      my $pkg = shift;
      my @what_to_export;
      my $no_export;
  
      for my $tag (@_) {
          if ($tag eq '-support_by_pp') {
              if (!$_ALLOW_UNSUPPORTED++) {
                  JSON::Backend::XS
                      ->support_by_pp(@PPOnlyMethods) if ($JSON::Backend eq $Module_XS);
              }
              next;
          }
          elsif ($tag eq '-no_export') {
              $no_export++, next;
          }
          elsif ( $tag eq '-convert_blessed_universally' ) {
              eval q|
                  require B;
                  *UNIVERSAL::TO_JSON = sub {
                      my $b_obj = B::svref_2object( $_[0] );
                      return    $b_obj->isa('B::HV') ? { %{ $_[0] } }
                              : $b_obj->isa('B::AV') ? [ @{ $_[0] } ]
                              : undef
                              ;
                  }
              | if ( !$_UNIV_CONV_BLESSED++ );
              next;
          }
          push @what_to_export, $tag;
      }
  
      return if ($no_export);
  
      __PACKAGE__->export_to_level(1, $pkg, @what_to_export);
  }
  
  
  # OBSOLETED
  
  sub jsonToObj {
      my $alternative = 'from_json';
      if (defined $_[0] and UNIVERSAL::isa($_[0], 'JSON')) {
          shift @_; $alternative = 'decode';
      }
      Carp::carp "'jsonToObj' will be obsoleted. Please use '$alternative' instead.";
      return JSON::from_json(@_);
  };
  
  sub objToJson {
      my $alternative = 'to_json';
      if (defined $_[0] and UNIVERSAL::isa($_[0], 'JSON')) {
          shift @_; $alternative = 'encode';
      }
      Carp::carp "'objToJson' will be obsoleted. Please use '$alternative' instead.";
      JSON::to_json(@_);
  };
  
  
  # INTERFACES
  
  sub to_json ($@) {
      if (
          ref($_[0]) eq 'JSON'
          or (@_ > 2 and $_[0] eq 'JSON')
      ) {
          Carp::croak "to_json should not be called as a method.";
      }
      my $json = JSON->new;
  
      if (@_ == 2 and ref $_[1] eq 'HASH') {
          my $opt  = $_[1];
          for my $method (keys %$opt) {
              $json->$method( $opt->{$method} );
          }
      }
  
      $json->encode($_[0]);
  }
  
  
  sub from_json ($@) {
      if ( ref($_[0]) eq 'JSON' or $_[0] eq 'JSON' ) {
          Carp::croak "from_json should not be called as a method.";
      }
      my $json = JSON->new;
  
      if (@_ == 2 and ref $_[1] eq 'HASH') {
          my $opt  = $_[1];
          for my $method (keys %$opt) {
              $json->$method( $opt->{$method} );
          }
      }
  
      return $json->decode( $_[0] );
  }
  
  
  sub true  { $JSON::true  }
  
  sub false { $JSON::false }
  
  sub null  { undef; }
  
  
  sub require_xs_version { $XS_Version; }
  
  sub backend {
      my $proto = shift;
      $JSON::Backend;
  }
  
  #*module = *backend;
  
  
  sub is_xs {
      return $_[0]->module eq $Module_XS;
  }
  
  
  sub is_pp {
      return not $_[0]->xs;
  }
  
  
  sub pureperl_only_methods { @PPOnlyMethods; }
  
  
  sub property {
      my ($self, $name, $value) = @_;
  
      if (@_ == 1) {
          my %props;
          for $name (@Properties) {
              my $method = 'get_' . $name;
              if ($name eq 'max_size') {
                  my $value = $self->$method();
                  $props{$name} = $value == 1 ? 0 : $value;
                  next;
              }
              $props{$name} = $self->$method();
          }
          return \%props;
      }
      elsif (@_ > 3) {
          Carp::croak('property() can take only the option within 2 arguments.');
      }
      elsif (@_ == 2) {
          if ( my $method = $self->can('get_' . $name) ) {
              if ($name eq 'max_size') {
                  my $value = $self->$method();
                  return $value == 1 ? 0 : $value;
              }
              $self->$method();
          }
      }
      else {
          $self->$name($value);
      }
  
  }
  
  
  
  # INTERNAL
  
  sub _load_xs {
      my $opt = shift;
  
      $JSON::DEBUG and Carp::carp "Load $Module_XS.";
  
      # if called after install module, overload is disable.... why?
      JSON::Boolean::_overrride_overload($Module_XS);
      JSON::Boolean::_overrride_overload($Module_PP);
  
      eval qq|
          use $Module_XS $XS_Version ();
      |;
  
      if ($@) {
          if (defined $opt and $opt & $_INSTALL_DONT_DIE) {
              $JSON::DEBUG and Carp::carp "Can't load $Module_XS...($@)";
              return 0;
          }
          Carp::croak $@;
      }
  
      unless (defined $opt and $opt & $_INSTALL_ONLY) {
          _set_module( $JSON::Backend = $Module_XS );
          my $data = join("", <DATA>); # this code is from Jcode 2.xx.
          close(DATA);
          eval $data;
          JSON::Backend::XS->init;
      }
  
      return 1;
  };
  
  
  sub _load_pp {
      my $opt = shift;
      my $backend = $_USSING_bpPP ? $Module_bp : $Module_PP;
  
      $JSON::DEBUG and Carp::carp "Load $backend.";
  
      # if called after install module, overload is disable.... why?
      JSON::Boolean::_overrride_overload($Module_XS);
      JSON::Boolean::_overrride_overload($backend);
  
      if ( $_USSING_bpPP ) {
          eval qq| require $backend |;
      }
      else {
          eval qq| use $backend $PP_Version () |;
      }
  
      if ($@) {
          if ( $backend eq $Module_PP ) {
              $JSON::DEBUG and Carp::carp "Can't load $Module_PP ($@), so try to load $Module_bp";
              $_USSING_bpPP++;
              $backend = $Module_bp;
              JSON::Boolean::_overrride_overload($backend);
              local $^W; # if PP installed but invalid version, backportPP redefines methods.
              eval qq| require $Module_bp |;
          }
          Carp::croak $@ if $@;
      }
  
      unless (defined $opt and $opt & $_INSTALL_ONLY) {
          _set_module( $JSON::Backend = $Module_PP ); # even if backportPP, set $Backend with 'JSON::PP'
          JSON::Backend::PP->init;
      }
  };
  
  
  sub _set_module {
      return if defined $JSON::true;
  
      my $module = shift;
  
      local $^W;
      no strict qw(refs);
  
      $JSON::true  = ${"$module\::true"};
      $JSON::false = ${"$module\::false"};
  
      push @JSON::ISA, $module;
      push @{"$module\::Boolean::ISA"}, qw(JSON::Boolean);
  
      *{"JSON::is_bool"} = \&{"$module\::is_bool"};
  
      for my $method ($module eq $Module_XS ? @PPOnlyMethods : @XSOnlyMethods) {
          *{"JSON::$method"} = sub {
              Carp::carp("$method is not supported in $module.");
              $_[0];
          };
      }
  
      return 1;
  }
  
  
  
  #
  # JSON Boolean
  #
  
  package JSON::Boolean;
  
  my %Installed;
  
  sub _overrride_overload {
      return if ($Installed{ $_[0] }++);
  
      my $boolean = $_[0] . '::Boolean';
  
      eval sprintf(q|
          package %s;
          use overload (
              '""' => sub { ${$_[0]} == 1 ? 'true' : 'false' },
              'eq' => sub {
                  my ($obj, $op) = ref ($_[0]) ? ($_[0], $_[1]) : ($_[1], $_[0]);
                  if ($op eq 'true' or $op eq 'false') {
                      return "$obj" eq 'true' ? 'true' eq $op : 'false' eq $op;
                  }
                  else {
                      return $obj ? 1 == $op : 0 == $op;
                  }
              },
          );
      |, $boolean);
  
      if ($@) { Carp::croak $@; }
  
      if ( exists $INC{'JSON/XS.pm'} and $boolean eq 'JSON::XS::Boolean' ) {
          local $^W;
          my $true  = do { bless \(my $dummy = 1), $boolean };
          my $false = do { bless \(my $dummy = 0), $boolean };
          *JSON::XS::true  = sub () { $true };
          *JSON::XS::false = sub () { $false };
      }
      elsif ( exists $INC{'JSON/PP.pm'} and $boolean eq 'JSON::PP::Boolean' ) {
          local $^W;
          my $true  = do { bless \(my $dummy = 1), $boolean };
          my $false = do { bless \(my $dummy = 0), $boolean };
          *JSON::PP::true  = sub { $true };
          *JSON::PP::false = sub { $false };
      }
  
      return 1;
  }
  
  
  #
  # Helper classes for Backend Module (PP)
  #
  
  package JSON::Backend::PP;
  
  sub init {
      local $^W;
      no strict qw(refs); # this routine may be called after JSON::Backend::XS init was called.
      *{"JSON::decode_json"} = \&{"JSON::PP::decode_json"};
      *{"JSON::encode_json"} = \&{"JSON::PP::encode_json"};
      *{"JSON::PP::is_xs"}  = sub { 0 };
      *{"JSON::PP::is_pp"}  = sub { 1 };
      return 1;
  }
  
  #
  # To save memory, the below lines are read only when XS backend is used.
  #
  
  package JSON;
  
  1;
  __DATA__
  
  
  #
  # Helper classes for Backend Module (XS)
  #
  
  package JSON::Backend::XS;
  
  use constant INDENT_LENGTH_FLAG => 15 << 12;
  
  use constant UNSUPPORTED_ENCODE_FLAG => {
      ESCAPE_SLASH      => 0x00000010,
      ALLOW_BIGNUM      => 0x00000020,
      AS_NONBLESSED     => 0x00000040,
      EXPANDED          => 0x10000000, # for developer's
  };
  
  use constant UNSUPPORTED_DECODE_FLAG => {
      LOOSE             => 0x00000001,
      ALLOW_BIGNUM      => 0x00000002,
      ALLOW_BAREKEY     => 0x00000004,
      ALLOW_SINGLEQUOTE => 0x00000008,
      EXPANDED          => 0x20000000, # for developer's
  };
  
  
  sub init {
      local $^W;
      no strict qw(refs);
      *{"JSON::decode_json"} = \&{"JSON::XS::decode_json"};
      *{"JSON::encode_json"} = \&{"JSON::XS::encode_json"};
      *{"JSON::XS::is_xs"}  = sub { 1 };
      *{"JSON::XS::is_pp"}  = sub { 0 };
      return 1;
  }
  
  
  sub support_by_pp {
      my ($class, @methods) = @_;
  
      local $^W;
      no strict qw(refs);
  
      my $JSON_XS_encode_orignal     = \&JSON::XS::encode;
      my $JSON_XS_decode_orignal     = \&JSON::XS::decode;
      my $JSON_XS_incr_parse_orignal = \&JSON::XS::incr_parse;
  
      *JSON::XS::decode     = \&JSON::Backend::XS::Supportable::_decode;
      *JSON::XS::encode     = \&JSON::Backend::XS::Supportable::_encode;
      *JSON::XS::incr_parse = \&JSON::Backend::XS::Supportable::_incr_parse;
  
      *{JSON::XS::_original_decode}     = $JSON_XS_decode_orignal;
      *{JSON::XS::_original_encode}     = $JSON_XS_encode_orignal;
      *{JSON::XS::_original_incr_parse} = $JSON_XS_incr_parse_orignal;
  
      push @JSON::Backend::XS::Supportable::ISA, 'JSON';
  
      my $pkg = 'JSON::Backend::XS::Supportable';
  
      *{JSON::new} = sub {
          my $proto = JSON::XS->new; $$proto = 0;
          bless  $proto, $pkg;
      };
  
  
      for my $method (@methods) {
          my $flag = uc($method);
          my $type |= (UNSUPPORTED_ENCODE_FLAG->{$flag} || 0);
             $type |= (UNSUPPORTED_DECODE_FLAG->{$flag} || 0);
  
          next unless($type);
  
          $pkg->_make_unsupported_method($method => $type);
      }
  
      push @{"JSON::XS::Boolean::ISA"}, qw(JSON::PP::Boolean);
      push @{"JSON::PP::Boolean::ISA"}, qw(JSON::Boolean);
  
      $JSON::DEBUG and Carp::carp("set -support_by_pp mode.");
  
      return 1;
  }
  
  
  
  
  #
  # Helper classes for XS
  #
  
  package JSON::Backend::XS::Supportable;
  
  $Carp::Internal{'JSON::Backend::XS::Supportable'} = 1;
  
  sub _make_unsupported_method {
      my ($pkg, $method, $type) = @_;
  
      local $^W;
      no strict qw(refs);
  
      *{"$pkg\::$method"} = sub {
          local $^W;
          if (defined $_[1] ? $_[1] : 1) {
              ${$_[0]} |= $type;
          }
          else {
              ${$_[0]} &= ~$type;
          }
          $_[0];
      };
  
      *{"$pkg\::get_$method"} = sub {
          ${$_[0]} & $type ? 1 : '';
      };
  
  }
  
  
  sub _set_for_pp {
      JSON::_load_pp( $_INSTALL_ONLY );
  
      my $type  = shift;
      my $pp    = JSON::PP->new;
      my $prop = $_[0]->property;
  
      for my $name (keys %$prop) {
          $pp->$name( $prop->{$name} ? $prop->{$name} : 0 );
      }
  
      my $unsupported = $type eq 'encode' ? JSON::Backend::XS::UNSUPPORTED_ENCODE_FLAG
                                          : JSON::Backend::XS::UNSUPPORTED_DECODE_FLAG;
      my $flags       = ${$_[0]} || 0;
  
      for my $name (keys %$unsupported) {
          next if ($name eq 'EXPANDED'); # for developer's
          my $enable = ($flags & $unsupported->{$name}) ? 1 : 0;
          my $method = lc $name;
          $pp->$method($enable);
      }
  
      $pp->indent_length( $_[0]->get_indent_length );
  
      return $pp;
  }
  
  sub _encode { # using with PP encode
      if (${$_[0]}) {
          _set_for_pp('encode' => @_)->encode($_[1]);
      }
      else {
          $_[0]->_original_encode( $_[1] );
      }
  }
  
  
  sub _decode { # if unsupported-flag is set, use PP
      if (${$_[0]}) {
          _set_for_pp('decode' => @_)->decode($_[1]);
      }
      else {
          $_[0]->_original_decode( $_[1] );
      }
  }
  
  
  sub decode_prefix { # if unsupported-flag is set, use PP
      _set_for_pp('decode' => @_)->decode_prefix($_[1]);
  }
  
  
  sub _incr_parse {
      if (${$_[0]}) {
          _set_for_pp('decode' => @_)->incr_parse($_[1]);
      }
      else {
          $_[0]->_original_incr_parse( $_[1] );
      }
  }
  
  
  sub get_indent_length {
      ${$_[0]} << 4 >> 16;
  }
  
  
  sub indent_length {
      my $length = $_[1];
  
      if (!defined $length or $length > 15 or $length < 0) {
          Carp::carp "The acceptable range of indent_length() is 0 to 15.";
      }
      else {
          local $^W;
          $length <<= 12;
          ${$_[0]} &= ~ JSON::Backend::XS::INDENT_LENGTH_FLAG;
          ${$_[0]} |= $length;
          *JSON::XS::encode = \&JSON::Backend::XS::Supportable::_encode;
      }
  
      $_[0];
  }
  
  
  1;
  __END__
  
  =head1 NAME
  
  JSON - JSON (JavaScript Object Notation) encoder/decoder
  
  =head1 SYNOPSIS
  
   use JSON; # imports encode_json, decode_json, to_json and from_json.
   
   # simple and fast interfaces (expect/generate UTF-8)
   
   $utf8_encoded_json_text = encode_json $perl_hash_or_arrayref;
   $perl_hash_or_arrayref  = decode_json $utf8_encoded_json_text;
   
   # OO-interface
   
   $json = JSON->new->allow_nonref;
   
   $json_text   = $json->encode( $perl_scalar );
   $perl_scalar = $json->decode( $json_text );
   
   $pretty_printed = $json->pretty->encode( $perl_scalar ); # pretty-printing
   
   # If you want to use PP only support features, call with '-support_by_pp'
   # When XS unsupported feature is enable, using PP (de|en)code instead of XS ones.
   
   use JSON -support_by_pp;
   
   # option-acceptable interfaces (expect/generate UNICODE by default)
   
   $json_text   = to_json( $perl_scalar, { ascii => 1, pretty => 1 } );
   $perl_scalar = from_json( $json_text, { utf8  => 1 } );
   
   # Between (en|de)code_json and (to|from)_json, if you want to write
   # a code which communicates to an outer world (encoded in UTF-8),
   # recommend to use (en|de)code_json.
   
  =head1 VERSION
  
      2.59
  
  This version is compatible with JSON::XS B<2.34> and later.
  
  
  =head1 NOTE
  
  JSON::PP was earlier included in the C<JSON> distribution, but
  has since Perl 5.14 been a core module. For this reason,
  L<JSON::PP> was removed from the JSON distribution and can now
  be found also in the Perl5 repository at
  
  =over
  
  =item * L<http://perl5.git.perl.org/perl.git>
  
  =back
  
  (The newest JSON::PP version still exists in CPAN.)
  
  Instead, the C<JSON> distribution will include JSON::backportPP
  for backwards computability. JSON.pm should thus work as it did
  before.
  
  =head1 DESCRIPTION
  
   ************************** CAUTION ********************************
   * This is 'JSON module version 2' and there are many differences  *
   * to version 1.xx                                                 *
   * Please check your applications using old version.              *
   *   See to 'INCOMPATIBLE CHANGES TO OLD VERSION'                  *
   *******************************************************************
  
  JSON (JavaScript Object Notation) is a simple data format.
  See to L<http://www.json.org/> and C<RFC4627>(L<http://www.ietf.org/rfc/rfc4627.txt>).
  
  This module converts Perl data structures to JSON and vice versa using either
  L<JSON::XS> or L<JSON::PP>.
  
  JSON::XS is the fastest and most proper JSON module on CPAN which must be
  compiled and installed in your environment.
  JSON::PP is a pure-Perl module which is bundled in this distribution and
  has a strong compatibility to JSON::XS.
  
  This module try to use JSON::XS by default and fail to it, use JSON::PP instead.
  So its features completely depend on JSON::XS or JSON::PP.
  
  See to L<BACKEND MODULE DECISION>.
  
  To distinguish the module name 'JSON' and the format type JSON,
  the former is quoted by CE<lt>E<gt> (its results vary with your using media),
  and the latter is left just as it is.
  
  Module name : C<JSON>
  
  Format type : JSON
  
  =head2 FEATURES
  
  =over
  
  =item * correct unicode handling
  
  This module (i.e. backend modules) knows how to handle Unicode, documents
  how and when it does so, and even documents what "correct" means.
  
  Even though there are limitations, this feature is available since Perl version 5.6.
  
  JSON::XS requires Perl 5.8.2 (but works correctly in 5.8.8 or later), so in older versions
  C<JSON> should call JSON::PP as the backend which can be used since Perl 5.005.
  
  With Perl 5.8.x JSON::PP works, but from 5.8.0 to 5.8.2, because of a Perl side problem,
  JSON::PP works slower in the versions. And in 5.005, the Unicode handling is not available.
  See to L<JSON::PP/UNICODE HANDLING ON PERLS> for more information.
  
  See also to L<JSON::XS/A FEW NOTES ON UNICODE AND PERL>
  and L<JSON::XS/ENCODING/CODESET_FLAG_NOTES>.
  
  
  =item * round-trip integrity
  
  When you serialise a perl data structure using only data types supported
  by JSON and Perl, the deserialised data structure is identical on the Perl
  level. (e.g. the string "2.0" doesn't suddenly become "2" just because
  it looks like a number). There I<are> minor exceptions to this, read the
  L</MAPPING> section below to learn about those.
  
  
  =item * strict checking of JSON correctness
  
  There is no guessing, no generating of illegal JSON texts by default,
  and only JSON is accepted as input by default (the latter is a security
  feature).
  
  See to L<JSON::XS/FEATURES> and L<JSON::PP/FEATURES>.
  
  =item * fast
  
  This module returns a JSON::XS object itself if available.
  Compared to other JSON modules and other serialisers such as Storable,
  JSON::XS usually compares favorably in terms of speed, too.
  
  If not available, C<JSON> returns a JSON::PP object instead of JSON::XS and
  it is very slow as pure-Perl.
  
  =item * simple to use
  
  This module has both a simple functional interface as well as an
  object oriented interface interface.
  
  =item * reasonably versatile output formats
  
  You can choose between the most compact guaranteed-single-line format possible
  (nice for simple line-based protocols), a pure-ASCII format (for when your transport
  is not 8-bit clean, still supports the whole Unicode range), or a pretty-printed
  format (for when you want to read that stuff). Or you can combine those features
  in whatever way you like.
  
  =back
  
  =head1 FUNCTIONAL INTERFACE
  
  Some documents are copied and modified from L<JSON::XS/FUNCTIONAL INTERFACE>.
  C<to_json> and C<from_json> are additional functions.
  
  =head2 encode_json
  
      $json_text = encode_json $perl_scalar
  
  Converts the given Perl data structure to a UTF-8 encoded, binary string.
  
  This function call is functionally identical to:
  
      $json_text = JSON->new->utf8->encode($perl_scalar)
  
  =head2 decode_json
  
      $perl_scalar = decode_json $json_text
  
  The opposite of C<encode_json>: expects an UTF-8 (binary) string and tries
  to parse that as an UTF-8 encoded JSON text, returning the resulting
  reference.
  
  This function call is functionally identical to:
  
      $perl_scalar = JSON->new->utf8->decode($json_text)
  
  
  =head2 to_json
  
     $json_text = to_json($perl_scalar)
  
  Converts the given Perl data structure to a json string.
  
  This function call is functionally identical to:
  
     $json_text = JSON->new->encode($perl_scalar)
  
  Takes a hash reference as the second.
  
     $json_text = to_json($perl_scalar, $flag_hashref)
  
  So,
  
     $json_text = to_json($perl_scalar, {utf8 => 1, pretty => 1})
  
  equivalent to:
  
     $json_text = JSON->new->utf8(1)->pretty(1)->encode($perl_scalar)
  
  If you want to write a modern perl code which communicates to outer world,
  you should use C<encode_json> (supposed that JSON data are encoded in UTF-8).
  
  =head2 from_json
  
     $perl_scalar = from_json($json_text)
  
  The opposite of C<to_json>: expects a json string and tries
  to parse it, returning the resulting reference.
  
  This function call is functionally identical to:
  
      $perl_scalar = JSON->decode($json_text)
  
  Takes a hash reference as the second.
  
      $perl_scalar = from_json($json_text, $flag_hashref)
  
  So,
  
      $perl_scalar = from_json($json_text, {utf8 => 1})
  
  equivalent to:
  
      $perl_scalar = JSON->new->utf8(1)->decode($json_text)
  
  If you want to write a modern perl code which communicates to outer world,
  you should use C<decode_json> (supposed that JSON data are encoded in UTF-8).
  
  =head2 JSON::is_bool
  
      $is_boolean = JSON::is_bool($scalar)
  
  Returns true if the passed scalar represents either JSON::true or
  JSON::false, two constants that act like C<1> and C<0> respectively
  and are also used to represent JSON C<true> and C<false> in Perl strings.
  
  =head2 JSON::true
  
  Returns JSON true value which is blessed object.
  It C<isa> JSON::Boolean object.
  
  =head2 JSON::false
  
  Returns JSON false value which is blessed object.
  It C<isa> JSON::Boolean object.
  
  =head2 JSON::null
  
  Returns C<undef>.
  
  See L<MAPPING>, below, for more information on how JSON values are mapped to
  Perl.
  
  =head1 HOW DO I DECODE A DATA FROM OUTER AND ENCODE TO OUTER
  
  This section supposes that your perl version is 5.8 or later.
  
  If you know a JSON text from an outer world - a network, a file content, and so on,
  is encoded in UTF-8, you should use C<decode_json> or C<JSON> module object
  with C<utf8> enable. And the decoded result will contain UNICODE characters.
  
    # from network
    my $json        = JSON->new->utf8;
    my $json_text   = CGI->new->param( 'json_data' );
    my $perl_scalar = $json->decode( $json_text );
    
    # from file content
    local $/;
    open( my $fh, '<', 'json.data' );
    $json_text   = <$fh>;
    $perl_scalar = decode_json( $json_text );
  
  If an outer data is not encoded in UTF-8, firstly you should C<decode> it.
  
    use Encode;
    local $/;
    open( my $fh, '<', 'json.data' );
    my $encoding = 'cp932';
    my $unicode_json_text = decode( $encoding, <$fh> ); # UNICODE
    
    # or you can write the below code.
    #
    # open( my $fh, "<:encoding($encoding)", 'json.data' );
    # $unicode_json_text = <$fh>;
  
  In this case, C<$unicode_json_text> is of course UNICODE string.
  So you B<cannot> use C<decode_json> nor C<JSON> module object with C<utf8> enable.
  Instead of them, you use C<JSON> module object with C<utf8> disable or C<from_json>.
  
    $perl_scalar = $json->utf8(0)->decode( $unicode_json_text );
    # or
    $perl_scalar = from_json( $unicode_json_text );
  
  Or C<encode 'utf8'> and C<decode_json>:
  
    $perl_scalar = decode_json( encode( 'utf8', $unicode_json_text ) );
    # this way is not efficient.
  
  And now, you want to convert your C<$perl_scalar> into JSON data and
  send it to an outer world - a network or a file content, and so on.
  
  Your data usually contains UNICODE strings and you want the converted data to be encoded
  in UTF-8, you should use C<encode_json> or C<JSON> module object with C<utf8> enable.
  
    print encode_json( $perl_scalar ); # to a network? file? or display?
    # or
    print $json->utf8->encode( $perl_scalar );
  
  If C<$perl_scalar> does not contain UNICODE but C<$encoding>-encoded strings
  for some reason, then its characters are regarded as B<latin1> for perl
  (because it does not concern with your $encoding).
  You B<cannot> use C<encode_json> nor C<JSON> module object with C<utf8> enable.
  Instead of them, you use C<JSON> module object with C<utf8> disable or C<to_json>.
  Note that the resulted text is a UNICODE string but no problem to print it.
  
    # $perl_scalar contains $encoding encoded string values
    $unicode_json_text = $json->utf8(0)->encode( $perl_scalar );
    # or 
    $unicode_json_text = to_json( $perl_scalar );
    # $unicode_json_text consists of characters less than 0x100
    print $unicode_json_text;
  
  Or C<decode $encoding> all string values and C<encode_json>:
  
    $perl_scalar->{ foo } = decode( $encoding, $perl_scalar->{ foo } );
    # ... do it to each string values, then encode_json
    $json_text = encode_json( $perl_scalar );
  
  This method is a proper way but probably not efficient.
  
  See to L<Encode>, L<perluniintro>.
  
  
  =head1 COMMON OBJECT-ORIENTED INTERFACE
  
  =head2 new
  
      $json = JSON->new
  
  Returns a new C<JSON> object inherited from either JSON::XS or JSON::PP
  that can be used to de/encode JSON strings.
  
  All boolean flags described below are by default I<disabled>.
  
  The mutators for flags all return the JSON object again and thus calls can
  be chained:
  
     my $json = JSON->new->utf8->space_after->encode({a => [1,2]})
     => {"a": [1, 2]}
  
  =head2 ascii
  
      $json = $json->ascii([$enable])
      
      $enabled = $json->get_ascii
  
  If $enable is true (or missing), then the encode method will not generate characters outside
  the code range 0..127. Any Unicode characters outside that range will be escaped using either
  a single \uXXXX or a double \uHHHH\uLLLLL escape sequence, as per RFC4627.
  
  If $enable is false, then the encode method will not escape Unicode characters unless
  required by the JSON syntax or other flags. This results in a faster and more compact format.
  
  This feature depends on the used Perl version and environment.
  
  See to L<JSON::PP/UNICODE HANDLING ON PERLS> if the backend is PP.
  
    JSON->new->ascii(1)->encode([chr 0x10401])
    => ["\ud801\udc01"]
  
  =head2 latin1
  
      $json = $json->latin1([$enable])
      
      $enabled = $json->get_latin1
  
  If $enable is true (or missing), then the encode method will encode the resulting JSON
  text as latin1 (or iso-8859-1), escaping any characters outside the code range 0..255.
  
  If $enable is false, then the encode method will not escape Unicode characters
  unless required by the JSON syntax or other flags.
  
    JSON->new->latin1->encode (["\x{89}\x{abc}"]
    => ["\x{89}\\u0abc"]    # (perl syntax, U+abc escaped, U+89 not)
  
  =head2 utf8
  
      $json = $json->utf8([$enable])
      
      $enabled = $json->get_utf8
  
  If $enable is true (or missing), then the encode method will encode the JSON result
  into UTF-8, as required by many protocols, while the decode method expects to be handled
  an UTF-8-encoded string. Please note that UTF-8-encoded strings do not contain any
  characters outside the range 0..255, they are thus useful for bytewise/binary I/O.
  
  In future versions, enabling this option might enable autodetection of the UTF-16 and UTF-32
  encoding families, as described in RFC4627.
  
  If $enable is false, then the encode method will return the JSON string as a (non-encoded)
  Unicode string, while decode expects thus a Unicode string. Any decoding or encoding
  (e.g. to UTF-8 or UTF-16) needs to be done yourself, e.g. using the Encode module.
  
  
  Example, output UTF-16BE-encoded JSON:
  
    use Encode;
    $jsontext = encode "UTF-16BE", JSON::XS->new->encode ($object);
  
  Example, decode UTF-32LE-encoded JSON:
  
    use Encode;
    $object = JSON::XS->new->decode (decode "UTF-32LE", $jsontext);
  
  See to L<JSON::PP/UNICODE HANDLING ON PERLS> if the backend is PP.
  
  
  =head2 pretty
  
      $json = $json->pretty([$enable])
  
  This enables (or disables) all of the C<indent>, C<space_before> and
  C<space_after> (and in the future possibly more) flags in one call to
  generate the most readable (or most compact) form possible.
  
  Equivalent to:
  
     $json->indent->space_before->space_after
  
  The indent space length is three and JSON::XS cannot change the indent
  space length.
  
  =head2 indent
  
      $json = $json->indent([$enable])
      
      $enabled = $json->get_indent
  
  If C<$enable> is true (or missing), then the C<encode> method will use a multiline
  format as output, putting every array member or object/hash key-value pair
  into its own line, identifying them properly.
  
  If C<$enable> is false, no newlines or indenting will be produced, and the
  resulting JSON text is guaranteed not to contain any C<newlines>.
  
  This setting has no effect when decoding JSON texts.
  
  The indent space length is three.
  With JSON::PP, you can also access C<indent_length> to change indent space length.
  
  
  =head2 space_before
  
      $json = $json->space_before([$enable])
      
      $enabled = $json->get_space_before
  
  If C<$enable> is true (or missing), then the C<encode> method will add an extra
  optional space before the C<:> separating keys from values in JSON objects.
  
  If C<$enable> is false, then the C<encode> method will not add any extra
  space at those places.
  
  This setting has no effect when decoding JSON texts.
  
  Example, space_before enabled, space_after and indent disabled:
  
     {"key" :"value"}
  
  
  =head2 space_after
  
      $json = $json->space_after([$enable])
      
      $enabled = $json->get_space_after
  
  If C<$enable> is true (or missing), then the C<encode> method will add an extra
  optional space after the C<:> separating keys from values in JSON objects
  and extra whitespace after the C<,> separating key-value pairs and array
  members.
  
  If C<$enable> is false, then the C<encode> method will not add any extra
  space at those places.
  
  This setting has no effect when decoding JSON texts.
  
  Example, space_before and indent disabled, space_after enabled:
  
     {"key": "value"}
  
  
  =head2 relaxed
  
      $json = $json->relaxed([$enable])
      
      $enabled = $json->get_relaxed
  
  If C<$enable> is true (or missing), then C<decode> will accept some
  extensions to normal JSON syntax (see below). C<encode> will not be
  affected in anyway. I<Be aware that this option makes you accept invalid
  JSON texts as if they were valid!>. I suggest only to use this option to
  parse application-specific files written by humans (configuration files,
  resource files etc.)
  
  If C<$enable> is false (the default), then C<decode> will only accept
  valid JSON texts.
  
  Currently accepted extensions are:
  
  =over 4
  
  =item * list items can have an end-comma
  
  JSON I<separates> array elements and key-value pairs with commas. This
  can be annoying if you write JSON texts manually and want to be able to
  quickly append elements, so this extension accepts comma at the end of
  such items not just between them:
  
     [
        1,
        2, <- this comma not normally allowed
     ]
     {
        "k1": "v1",
        "k2": "v2", <- this comma not normally allowed
     }
  
  =item * shell-style '#'-comments
  
  Whenever JSON allows whitespace, shell-style comments are additionally
  allowed. They are terminated by the first carriage-return or line-feed
  character, after which more white-space and comments are allowed.
  
    [
       1, # this comment not allowed in JSON
          # neither this one...
    ]
  
  =back
  
  
  =head2 canonical
  
      $json = $json->canonical([$enable])
      
      $enabled = $json->get_canonical
  
  If C<$enable> is true (or missing), then the C<encode> method will output JSON objects
  by sorting their keys. This is adding a comparatively high overhead.
  
  If C<$enable> is false, then the C<encode> method will output key-value
  pairs in the order Perl stores them (which will likely change between runs
  of the same script).
  
  This option is useful if you want the same data structure to be encoded as
  the same JSON text (given the same overall settings). If it is disabled,
  the same hash might be encoded differently even if contains the same data,
  as key-value pairs have no inherent ordering in Perl.
  
  This setting has no effect when decoding JSON texts.
  
  =head2 allow_nonref
  
      $json = $json->allow_nonref([$enable])
      
      $enabled = $json->get_allow_nonref
  
  If C<$enable> is true (or missing), then the C<encode> method can convert a
  non-reference into its corresponding string, number or null JSON value,
  which is an extension to RFC4627. Likewise, C<decode> will accept those JSON
  values instead of croaking.
  
  If C<$enable> is false, then the C<encode> method will croak if it isn't
  passed an arrayref or hashref, as JSON texts must either be an object
  or array. Likewise, C<decode> will croak if given something that is not a
  JSON object or array.
  
     JSON->new->allow_nonref->encode ("Hello, World!")
     => "Hello, World!"
  
  =head2 allow_unknown
  
      $json = $json->allow_unknown ([$enable])
      
      $enabled = $json->get_allow_unknown
  
  If $enable is true (or missing), then "encode" will *not* throw an
  exception when it encounters values it cannot represent in JSON (for
  example, filehandles) but instead will encode a JSON "null" value.
  Note that blessed objects are not included here and are handled
  separately by c<allow_nonref>.
  
  If $enable is false (the default), then "encode" will throw an
  exception when it encounters anything it cannot encode as JSON.
  
  This option does not affect "decode" in any way, and it is
  recommended to leave it off unless you know your communications
  partner.
  
  =head2 allow_blessed
  
      $json = $json->allow_blessed([$enable])
      
      $enabled = $json->get_allow_blessed
  
  If C<$enable> is true (or missing), then the C<encode> method will not
  barf when it encounters a blessed reference. Instead, the value of the
  B<convert_blessed> option will decide whether C<null> (C<convert_blessed>
  disabled or no C<TO_JSON> method found) or a representation of the
  object (C<convert_blessed> enabled and C<TO_JSON> method found) is being
  encoded. Has no effect on C<decode>.
  
  If C<$enable> is false (the default), then C<encode> will throw an
  exception when it encounters a blessed object.
  
  
  =head2 convert_blessed
  
      $json = $json->convert_blessed([$enable])
      
      $enabled = $json->get_convert_blessed
  
  If C<$enable> is true (or missing), then C<encode>, upon encountering a
  blessed object, will check for the availability of the C<TO_JSON> method
  on the object's class. If found, it will be called in scalar context
  and the resulting scalar will be encoded instead of the object. If no
  C<TO_JSON> method is found, the value of C<allow_blessed> will decide what
  to do.
  
  The C<TO_JSON> method may safely call die if it wants. If C<TO_JSON>
  returns other blessed objects, those will be handled in the same
  way. C<TO_JSON> must take care of not causing an endless recursion cycle
  (== crash) in this case. The name of C<TO_JSON> was chosen because other
  methods called by the Perl core (== not by the user of the object) are
  usually in upper case letters and to avoid collisions with the C<to_json>
  function or method.
  
  This setting does not yet influence C<decode> in any way.
  
  If C<$enable> is false, then the C<allow_blessed> setting will decide what
  to do when a blessed object is found.
  
  =over
  
  =item convert_blessed_universally mode
  
  If use C<JSON> with C<-convert_blessed_universally>, the C<UNIVERSAL::TO_JSON>
  subroutine is defined as the below code:
  
     *UNIVERSAL::TO_JSON = sub {
         my $b_obj = B::svref_2object( $_[0] );
         return    $b_obj->isa('B::HV') ? { %{ $_[0] } }
                 : $b_obj->isa('B::AV') ? [ @{ $_[0] } ]
                 : undef
                 ;
     }
  
  This will cause that C<encode> method converts simple blessed objects into
  JSON objects as non-blessed object.
  
     JSON -convert_blessed_universally;
     $json->allow_blessed->convert_blessed->encode( $blessed_object )
  
  This feature is experimental and may be removed in the future.
  
  =back
  
  =head2 filter_json_object
  
      $json = $json->filter_json_object([$coderef])
  
  When C<$coderef> is specified, it will be called from C<decode> each
  time it decodes a JSON object. The only argument passed to the coderef
  is a reference to the newly-created hash. If the code references returns
  a single scalar (which need not be a reference), this value
  (i.e. a copy of that scalar to avoid aliasing) is inserted into the
  deserialised data structure. If it returns an empty list
  (NOTE: I<not> C<undef>, which is a valid scalar), the original deserialised
  hash will be inserted. This setting can slow down decoding considerably.
  
  When C<$coderef> is omitted or undefined, any existing callback will
  be removed and C<decode> will not change the deserialised hash in any
  way.
  
  Example, convert all JSON objects into the integer 5:
  
     my $js = JSON->new->filter_json_object (sub { 5 });
     # returns [5]
     $js->decode ('[{}]'); # the given subroutine takes a hash reference.
     # throw an exception because allow_nonref is not enabled
     # so a lone 5 is not allowed.
     $js->decode ('{"a":1, "b":2}');
  
  
  =head2 filter_json_single_key_object
  
      $json = $json->filter_json_single_key_object($key [=> $coderef])
  
  Works remotely similar to C<filter_json_object>, but is only called for
  JSON objects having a single key named C<$key>.
  
  This C<$coderef> is called before the one specified via
  C<filter_json_object>, if any. It gets passed the single value in the JSON
  object. If it returns a single value, it will be inserted into the data
  structure. If it returns nothing (not even C<undef> but the empty list),
  the callback from C<filter_json_object> will be called next, as if no
  single-key callback were specified.
  
  If C<$coderef> is omitted or undefined, the corresponding callback will be
  disabled. There can only ever be one callback for a given key.
  
  As this callback gets called less often then the C<filter_json_object>
  one, decoding speed will not usually suffer as much. Therefore, single-key
  objects make excellent targets to serialise Perl objects into, especially
  as single-key JSON objects are as close to the type-tagged value concept
  as JSON gets (it's basically an ID/VALUE tuple). Of course, JSON does not
  support this in any way, so you need to make sure your data never looks
  like a serialised Perl hash.
  
  Typical names for the single object key are C<__class_whatever__>, or
  C<$__dollars_are_rarely_used__$> or C<}ugly_brace_placement>, or even
  things like C<__class_md5sum(classname)__>, to reduce the risk of clashing
  with real hashes.
  
  Example, decode JSON objects of the form C<< { "__widget__" => <id> } >>
  into the corresponding C<< $WIDGET{<id>} >> object:
  
     # return whatever is in $WIDGET{5}:
     JSON
        ->new
        ->filter_json_single_key_object (__widget__ => sub {
              $WIDGET{ $_[0] }
           })
        ->decode ('{"__widget__": 5')
  
     # this can be used with a TO_JSON method in some "widget" class
     # for serialisation to json:
     sub WidgetBase::TO_JSON {
        my ($self) = @_;
  
        unless ($self->{id}) {
           $self->{id} = ..get..some..id..;
           $WIDGET{$self->{id}} = $self;
        }
  
        { __widget__ => $self->{id} }
     }
  
  
  =head2 shrink
  
      $json = $json->shrink([$enable])
      
      $enabled = $json->get_shrink
  
  With JSON::XS, this flag resizes strings generated by either
  C<encode> or C<decode> to their minimum size possible. This can save
  memory when your JSON texts are either very very long or you have many
  short strings. It will also try to downgrade any strings to octet-form
  if possible: perl stores strings internally either in an encoding called
  UTF-X or in octet-form. The latter cannot store everything but uses less
  space in general (and some buggy Perl or C code might even rely on that
  internal representation being used).
  
  With JSON::PP, it is noop about resizing strings but tries
  C<utf8::downgrade> to the returned string by C<encode>. See to L<utf8>.
  
  See to L<JSON::XS/OBJECT-ORIENTED INTERFACE> and L<JSON::PP/METHODS>.
  
  =head2 max_depth
  
      $json = $json->max_depth([$maximum_nesting_depth])
      
      $max_depth = $json->get_max_depth
  
  Sets the maximum nesting level (default C<512>) accepted while encoding
  or decoding. If a higher nesting level is detected in JSON text or a Perl
  data structure, then the encoder and decoder will stop and croak at that
  point.
  
  Nesting level is defined by number of hash- or arrayrefs that the encoder
  needs to traverse to reach a given point or the number of C<{> or C<[>
  characters without their matching closing parenthesis crossed to reach a
  given character in a string.
  
  If no argument is given, the highest possible setting will be used, which
  is rarely useful.
  
  Note that nesting is implemented by recursion in C. The default value has
  been chosen to be as large as typical operating systems allow without
  crashing. (JSON::XS)
  
  With JSON::PP as the backend, when a large value (100 or more) was set and
  it de/encodes a deep nested object/text, it may raise a warning
  'Deep recursion on subroutine' at the perl runtime phase.
  
  See L<JSON::XS/SECURITY CONSIDERATIONS> for more info on why this is useful.
  
  =head2 max_size
  
      $json = $json->max_size([$maximum_string_size])
      
      $max_size = $json->get_max_size
  
  Set the maximum length a JSON text may have (in bytes) where decoding is
  being attempted. The default is C<0>, meaning no limit. When C<decode>
  is called on a string that is longer then this many bytes, it will not
  attempt to decode the string but throw an exception. This setting has no
  effect on C<encode> (yet).
  
  If no argument is given, the limit check will be deactivated (same as when
  C<0> is specified).
  
  See L<JSON::XS/SECURITY CONSIDERATIONS>, below, for more info on why this is useful.
  
  =head2 encode
  
      $json_text = $json->encode($perl_scalar)
  
  Converts the given Perl data structure (a simple scalar or a reference
  to a hash or array) to its JSON representation. Simple scalars will be
  converted into JSON string or number sequences, while references to arrays
  become JSON arrays and references to hashes become JSON objects. Undefined
  Perl values (e.g. C<undef>) become JSON C<null> values.
  References to the integers C<0> and C<1> are converted into C<true> and C<false>.
  
  =head2 decode
  
      $perl_scalar = $json->decode($json_text)
  
  The opposite of C<encode>: expects a JSON text and tries to parse it,
  returning the resulting simple scalar or reference. Croaks on error.
  
  JSON numbers and strings become simple Perl scalars. JSON arrays become
  Perl arrayrefs and JSON objects become Perl hashrefs. C<true> becomes
  C<1> (C<JSON::true>), C<false> becomes C<0> (C<JSON::false>) and
  C<null> becomes C<undef>.
  
  =head2 decode_prefix
  
      ($perl_scalar, $characters) = $json->decode_prefix($json_text)
  
  This works like the C<decode> method, but instead of raising an exception
  when there is trailing garbage after the first JSON object, it will
  silently stop parsing there and return the number of characters consumed
  so far.
  
     JSON->new->decode_prefix ("[1] the tail")
     => ([], 3)
  
  See to L<JSON::XS/OBJECT-ORIENTED INTERFACE>
  
  =head2 property
  
      $boolean = $json->property($property_name)
  
  Returns a boolean value about above some properties.
  
  The available properties are C<ascii>, C<latin1>, C<utf8>,
  C<indent>,C<space_before>, C<space_after>, C<relaxed>, C<canonical>,
  C<allow_nonref>, C<allow_unknown>, C<allow_blessed>, C<convert_blessed>,
  C<shrink>, C<max_depth> and C<max_size>.
  
     $boolean = $json->property('utf8');
      => 0
     $json->utf8;
     $boolean = $json->property('utf8');
      => 1
  
  Sets the property with a given boolean value.
  
      $json = $json->property($property_name => $boolean);
  
  With no argument, it returns all the above properties as a hash reference.
  
      $flag_hashref = $json->property();
  
  =head1 INCREMENTAL PARSING
  
  Most of this section are copied and modified from L<JSON::XS/INCREMENTAL PARSING>.
  
  In some cases, there is the need for incremental parsing of JSON texts.
  This module does allow you to parse a JSON stream incrementally.
  It does so by accumulating text until it has a full JSON object, which
  it then can decode. This process is similar to using C<decode_prefix>
  to see if a full JSON object is available, but is much more efficient
  (and can be implemented with a minimum of method calls).
  
  The backend module will only attempt to parse the JSON text once it is sure it
  has enough text to get a decisive result, using a very simple but
  truly incremental parser. This means that it sometimes won't stop as
  early as the full parser, for example, it doesn't detect parenthesis
  mismatches. The only thing it guarantees is that it starts decoding as
  soon as a syntactically valid JSON text has been seen. This means you need
  to set resource limits (e.g. C<max_size>) to ensure the parser will stop
  parsing in the presence if syntax errors.
  
  The following methods implement this incremental parser.
  
  =head2 incr_parse
  
      $json->incr_parse( [$string] ) # void context
      
      $obj_or_undef = $json->incr_parse( [$string] ) # scalar context
      
      @obj_or_empty = $json->incr_parse( [$string] ) # list context
  
  This is the central parsing function. It can both append new text and
  extract objects from the stream accumulated so far (both of these
  functions are optional).
  
  If C<$string> is given, then this string is appended to the already
  existing JSON fragment stored in the C<$json> object.
  
  After that, if the function is called in void context, it will simply
  return without doing anything further. This can be used to add more text
  in as many chunks as you want.
  
  If the method is called in scalar context, then it will try to extract
  exactly I<one> JSON object. If that is successful, it will return this
  object, otherwise it will return C<undef>. If there is a parse error,
  this method will croak just as C<decode> would do (one can then use
  C<incr_skip> to skip the erroneous part). This is the most common way of
  using the method.
  
  And finally, in list context, it will try to extract as many objects
  from the stream as it can find and return them, or the empty list
  otherwise. For this to work, there must be no separators between the JSON
  objects or arrays, instead they must be concatenated back-to-back. If
  an error occurs, an exception will be raised as in the scalar context
  case. Note that in this case, any previously-parsed JSON texts will be
  lost.
  
  Example: Parse some JSON arrays/objects in a given string and return them.
  
      my @objs = JSON->new->incr_parse ("[5][7][1,2]");
  
  =head2 incr_text
  
      $lvalue_string = $json->incr_text
  
  This method returns the currently stored JSON fragment as an lvalue, that
  is, you can manipulate it. This I<only> works when a preceding call to
  C<incr_parse> in I<scalar context> successfully returned an object. Under
  all other circumstances you must not call this function (I mean it.
  although in simple tests it might actually work, it I<will> fail under
  real world conditions). As a special exception, you can also call this
  method before having parsed anything.
  
  This function is useful in two cases: a) finding the trailing text after a
  JSON object or b) parsing multiple JSON objects separated by non-JSON text
  (such as commas).
  
      $json->incr_text =~ s/\s*,\s*//;
  
  In Perl 5.005, C<lvalue> attribute is not available.
  You must write codes like the below:
  
      $string = $json->incr_text;
      $string =~ s/\s*,\s*//;
      $json->incr_text( $string );
  
  =head2 incr_skip
  
      $json->incr_skip
  
  This will reset the state of the incremental parser and will remove the
  parsed text from the input buffer. This is useful after C<incr_parse>
  died, in which case the input buffer and incremental parser state is left
  unchanged, to skip the text parsed so far and to reset the parse state.
  
  =head2 incr_reset
  
      $json->incr_reset
  
  This completely resets the incremental parser, that is, after this call,
  it will be as if the parser had never parsed anything.
  
  This is useful if you want to repeatedly parse JSON objects and want to
  ignore any trailing data, which means you have to reset the parser after
  each successful decode.
  
  See to L<JSON::XS/INCREMENTAL PARSING> for examples.
  
  
  =head1 JSON::PP SUPPORT METHODS
  
  The below methods are JSON::PP own methods, so when C<JSON> works
  with JSON::PP (i.e. the created object is a JSON::PP object), available.
  See to L<JSON::PP/JSON::PP OWN METHODS> in detail.
  
  If you use C<JSON> with additional C<-support_by_pp>, some methods
  are available even with JSON::XS. See to L<USE PP FEATURES EVEN THOUGH XS BACKEND>.
  
     BEING { $ENV{PERL_JSON_BACKEND} = 'JSON::XS' }
     
     use JSON -support_by_pp;
     
     my $json = JSON->new;
     $json->allow_nonref->escape_slash->encode("/");
  
     # functional interfaces too.
     print to_json(["/"], {escape_slash => 1});
     print from_json('["foo"]', {utf8 => 1});
  
  If you do not want to all functions but C<-support_by_pp>,
  use C<-no_export>.
  
     use JSON -support_by_pp, -no_export;
     # functional interfaces are not exported.
  
  =head2 allow_singlequote
  
      $json = $json->allow_singlequote([$enable])
  
  If C<$enable> is true (or missing), then C<decode> will accept
  any JSON strings quoted by single quotations that are invalid JSON
  format.
  
      $json->allow_singlequote->decode({"foo":'bar'});
      $json->allow_singlequote->decode({'foo':"bar"});
      $json->allow_singlequote->decode({'foo':'bar'});
  
  As same as the C<relaxed> option, this option may be used to parse
  application-specific files written by humans.
  
  =head2 allow_barekey
  
      $json = $json->allow_barekey([$enable])
  
  If C<$enable> is true (or missing), then C<decode> will accept
  bare keys of JSON object that are invalid JSON format.
  
  As same as the C<relaxed> option, this option may be used to parse
  application-specific files written by humans.
  
      $json->allow_barekey->decode('{foo:"bar"}');
  
  =head2 allow_bignum
  
      $json = $json->allow_bignum([$enable])
  
  If C<$enable> is true (or missing), then C<decode> will convert
  the big integer Perl cannot handle as integer into a L<Math::BigInt>
  object and convert a floating number (any) into a L<Math::BigFloat>.
  
  On the contrary, C<encode> converts C<Math::BigInt> objects and C<Math::BigFloat>
  objects into JSON numbers with C<allow_blessed> enable.
  
     $json->allow_nonref->allow_blessed->allow_bignum;
     $bigfloat = $json->decode('2.000000000000000000000000001');
     print $json->encode($bigfloat);
     # => 2.000000000000000000000000001
  
  See to L<MAPPING> about the conversion of JSON number.
  
  =head2 loose
  
      $json = $json->loose([$enable])
  
  The unescaped [\x00-\x1f\x22\x2f\x5c] strings are invalid in JSON strings
  and the module doesn't allow to C<decode> to these (except for \x2f).
  If C<$enable> is true (or missing), then C<decode>  will accept these
  unescaped strings.
  
      $json->loose->decode(qq|["abc
                                     def"]|);
  
  See to L<JSON::PP/JSON::PP OWN METHODS>.
  
  =head2 escape_slash
  
      $json = $json->escape_slash([$enable])
  
  According to JSON Grammar, I<slash> (U+002F) is escaped. But by default
  JSON backend modules encode strings without escaping slash.
  
  If C<$enable> is true (or missing), then C<encode> will escape slashes.
  
  =head2 indent_length
  
      $json = $json->indent_length($length)
  
  With JSON::XS, The indent space length is 3 and cannot be changed.
  With JSON::PP, it sets the indent space length with the given $length.
  The default is 3. The acceptable range is 0 to 15.
  
  =head2 sort_by
  
      $json = $json->sort_by($function_name)
      $json = $json->sort_by($subroutine_ref)
  
  If $function_name or $subroutine_ref are set, its sort routine are used.
  
     $js = $pc->sort_by(sub { $JSON::PP::a cmp $JSON::PP::b })->encode($obj);
     # is($js, q|{"a":1,"b":2,"c":3,"d":4,"e":5,"f":6,"g":7,"h":8,"i":9}|);
  
     $js = $pc->sort_by('own_sort')->encode($obj);
     # is($js, q|{"a":1,"b":2,"c":3,"d":4,"e":5,"f":6,"g":7,"h":8,"i":9}|);
  
     sub JSON::PP::own_sort { $JSON::PP::a cmp $JSON::PP::b }
  
  As the sorting routine runs in the JSON::PP scope, the given
  subroutine name and the special variables C<$a>, C<$b> will begin
  with 'JSON::PP::'.
  
  If $integer is set, then the effect is same as C<canonical> on.
  
  See to L<JSON::PP/JSON::PP OWN METHODS>.
  
  =head1 MAPPING
  
  This section is copied from JSON::XS and modified to C<JSON>.
  JSON::XS and JSON::PP mapping mechanisms are almost equivalent.
  
  See to L<JSON::XS/MAPPING>.
  
  =head2 JSON -> PERL
  
  =over 4
  
  =item object
  
  A JSON object becomes a reference to a hash in Perl. No ordering of object
  keys is preserved (JSON does not preserver object key ordering itself).
  
  =item array
  
  A JSON array becomes a reference to an array in Perl.
  
  =item string
  
  A JSON string becomes a string scalar in Perl - Unicode codepoints in JSON
  are represented by the same codepoints in the Perl string, so no manual
  decoding is necessary.
  
  =item number
  
  A JSON number becomes either an integer, numeric (floating point) or
  string scalar in perl, depending on its range and any fractional parts. On
  the Perl level, there is no difference between those as Perl handles all
  the conversion details, but an integer may take slightly less memory and
  might represent more values exactly than floating point numbers.
  
  If the number consists of digits only, C<JSON> will try to represent
  it as an integer value. If that fails, it will try to represent it as
  a numeric (floating point) value if that is possible without loss of
  precision. Otherwise it will preserve the number as a string value (in
  which case you lose roundtripping ability, as the JSON number will be
  re-encoded to a JSON string).
  
  Numbers containing a fractional or exponential part will always be
  represented as numeric (floating point) values, possibly at a loss of
  precision (in which case you might lose perfect roundtripping ability, but
  the JSON number will still be re-encoded as a JSON number).
  
  Note that precision is not accuracy - binary floating point values cannot
  represent most decimal fractions exactly, and when converting from and to
  floating point, C<JSON> only guarantees precision up to but not including
  the least significant bit.
  
  If the backend is JSON::PP and C<allow_bignum> is enable, the big integers 
  and the numeric can be optionally converted into L<Math::BigInt> and
  L<Math::BigFloat> objects.
  
  =item true, false
  
  These JSON atoms become C<JSON::true> and C<JSON::false>,
  respectively. They are overloaded to act almost exactly like the numbers
  C<1> and C<0>. You can check whether a scalar is a JSON boolean by using
  the C<JSON::is_bool> function.
  
  If C<JSON::true> and C<JSON::false> are used as strings or compared as strings,
  they represent as C<true> and C<false> respectively.
  
     print JSON::true . "\n";
      => true
     print JSON::true + 1;
      => 1
  
     ok(JSON::true eq 'true');
     ok(JSON::true eq  '1');
     ok(JSON::true == 1);
  
  C<JSON> will install these missing overloading features to the backend modules.
  
  
  =item null
  
  A JSON null atom becomes C<undef> in Perl.
  
  C<JSON::null> returns C<undef>.
  
  =back
  
  
  =head2 PERL -> JSON
  
  The mapping from Perl to JSON is slightly more difficult, as Perl is a
  truly typeless language, so we can only guess which JSON type is meant by
  a Perl value.
  
  =over 4
  
  =item hash references
  
  Perl hash references become JSON objects. As there is no inherent ordering
  in hash keys (or JSON objects), they will usually be encoded in a
  pseudo-random order that can change between runs of the same program but
  stays generally the same within a single run of a program. C<JSON>
  optionally sort the hash keys (determined by the I<canonical> flag), so
  the same data structure will serialise to the same JSON text (given same
  settings and version of JSON::XS), but this incurs a runtime overhead
  and is only rarely useful, e.g. when you want to compare some JSON text
  against another for equality.
  
  In future, the ordered object feature will be added to JSON::PP using C<tie> mechanism.
  
  
  =item array references
  
  Perl array references become JSON arrays.
  
  =item other references
  
  Other unblessed references are generally not allowed and will cause an
  exception to be thrown, except for references to the integers C<0> and
  C<1>, which get turned into C<false> and C<true> atoms in JSON. You can
  also use C<JSON::false> and C<JSON::true> to improve readability.
  
     to_json [\0,JSON::true]      # yields [false,true]
  
  =item JSON::true, JSON::false, JSON::null
  
  These special values become JSON true and JSON false values,
  respectively. You can also use C<\1> and C<\0> directly if you want.
  
  JSON::null returns C<undef>.
  
  =item blessed objects
  
  Blessed objects are not directly representable in JSON. See the
  C<allow_blessed> and C<convert_blessed> methods on various options on
  how to deal with this: basically, you can choose between throwing an
  exception, encoding the reference as if it weren't blessed, or provide
  your own serialiser method.
  
  With C<convert_blessed_universally> mode,  C<encode> converts blessed
  hash references or blessed array references (contains other blessed references)
  into JSON members and arrays.
  
     use JSON -convert_blessed_universally;
     JSON->new->allow_blessed->convert_blessed->encode( $blessed_object );
  
  See to L<convert_blessed>.
  
  =item simple scalars
  
  Simple Perl scalars (any scalar that is not a reference) are the most
  difficult objects to encode: JSON::XS and JSON::PP will encode undefined scalars as
  JSON C<null> values, scalars that have last been used in a string context
  before encoding as JSON strings, and anything else as number value:
  
     # dump as number
     encode_json [2]                      # yields [2]
     encode_json [-3.0e17]                # yields [-3e+17]
     my $value = 5; encode_json [$value]  # yields [5]
  
     # used as string, so dump as string
     print $value;
     encode_json [$value]                 # yields ["5"]
  
     # undef becomes null
     encode_json [undef]                  # yields [null]
  
  You can force the type to be a string by stringifying it:
  
     my $x = 3.1; # some variable containing a number
     "$x";        # stringified
     $x .= "";    # another, more awkward way to stringify
     print $x;    # perl does it for you, too, quite often
  
  You can force the type to be a number by numifying it:
  
     my $x = "3"; # some variable containing a string
     $x += 0;     # numify it, ensuring it will be dumped as a number
     $x *= 1;     # same thing, the choice is yours.
  
  You can not currently force the type in other, less obscure, ways.
  
  Note that numerical precision has the same meaning as under Perl (so
  binary to decimal conversion follows the same rules as in Perl, which
  can differ to other languages). Also, your perl interpreter might expose
  extensions to the floating point numbers of your platform, such as
  infinities or NaN's - these cannot be represented in JSON, and it is an
  error to pass those in.
  
  =item Big Number
  
  If the backend is JSON::PP and C<allow_bignum> is enable, 
  C<encode> converts C<Math::BigInt> objects and C<Math::BigFloat>
  objects into JSON numbers.
  
  
  =back
  
  =head1 JSON and ECMAscript
  
  See to L<JSON::XS/JSON and ECMAscript>.
  
  =head1 JSON and YAML
  
  JSON is not a subset of YAML.
  See to L<JSON::XS/JSON and YAML>.
  
  
  =head1 BACKEND MODULE DECISION
  
  When you use C<JSON>, C<JSON> tries to C<use> JSON::XS. If this call failed, it will
  C<uses> JSON::PP. The required JSON::XS version is I<2.2> or later.
  
  The C<JSON> constructor method returns an object inherited from the backend module,
  and JSON::XS object is a blessed scalar reference while JSON::PP is a blessed hash
  reference.
  
  So, your program should not depend on the backend module, especially
  returned objects should not be modified.
  
   my $json = JSON->new; # XS or PP?
   $json->{stash} = 'this is xs object'; # this code may raise an error!
  
  To check the backend module, there are some methods - C<backend>, C<is_pp> and C<is_xs>.
  
    JSON->backend; # 'JSON::XS' or 'JSON::PP'
    
    JSON->backend->is_pp: # 0 or 1
    
    JSON->backend->is_xs: # 1 or 0
    
    $json->is_xs; # 1 or 0
    
    $json->is_pp; # 0 or 1
  
  
  If you set an environment variable C<PERL_JSON_BACKEND>, the calling action will be changed.
  
  =over
  
  =item PERL_JSON_BACKEND = 0 or PERL_JSON_BACKEND = 'JSON::PP'
  
  Always use JSON::PP
  
  =item PERL_JSON_BACKEND == 1 or PERL_JSON_BACKEND = 'JSON::XS,JSON::PP'
  
  (The default) Use compiled JSON::XS if it is properly compiled & installed,
  otherwise use JSON::PP.
  
  =item PERL_JSON_BACKEND == 2 or PERL_JSON_BACKEND = 'JSON::XS'
  
  Always use compiled JSON::XS, die if it isn't properly compiled & installed.
  
  =item PERL_JSON_BACKEND = 'JSON::backportPP'
  
  Always use JSON::backportPP.
  JSON::backportPP is JSON::PP back port module.
  C<JSON> includes JSON::backportPP instead of JSON::PP.
  
  =back
  
  These ideas come from L<DBI::PurePerl> mechanism.
  
  example:
  
   BEGIN { $ENV{PERL_JSON_BACKEND} = 'JSON::PP' }
   use JSON; # always uses JSON::PP
  
  In future, it may be able to specify another module.
  
  =head1 USE PP FEATURES EVEN THOUGH XS BACKEND
  
  Many methods are available with either JSON::XS or JSON::PP and
  when the backend module is JSON::XS, if any JSON::PP specific (i.e. JSON::XS unsupported)
  method is called, it will C<warn> and be noop.
  
  But If you C<use> C<JSON> passing the optional string C<-support_by_pp>,
  it makes a part of those unsupported methods available.
  This feature is achieved by using JSON::PP in C<de/encode>.
  
     BEGIN { $ENV{PERL_JSON_BACKEND} = 2 } # with JSON::XS
     use JSON -support_by_pp;
     my $json = JSON->new;
     $json->allow_nonref->escape_slash->encode("/");
  
  At this time, the returned object is a C<JSON::Backend::XS::Supportable>
  object (re-blessed XS object), and  by checking JSON::XS unsupported flags
  in de/encoding, can support some unsupported methods - C<loose>, C<allow_bignum>,
  C<allow_barekey>, C<allow_singlequote>, C<escape_slash> and C<indent_length>.
  
  When any unsupported methods are not enable, C<XS de/encode> will be
  used as is. The switch is achieved by changing the symbolic tables.
  
  C<-support_by_pp> is effective only when the backend module is JSON::XS
  and it makes the de/encoding speed down a bit.
  
  See to L<JSON::PP SUPPORT METHODS>.
  
  =head1 INCOMPATIBLE CHANGES TO OLD VERSION
  
  There are big incompatibility between new version (2.00) and old (1.xx).
  If you use old C<JSON> 1.xx in your code, please check it.
  
  See to L<Transition ways from 1.xx to 2.xx.>
  
  =over
  
  =item jsonToObj and objToJson are obsoleted.
  
  Non Perl-style name C<jsonToObj> and C<objToJson> are obsoleted
  (but not yet deleted from the source).
  If you use these functions in your code, please replace them
  with C<from_json> and C<to_json>.
  
  
  =item Global variables are no longer available.
  
  C<JSON> class variables - C<$JSON::AUTOCONVERT>, C<$JSON::BareKey>, etc...
  - are not available any longer.
  Instead, various features can be used through object methods.
  
  
  =item Package JSON::Converter and JSON::Parser are deleted.
  
  Now C<JSON> bundles with JSON::PP which can handle JSON more properly than them.
  
  =item Package JSON::NotString is deleted.
  
  There was C<JSON::NotString> class which represents JSON value C<true>, C<false>, C<null>
  and numbers. It was deleted and replaced by C<JSON::Boolean>.
  
  C<JSON::Boolean> represents C<true> and C<false>.
  
  C<JSON::Boolean> does not represent C<null>.
  
  C<JSON::null> returns C<undef>.
  
  C<JSON> makes L<JSON::XS::Boolean> and L<JSON::PP::Boolean> is-a relation
  to L<JSON::Boolean>.
  
  =item function JSON::Number is obsoleted.
  
  C<JSON::Number> is now needless because JSON::XS and JSON::PP have
  round-trip integrity.
  
  =item JSONRPC modules are deleted.
  
  Perl implementation of JSON-RPC protocol - C<JSONRPC >, C<JSONRPC::Transport::HTTP>
  and C<Apache::JSONRPC > are deleted in this distribution.
  Instead of them, there is L<JSON::RPC> which supports JSON-RPC protocol version 1.1.
  
  =back
  
  =head2 Transition ways from 1.xx to 2.xx.
  
  You should set C<suport_by_pp> mode firstly, because
  it is always successful for the below codes even with JSON::XS.
  
      use JSON -support_by_pp;
  
  =over
  
  =item Exported jsonToObj (simple)
  
    from_json($json_text);
  
  =item Exported objToJson (simple)
  
    to_json($perl_scalar);
  
  =item Exported jsonToObj (advanced)
  
    $flags = {allow_barekey => 1, allow_singlequote => 1};
    from_json($json_text, $flags);
  
  equivalent to:
  
    $JSON::BareKey = 1;
    $JSON::QuotApos = 1;
    jsonToObj($json_text);
  
  =item Exported objToJson (advanced)
  
    $flags = {allow_blessed => 1, allow_barekey => 1};
    to_json($perl_scalar, $flags);
  
  equivalent to:
  
    $JSON::BareKey = 1;
    objToJson($perl_scalar);
  
  =item jsonToObj as object method
  
    $json->decode($json_text);
  
  =item objToJson as object method
  
    $json->encode($perl_scalar);
  
  =item new method with parameters
  
  The C<new> method in 2.x takes any parameters no longer.
  You can set parameters instead;
  
     $json = JSON->new->pretty;
  
  =item $JSON::Pretty, $JSON::Indent, $JSON::Delimiter
  
  If C<indent> is enable, that means C<$JSON::Pretty> flag set. And
  C<$JSON::Delimiter> was substituted by C<space_before> and C<space_after>.
  In conclusion:
  
     $json->indent->space_before->space_after;
  
  Equivalent to:
  
    $json->pretty;
  
  To change indent length, use C<indent_length>.
  
  (Only with JSON::PP, if C<-support_by_pp> is not used.)
  
    $json->pretty->indent_length(2)->encode($perl_scalar);
  
  =item $JSON::BareKey
  
  (Only with JSON::PP, if C<-support_by_pp> is not used.)
  
    $json->allow_barekey->decode($json_text)
  
  =item $JSON::ConvBlessed
  
  use C<-convert_blessed_universally>. See to L<convert_blessed>.
  
  =item $JSON::QuotApos
  
  (Only with JSON::PP, if C<-support_by_pp> is not used.)
  
    $json->allow_singlequote->decode($json_text)
  
  =item $JSON::SingleQuote
  
  Disable. C<JSON> does not make such a invalid JSON string any longer.
  
  =item $JSON::KeySort
  
    $json->canonical->encode($perl_scalar)
  
  This is the ascii sort.
  
  If you want to use with your own sort routine, check the C<sort_by> method.
  
  (Only with JSON::PP, even if C<-support_by_pp> is used currently.)
  
    $json->sort_by($sort_routine_ref)->encode($perl_scalar)
   
    $json->sort_by(sub { $JSON::PP::a <=> $JSON::PP::b })->encode($perl_scalar)
  
  Can't access C<$a> and C<$b> but C<$JSON::PP::a> and C<$JSON::PP::b>.
  
  =item $JSON::SkipInvalid
  
    $json->allow_unknown
  
  =item $JSON::AUTOCONVERT
  
  Needless. C<JSON> backend modules have the round-trip integrity.
  
  =item $JSON::UTF8
  
  Needless because C<JSON> (JSON::XS/JSON::PP) sets
  the UTF8 flag on properly.
  
      # With UTF8-flagged strings
  
      $json->allow_nonref;
      $str = chr(1000); # UTF8-flagged
  
      $json_text  = $json->utf8(0)->encode($str);
      utf8::is_utf8($json_text);
      # true
      $json_text  = $json->utf8(1)->encode($str);
      utf8::is_utf8($json_text);
      # false
  
      $str = '"' . chr(1000) . '"'; # UTF8-flagged
  
      $perl_scalar  = $json->utf8(0)->decode($str);
      utf8::is_utf8($perl_scalar);
      # true
      $perl_scalar  = $json->utf8(1)->decode($str);
      # died because of 'Wide character in subroutine'
  
  See to L<JSON::XS/A FEW NOTES ON UNICODE AND PERL>.
  
  =item $JSON::UnMapping
  
  Disable. See to L<MAPPING>.
  
  =item $JSON::SelfConvert
  
  This option was deleted.
  Instead of it, if a given blessed object has the C<TO_JSON> method,
  C<TO_JSON> will be executed with C<convert_blessed>.
  
    $json->convert_blessed->encode($blessed_hashref_or_arrayref)
    # if need, call allow_blessed
  
  Note that it was C<toJson> in old version, but now not C<toJson> but C<TO_JSON>.
  
  =back
  
  =head1 TODO
  
  =over
  
  =item example programs
  
  =back
  
  =head1 THREADS
  
  No test with JSON::PP. If with JSON::XS, See to L<JSON::XS/THREADS>.
  
  
  =head1 BUGS
  
  Please report bugs relevant to C<JSON> to E<lt>makamaka[at]cpan.orgE<gt>.
  
  
  =head1 SEE ALSO
  
  Most of the document is copied and modified from JSON::XS doc.
  
  L<JSON::XS>, L<JSON::PP>
  
  C<RFC4627>(L<http://www.ietf.org/rfc/rfc4627.txt>)
  
  =head1 AUTHOR
  
  Makamaka Hannyaharamitu, E<lt>makamaka[at]cpan.orgE<gt>
  
  JSON::XS was written by  Marc Lehmann <schmorp[at]schmorp.de>
  
  The release of this new version owes to the courtesy of Marc Lehmann.
  
  
  =head1 COPYRIGHT AND LICENSE
  
  Copyright 2005-2013 by Makamaka Hannyaharamitu
  
  This library is free software; you can redistribute it and/or modify
  it under the same terms as Perl itself. 
  
  =cut
  
JSON

$fatpacked{"JSON/PP.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'JSON_PP';
  package JSON::PP;
  
  # JSON-2.0
  
  use 5.005;
  use strict;
  use base qw(Exporter);
  use overload ();
  
  use Carp ();
  use B ();
  #use Devel::Peek;
  
  $JSON::PP::VERSION = '2.27300';
  
  @JSON::PP::EXPORT = qw(encode_json decode_json from_json to_json);
  
  # instead of hash-access, i tried index-access for speed.
  # but this method is not faster than what i expected. so it will be changed.
  
  use constant P_ASCII                => 0;
  use constant P_LATIN1               => 1;
  use constant P_UTF8                 => 2;
  use constant P_INDENT               => 3;
  use constant P_CANONICAL            => 4;
  use constant P_SPACE_BEFORE         => 5;
  use constant P_SPACE_AFTER          => 6;
  use constant P_ALLOW_NONREF         => 7;
  use constant P_SHRINK               => 8;
  use constant P_ALLOW_BLESSED        => 9;
  use constant P_CONVERT_BLESSED      => 10;
  use constant P_RELAXED              => 11;
  
  use constant P_LOOSE                => 12;
  use constant P_ALLOW_BIGNUM         => 13;
  use constant P_ALLOW_BAREKEY        => 14;
  use constant P_ALLOW_SINGLEQUOTE    => 15;
  use constant P_ESCAPE_SLASH         => 16;
  use constant P_AS_NONBLESSED        => 17;
  
  use constant P_ALLOW_UNKNOWN        => 18;
  
  use constant OLD_PERL => $] < 5.008 ? 1 : 0;
  
  BEGIN {
      my @xs_compati_bit_properties = qw(
              latin1 ascii utf8 indent canonical space_before space_after allow_nonref shrink
              allow_blessed convert_blessed relaxed allow_unknown
      );
      my @pp_bit_properties = qw(
              allow_singlequote allow_bignum loose
              allow_barekey escape_slash as_nonblessed
      );
  
      # Perl version check, Unicode handling is enable?
      # Helper module sets @JSON::PP::_properties.
      if ($] < 5.008 ) {
          my $helper = $] >= 5.006 ? 'JSON::PP::Compat5006' : 'JSON::PP::Compat5005';
          eval qq| require $helper |;
          if ($@) { Carp::croak $@; }
      }
  
      for my $name (@xs_compati_bit_properties, @pp_bit_properties) {
          my $flag_name = 'P_' . uc($name);
  
          eval qq/
              sub $name {
                  my \$enable = defined \$_[1] ? \$_[1] : 1;
  
                  if (\$enable) {
                      \$_[0]->{PROPS}->[$flag_name] = 1;
                  }
                  else {
                      \$_[0]->{PROPS}->[$flag_name] = 0;
                  }
  
                  \$_[0];
              }
  
              sub get_$name {
                  \$_[0]->{PROPS}->[$flag_name] ? 1 : '';
              }
          /;
      }
  
  }
  
  
  
  # Functions
  
  my %encode_allow_method
       = map {($_ => 1)} qw/utf8 pretty allow_nonref latin1 self_encode escape_slash
                            allow_blessed convert_blessed indent indent_length allow_bignum
                            as_nonblessed
                          /;
  my %decode_allow_method
       = map {($_ => 1)} qw/utf8 allow_nonref loose allow_singlequote allow_bignum
                            allow_barekey max_size relaxed/;
  
  
  my $JSON; # cache
  
  sub encode_json ($) { # encode
      ($JSON ||= __PACKAGE__->new->utf8)->encode(@_);
  }
  
  
  sub decode_json { # decode
      ($JSON ||= __PACKAGE__->new->utf8)->decode(@_);
  }
  
  # Obsoleted
  
  sub to_json($) {
     Carp::croak ("JSON::PP::to_json has been renamed to encode_json.");
  }
  
  
  sub from_json($) {
     Carp::croak ("JSON::PP::from_json has been renamed to decode_json.");
  }
  
  
  # Methods
  
  sub new {
      my $class = shift;
      my $self  = {
          max_depth   => 512,
          max_size    => 0,
          indent      => 0,
          FLAGS       => 0,
          fallback      => sub { encode_error('Invalid value. JSON can only reference.') },
          indent_length => 3,
      };
  
      bless $self, $class;
  }
  
  
  sub encode {
      return $_[0]->PP_encode_json($_[1]);
  }
  
  
  sub decode {
      return $_[0]->PP_decode_json($_[1], 0x00000000);
  }
  
  
  sub decode_prefix {
      return $_[0]->PP_decode_json($_[1], 0x00000001);
  }
  
  
  # accessor
  
  
  # pretty printing
  
  sub pretty {
      my ($self, $v) = @_;
      my $enable = defined $v ? $v : 1;
  
      if ($enable) { # indent_length(3) for JSON::XS compatibility
          $self->indent(1)->indent_length(3)->space_before(1)->space_after(1);
      }
      else {
          $self->indent(0)->space_before(0)->space_after(0);
      }
  
      $self;
  }
  
  # etc
  
  sub max_depth {
      my $max  = defined $_[1] ? $_[1] : 0x80000000;
      $_[0]->{max_depth} = $max;
      $_[0];
  }
  
  
  sub get_max_depth { $_[0]->{max_depth}; }
  
  
  sub max_size {
      my $max  = defined $_[1] ? $_[1] : 0;
      $_[0]->{max_size} = $max;
      $_[0];
  }
  
  
  sub get_max_size { $_[0]->{max_size}; }
  
  
  sub filter_json_object {
      $_[0]->{cb_object} = defined $_[1] ? $_[1] : 0;
      $_[0]->{F_HOOK} = ($_[0]->{cb_object} or $_[0]->{cb_sk_object}) ? 1 : 0;
      $_[0];
  }
  
  sub filter_json_single_key_object {
      if (@_ > 1) {
          $_[0]->{cb_sk_object}->{$_[1]} = $_[2];
      }
      $_[0]->{F_HOOK} = ($_[0]->{cb_object} or $_[0]->{cb_sk_object}) ? 1 : 0;
      $_[0];
  }
  
  sub indent_length {
      if (!defined $_[1] or $_[1] > 15 or $_[1] < 0) {
          Carp::carp "The acceptable range of indent_length() is 0 to 15.";
      }
      else {
          $_[0]->{indent_length} = $_[1];
      }
      $_[0];
  }
  
  sub get_indent_length {
      $_[0]->{indent_length};
  }
  
  sub sort_by {
      $_[0]->{sort_by} = defined $_[1] ? $_[1] : 1;
      $_[0];
  }
  
  sub allow_bigint {
      Carp::carp("allow_bigint() is obsoleted. use allow_bignum() insted.");
  }
  
  ###############################
  
  ###
  ### Perl => JSON
  ###
  
  
  { # Convert
  
      my $max_depth;
      my $indent;
      my $ascii;
      my $latin1;
      my $utf8;
      my $space_before;
      my $space_after;
      my $canonical;
      my $allow_blessed;
      my $convert_blessed;
  
      my $indent_length;
      my $escape_slash;
      my $bignum;
      my $as_nonblessed;
  
      my $depth;
      my $indent_count;
      my $keysort;
  
  
      sub PP_encode_json {
          my $self = shift;
          my $obj  = shift;
  
          $indent_count = 0;
          $depth        = 0;
  
          my $idx = $self->{PROPS};
  
          ($ascii, $latin1, $utf8, $indent, $canonical, $space_before, $space_after, $allow_blessed,
              $convert_blessed, $escape_slash, $bignum, $as_nonblessed)
           = @{$idx}[P_ASCII .. P_SPACE_AFTER, P_ALLOW_BLESSED, P_CONVERT_BLESSED,
                      P_ESCAPE_SLASH, P_ALLOW_BIGNUM, P_AS_NONBLESSED];
  
          ($max_depth, $indent_length) = @{$self}{qw/max_depth indent_length/};
  
          $keysort = $canonical ? sub { $a cmp $b } : undef;
  
          if ($self->{sort_by}) {
              $keysort = ref($self->{sort_by}) eq 'CODE' ? $self->{sort_by}
                       : $self->{sort_by} =~ /\D+/       ? $self->{sort_by}
                       : sub { $a cmp $b };
          }
  
          encode_error("hash- or arrayref expected (not a simple scalar, use allow_nonref to allow this)")
               if(!ref $obj and !$idx->[ P_ALLOW_NONREF ]);
  
          my $str  = $self->object_to_json($obj);
  
          $str .= "\n" if ( $indent ); # JSON::XS 2.26 compatible
  
          unless ($ascii or $latin1 or $utf8) {
              utf8::upgrade($str);
          }
  
          if ($idx->[ P_SHRINK ]) {
              utf8::downgrade($str, 1);
          }
  
          return $str;
      }
  
  
      sub object_to_json {
          my ($self, $obj) = @_;
          my $type = ref($obj);
  
          if($type eq 'HASH'){
              return $self->hash_to_json($obj);
          }
          elsif($type eq 'ARRAY'){
              return $self->array_to_json($obj);
          }
          elsif ($type) { # blessed object?
              if (blessed($obj)) {
  
                  return $self->value_to_json($obj) if ( $obj->isa('JSON::PP::Boolean') );
  
                  if ( $convert_blessed and $obj->can('TO_JSON') ) {
                      my $result = $obj->TO_JSON();
                      if ( defined $result and ref( $result ) ) {
                          if ( refaddr( $obj ) eq refaddr( $result ) ) {
                              encode_error( sprintf(
                                  "%s::TO_JSON method returned same object as was passed instead of a new one",
                                  ref $obj
                              ) );
                          }
                      }
  
                      return $self->object_to_json( $result );
                  }
  
                  return "$obj" if ( $bignum and _is_bignum($obj) );
                  return $self->blessed_to_json($obj) if ($allow_blessed and $as_nonblessed); # will be removed.
  
                  encode_error( sprintf("encountered object '%s', but neither allow_blessed "
                      . "nor convert_blessed settings are enabled", $obj)
                  ) unless ($allow_blessed);
  
                  return 'null';
              }
              else {
                  return $self->value_to_json($obj);
              }
          }
          else{
              return $self->value_to_json($obj);
          }
      }
  
  
      sub hash_to_json {
          my ($self, $obj) = @_;
          my @res;
  
          encode_error("json text or perl structure exceeds maximum nesting level (max_depth set too low?)")
                                           if (++$depth > $max_depth);
  
          my ($pre, $post) = $indent ? $self->_up_indent() : ('', '');
          my $del = ($space_before ? ' ' : '') . ':' . ($space_after ? ' ' : '');
  
          for my $k ( _sort( $obj ) ) {
              if ( OLD_PERL ) { utf8::decode($k) } # key for Perl 5.6 / be optimized
              push @res, string_to_json( $self, $k )
                            .  $del
                            . ( $self->object_to_json( $obj->{$k} ) || $self->value_to_json( $obj->{$k} ) );
          }
  
          --$depth;
          $self->_down_indent() if ($indent);
  
          return   '{' . ( @res ? $pre : '' ) . ( @res ? join( ",$pre", @res ) . $post : '' )  . '}';
      }
  
  
      sub array_to_json {
          my ($self, $obj) = @_;
          my @res;
  
          encode_error("json text or perl structure exceeds maximum nesting level (max_depth set too low?)")
                                           if (++$depth > $max_depth);
  
          my ($pre, $post) = $indent ? $self->_up_indent() : ('', '');
  
          for my $v (@$obj){
              push @res, $self->object_to_json($v) || $self->value_to_json($v);
          }
  
          --$depth;
          $self->_down_indent() if ($indent);
  
          return '[' . ( @res ? $pre : '' ) . ( @res ? join( ",$pre", @res ) . $post : '' ) . ']';
      }
  
  
      sub value_to_json {
          my ($self, $value) = @_;
  
          return 'null' if(!defined $value);
  
          my $b_obj = B::svref_2object(\$value);  # for round trip problem
          my $flags = $b_obj->FLAGS;
  
          return $value # as is 
              if $flags & ( B::SVp_IOK | B::SVp_NOK ) and !( $flags & B::SVp_POK ); # SvTYPE is IV or NV?
  
          my $type = ref($value);
  
          if(!$type){
              return string_to_json($self, $value);
          }
          elsif( blessed($value) and  $value->isa('JSON::PP::Boolean') ){
              return $$value == 1 ? 'true' : 'false';
          }
          elsif ($type) {
              if ((overload::StrVal($value) =~ /=(\w+)/)[0]) {
                  return $self->value_to_json("$value");
              }
  
              if ($type eq 'SCALAR' and defined $$value) {
                  return   $$value eq '1' ? 'true'
                         : $$value eq '0' ? 'false'
                         : $self->{PROPS}->[ P_ALLOW_UNKNOWN ] ? 'null'
                         : encode_error("cannot encode reference to scalar");
              }
  
               if ( $self->{PROPS}->[ P_ALLOW_UNKNOWN ] ) {
                   return 'null';
               }
               else {
                   if ( $type eq 'SCALAR' or $type eq 'REF' ) {
                      encode_error("cannot encode reference to scalar");
                   }
                   else {
                      encode_error("encountered $value, but JSON can only represent references to arrays or hashes");
                   }
               }
  
          }
          else {
              return $self->{fallback}->($value)
                   if ($self->{fallback} and ref($self->{fallback}) eq 'CODE');
              return 'null';
          }
  
      }
  
  
      my %esc = (
          "\n" => '\n',
          "\r" => '\r',
          "\t" => '\t',
          "\f" => '\f',
          "\b" => '\b',
          "\"" => '\"',
          "\\" => '\\\\',
          "\'" => '\\\'',
      );
  
  
      sub string_to_json {
          my ($self, $arg) = @_;
  
          $arg =~ s/([\x22\x5c\n\r\t\f\b])/$esc{$1}/g;
          $arg =~ s/\//\\\//g if ($escape_slash);
          $arg =~ s/([\x00-\x08\x0b\x0e-\x1f])/'\\u00' . unpack('H2', $1)/eg;
  
          if ($ascii) {
              $arg = JSON_PP_encode_ascii($arg);
          }
  
          if ($latin1) {
              $arg = JSON_PP_encode_latin1($arg);
          }
  
          if ($utf8) {
              utf8::encode($arg);
          }
  
          return '"' . $arg . '"';
      }
  
  
      sub blessed_to_json {
          my $reftype = reftype($_[1]) || '';
          if ($reftype eq 'HASH') {
              return $_[0]->hash_to_json($_[1]);
          }
          elsif ($reftype eq 'ARRAY') {
              return $_[0]->array_to_json($_[1]);
          }
          else {
              return 'null';
          }
      }
  
  
      sub encode_error {
          my $error  = shift;
          Carp::croak "$error";
      }
  
  
      sub _sort {
          defined $keysort ? (sort $keysort (keys %{$_[0]})) : keys %{$_[0]};
      }
  
  
      sub _up_indent {
          my $self  = shift;
          my $space = ' ' x $indent_length;
  
          my ($pre,$post) = ('','');
  
          $post = "\n" . $space x $indent_count;
  
          $indent_count++;
  
          $pre = "\n" . $space x $indent_count;
  
          return ($pre,$post);
      }
  
  
      sub _down_indent { $indent_count--; }
  
  
      sub PP_encode_box {
          {
              depth        => $depth,
              indent_count => $indent_count,
          };
      }
  
  } # Convert
  
  
  sub _encode_ascii {
      join('',
          map {
              $_ <= 127 ?
                  chr($_) :
              $_ <= 65535 ?
                  sprintf('\u%04x', $_) : sprintf('\u%x\u%x', _encode_surrogates($_));
          } unpack('U*', $_[0])
      );
  }
  
  
  sub _encode_latin1 {
      join('',
          map {
              $_ <= 255 ?
                  chr($_) :
              $_ <= 65535 ?
                  sprintf('\u%04x', $_) : sprintf('\u%x\u%x', _encode_surrogates($_));
          } unpack('U*', $_[0])
      );
  }
  
  
  sub _encode_surrogates { # from perlunicode
      my $uni = $_[0] - 0x10000;
      return ($uni / 0x400 + 0xD800, $uni % 0x400 + 0xDC00);
  }
  
  
  sub _is_bignum {
      $_[0]->isa('Math::BigInt') or $_[0]->isa('Math::BigFloat');
  }
  
  
  
  #
  # JSON => Perl
  #
  
  my $max_intsize;
  
  BEGIN {
      my $checkint = 1111;
      for my $d (5..64) {
          $checkint .= 1;
          my $int   = eval qq| $checkint |;
          if ($int =~ /[eE]/) {
              $max_intsize = $d - 1;
              last;
          }
      }
  }
  
  { # PARSE 
  
      my %escapes = ( #  by Jeremy Muhlich <jmuhlich [at] bitflood.org>
          b    => "\x8",
          t    => "\x9",
          n    => "\xA",
          f    => "\xC",
          r    => "\xD",
          '\\' => '\\',
          '"'  => '"',
          '/'  => '/',
      );
  
      my $text; # json data
      my $at;   # offset
      my $ch;   # 1chracter
      my $len;  # text length (changed according to UTF8 or NON UTF8)
      # INTERNAL
      my $depth;          # nest counter
      my $encoding;       # json text encoding
      my $is_valid_utf8;  # temp variable
      my $utf8_len;       # utf8 byte length
      # FLAGS
      my $utf8;           # must be utf8
      my $max_depth;      # max nest nubmer of objects and arrays
      my $max_size;
      my $relaxed;
      my $cb_object;
      my $cb_sk_object;
  
      my $F_HOOK;
  
      my $allow_bigint;   # using Math::BigInt
      my $singlequote;    # loosely quoting
      my $loose;          # 
      my $allow_barekey;  # bareKey
  
      # $opt flag
      # 0x00000001 .... decode_prefix
      # 0x10000000 .... incr_parse
  
      sub PP_decode_json {
          my ($self, $opt); # $opt is an effective flag during this decode_json.
  
          ($self, $text, $opt) = @_;
  
          ($at, $ch, $depth) = (0, '', 0);
  
          if ( !defined $text or ref $text ) {
              decode_error("malformed JSON string, neither array, object, number, string or atom");
          }
  
          my $idx = $self->{PROPS};
  
          ($utf8, $relaxed, $loose, $allow_bigint, $allow_barekey, $singlequote)
              = @{$idx}[P_UTF8, P_RELAXED, P_LOOSE .. P_ALLOW_SINGLEQUOTE];
  
          if ( $utf8 ) {
              utf8::downgrade( $text, 1 ) or Carp::croak("Wide character in subroutine entry");
          }
          else {
              utf8::upgrade( $text );
              utf8::encode( $text );
          }
  
          $len = length $text;
  
          ($max_depth, $max_size, $cb_object, $cb_sk_object, $F_HOOK)
               = @{$self}{qw/max_depth  max_size cb_object cb_sk_object F_HOOK/};
  
          if ($max_size > 1) {
              use bytes;
              my $bytes = length $text;
              decode_error(
                  sprintf("attempted decode of JSON text of %s bytes size, but max_size is set to %s"
                      , $bytes, $max_size), 1
              ) if ($bytes > $max_size);
          }
  
          # Currently no effect
          # should use regexp
          my @octets = unpack('C4', $text);
          $encoding =   ( $octets[0] and  $octets[1]) ? 'UTF-8'
                      : (!$octets[0] and  $octets[1]) ? 'UTF-16BE'
                      : (!$octets[0] and !$octets[1]) ? 'UTF-32BE'
                      : ( $octets[2]                ) ? 'UTF-16LE'
                      : (!$octets[2]                ) ? 'UTF-32LE'
                      : 'unknown';
  
          white(); # remove head white space
  
          my $valid_start = defined $ch; # Is there a first character for JSON structure?
  
          my $result = value();
  
          return undef if ( !$result && ( $opt & 0x10000000 ) ); # for incr_parse
  
          decode_error("malformed JSON string, neither array, object, number, string or atom") unless $valid_start;
  
          if ( !$idx->[ P_ALLOW_NONREF ] and !ref $result ) {
                  decode_error(
                  'JSON text must be an object or array (but found number, string, true, false or null,'
                         . ' use allow_nonref to allow this)', 1);
          }
  
          Carp::croak('something wrong.') if $len < $at; # we won't arrive here.
  
          my $consumed = defined $ch ? $at - 1 : $at; # consumed JSON text length
  
          white(); # remove tail white space
  
          if ( $ch ) {
              return ( $result, $consumed ) if ($opt & 0x00000001); # all right if decode_prefix
              decode_error("garbage after JSON object");
          }
  
          ( $opt & 0x00000001 ) ? ( $result, $consumed ) : $result;
      }
  
  
      sub next_chr {
          return $ch = undef if($at >= $len);
          $ch = substr($text, $at++, 1);
      }
  
  
      sub value {
          white();
          return          if(!defined $ch);
          return object() if($ch eq '{');
          return array()  if($ch eq '[');
          return string() if($ch eq '"' or ($singlequote and $ch eq "'"));
          return number() if($ch =~ /[0-9]/ or $ch eq '-');
          return word();
      }
  
      sub string {
          my ($i, $s, $t, $u);
          my $utf16;
          my $is_utf8;
  
          ($is_valid_utf8, $utf8_len) = ('', 0);
  
          $s = ''; # basically UTF8 flag on
  
          if($ch eq '"' or ($singlequote and $ch eq "'")){
              my $boundChar = $ch;
  
              OUTER: while( defined(next_chr()) ){
  
                  if($ch eq $boundChar){
                      next_chr();
  
                      if ($utf16) {
                          decode_error("missing low surrogate character in surrogate pair");
                      }
  
                      utf8::decode($s) if($is_utf8);
  
                      return $s;
                  }
                  elsif($ch eq '\\'){
                      next_chr();
                      if(exists $escapes{$ch}){
                          $s .= $escapes{$ch};
                      }
                      elsif($ch eq 'u'){ # UNICODE handling
                          my $u = '';
  
                          for(1..4){
                              $ch = next_chr();
                              last OUTER if($ch !~ /[0-9a-fA-F]/);
                              $u .= $ch;
                          }
  
                          # U+D800 - U+DBFF
                          if ($u =~ /^[dD][89abAB][0-9a-fA-F]{2}/) { # UTF-16 high surrogate?
                              $utf16 = $u;
                          }
                          # U+DC00 - U+DFFF
                          elsif ($u =~ /^[dD][c-fC-F][0-9a-fA-F]{2}/) { # UTF-16 low surrogate?
                              unless (defined $utf16) {
                                  decode_error("missing high surrogate character in surrogate pair");
                              }
                              $is_utf8 = 1;
                              $s .= JSON_PP_decode_surrogates($utf16, $u) || next;
                              $utf16 = undef;
                          }
                          else {
                              if (defined $utf16) {
                                  decode_error("surrogate pair expected");
                              }
  
                              if ( ( my $hex = hex( $u ) ) > 127 ) {
                                  $is_utf8 = 1;
                                  $s .= JSON_PP_decode_unicode($u) || next;
                              }
                              else {
                                  $s .= chr $hex;
                              }
                          }
  
                      }
                      else{
                          unless ($loose) {
                              $at -= 2;
                              decode_error('illegal backslash escape sequence in string');
                          }
                          $s .= $ch;
                      }
                  }
                  else{
  
                      if ( ord $ch  > 127 ) {
                          unless( $ch = is_valid_utf8($ch) ) {
                              $at -= 1;
                              decode_error("malformed UTF-8 character in JSON string");
                          }
                          else {
                              $at += $utf8_len - 1;
                          }
  
                          $is_utf8 = 1;
                      }
  
                      if (!$loose) {
                          if ($ch =~ /[\x00-\x1f\x22\x5c]/)  { # '/' ok
                              $at--;
                              decode_error('invalid character encountered while parsing JSON string');
                          }
                      }
  
                      $s .= $ch;
                  }
              }
          }
  
          decode_error("unexpected end of string while parsing JSON string");
      }
  
  
      sub white {
          while( defined $ch  ){
              if($ch le ' '){
                  next_chr();
              }
              elsif($ch eq '/'){
                  next_chr();
                  if(defined $ch and $ch eq '/'){
                      1 while(defined(next_chr()) and $ch ne "\n" and $ch ne "\r");
                  }
                  elsif(defined $ch and $ch eq '*'){
                      next_chr();
                      while(1){
                          if(defined $ch){
                              if($ch eq '*'){
                                  if(defined(next_chr()) and $ch eq '/'){
                                      next_chr();
                                      last;
                                  }
                              }
                              else{
                                  next_chr();
                              }
                          }
                          else{
                              decode_error("Unterminated comment");
                          }
                      }
                      next;
                  }
                  else{
                      $at--;
                      decode_error("malformed JSON string, neither array, object, number, string or atom");
                  }
              }
              else{
                  if ($relaxed and $ch eq '#') { # correctly?
                      pos($text) = $at;
                      $text =~ /\G([^\n]*(?:\r\n|\r|\n|$))/g;
                      $at = pos($text);
                      next_chr;
                      next;
                  }
  
                  last;
              }
          }
      }
  
  
      sub array {
          my $a  = $_[0] || []; # you can use this code to use another array ref object.
  
          decode_error('json text or perl structure exceeds maximum nesting level (max_depth set too low?)')
                                                      if (++$depth > $max_depth);
  
          next_chr();
          white();
  
          if(defined $ch and $ch eq ']'){
              --$depth;
              next_chr();
              return $a;
          }
          else {
              while(defined($ch)){
                  push @$a, value();
  
                  white();
  
                  if (!defined $ch) {
                      last;
                  }
  
                  if($ch eq ']'){
                      --$depth;
                      next_chr();
                      return $a;
                  }
  
                  if($ch ne ','){
                      last;
                  }
  
                  next_chr();
                  white();
  
                  if ($relaxed and $ch eq ']') {
                      --$depth;
                      next_chr();
                      return $a;
                  }
  
              }
          }
  
          decode_error(", or ] expected while parsing array");
      }
  
  
      sub object {
          my $o = $_[0] || {}; # you can use this code to use another hash ref object.
          my $k;
  
          decode_error('json text or perl structure exceeds maximum nesting level (max_depth set too low?)')
                                                  if (++$depth > $max_depth);
          next_chr();
          white();
  
          if(defined $ch and $ch eq '}'){
              --$depth;
              next_chr();
              if ($F_HOOK) {
                  return _json_object_hook($o);
              }
              return $o;
          }
          else {
              while (defined $ch) {
                  $k = ($allow_barekey and $ch ne '"' and $ch ne "'") ? bareKey() : string();
                  white();
  
                  if(!defined $ch or $ch ne ':'){
                      $at--;
                      decode_error("':' expected");
                  }
  
                  next_chr();
                  $o->{$k} = value();
                  white();
  
                  last if (!defined $ch);
  
                  if($ch eq '}'){
                      --$depth;
                      next_chr();
                      if ($F_HOOK) {
                          return _json_object_hook($o);
                      }
                      return $o;
                  }
  
                  if($ch ne ','){
                      last;
                  }
  
                  next_chr();
                  white();
  
                  if ($relaxed and $ch eq '}') {
                      --$depth;
                      next_chr();
                      if ($F_HOOK) {
                          return _json_object_hook($o);
                      }
                      return $o;
                  }
  
              }
  
          }
  
          $at--;
          decode_error(", or } expected while parsing object/hash");
      }
  
  
      sub bareKey { # doesn't strictly follow Standard ECMA-262 3rd Edition
          my $key;
          while($ch =~ /[^\x00-\x23\x25-\x2F\x3A-\x40\x5B-\x5E\x60\x7B-\x7F]/){
              $key .= $ch;
              next_chr();
          }
          return $key;
      }
  
  
      sub word {
          my $word =  substr($text,$at-1,4);
  
          if($word eq 'true'){
              $at += 3;
              next_chr;
              return $JSON::PP::true;
          }
          elsif($word eq 'null'){
              $at += 3;
              next_chr;
              return undef;
          }
          elsif($word eq 'fals'){
              $at += 3;
              if(substr($text,$at,1) eq 'e'){
                  $at++;
                  next_chr;
                  return $JSON::PP::false;
              }
          }
  
          $at--; # for decode_error report
  
          decode_error("'null' expected")  if ($word =~ /^n/);
          decode_error("'true' expected")  if ($word =~ /^t/);
          decode_error("'false' expected") if ($word =~ /^f/);
          decode_error("malformed JSON string, neither array, object, number, string or atom");
      }
  
  
      sub number {
          my $n    = '';
          my $v;
  
          # According to RFC4627, hex or oct digts are invalid.
          if($ch eq '0'){
              my $peek = substr($text,$at,1);
              my $hex  = $peek =~ /[xX]/; # 0 or 1
  
              if($hex){
                  decode_error("malformed number (leading zero must not be followed by another digit)");
                  ($n) = ( substr($text, $at+1) =~ /^([0-9a-fA-F]+)/);
              }
              else{ # oct
                  ($n) = ( substr($text, $at) =~ /^([0-7]+)/);
                  if (defined $n and length $n > 1) {
                      decode_error("malformed number (leading zero must not be followed by another digit)");
                  }
              }
  
              if(defined $n and length($n)){
                  if (!$hex and length($n) == 1) {
                     decode_error("malformed number (leading zero must not be followed by another digit)");
                  }
                  $at += length($n) + $hex;
                  next_chr;
                  return $hex ? hex($n) : oct($n);
              }
          }
  
          if($ch eq '-'){
              $n = '-';
              next_chr;
              if (!defined $ch or $ch !~ /\d/) {
                  decode_error("malformed number (no digits after initial minus)");
              }
          }
  
          while(defined $ch and $ch =~ /\d/){
              $n .= $ch;
              next_chr;
          }
  
          if(defined $ch and $ch eq '.'){
              $n .= '.';
  
              next_chr;
              if (!defined $ch or $ch !~ /\d/) {
                  decode_error("malformed number (no digits after decimal point)");
              }
              else {
                  $n .= $ch;
              }
  
              while(defined(next_chr) and $ch =~ /\d/){
                  $n .= $ch;
              }
          }
  
          if(defined $ch and ($ch eq 'e' or $ch eq 'E')){
              $n .= $ch;
              next_chr;
  
              if(defined($ch) and ($ch eq '+' or $ch eq '-')){
                  $n .= $ch;
                  next_chr;
                  if (!defined $ch or $ch =~ /\D/) {
                      decode_error("malformed number (no digits after exp sign)");
                  }
                  $n .= $ch;
              }
              elsif(defined($ch) and $ch =~ /\d/){
                  $n .= $ch;
              }
              else {
                  decode_error("malformed number (no digits after exp sign)");
              }
  
              while(defined(next_chr) and $ch =~ /\d/){
                  $n .= $ch;
              }
  
          }
  
          $v .= $n;
  
          if ($v !~ /[.eE]/ and length $v > $max_intsize) {
              if ($allow_bigint) { # from Adam Sussman
                  require Math::BigInt;
                  return Math::BigInt->new($v);
              }
              else {
                  return "$v";
              }
          }
          elsif ($allow_bigint) {
              require Math::BigFloat;
              return Math::BigFloat->new($v);
          }
  
          return 0+$v;
      }
  
  
      sub is_valid_utf8 {
  
          $utf8_len = $_[0] =~ /[\x00-\x7F]/  ? 1
                    : $_[0] =~ /[\xC2-\xDF]/  ? 2
                    : $_[0] =~ /[\xE0-\xEF]/  ? 3
                    : $_[0] =~ /[\xF0-\xF4]/  ? 4
                    : 0
                    ;
  
          return unless $utf8_len;
  
          my $is_valid_utf8 = substr($text, $at - 1, $utf8_len);
  
          return ( $is_valid_utf8 =~ /^(?:
               [\x00-\x7F]
              |[\xC2-\xDF][\x80-\xBF]
              |[\xE0][\xA0-\xBF][\x80-\xBF]
              |[\xE1-\xEC][\x80-\xBF][\x80-\xBF]
              |[\xED][\x80-\x9F][\x80-\xBF]
              |[\xEE-\xEF][\x80-\xBF][\x80-\xBF]
              |[\xF0][\x90-\xBF][\x80-\xBF][\x80-\xBF]
              |[\xF1-\xF3][\x80-\xBF][\x80-\xBF][\x80-\xBF]
              |[\xF4][\x80-\x8F][\x80-\xBF][\x80-\xBF]
          )$/x )  ? $is_valid_utf8 : '';
      }
  
  
      sub decode_error {
          my $error  = shift;
          my $no_rep = shift;
          my $str    = defined $text ? substr($text, $at) : '';
          my $mess   = '';
          my $type   = $] >= 5.008           ? 'U*'
                     : $] <  5.006           ? 'C*'
                     : utf8::is_utf8( $str ) ? 'U*' # 5.6
                     : 'C*'
                     ;
  
          for my $c ( unpack( $type, $str ) ) { # emulate pv_uni_display() ?
              $mess .=  $c == 0x07 ? '\a'
                      : $c == 0x09 ? '\t'
                      : $c == 0x0a ? '\n'
                      : $c == 0x0d ? '\r'
                      : $c == 0x0c ? '\f'
                      : $c <  0x20 ? sprintf('\x{%x}', $c)
                      : $c == 0x5c ? '\\\\'
                      : $c <  0x80 ? chr($c)
                      : sprintf('\x{%x}', $c)
                      ;
              if ( length $mess >= 20 ) {
                  $mess .= '...';
                  last;
              }
          }
  
          unless ( length $mess ) {
              $mess = '(end of string)';
          }
  
          Carp::croak (
              $no_rep ? "$error" : "$error, at character offset $at (before \"$mess\")"
          );
  
      }
  
  
      sub _json_object_hook {
          my $o    = $_[0];
          my @ks = keys %{$o};
  
          if ( $cb_sk_object and @ks == 1 and exists $cb_sk_object->{ $ks[0] } and ref $cb_sk_object->{ $ks[0] } ) {
              my @val = $cb_sk_object->{ $ks[0] }->( $o->{$ks[0]} );
              if (@val == 1) {
                  return $val[0];
              }
          }
  
          my @val = $cb_object->($o) if ($cb_object);
          if (@val == 0 or @val > 1) {
              return $o;
          }
          else {
              return $val[0];
          }
      }
  
  
      sub PP_decode_box {
          {
              text    => $text,
              at      => $at,
              ch      => $ch,
              len     => $len,
              depth   => $depth,
              encoding      => $encoding,
              is_valid_utf8 => $is_valid_utf8,
          };
      }
  
  } # PARSE
  
  
  sub _decode_surrogates { # from perlunicode
      my $uni = 0x10000 + (hex($_[0]) - 0xD800) * 0x400 + (hex($_[1]) - 0xDC00);
      my $un  = pack('U*', $uni);
      utf8::encode( $un );
      return $un;
  }
  
  
  sub _decode_unicode {
      my $un = pack('U', hex shift);
      utf8::encode( $un );
      return $un;
  }
  
  #
  # Setup for various Perl versions (the code from JSON::PP58)
  #
  
  BEGIN {
  
      unless ( defined &utf8::is_utf8 ) {
         require Encode;
         *utf8::is_utf8 = *Encode::is_utf8;
      }
  
      if ( $] >= 5.008 ) {
          *JSON::PP::JSON_PP_encode_ascii      = \&_encode_ascii;
          *JSON::PP::JSON_PP_encode_latin1     = \&_encode_latin1;
          *JSON::PP::JSON_PP_decode_surrogates = \&_decode_surrogates;
          *JSON::PP::JSON_PP_decode_unicode    = \&_decode_unicode;
      }
  
      if ($] >= 5.008 and $] < 5.008003) { # join() in 5.8.0 - 5.8.2 is broken.
          package JSON::PP;
          require subs;
          subs->import('join');
          eval q|
              sub join {
                  return '' if (@_ < 2);
                  my $j   = shift;
                  my $str = shift;
                  for (@_) { $str .= $j . $_; }
                  return $str;
              }
          |;
      }
  
  
      sub JSON::PP::incr_parse {
          local $Carp::CarpLevel = 1;
          ( $_[0]->{_incr_parser} ||= JSON::PP::IncrParser->new )->incr_parse( @_ );
      }
  
  
      sub JSON::PP::incr_skip {
          ( $_[0]->{_incr_parser} ||= JSON::PP::IncrParser->new )->incr_skip;
      }
  
  
      sub JSON::PP::incr_reset {
          ( $_[0]->{_incr_parser} ||= JSON::PP::IncrParser->new )->incr_reset;
      }
  
      eval q{
          sub JSON::PP::incr_text : lvalue {
              $_[0]->{_incr_parser} ||= JSON::PP::IncrParser->new;
  
              if ( $_[0]->{_incr_parser}->{incr_parsing} ) {
                  Carp::croak("incr_text can not be called when the incremental parser already started parsing");
              }
              $_[0]->{_incr_parser}->{incr_text};
          }
      } if ( $] >= 5.006 );
  
  } # Setup for various Perl versions (the code from JSON::PP58)
  
  
  ###############################
  # Utilities
  #
  
  BEGIN {
      eval 'require Scalar::Util';
      unless($@){
          *JSON::PP::blessed = \&Scalar::Util::blessed;
          *JSON::PP::reftype = \&Scalar::Util::reftype;
          *JSON::PP::refaddr = \&Scalar::Util::refaddr;
      }
      else{ # This code is from Sclar::Util.
          # warn $@;
          eval 'sub UNIVERSAL::a_sub_not_likely_to_be_here { ref($_[0]) }';
          *JSON::PP::blessed = sub {
              local($@, $SIG{__DIE__}, $SIG{__WARN__});
              ref($_[0]) ? eval { $_[0]->a_sub_not_likely_to_be_here } : undef;
          };
          my %tmap = qw(
              B::NULL   SCALAR
              B::HV     HASH
              B::AV     ARRAY
              B::CV     CODE
              B::IO     IO
              B::GV     GLOB
              B::REGEXP REGEXP
          );
          *JSON::PP::reftype = sub {
              my $r = shift;
  
              return undef unless length(ref($r));
  
              my $t = ref(B::svref_2object($r));
  
              return
                  exists $tmap{$t} ? $tmap{$t}
                : length(ref($$r)) ? 'REF'
                :                    'SCALAR';
          };
          *JSON::PP::refaddr = sub {
            return undef unless length(ref($_[0]));
  
            my $addr;
            if(defined(my $pkg = blessed($_[0]))) {
              $addr .= bless $_[0], 'Scalar::Util::Fake';
              bless $_[0], $pkg;
            }
            else {
              $addr .= $_[0]
            }
  
            $addr =~ /0x(\w+)/;
            local $^W;
            #no warnings 'portable';
            hex($1);
          }
      }
  }
  
  
  # shamely copied and modified from JSON::XS code.
  
  $JSON::PP::true  = do { bless \(my $dummy = 1), "JSON::PP::Boolean" };
  $JSON::PP::false = do { bless \(my $dummy = 0), "JSON::PP::Boolean" };
  
  sub is_bool { defined $_[0] and UNIVERSAL::isa($_[0], "JSON::PP::Boolean"); }
  
  sub true  { $JSON::PP::true  }
  sub false { $JSON::PP::false }
  sub null  { undef; }
  
  ###############################
  
  package JSON::PP::Boolean;
  
  use overload (
     "0+"     => sub { ${$_[0]} },
     "++"     => sub { $_[0] = ${$_[0]} + 1 },
     "--"     => sub { $_[0] = ${$_[0]} - 1 },
     fallback => 1,
  );
  
  
  ###############################
  
  package JSON::PP::IncrParser;
  
  use strict;
  
  use constant INCR_M_WS   => 0; # initial whitespace skipping
  use constant INCR_M_STR  => 1; # inside string
  use constant INCR_M_BS   => 2; # inside backslash
  use constant INCR_M_JSON => 3; # outside anything, count nesting
  use constant INCR_M_C0   => 4;
  use constant INCR_M_C1   => 5;
  
  $JSON::PP::IncrParser::VERSION = '1.01';
  
  my $unpack_format = $] < 5.006 ? 'C*' : 'U*';
  
  sub new {
      my ( $class ) = @_;
  
      bless {
          incr_nest    => 0,
          incr_text    => undef,
          incr_parsing => 0,
          incr_p       => 0,
      }, $class;
  }
  
  
  sub incr_parse {
      my ( $self, $coder, $text ) = @_;
  
      $self->{incr_text} = '' unless ( defined $self->{incr_text} );
  
      if ( defined $text ) {
          if ( utf8::is_utf8( $text ) and !utf8::is_utf8( $self->{incr_text} ) ) {
              utf8::upgrade( $self->{incr_text} ) ;
              utf8::decode( $self->{incr_text} ) ;
          }
          $self->{incr_text} .= $text;
      }
  
  
      my $max_size = $coder->get_max_size;
  
      if ( defined wantarray ) {
  
          $self->{incr_mode} = INCR_M_WS unless defined $self->{incr_mode};
  
          if ( wantarray ) {
              my @ret;
  
              $self->{incr_parsing} = 1;
  
              do {
                  push @ret, $self->_incr_parse( $coder, $self->{incr_text} );
  
                  unless ( !$self->{incr_nest} and $self->{incr_mode} == INCR_M_JSON ) {
                      $self->{incr_mode} = INCR_M_WS if $self->{incr_mode} != INCR_M_STR;
                  }
  
              } until ( length $self->{incr_text} >= $self->{incr_p} );
  
              $self->{incr_parsing} = 0;
  
              return @ret;
          }
          else { # in scalar context
              $self->{incr_parsing} = 1;
              my $obj = $self->_incr_parse( $coder, $self->{incr_text} );
              $self->{incr_parsing} = 0 if defined $obj; # pointed by Martin J. Evans
              return $obj ? $obj : undef; # $obj is an empty string, parsing was completed.
          }
  
      }
  
  }
  
  
  sub _incr_parse {
      my ( $self, $coder, $text, $skip ) = @_;
      my $p = $self->{incr_p};
      my $restore = $p;
  
      my @obj;
      my $len = length $text;
  
      if ( $self->{incr_mode} == INCR_M_WS ) {
          while ( $len > $p ) {
              my $s = substr( $text, $p, 1 );
              $p++ and next if ( 0x20 >= unpack($unpack_format, $s) );
              $self->{incr_mode} = INCR_M_JSON;
              last;
         }
      }
  
      while ( $len > $p ) {
          my $s = substr( $text, $p++, 1 );
  
          if ( $s eq '"' ) {
              if (substr( $text, $p - 2, 1 ) eq '\\' ) {
                  next;
              }
  
              if ( $self->{incr_mode} != INCR_M_STR  ) {
                  $self->{incr_mode} = INCR_M_STR;
              }
              else {
                  $self->{incr_mode} = INCR_M_JSON;
                  unless ( $self->{incr_nest} ) {
                      last;
                  }
              }
          }
  
          if ( $self->{incr_mode} == INCR_M_JSON ) {
  
              if ( $s eq '[' or $s eq '{' ) {
                  if ( ++$self->{incr_nest} > $coder->get_max_depth ) {
                      Carp::croak('json text or perl structure exceeds maximum nesting level (max_depth set too low?)');
                  }
              }
              elsif ( $s eq ']' or $s eq '}' ) {
                  last if ( --$self->{incr_nest} <= 0 );
              }
              elsif ( $s eq '#' ) {
                  while ( $len > $p ) {
                      last if substr( $text, $p++, 1 ) eq "\n";
                  }
              }
  
          }
  
      }
  
      $self->{incr_p} = $p;
  
      return if ( $self->{incr_mode} == INCR_M_STR and not $self->{incr_nest} );
      return if ( $self->{incr_mode} == INCR_M_JSON and $self->{incr_nest} > 0 );
  
      return '' unless ( length substr( $self->{incr_text}, 0, $p ) );
  
      local $Carp::CarpLevel = 2;
  
      $self->{incr_p} = $restore;
      $self->{incr_c} = $p;
  
      my ( $obj, $tail ) = $coder->PP_decode_json( substr( $self->{incr_text}, 0, $p ), 0x10000001 );
  
      $self->{incr_text} = substr( $self->{incr_text}, $p );
      $self->{incr_p} = 0;
  
      return $obj || '';
  }
  
  
  sub incr_text {
      if ( $_[0]->{incr_parsing} ) {
          Carp::croak("incr_text can not be called when the incremental parser already started parsing");
      }
      $_[0]->{incr_text};
  }
  
  
  sub incr_skip {
      my $self  = shift;
      $self->{incr_text} = substr( $self->{incr_text}, $self->{incr_c} );
      $self->{incr_p} = 0;
  }
  
  
  sub incr_reset {
      my $self = shift;
      $self->{incr_text}    = undef;
      $self->{incr_p}       = 0;
      $self->{incr_mode}    = 0;
      $self->{incr_nest}    = 0;
      $self->{incr_parsing} = 0;
  }
  
  ###############################
  
  
  1;
  __END__
  =pod
  
  =head1 NAME
  
  JSON::PP - JSON::XS compatible pure-Perl module.
  
  =head1 SYNOPSIS
  
   use JSON::PP;
  
   # exported functions, they croak on error
   # and expect/generate UTF-8
  
   $utf8_encoded_json_text = encode_json $perl_hash_or_arrayref;
   $perl_hash_or_arrayref  = decode_json $utf8_encoded_json_text;
  
   # OO-interface
  
   $coder = JSON::PP->new->ascii->pretty->allow_nonref;
   
   $json_text   = $json->encode( $perl_scalar );
   $perl_scalar = $json->decode( $json_text );
   
   $pretty_printed = $json->pretty->encode( $perl_scalar ); # pretty-printing
   
   # Note that JSON version 2.0 and above will automatically use
   # JSON::XS or JSON::PP, so you should be able to just:
   
   use JSON;
  
  
  =head1 VERSION
  
      2.27300
  
  L<JSON::XS> 2.27 (~2.30) compatible.
  
  =head1 NOTE
  
  JSON::PP had been inculded in JSON distribution (CPAN module).
  It was a perl core module in Perl 5.14.
  
  =head1 DESCRIPTION
  
  This module is L<JSON::XS> compatible pure Perl module.
  (Perl 5.8 or later is recommended)
  
  JSON::XS is the fastest and most proper JSON module on CPAN.
  It is written by Marc Lehmann in C, so must be compiled and
  installed in the used environment.
  
  JSON::PP is a pure-Perl module and has compatibility to JSON::XS.
  
  
  =head2 FEATURES
  
  =over
  
  =item * correct unicode handling
  
  This module knows how to handle Unicode (depending on Perl version).
  
  See to L<JSON::XS/A FEW NOTES ON UNICODE AND PERL> and L<UNICODE HANDLING ON PERLS>.
  
  
  =item * round-trip integrity
  
  When you serialise a perl data structure using only data types supported
  by JSON and Perl, the deserialised data structure is identical on the Perl
  level. (e.g. the string "2.0" doesn't suddenly become "2" just because
  it looks like a number). There I<are> minor exceptions to this, read the
  MAPPING section below to learn about those.
  
  
  =item * strict checking of JSON correctness
  
  There is no guessing, no generating of illegal JSON texts by default,
  and only JSON is accepted as input by default (the latter is a security feature).
  But when some options are set, loose chcking features are available.
  
  =back
  
  =head1 FUNCTIONAL INTERFACE
  
  Some documents are copied and modified from L<JSON::XS/FUNCTIONAL INTERFACE>.
  
  =head2 encode_json
  
      $json_text = encode_json $perl_scalar
  
  Converts the given Perl data structure to a UTF-8 encoded, binary string.
  
  This function call is functionally identical to:
  
      $json_text = JSON::PP->new->utf8->encode($perl_scalar)
  
  =head2 decode_json
  
      $perl_scalar = decode_json $json_text
  
  The opposite of C<encode_json>: expects an UTF-8 (binary) string and tries
  to parse that as an UTF-8 encoded JSON text, returning the resulting
  reference.
  
  This function call is functionally identical to:
  
      $perl_scalar = JSON::PP->new->utf8->decode($json_text)
  
  =head2 JSON::PP::is_bool
  
      $is_boolean = JSON::PP::is_bool($scalar)
  
  Returns true if the passed scalar represents either JSON::PP::true or
  JSON::PP::false, two constants that act like C<1> and C<0> respectively
  and are also used to represent JSON C<true> and C<false> in Perl strings.
  
  =head2 JSON::PP::true
  
  Returns JSON true value which is blessed object.
  It C<isa> JSON::PP::Boolean object.
  
  =head2 JSON::PP::false
  
  Returns JSON false value which is blessed object.
  It C<isa> JSON::PP::Boolean object.
  
  =head2 JSON::PP::null
  
  Returns C<undef>.
  
  See L<MAPPING>, below, for more information on how JSON values are mapped to
  Perl.
  
  
  =head1 HOW DO I DECODE A DATA FROM OUTER AND ENCODE TO OUTER
  
  This section supposes that your perl vresion is 5.8 or later.
  
  If you know a JSON text from an outer world - a network, a file content, and so on,
  is encoded in UTF-8, you should use C<decode_json> or C<JSON> module object
  with C<utf8> enable. And the decoded result will contain UNICODE characters.
  
    # from network
    my $json        = JSON::PP->new->utf8;
    my $json_text   = CGI->new->param( 'json_data' );
    my $perl_scalar = $json->decode( $json_text );
    
    # from file content
    local $/;
    open( my $fh, '<', 'json.data' );
    $json_text   = <$fh>;
    $perl_scalar = decode_json( $json_text );
  
  If an outer data is not encoded in UTF-8, firstly you should C<decode> it.
  
    use Encode;
    local $/;
    open( my $fh, '<', 'json.data' );
    my $encoding = 'cp932';
    my $unicode_json_text = decode( $encoding, <$fh> ); # UNICODE
    
    # or you can write the below code.
    #
    # open( my $fh, "<:encoding($encoding)", 'json.data' );
    # $unicode_json_text = <$fh>;
  
  In this case, C<$unicode_json_text> is of course UNICODE string.
  So you B<cannot> use C<decode_json> nor C<JSON> module object with C<utf8> enable.
  Instead of them, you use C<JSON> module object with C<utf8> disable.
  
    $perl_scalar = $json->utf8(0)->decode( $unicode_json_text );
  
  Or C<encode 'utf8'> and C<decode_json>:
  
    $perl_scalar = decode_json( encode( 'utf8', $unicode_json_text ) );
    # this way is not efficient.
  
  And now, you want to convert your C<$perl_scalar> into JSON data and
  send it to an outer world - a network or a file content, and so on.
  
  Your data usually contains UNICODE strings and you want the converted data to be encoded
  in UTF-8, you should use C<encode_json> or C<JSON> module object with C<utf8> enable.
  
    print encode_json( $perl_scalar ); # to a network? file? or display?
    # or
    print $json->utf8->encode( $perl_scalar );
  
  If C<$perl_scalar> does not contain UNICODE but C<$encoding>-encoded strings
  for some reason, then its characters are regarded as B<latin1> for perl
  (because it does not concern with your $encoding).
  You B<cannot> use C<encode_json> nor C<JSON> module object with C<utf8> enable.
  Instead of them, you use C<JSON> module object with C<utf8> disable.
  Note that the resulted text is a UNICODE string but no problem to print it.
  
    # $perl_scalar contains $encoding encoded string values
    $unicode_json_text = $json->utf8(0)->encode( $perl_scalar );
    # $unicode_json_text consists of characters less than 0x100
    print $unicode_json_text;
  
  Or C<decode $encoding> all string values and C<encode_json>:
  
    $perl_scalar->{ foo } = decode( $encoding, $perl_scalar->{ foo } );
    # ... do it to each string values, then encode_json
    $json_text = encode_json( $perl_scalar );
  
  This method is a proper way but probably not efficient.
  
  See to L<Encode>, L<perluniintro>.
  
  
  =head1 METHODS
  
  Basically, check to L<JSON> or L<JSON::XS>.
  
  =head2 new
  
      $json = JSON::PP->new
  
  Rturns a new JSON::PP object that can be used to de/encode JSON
  strings.
  
  All boolean flags described below are by default I<disabled>.
  
  The mutators for flags all return the JSON object again and thus calls can
  be chained:
  
     my $json = JSON::PP->new->utf8->space_after->encode({a => [1,2]})
     => {"a": [1, 2]}
  
  =head2 ascii
  
      $json = $json->ascii([$enable])
      
      $enabled = $json->get_ascii
  
  If $enable is true (or missing), then the encode method will not generate characters outside
  the code range 0..127. Any Unicode characters outside that range will be escaped using either
  a single \uXXXX or a double \uHHHH\uLLLLL escape sequence, as per RFC4627.
  (See to L<JSON::XS/OBJECT-ORIENTED INTERFACE>).
  
  In Perl 5.005, there is no character having high value (more than 255).
  See to L<UNICODE HANDLING ON PERLS>.
  
  If $enable is false, then the encode method will not escape Unicode characters unless
  required by the JSON syntax or other flags. This results in a faster and more compact format.
  
    JSON::PP->new->ascii(1)->encode([chr 0x10401])
    => ["\ud801\udc01"]
  
  =head2 latin1
  
      $json = $json->latin1([$enable])
      
      $enabled = $json->get_latin1
  
  If $enable is true (or missing), then the encode method will encode the resulting JSON
  text as latin1 (or iso-8859-1), escaping any characters outside the code range 0..255.
  
  If $enable is false, then the encode method will not escape Unicode characters
  unless required by the JSON syntax or other flags.
  
    JSON::XS->new->latin1->encode (["\x{89}\x{abc}"]
    => ["\x{89}\\u0abc"]    # (perl syntax, U+abc escaped, U+89 not)
  
  See to L<UNICODE HANDLING ON PERLS>.
  
  =head2 utf8
  
      $json = $json->utf8([$enable])
      
      $enabled = $json->get_utf8
  
  If $enable is true (or missing), then the encode method will encode the JSON result
  into UTF-8, as required by many protocols, while the decode method expects to be handled
  an UTF-8-encoded string. Please note that UTF-8-encoded strings do not contain any
  characters outside the range 0..255, they are thus useful for bytewise/binary I/O.
  
  (In Perl 5.005, any character outside the range 0..255 does not exist.
  See to L<UNICODE HANDLING ON PERLS>.)
  
  In future versions, enabling this option might enable autodetection of the UTF-16 and UTF-32
  encoding families, as described in RFC4627.
  
  If $enable is false, then the encode method will return the JSON string as a (non-encoded)
  Unicode string, while decode expects thus a Unicode string. Any decoding or encoding
  (e.g. to UTF-8 or UTF-16) needs to be done yourself, e.g. using the Encode module.
  
  Example, output UTF-16BE-encoded JSON:
  
    use Encode;
    $jsontext = encode "UTF-16BE", JSON::PP->new->encode ($object);
  
  Example, decode UTF-32LE-encoded JSON:
  
    use Encode;
    $object = JSON::PP->new->decode (decode "UTF-32LE", $jsontext);
  
  
  =head2 pretty
  
      $json = $json->pretty([$enable])
  
  This enables (or disables) all of the C<indent>, C<space_before> and
  C<space_after> flags in one call to generate the most readable
  (or most compact) form possible.
  
  Equivalent to:
  
     $json->indent->space_before->space_after
  
  =head2 indent
  
      $json = $json->indent([$enable])
      
      $enabled = $json->get_indent
  
  The default indent space length is three.
  You can use C<indent_length> to change the length.
  
  =head2 space_before
  
      $json = $json->space_before([$enable])
      
      $enabled = $json->get_space_before
  
  If C<$enable> is true (or missing), then the C<encode> method will add an extra
  optional space before the C<:> separating keys from values in JSON objects.
  
  If C<$enable> is false, then the C<encode> method will not add any extra
  space at those places.
  
  This setting has no effect when decoding JSON texts.
  
  Example, space_before enabled, space_after and indent disabled:
  
     {"key" :"value"}
  
  =head2 space_after
  
      $json = $json->space_after([$enable])
      
      $enabled = $json->get_space_after
  
  If C<$enable> is true (or missing), then the C<encode> method will add an extra
  optional space after the C<:> separating keys from values in JSON objects
  and extra whitespace after the C<,> separating key-value pairs and array
  members.
  
  If C<$enable> is false, then the C<encode> method will not add any extra
  space at those places.
  
  This setting has no effect when decoding JSON texts.
  
  Example, space_before and indent disabled, space_after enabled:
  
     {"key": "value"}
  
  =head2 relaxed
  
      $json = $json->relaxed([$enable])
      
      $enabled = $json->get_relaxed
  
  If C<$enable> is true (or missing), then C<decode> will accept some
  extensions to normal JSON syntax (see below). C<encode> will not be
  affected in anyway. I<Be aware that this option makes you accept invalid
  JSON texts as if they were valid!>. I suggest only to use this option to
  parse application-specific files written by humans (configuration files,
  resource files etc.)
  
  If C<$enable> is false (the default), then C<decode> will only accept
  valid JSON texts.
  
  Currently accepted extensions are:
  
  =over 4
  
  =item * list items can have an end-comma
  
  JSON I<separates> array elements and key-value pairs with commas. This
  can be annoying if you write JSON texts manually and want to be able to
  quickly append elements, so this extension accepts comma at the end of
  such items not just between them:
  
     [
        1,
        2, <- this comma not normally allowed
     ]
     {
        "k1": "v1",
        "k2": "v2", <- this comma not normally allowed
     }
  
  =item * shell-style '#'-comments
  
  Whenever JSON allows whitespace, shell-style comments are additionally
  allowed. They are terminated by the first carriage-return or line-feed
  character, after which more white-space and comments are allowed.
  
    [
       1, # this comment not allowed in JSON
          # neither this one...
    ]
  
  =back
  
  =head2 canonical
  
      $json = $json->canonical([$enable])
      
      $enabled = $json->get_canonical
  
  If C<$enable> is true (or missing), then the C<encode> method will output JSON objects
  by sorting their keys. This is adding a comparatively high overhead.
  
  If C<$enable> is false, then the C<encode> method will output key-value
  pairs in the order Perl stores them (which will likely change between runs
  of the same script).
  
  This option is useful if you want the same data structure to be encoded as
  the same JSON text (given the same overall settings). If it is disabled,
  the same hash might be encoded differently even if contains the same data,
  as key-value pairs have no inherent ordering in Perl.
  
  This setting has no effect when decoding JSON texts.
  
  If you want your own sorting routine, you can give a code referece
  or a subroutine name to C<sort_by>. See to C<JSON::PP OWN METHODS>.
  
  =head2 allow_nonref
  
      $json = $json->allow_nonref([$enable])
      
      $enabled = $json->get_allow_nonref
  
  If C<$enable> is true (or missing), then the C<encode> method can convert a
  non-reference into its corresponding string, number or null JSON value,
  which is an extension to RFC4627. Likewise, C<decode> will accept those JSON
  values instead of croaking.
  
  If C<$enable> is false, then the C<encode> method will croak if it isn't
  passed an arrayref or hashref, as JSON texts must either be an object
  or array. Likewise, C<decode> will croak if given something that is not a
  JSON object or array.
  
     JSON::PP->new->allow_nonref->encode ("Hello, World!")
     => "Hello, World!"
  
  =head2 allow_unknown
  
      $json = $json->allow_unknown ([$enable])
      
      $enabled = $json->get_allow_unknown
  
  If $enable is true (or missing), then "encode" will *not* throw an
  exception when it encounters values it cannot represent in JSON (for
  example, filehandles) but instead will encode a JSON "null" value.
  Note that blessed objects are not included here and are handled
  separately by c<allow_nonref>.
  
  If $enable is false (the default), then "encode" will throw an
  exception when it encounters anything it cannot encode as JSON.
  
  This option does not affect "decode" in any way, and it is
  recommended to leave it off unless you know your communications
  partner.
  
  =head2 allow_blessed
  
      $json = $json->allow_blessed([$enable])
      
      $enabled = $json->get_allow_blessed
  
  If C<$enable> is true (or missing), then the C<encode> method will not
  barf when it encounters a blessed reference. Instead, the value of the
  B<convert_blessed> option will decide whether C<null> (C<convert_blessed>
  disabled or no C<TO_JSON> method found) or a representation of the
  object (C<convert_blessed> enabled and C<TO_JSON> method found) is being
  encoded. Has no effect on C<decode>.
  
  If C<$enable> is false (the default), then C<encode> will throw an
  exception when it encounters a blessed object.
  
  =head2 convert_blessed
  
      $json = $json->convert_blessed([$enable])
      
      $enabled = $json->get_convert_blessed
  
  If C<$enable> is true (or missing), then C<encode>, upon encountering a
  blessed object, will check for the availability of the C<TO_JSON> method
  on the object's class. If found, it will be called in scalar context
  and the resulting scalar will be encoded instead of the object. If no
  C<TO_JSON> method is found, the value of C<allow_blessed> will decide what
  to do.
  
  The C<TO_JSON> method may safely call die if it wants. If C<TO_JSON>
  returns other blessed objects, those will be handled in the same
  way. C<TO_JSON> must take care of not causing an endless recursion cycle
  (== crash) in this case. The name of C<TO_JSON> was chosen because other
  methods called by the Perl core (== not by the user of the object) are
  usually in upper case letters and to avoid collisions with the C<to_json>
  function or method.
  
  This setting does not yet influence C<decode> in any way.
  
  If C<$enable> is false, then the C<allow_blessed> setting will decide what
  to do when a blessed object is found.
  
  =head2 filter_json_object
  
      $json = $json->filter_json_object([$coderef])
  
  When C<$coderef> is specified, it will be called from C<decode> each
  time it decodes a JSON object. The only argument passed to the coderef
  is a reference to the newly-created hash. If the code references returns
  a single scalar (which need not be a reference), this value
  (i.e. a copy of that scalar to avoid aliasing) is inserted into the
  deserialised data structure. If it returns an empty list
  (NOTE: I<not> C<undef>, which is a valid scalar), the original deserialised
  hash will be inserted. This setting can slow down decoding considerably.
  
  When C<$coderef> is omitted or undefined, any existing callback will
  be removed and C<decode> will not change the deserialised hash in any
  way.
  
  Example, convert all JSON objects into the integer 5:
  
     my $js = JSON::PP->new->filter_json_object (sub { 5 });
     # returns [5]
     $js->decode ('[{}]'); # the given subroutine takes a hash reference.
     # throw an exception because allow_nonref is not enabled
     # so a lone 5 is not allowed.
     $js->decode ('{"a":1, "b":2}');
  
  =head2 filter_json_single_key_object
  
      $json = $json->filter_json_single_key_object($key [=> $coderef])
  
  Works remotely similar to C<filter_json_object>, but is only called for
  JSON objects having a single key named C<$key>.
  
  This C<$coderef> is called before the one specified via
  C<filter_json_object>, if any. It gets passed the single value in the JSON
  object. If it returns a single value, it will be inserted into the data
  structure. If it returns nothing (not even C<undef> but the empty list),
  the callback from C<filter_json_object> will be called next, as if no
  single-key callback were specified.
  
  If C<$coderef> is omitted or undefined, the corresponding callback will be
  disabled. There can only ever be one callback for a given key.
  
  As this callback gets called less often then the C<filter_json_object>
  one, decoding speed will not usually suffer as much. Therefore, single-key
  objects make excellent targets to serialise Perl objects into, especially
  as single-key JSON objects are as close to the type-tagged value concept
  as JSON gets (it's basically an ID/VALUE tuple). Of course, JSON does not
  support this in any way, so you need to make sure your data never looks
  like a serialised Perl hash.
  
  Typical names for the single object key are C<__class_whatever__>, or
  C<$__dollars_are_rarely_used__$> or C<}ugly_brace_placement>, or even
  things like C<__class_md5sum(classname)__>, to reduce the risk of clashing
  with real hashes.
  
  Example, decode JSON objects of the form C<< { "__widget__" => <id> } >>
  into the corresponding C<< $WIDGET{<id>} >> object:
  
     # return whatever is in $WIDGET{5}:
     JSON::PP
        ->new
        ->filter_json_single_key_object (__widget__ => sub {
              $WIDGET{ $_[0] }
           })
        ->decode ('{"__widget__": 5')
  
     # this can be used with a TO_JSON method in some "widget" class
     # for serialisation to json:
     sub WidgetBase::TO_JSON {
        my ($self) = @_;
  
        unless ($self->{id}) {
           $self->{id} = ..get..some..id..;
           $WIDGET{$self->{id}} = $self;
        }
  
        { __widget__ => $self->{id} }
     }
  
  =head2 shrink
  
      $json = $json->shrink([$enable])
      
      $enabled = $json->get_shrink
  
  In JSON::XS, this flag resizes strings generated by either
  C<encode> or C<decode> to their minimum size possible.
  It will also try to downgrade any strings to octet-form if possible.
  
  In JSON::PP, it is noop about resizing strings but tries
  C<utf8::downgrade> to the returned string by C<encode>.
  See to L<utf8>.
  
  See to L<JSON::XS/OBJECT-ORIENTED INTERFACE>
  
  =head2 max_depth
  
      $json = $json->max_depth([$maximum_nesting_depth])
      
      $max_depth = $json->get_max_depth
  
  Sets the maximum nesting level (default C<512>) accepted while encoding
  or decoding. If a higher nesting level is detected in JSON text or a Perl
  data structure, then the encoder and decoder will stop and croak at that
  point.
  
  Nesting level is defined by number of hash- or arrayrefs that the encoder
  needs to traverse to reach a given point or the number of C<{> or C<[>
  characters without their matching closing parenthesis crossed to reach a
  given character in a string.
  
  If no argument is given, the highest possible setting will be used, which
  is rarely useful.
  
  See L<JSON::XS/SSECURITY CONSIDERATIONS> for more info on why this is useful.
  
  When a large value (100 or more) was set and it de/encodes a deep nested object/text,
  it may raise a warning 'Deep recursion on subroutin' at the perl runtime phase.
  
  =head2 max_size
  
      $json = $json->max_size([$maximum_string_size])
      
      $max_size = $json->get_max_size
  
  Set the maximum length a JSON text may have (in bytes) where decoding is
  being attempted. The default is C<0>, meaning no limit. When C<decode>
  is called on a string that is longer then this many bytes, it will not
  attempt to decode the string but throw an exception. This setting has no
  effect on C<encode> (yet).
  
  If no argument is given, the limit check will be deactivated (same as when
  C<0> is specified).
  
  See L<JSON::XS/SSECURITY CONSIDERATIONS> for more info on why this is useful.
  
  =head2 encode
  
      $json_text = $json->encode($perl_scalar)
  
  Converts the given Perl data structure (a simple scalar or a reference
  to a hash or array) to its JSON representation. Simple scalars will be
  converted into JSON string or number sequences, while references to arrays
  become JSON arrays and references to hashes become JSON objects. Undefined
  Perl values (e.g. C<undef>) become JSON C<null> values.
  References to the integers C<0> and C<1> are converted into C<true> and C<false>.
  
  =head2 decode
  
      $perl_scalar = $json->decode($json_text)
  
  The opposite of C<encode>: expects a JSON text and tries to parse it,
  returning the resulting simple scalar or reference. Croaks on error.
  
  JSON numbers and strings become simple Perl scalars. JSON arrays become
  Perl arrayrefs and JSON objects become Perl hashrefs. C<true> becomes
  C<1> (C<JSON::true>), C<false> becomes C<0> (C<JSON::false>) and
  C<null> becomes C<undef>.
  
  =head2 decode_prefix
  
      ($perl_scalar, $characters) = $json->decode_prefix($json_text)
  
  This works like the C<decode> method, but instead of raising an exception
  when there is trailing garbage after the first JSON object, it will
  silently stop parsing there and return the number of characters consumed
  so far.
  
     JSON->new->decode_prefix ("[1] the tail")
     => ([], 3)
  
  =head1 INCREMENTAL PARSING
  
  Most of this section are copied and modified from L<JSON::XS/INCREMENTAL PARSING>.
  
  In some cases, there is the need for incremental parsing of JSON texts.
  This module does allow you to parse a JSON stream incrementally.
  It does so by accumulating text until it has a full JSON object, which
  it then can decode. This process is similar to using C<decode_prefix>
  to see if a full JSON object is available, but is much more efficient
  (and can be implemented with a minimum of method calls).
  
  This module will only attempt to parse the JSON text once it is sure it
  has enough text to get a decisive result, using a very simple but
  truly incremental parser. This means that it sometimes won't stop as
  early as the full parser, for example, it doesn't detect parenthese
  mismatches. The only thing it guarantees is that it starts decoding as
  soon as a syntactically valid JSON text has been seen. This means you need
  to set resource limits (e.g. C<max_size>) to ensure the parser will stop
  parsing in the presence if syntax errors.
  
  The following methods implement this incremental parser.
  
  =head2 incr_parse
  
      $json->incr_parse( [$string] ) # void context
      
      $obj_or_undef = $json->incr_parse( [$string] ) # scalar context
      
      @obj_or_empty = $json->incr_parse( [$string] ) # list context
  
  This is the central parsing function. It can both append new text and
  extract objects from the stream accumulated so far (both of these
  functions are optional).
  
  If C<$string> is given, then this string is appended to the already
  existing JSON fragment stored in the C<$json> object.
  
  After that, if the function is called in void context, it will simply
  return without doing anything further. This can be used to add more text
  in as many chunks as you want.
  
  If the method is called in scalar context, then it will try to extract
  exactly I<one> JSON object. If that is successful, it will return this
  object, otherwise it will return C<undef>. If there is a parse error,
  this method will croak just as C<decode> would do (one can then use
  C<incr_skip> to skip the errornous part). This is the most common way of
  using the method.
  
  And finally, in list context, it will try to extract as many objects
  from the stream as it can find and return them, or the empty list
  otherwise. For this to work, there must be no separators between the JSON
  objects or arrays, instead they must be concatenated back-to-back. If
  an error occurs, an exception will be raised as in the scalar context
  case. Note that in this case, any previously-parsed JSON texts will be
  lost.
  
  Example: Parse some JSON arrays/objects in a given string and return them.
  
      my @objs = JSON->new->incr_parse ("[5][7][1,2]");
  
  =head2 incr_text
  
      $lvalue_string = $json->incr_text
  
  This method returns the currently stored JSON fragment as an lvalue, that
  is, you can manipulate it. This I<only> works when a preceding call to
  C<incr_parse> in I<scalar context> successfully returned an object. Under
  all other circumstances you must not call this function (I mean it.
  although in simple tests it might actually work, it I<will> fail under
  real world conditions). As a special exception, you can also call this
  method before having parsed anything.
  
  This function is useful in two cases: a) finding the trailing text after a
  JSON object or b) parsing multiple JSON objects separated by non-JSON text
  (such as commas).
  
      $json->incr_text =~ s/\s*,\s*//;
  
  In Perl 5.005, C<lvalue> attribute is not available.
  You must write codes like the below:
  
      $string = $json->incr_text;
      $string =~ s/\s*,\s*//;
      $json->incr_text( $string );
  
  =head2 incr_skip
  
      $json->incr_skip
  
  This will reset the state of the incremental parser and will remove the
  parsed text from the input buffer. This is useful after C<incr_parse>
  died, in which case the input buffer and incremental parser state is left
  unchanged, to skip the text parsed so far and to reset the parse state.
  
  =head2 incr_reset
  
      $json->incr_reset
  
  This completely resets the incremental parser, that is, after this call,
  it will be as if the parser had never parsed anything.
  
  This is useful if you want ot repeatedly parse JSON objects and want to
  ignore any trailing data, which means you have to reset the parser after
  each successful decode.
  
  See to L<JSON::XS/INCREMENTAL PARSING> for examples.
  
  
  =head1 JSON::PP OWN METHODS
  
  =head2 allow_singlequote
  
      $json = $json->allow_singlequote([$enable])
  
  If C<$enable> is true (or missing), then C<decode> will accept
  JSON strings quoted by single quotations that are invalid JSON
  format.
  
      $json->allow_singlequote->decode({"foo":'bar'});
      $json->allow_singlequote->decode({'foo':"bar"});
      $json->allow_singlequote->decode({'foo':'bar'});
  
  As same as the C<relaxed> option, this option may be used to parse
  application-specific files written by humans.
  
  
  =head2 allow_barekey
  
      $json = $json->allow_barekey([$enable])
  
  If C<$enable> is true (or missing), then C<decode> will accept
  bare keys of JSON object that are invalid JSON format.
  
  As same as the C<relaxed> option, this option may be used to parse
  application-specific files written by humans.
  
      $json->allow_barekey->decode('{foo:"bar"}');
  
  =head2 allow_bignum
  
      $json = $json->allow_bignum([$enable])
  
  If C<$enable> is true (or missing), then C<decode> will convert
  the big integer Perl cannot handle as integer into a L<Math::BigInt>
  object and convert a floating number (any) into a L<Math::BigFloat>.
  
  On the contary, C<encode> converts C<Math::BigInt> objects and C<Math::BigFloat>
  objects into JSON numbers with C<allow_blessed> enable.
  
     $json->allow_nonref->allow_blessed->allow_bignum;
     $bigfloat = $json->decode('2.000000000000000000000000001');
     print $json->encode($bigfloat);
     # => 2.000000000000000000000000001
  
  See to L<JSON::XS/MAPPING> aboout the normal conversion of JSON number.
  
  =head2 loose
  
      $json = $json->loose([$enable])
  
  The unescaped [\x00-\x1f\x22\x2f\x5c] strings are invalid in JSON strings
  and the module doesn't allow to C<decode> to these (except for \x2f).
  If C<$enable> is true (or missing), then C<decode>  will accept these
  unescaped strings.
  
      $json->loose->decode(qq|["abc
                                     def"]|);
  
  See L<JSON::XS/SSECURITY CONSIDERATIONS>.
  
  =head2 escape_slash
  
      $json = $json->escape_slash([$enable])
  
  According to JSON Grammar, I<slash> (U+002F) is escaped. But default
  JSON::PP (as same as JSON::XS) encodes strings without escaping slash.
  
  If C<$enable> is true (or missing), then C<encode> will escape slashes.
  
  =head2 indent_length
  
      $json = $json->indent_length($length)
  
  JSON::XS indent space length is 3 and cannot be changed.
  JSON::PP set the indent space length with the given $length.
  The default is 3. The acceptable range is 0 to 15.
  
  =head2 sort_by
  
      $json = $json->sort_by($function_name)
      $json = $json->sort_by($subroutine_ref)
  
  If $function_name or $subroutine_ref are set, its sort routine are used
  in encoding JSON objects.
  
     $js = $pc->sort_by(sub { $JSON::PP::a cmp $JSON::PP::b })->encode($obj);
     # is($js, q|{"a":1,"b":2,"c":3,"d":4,"e":5,"f":6,"g":7,"h":8,"i":9}|);
  
     $js = $pc->sort_by('own_sort')->encode($obj);
     # is($js, q|{"a":1,"b":2,"c":3,"d":4,"e":5,"f":6,"g":7,"h":8,"i":9}|);
  
     sub JSON::PP::own_sort { $JSON::PP::a cmp $JSON::PP::b }
  
  As the sorting routine runs in the JSON::PP scope, the given
  subroutine name and the special variables C<$a>, C<$b> will begin
  'JSON::PP::'.
  
  If $integer is set, then the effect is same as C<canonical> on.
  
  =head1 INTERNAL
  
  For developers.
  
  =over
  
  =item PP_encode_box
  
  Returns
  
          {
              depth        => $depth,
              indent_count => $indent_count,
          }
  
  
  =item PP_decode_box
  
  Returns
  
          {
              text    => $text,
              at      => $at,
              ch      => $ch,
              len     => $len,
              depth   => $depth,
              encoding      => $encoding,
              is_valid_utf8 => $is_valid_utf8,
          };
  
  =back
  
  =head1 MAPPING
  
  This section is copied from JSON::XS and modified to C<JSON::PP>.
  JSON::XS and JSON::PP mapping mechanisms are almost equivalent.
  
  See to L<JSON::XS/MAPPING>.
  
  =head2 JSON -> PERL
  
  =over 4
  
  =item object
  
  A JSON object becomes a reference to a hash in Perl. No ordering of object
  keys is preserved (JSON does not preserver object key ordering itself).
  
  =item array
  
  A JSON array becomes a reference to an array in Perl.
  
  =item string
  
  A JSON string becomes a string scalar in Perl - Unicode codepoints in JSON
  are represented by the same codepoints in the Perl string, so no manual
  decoding is necessary.
  
  =item number
  
  A JSON number becomes either an integer, numeric (floating point) or
  string scalar in perl, depending on its range and any fractional parts. On
  the Perl level, there is no difference between those as Perl handles all
  the conversion details, but an integer may take slightly less memory and
  might represent more values exactly than floating point numbers.
  
  If the number consists of digits only, C<JSON> will try to represent
  it as an integer value. If that fails, it will try to represent it as
  a numeric (floating point) value if that is possible without loss of
  precision. Otherwise it will preserve the number as a string value (in
  which case you lose roundtripping ability, as the JSON number will be
  re-encoded toa JSON string).
  
  Numbers containing a fractional or exponential part will always be
  represented as numeric (floating point) values, possibly at a loss of
  precision (in which case you might lose perfect roundtripping ability, but
  the JSON number will still be re-encoded as a JSON number).
  
  Note that precision is not accuracy - binary floating point values cannot
  represent most decimal fractions exactly, and when converting from and to
  floating point, C<JSON> only guarantees precision up to but not including
  the leats significant bit.
  
  When C<allow_bignum> is enable, the big integers 
  and the numeric can be optionally converted into L<Math::BigInt> and
  L<Math::BigFloat> objects.
  
  =item true, false
  
  These JSON atoms become C<JSON::PP::true> and C<JSON::PP::false>,
  respectively. They are overloaded to act almost exactly like the numbers
  C<1> and C<0>. You can check wether a scalar is a JSON boolean by using
  the C<JSON::is_bool> function.
  
     print JSON::PP::true . "\n";
      => true
     print JSON::PP::true + 1;
      => 1
  
     ok(JSON::true eq  '1');
     ok(JSON::true == 1);
  
  C<JSON> will install these missing overloading features to the backend modules.
  
  
  =item null
  
  A JSON null atom becomes C<undef> in Perl.
  
  C<JSON::PP::null> returns C<unddef>.
  
  =back
  
  
  =head2 PERL -> JSON
  
  The mapping from Perl to JSON is slightly more difficult, as Perl is a
  truly typeless language, so we can only guess which JSON type is meant by
  a Perl value.
  
  =over 4
  
  =item hash references
  
  Perl hash references become JSON objects. As there is no inherent ordering
  in hash keys (or JSON objects), they will usually be encoded in a
  pseudo-random order that can change between runs of the same program but
  stays generally the same within a single run of a program. C<JSON>
  optionally sort the hash keys (determined by the I<canonical> flag), so
  the same datastructure will serialise to the same JSON text (given same
  settings and version of JSON::XS), but this incurs a runtime overhead
  and is only rarely useful, e.g. when you want to compare some JSON text
  against another for equality.
  
  
  =item array references
  
  Perl array references become JSON arrays.
  
  =item other references
  
  Other unblessed references are generally not allowed and will cause an
  exception to be thrown, except for references to the integers C<0> and
  C<1>, which get turned into C<false> and C<true> atoms in JSON. You can
  also use C<JSON::false> and C<JSON::true> to improve readability.
  
     to_json [\0,JSON::PP::true]      # yields [false,true]
  
  =item JSON::PP::true, JSON::PP::false, JSON::PP::null
  
  These special values become JSON true and JSON false values,
  respectively. You can also use C<\1> and C<\0> directly if you want.
  
  JSON::PP::null returns C<undef>.
  
  =item blessed objects
  
  Blessed objects are not directly representable in JSON. See the
  C<allow_blessed> and C<convert_blessed> methods on various options on
  how to deal with this: basically, you can choose between throwing an
  exception, encoding the reference as if it weren't blessed, or provide
  your own serialiser method.
  
  See to L<convert_blessed>.
  
  =item simple scalars
  
  Simple Perl scalars (any scalar that is not a reference) are the most
  difficult objects to encode: JSON::XS and JSON::PP will encode undefined scalars as
  JSON C<null> values, scalars that have last been used in a string context
  before encoding as JSON strings, and anything else as number value:
  
     # dump as number
     encode_json [2]                      # yields [2]
     encode_json [-3.0e17]                # yields [-3e+17]
     my $value = 5; encode_json [$value]  # yields [5]
  
     # used as string, so dump as string
     print $value;
     encode_json [$value]                 # yields ["5"]
  
     # undef becomes null
     encode_json [undef]                  # yields [null]
  
  You can force the type to be a string by stringifying it:
  
     my $x = 3.1; # some variable containing a number
     "$x";        # stringified
     $x .= "";    # another, more awkward way to stringify
     print $x;    # perl does it for you, too, quite often
  
  You can force the type to be a number by numifying it:
  
     my $x = "3"; # some variable containing a string
     $x += 0;     # numify it, ensuring it will be dumped as a number
     $x *= 1;     # same thing, the choise is yours.
  
  You can not currently force the type in other, less obscure, ways.
  
  Note that numerical precision has the same meaning as under Perl (so
  binary to decimal conversion follows the same rules as in Perl, which
  can differ to other languages). Also, your perl interpreter might expose
  extensions to the floating point numbers of your platform, such as
  infinities or NaN's - these cannot be represented in JSON, and it is an
  error to pass those in.
  
  =item Big Number
  
  When C<allow_bignum> is enable, 
  C<encode> converts C<Math::BigInt> objects and C<Math::BigFloat>
  objects into JSON numbers.
  
  
  =back
  
  =head1 UNICODE HANDLING ON PERLS
  
  If you do not know about Unicode on Perl well,
  please check L<JSON::XS/A FEW NOTES ON UNICODE AND PERL>.
  
  =head2 Perl 5.8 and later
  
  Perl can handle Unicode and the JSON::PP de/encode methods also work properly.
  
      $json->allow_nonref->encode(chr hex 3042);
      $json->allow_nonref->encode(chr hex 12345);
  
  Reuturns C<"\u3042"> and C<"\ud808\udf45"> respectively.
  
      $json->allow_nonref->decode('"\u3042"');
      $json->allow_nonref->decode('"\ud808\udf45"');
  
  Returns UTF-8 encoded strings with UTF8 flag, regarded as C<U+3042> and C<U+12345>.
  
  Note that the versions from Perl 5.8.0 to 5.8.2, Perl built-in C<join> was broken,
  so JSON::PP wraps the C<join> with a subroutine. Thus JSON::PP works slow in the versions.
  
  
  =head2 Perl 5.6
  
  Perl can handle Unicode and the JSON::PP de/encode methods also work.
  
  =head2 Perl 5.005
  
  Perl 5.005 is a byte sementics world -- all strings are sequences of bytes.
  That means the unicode handling is not available.
  
  In encoding,
  
      $json->allow_nonref->encode(chr hex 3042);  # hex 3042 is 12354.
      $json->allow_nonref->encode(chr hex 12345); # hex 12345 is 74565.
  
  Returns C<B> and C<E>, as C<chr> takes a value more than 255, it treats
  as C<$value % 256>, so the above codes are equivalent to :
  
      $json->allow_nonref->encode(chr 66);
      $json->allow_nonref->encode(chr 69);
  
  In decoding,
  
      $json->decode('"\u00e3\u0081\u0082"');
  
  The returned is a byte sequence C<0xE3 0x81 0x82> for UTF-8 encoded
  japanese character (C<HIRAGANA LETTER A>).
  And if it is represented in Unicode code point, C<U+3042>.
  
  Next, 
  
      $json->decode('"\u3042"');
  
  We ordinary expect the returned value is a Unicode character C<U+3042>.
  But here is 5.005 world. This is C<0xE3 0x81 0x82>.
  
      $json->decode('"\ud808\udf45"');
  
  This is not a character C<U+12345> but bytes - C<0xf0 0x92 0x8d 0x85>.
  
  
  =head1 TODO
  
  =over
  
  =item speed
  
  =item memory saving
  
  =back
  
  
  =head1 SEE ALSO
  
  Most of the document are copied and modified from JSON::XS doc.
  
  L<JSON::XS>
  
  RFC4627 (L<http://www.ietf.org/rfc/rfc4627.txt>)
  
  =head1 AUTHOR
  
  Makamaka Hannyaharamitu, E<lt>makamaka[at]cpan.orgE<gt>
  
  
  =head1 COPYRIGHT AND LICENSE
  
  Copyright 2007-2014 by Makamaka Hannyaharamitu
  
  This library is free software; you can redistribute it and/or modify
  it under the same terms as Perl itself. 
  
  =cut
JSON_PP

$fatpacked{"JSON/PP/Boolean.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'JSON_PP_BOOLEAN';
  =head1 NAME
  
  JSON::PP::Boolean - dummy module providing JSON::PP::Boolean
  
  =head1 SYNOPSIS
  
   # do not "use" yourself
  
  =head1 DESCRIPTION
  
  This module exists only to provide overload resolution for Storable and similar modules. See
  L<JSON::PP> for more info about this class.
  
  =cut
  
  use JSON::PP ();
  use strict;
  
  1;
  
  =head1 AUTHOR
  
  This idea is from L<JSON::XS::Boolean> written by Marc Lehmann <schmorp[at]schmorp.de>
  
  =cut
  
JSON_PP_BOOLEAN

$fatpacked{"JSON/backportPP.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'JSON_BACKPORTPP';
  package # This is JSON::backportPP
      JSON::PP;
  
  # JSON-2.0
  
  use 5.005;
  use strict;
  use base qw(Exporter);
  use overload ();
  
  use Carp ();
  use B ();
  #use Devel::Peek;
  
  use vars qw($VERSION);
  $VERSION = '2.27202';
  
  @JSON::PP::EXPORT = qw(encode_json decode_json from_json to_json);
  
  # instead of hash-access, i tried index-access for speed.
  # but this method is not faster than what i expected. so it will be changed.
  
  use constant P_ASCII                => 0;
  use constant P_LATIN1               => 1;
  use constant P_UTF8                 => 2;
  use constant P_INDENT               => 3;
  use constant P_CANONICAL            => 4;
  use constant P_SPACE_BEFORE         => 5;
  use constant P_SPACE_AFTER          => 6;
  use constant P_ALLOW_NONREF         => 7;
  use constant P_SHRINK               => 8;
  use constant P_ALLOW_BLESSED        => 9;
  use constant P_CONVERT_BLESSED      => 10;
  use constant P_RELAXED              => 11;
  
  use constant P_LOOSE                => 12;
  use constant P_ALLOW_BIGNUM         => 13;
  use constant P_ALLOW_BAREKEY        => 14;
  use constant P_ALLOW_SINGLEQUOTE    => 15;
  use constant P_ESCAPE_SLASH         => 16;
  use constant P_AS_NONBLESSED        => 17;
  
  use constant P_ALLOW_UNKNOWN        => 18;
  
  use constant OLD_PERL => $] < 5.008 ? 1 : 0;
  
  BEGIN {
      my @xs_compati_bit_properties = qw(
              latin1 ascii utf8 indent canonical space_before space_after allow_nonref shrink
              allow_blessed convert_blessed relaxed allow_unknown
      );
      my @pp_bit_properties = qw(
              allow_singlequote allow_bignum loose
              allow_barekey escape_slash as_nonblessed
      );
  
      # Perl version check, Unicode handling is enable?
      # Helper module sets @JSON::PP::_properties.
      if ($] < 5.008 ) {
          my $helper = $] >= 5.006 ? 'JSON::backportPP::Compat5006' : 'JSON::backportPP::Compat5005';
          eval qq| require $helper |;
          if ($@) { Carp::croak $@; }
      }
  
      for my $name (@xs_compati_bit_properties, @pp_bit_properties) {
          my $flag_name = 'P_' . uc($name);
  
          eval qq/
              sub $name {
                  my \$enable = defined \$_[1] ? \$_[1] : 1;
  
                  if (\$enable) {
                      \$_[0]->{PROPS}->[$flag_name] = 1;
                  }
                  else {
                      \$_[0]->{PROPS}->[$flag_name] = 0;
                  }
  
                  \$_[0];
              }
  
              sub get_$name {
                  \$_[0]->{PROPS}->[$flag_name] ? 1 : '';
              }
          /;
      }
  
  }
  
  
  
  # Functions
  
  my %encode_allow_method
       = map {($_ => 1)} qw/utf8 pretty allow_nonref latin1 self_encode escape_slash
                            allow_blessed convert_blessed indent indent_length allow_bignum
                            as_nonblessed
                          /;
  my %decode_allow_method
       = map {($_ => 1)} qw/utf8 allow_nonref loose allow_singlequote allow_bignum
                            allow_barekey max_size relaxed/;
  
  
  my $JSON; # cache
  
  sub encode_json ($) { # encode
      ($JSON ||= __PACKAGE__->new->utf8)->encode(@_);
  }
  
  
  sub decode_json { # decode
      ($JSON ||= __PACKAGE__->new->utf8)->decode(@_);
  }
  
  # Obsoleted
  
  sub to_json($) {
     Carp::croak ("JSON::PP::to_json has been renamed to encode_json.");
  }
  
  
  sub from_json($) {
     Carp::croak ("JSON::PP::from_json has been renamed to decode_json.");
  }
  
  
  # Methods
  
  sub new {
      my $class = shift;
      my $self  = {
          max_depth   => 512,
          max_size    => 0,
          indent      => 0,
          FLAGS       => 0,
          fallback      => sub { encode_error('Invalid value. JSON can only reference.') },
          indent_length => 3,
      };
  
      bless $self, $class;
  }
  
  
  sub encode {
      return $_[0]->PP_encode_json($_[1]);
  }
  
  
  sub decode {
      return $_[0]->PP_decode_json($_[1], 0x00000000);
  }
  
  
  sub decode_prefix {
      return $_[0]->PP_decode_json($_[1], 0x00000001);
  }
  
  
  # accessor
  
  
  # pretty printing
  
  sub pretty {
      my ($self, $v) = @_;
      my $enable = defined $v ? $v : 1;
  
      if ($enable) { # indent_length(3) for JSON::XS compatibility
          $self->indent(1)->indent_length(3)->space_before(1)->space_after(1);
      }
      else {
          $self->indent(0)->space_before(0)->space_after(0);
      }
  
      $self;
  }
  
  # etc
  
  sub max_depth {
      my $max  = defined $_[1] ? $_[1] : 0x80000000;
      $_[0]->{max_depth} = $max;
      $_[0];
  }
  
  
  sub get_max_depth { $_[0]->{max_depth}; }
  
  
  sub max_size {
      my $max  = defined $_[1] ? $_[1] : 0;
      $_[0]->{max_size} = $max;
      $_[0];
  }
  
  
  sub get_max_size { $_[0]->{max_size}; }
  
  
  sub filter_json_object {
      $_[0]->{cb_object} = defined $_[1] ? $_[1] : 0;
      $_[0]->{F_HOOK} = ($_[0]->{cb_object} or $_[0]->{cb_sk_object}) ? 1 : 0;
      $_[0];
  }
  
  sub filter_json_single_key_object {
      if (@_ > 1) {
          $_[0]->{cb_sk_object}->{$_[1]} = $_[2];
      }
      $_[0]->{F_HOOK} = ($_[0]->{cb_object} or $_[0]->{cb_sk_object}) ? 1 : 0;
      $_[0];
  }
  
  sub indent_length {
      if (!defined $_[1] or $_[1] > 15 or $_[1] < 0) {
          Carp::carp "The acceptable range of indent_length() is 0 to 15.";
      }
      else {
          $_[0]->{indent_length} = $_[1];
      }
      $_[0];
  }
  
  sub get_indent_length {
      $_[0]->{indent_length};
  }
  
  sub sort_by {
      $_[0]->{sort_by} = defined $_[1] ? $_[1] : 1;
      $_[0];
  }
  
  sub allow_bigint {
      Carp::carp("allow_bigint() is obsoleted. use allow_bignum() insted.");
  }
  
  ###############################
  
  ###
  ### Perl => JSON
  ###
  
  
  { # Convert
  
      my $max_depth;
      my $indent;
      my $ascii;
      my $latin1;
      my $utf8;
      my $space_before;
      my $space_after;
      my $canonical;
      my $allow_blessed;
      my $convert_blessed;
  
      my $indent_length;
      my $escape_slash;
      my $bignum;
      my $as_nonblessed;
  
      my $depth;
      my $indent_count;
      my $keysort;
  
  
      sub PP_encode_json {
          my $self = shift;
          my $obj  = shift;
  
          $indent_count = 0;
          $depth        = 0;
  
          my $idx = $self->{PROPS};
  
          ($ascii, $latin1, $utf8, $indent, $canonical, $space_before, $space_after, $allow_blessed,
              $convert_blessed, $escape_slash, $bignum, $as_nonblessed)
           = @{$idx}[P_ASCII .. P_SPACE_AFTER, P_ALLOW_BLESSED, P_CONVERT_BLESSED,
                      P_ESCAPE_SLASH, P_ALLOW_BIGNUM, P_AS_NONBLESSED];
  
          ($max_depth, $indent_length) = @{$self}{qw/max_depth indent_length/};
  
          $keysort = $canonical ? sub { $a cmp $b } : undef;
  
          if ($self->{sort_by}) {
              $keysort = ref($self->{sort_by}) eq 'CODE' ? $self->{sort_by}
                       : $self->{sort_by} =~ /\D+/       ? $self->{sort_by}
                       : sub { $a cmp $b };
          }
  
          encode_error("hash- or arrayref expected (not a simple scalar, use allow_nonref to allow this)")
               if(!ref $obj and !$idx->[ P_ALLOW_NONREF ]);
  
          my $str  = $self->object_to_json($obj);
  
          $str .= "\n" if ( $indent ); # JSON::XS 2.26 compatible
  
          unless ($ascii or $latin1 or $utf8) {
              utf8::upgrade($str);
          }
  
          if ($idx->[ P_SHRINK ]) {
              utf8::downgrade($str, 1);
          }
  
          return $str;
      }
  
  
      sub object_to_json {
          my ($self, $obj) = @_;
          my $type = ref($obj);
  
          if($type eq 'HASH'){
              return $self->hash_to_json($obj);
          }
          elsif($type eq 'ARRAY'){
              return $self->array_to_json($obj);
          }
          elsif ($type) { # blessed object?
              if (blessed($obj)) {
  
                  return $self->value_to_json($obj) if ( $obj->isa('JSON::PP::Boolean') );
  
                  if ( $convert_blessed and $obj->can('TO_JSON') ) {
                      my $result = $obj->TO_JSON();
                      if ( defined $result and ref( $result ) ) {
                          if ( refaddr( $obj ) eq refaddr( $result ) ) {
                              encode_error( sprintf(
                                  "%s::TO_JSON method returned same object as was passed instead of a new one",
                                  ref $obj
                              ) );
                          }
                      }
  
                      return $self->object_to_json( $result );
                  }
  
                  return "$obj" if ( $bignum and _is_bignum($obj) );
                  return $self->blessed_to_json($obj) if ($allow_blessed and $as_nonblessed); # will be removed.
  
                  encode_error( sprintf("encountered object '%s', but neither allow_blessed "
                      . "nor convert_blessed settings are enabled", $obj)
                  ) unless ($allow_blessed);
  
                  return 'null';
              }
              else {
                  return $self->value_to_json($obj);
              }
          }
          else{
              return $self->value_to_json($obj);
          }
      }
  
  
      sub hash_to_json {
          my ($self, $obj) = @_;
          my @res;
  
          encode_error("json text or perl structure exceeds maximum nesting level (max_depth set too low?)")
                                           if (++$depth > $max_depth);
  
          my ($pre, $post) = $indent ? $self->_up_indent() : ('', '');
          my $del = ($space_before ? ' ' : '') . ':' . ($space_after ? ' ' : '');
  
          for my $k ( _sort( $obj ) ) {
              if ( OLD_PERL ) { utf8::decode($k) } # key for Perl 5.6 / be optimized
              push @res, string_to_json( $self, $k )
                            .  $del
                            . ( $self->object_to_json( $obj->{$k} ) || $self->value_to_json( $obj->{$k} ) );
          }
  
          --$depth;
          $self->_down_indent() if ($indent);
  
          return   '{' . ( @res ? $pre : '' ) . ( @res ? join( ",$pre", @res ) . $post : '' )  . '}';
      }
  
  
      sub array_to_json {
          my ($self, $obj) = @_;
          my @res;
  
          encode_error("json text or perl structure exceeds maximum nesting level (max_depth set too low?)")
                                           if (++$depth > $max_depth);
  
          my ($pre, $post) = $indent ? $self->_up_indent() : ('', '');
  
          for my $v (@$obj){
              push @res, $self->object_to_json($v) || $self->value_to_json($v);
          }
  
          --$depth;
          $self->_down_indent() if ($indent);
  
          return '[' . ( @res ? $pre : '' ) . ( @res ? join( ",$pre", @res ) . $post : '' ) . ']';
      }
  
  
      sub value_to_json {
          my ($self, $value) = @_;
  
          return 'null' if(!defined $value);
  
          my $b_obj = B::svref_2object(\$value);  # for round trip problem
          my $flags = $b_obj->FLAGS;
  
          return $value # as is 
              if $flags & ( B::SVp_IOK | B::SVp_NOK ) and !( $flags & B::SVp_POK ); # SvTYPE is IV or NV?
  
          my $type = ref($value);
  
          if(!$type){
              return string_to_json($self, $value);
          }
          elsif( blessed($value) and  $value->isa('JSON::PP::Boolean') ){
              return $$value == 1 ? 'true' : 'false';
          }
          elsif ($type) {
              if ((overload::StrVal($value) =~ /=(\w+)/)[0]) {
                  return $self->value_to_json("$value");
              }
  
              if ($type eq 'SCALAR' and defined $$value) {
                  return   $$value eq '1' ? 'true'
                         : $$value eq '0' ? 'false'
                         : $self->{PROPS}->[ P_ALLOW_UNKNOWN ] ? 'null'
                         : encode_error("cannot encode reference to scalar");
              }
  
               if ( $self->{PROPS}->[ P_ALLOW_UNKNOWN ] ) {
                   return 'null';
               }
               else {
                   if ( $type eq 'SCALAR' or $type eq 'REF' ) {
                      encode_error("cannot encode reference to scalar");
                   }
                   else {
                      encode_error("encountered $value, but JSON can only represent references to arrays or hashes");
                   }
               }
  
          }
          else {
              return $self->{fallback}->($value)
                   if ($self->{fallback} and ref($self->{fallback}) eq 'CODE');
              return 'null';
          }
  
      }
  
  
      my %esc = (
          "\n" => '\n',
          "\r" => '\r',
          "\t" => '\t',
          "\f" => '\f',
          "\b" => '\b',
          "\"" => '\"',
          "\\" => '\\\\',
          "\'" => '\\\'',
      );
  
  
      sub string_to_json {
          my ($self, $arg) = @_;
  
          $arg =~ s/([\x22\x5c\n\r\t\f\b])/$esc{$1}/g;
          $arg =~ s/\//\\\//g if ($escape_slash);
          $arg =~ s/([\x00-\x08\x0b\x0e-\x1f])/'\\u00' . unpack('H2', $1)/eg;
  
          if ($ascii) {
              $arg = JSON_PP_encode_ascii($arg);
          }
  
          if ($latin1) {
              $arg = JSON_PP_encode_latin1($arg);
          }
  
          if ($utf8) {
              utf8::encode($arg);
          }
  
          return '"' . $arg . '"';
      }
  
  
      sub blessed_to_json {
          my $reftype = reftype($_[1]) || '';
          if ($reftype eq 'HASH') {
              return $_[0]->hash_to_json($_[1]);
          }
          elsif ($reftype eq 'ARRAY') {
              return $_[0]->array_to_json($_[1]);
          }
          else {
              return 'null';
          }
      }
  
  
      sub encode_error {
          my $error  = shift;
          Carp::croak "$error";
      }
  
  
      sub _sort {
          defined $keysort ? (sort $keysort (keys %{$_[0]})) : keys %{$_[0]};
      }
  
  
      sub _up_indent {
          my $self  = shift;
          my $space = ' ' x $indent_length;
  
          my ($pre,$post) = ('','');
  
          $post = "\n" . $space x $indent_count;
  
          $indent_count++;
  
          $pre = "\n" . $space x $indent_count;
  
          return ($pre,$post);
      }
  
  
      sub _down_indent { $indent_count--; }
  
  
      sub PP_encode_box {
          {
              depth        => $depth,
              indent_count => $indent_count,
          };
      }
  
  } # Convert
  
  
  sub _encode_ascii {
      join('',
          map {
              $_ <= 127 ?
                  chr($_) :
              $_ <= 65535 ?
                  sprintf('\u%04x', $_) : sprintf('\u%x\u%x', _encode_surrogates($_));
          } unpack('U*', $_[0])
      );
  }
  
  
  sub _encode_latin1 {
      join('',
          map {
              $_ <= 255 ?
                  chr($_) :
              $_ <= 65535 ?
                  sprintf('\u%04x', $_) : sprintf('\u%x\u%x', _encode_surrogates($_));
          } unpack('U*', $_[0])
      );
  }
  
  
  sub _encode_surrogates { # from perlunicode
      my $uni = $_[0] - 0x10000;
      return ($uni / 0x400 + 0xD800, $uni % 0x400 + 0xDC00);
  }
  
  
  sub _is_bignum {
      $_[0]->isa('Math::BigInt') or $_[0]->isa('Math::BigFloat');
  }
  
  
  
  #
  # JSON => Perl
  #
  
  my $max_intsize;
  
  BEGIN {
      my $checkint = 1111;
      for my $d (5..64) {
          $checkint .= 1;
          my $int   = eval qq| $checkint |;
          if ($int =~ /[eE]/) {
              $max_intsize = $d - 1;
              last;
          }
      }
  }
  
  { # PARSE 
  
      my %escapes = ( #  by Jeremy Muhlich <jmuhlich [at] bitflood.org>
          b    => "\x8",
          t    => "\x9",
          n    => "\xA",
          f    => "\xC",
          r    => "\xD",
          '\\' => '\\',
          '"'  => '"',
          '/'  => '/',
      );
  
      my $text; # json data
      my $at;   # offset
      my $ch;   # 1chracter
      my $len;  # text length (changed according to UTF8 or NON UTF8)
      # INTERNAL
      my $depth;          # nest counter
      my $encoding;       # json text encoding
      my $is_valid_utf8;  # temp variable
      my $utf8_len;       # utf8 byte length
      # FLAGS
      my $utf8;           # must be utf8
      my $max_depth;      # max nest number of objects and arrays
      my $max_size;
      my $relaxed;
      my $cb_object;
      my $cb_sk_object;
  
      my $F_HOOK;
  
      my $allow_bigint;   # using Math::BigInt
      my $singlequote;    # loosely quoting
      my $loose;          # 
      my $allow_barekey;  # bareKey
  
      # $opt flag
      # 0x00000001 .... decode_prefix
      # 0x10000000 .... incr_parse
  
      sub PP_decode_json {
          my ($self, $opt); # $opt is an effective flag during this decode_json.
  
          ($self, $text, $opt) = @_;
  
          ($at, $ch, $depth) = (0, '', 0);
  
          if ( !defined $text or ref $text ) {
              decode_error("malformed JSON string, neither array, object, number, string or atom");
          }
  
          my $idx = $self->{PROPS};
  
          ($utf8, $relaxed, $loose, $allow_bigint, $allow_barekey, $singlequote)
              = @{$idx}[P_UTF8, P_RELAXED, P_LOOSE .. P_ALLOW_SINGLEQUOTE];
  
          if ( $utf8 ) {
              utf8::downgrade( $text, 1 ) or Carp::croak("Wide character in subroutine entry");
          }
          else {
              utf8::upgrade( $text );
          }
  
          $len = length $text;
  
          ($max_depth, $max_size, $cb_object, $cb_sk_object, $F_HOOK)
               = @{$self}{qw/max_depth  max_size cb_object cb_sk_object F_HOOK/};
  
          if ($max_size > 1) {
              use bytes;
              my $bytes = length $text;
              decode_error(
                  sprintf("attempted decode of JSON text of %s bytes size, but max_size is set to %s"
                      , $bytes, $max_size), 1
              ) if ($bytes > $max_size);
          }
  
          # Currently no effect
          # should use regexp
          my @octets = unpack('C4', $text);
          $encoding =   ( $octets[0] and  $octets[1]) ? 'UTF-8'
                      : (!$octets[0] and  $octets[1]) ? 'UTF-16BE'
                      : (!$octets[0] and !$octets[1]) ? 'UTF-32BE'
                      : ( $octets[2]                ) ? 'UTF-16LE'
                      : (!$octets[2]                ) ? 'UTF-32LE'
                      : 'unknown';
  
          white(); # remove head white space
  
          my $valid_start = defined $ch; # Is there a first character for JSON structure?
  
          my $result = value();
  
          return undef if ( !$result && ( $opt & 0x10000000 ) ); # for incr_parse
  
          decode_error("malformed JSON string, neither array, object, number, string or atom") unless $valid_start;
  
          if ( !$idx->[ P_ALLOW_NONREF ] and !ref $result ) {
                  decode_error(
                  'JSON text must be an object or array (but found number, string, true, false or null,'
                         . ' use allow_nonref to allow this)', 1);
          }
  
          Carp::croak('something wrong.') if $len < $at; # we won't arrive here.
  
          my $consumed = defined $ch ? $at - 1 : $at; # consumed JSON text length
  
          white(); # remove tail white space
  
          if ( $ch ) {
              return ( $result, $consumed ) if ($opt & 0x00000001); # all right if decode_prefix
              decode_error("garbage after JSON object");
          }
  
          ( $opt & 0x00000001 ) ? ( $result, $consumed ) : $result;
      }
  
  
      sub next_chr {
          return $ch = undef if($at >= $len);
          $ch = substr($text, $at++, 1);
      }
  
  
      sub value {
          white();
          return          if(!defined $ch);
          return object() if($ch eq '{');
          return array()  if($ch eq '[');
          return string() if($ch eq '"' or ($singlequote and $ch eq "'"));
          return number() if($ch =~ /[0-9]/ or $ch eq '-');
          return word();
      }
  
      sub string {
          my ($i, $s, $t, $u);
          my $utf16;
          my $is_utf8;
  
          ($is_valid_utf8, $utf8_len) = ('', 0);
  
          $s = ''; # basically UTF8 flag on
  
          if($ch eq '"' or ($singlequote and $ch eq "'")){
              my $boundChar = $ch;
  
              OUTER: while( defined(next_chr()) ){
  
                  if($ch eq $boundChar){
                      next_chr();
  
                      if ($utf16) {
                          decode_error("missing low surrogate character in surrogate pair");
                      }
  
                      utf8::decode($s) if($is_utf8);
  
                      return $s;
                  }
                  elsif($ch eq '\\'){
                      next_chr();
                      if(exists $escapes{$ch}){
                          $s .= $escapes{$ch};
                      }
                      elsif($ch eq 'u'){ # UNICODE handling
                          my $u = '';
  
                          for(1..4){
                              $ch = next_chr();
                              last OUTER if($ch !~ /[0-9a-fA-F]/);
                              $u .= $ch;
                          }
  
                          # U+D800 - U+DBFF
                          if ($u =~ /^[dD][89abAB][0-9a-fA-F]{2}/) { # UTF-16 high surrogate?
                              $utf16 = $u;
                          }
                          # U+DC00 - U+DFFF
                          elsif ($u =~ /^[dD][c-fC-F][0-9a-fA-F]{2}/) { # UTF-16 low surrogate?
                              unless (defined $utf16) {
                                  decode_error("missing high surrogate character in surrogate pair");
                              }
                              $is_utf8 = 1;
                              $s .= JSON_PP_decode_surrogates($utf16, $u) || next;
                              $utf16 = undef;
                          }
                          else {
                              if (defined $utf16) {
                                  decode_error("surrogate pair expected");
                              }
  
                              if ( ( my $hex = hex( $u ) ) > 127 ) {
                                  $is_utf8 = 1;
                                  $s .= JSON_PP_decode_unicode($u) || next;
                              }
                              else {
                                  $s .= chr $hex;
                              }
                          }
  
                      }
                      else{
                          unless ($loose) {
                              $at -= 2;
                              decode_error('illegal backslash escape sequence in string');
                          }
                          $s .= $ch;
                      }
                  }
                  else{
  
                      if ( ord $ch  > 127 ) {
                          if ( $utf8 ) {
                              unless( $ch = is_valid_utf8($ch) ) {
                                  $at -= 1;
                                  decode_error("malformed UTF-8 character in JSON string");
                              }
                              else {
                                  $at += $utf8_len - 1;
                              }
                          }
                          else {
                              utf8::encode( $ch );
                          }
  
                          $is_utf8 = 1;
                      }
  
                      if (!$loose) {
                          if ($ch =~ /[\x00-\x1f\x22\x5c]/)  { # '/' ok
                              $at--;
                              decode_error('invalid character encountered while parsing JSON string');
                          }
                      }
  
                      $s .= $ch;
                  }
              }
          }
  
          decode_error("unexpected end of string while parsing JSON string");
      }
  
  
      sub white {
          while( defined $ch  ){
              if($ch le ' '){
                  next_chr();
              }
              elsif($ch eq '/'){
                  next_chr();
                  if(defined $ch and $ch eq '/'){
                      1 while(defined(next_chr()) and $ch ne "\n" and $ch ne "\r");
                  }
                  elsif(defined $ch and $ch eq '*'){
                      next_chr();
                      while(1){
                          if(defined $ch){
                              if($ch eq '*'){
                                  if(defined(next_chr()) and $ch eq '/'){
                                      next_chr();
                                      last;
                                  }
                              }
                              else{
                                  next_chr();
                              }
                          }
                          else{
                              decode_error("Unterminated comment");
                          }
                      }
                      next;
                  }
                  else{
                      $at--;
                      decode_error("malformed JSON string, neither array, object, number, string or atom");
                  }
              }
              else{
                  if ($relaxed and $ch eq '#') { # correctly?
                      pos($text) = $at;
                      $text =~ /\G([^\n]*(?:\r\n|\r|\n|$))/g;
                      $at = pos($text);
                      next_chr;
                      next;
                  }
  
                  last;
              }
          }
      }
  
  
      sub array {
          my $a  = $_[0] || []; # you can use this code to use another array ref object.
  
          decode_error('json text or perl structure exceeds maximum nesting level (max_depth set too low?)')
                                                      if (++$depth > $max_depth);
  
          next_chr();
          white();
  
          if(defined $ch and $ch eq ']'){
              --$depth;
              next_chr();
              return $a;
          }
          else {
              while(defined($ch)){
                  push @$a, value();
  
                  white();
  
                  if (!defined $ch) {
                      last;
                  }
  
                  if($ch eq ']'){
                      --$depth;
                      next_chr();
                      return $a;
                  }
  
                  if($ch ne ','){
                      last;
                  }
  
                  next_chr();
                  white();
  
                  if ($relaxed and $ch eq ']') {
                      --$depth;
                      next_chr();
                      return $a;
                  }
  
              }
          }
  
          decode_error(", or ] expected while parsing array");
      }
  
  
      sub object {
          my $o = $_[0] || {}; # you can use this code to use another hash ref object.
          my $k;
  
          decode_error('json text or perl structure exceeds maximum nesting level (max_depth set too low?)')
                                                  if (++$depth > $max_depth);
          next_chr();
          white();
  
          if(defined $ch and $ch eq '}'){
              --$depth;
              next_chr();
              if ($F_HOOK) {
                  return _json_object_hook($o);
              }
              return $o;
          }
          else {
              while (defined $ch) {
                  $k = ($allow_barekey and $ch ne '"' and $ch ne "'") ? bareKey() : string();
                  white();
  
                  if(!defined $ch or $ch ne ':'){
                      $at--;
                      decode_error("':' expected");
                  }
  
                  next_chr();
                  $o->{$k} = value();
                  white();
  
                  last if (!defined $ch);
  
                  if($ch eq '}'){
                      --$depth;
                      next_chr();
                      if ($F_HOOK) {
                          return _json_object_hook($o);
                      }
                      return $o;
                  }
  
                  if($ch ne ','){
                      last;
                  }
  
                  next_chr();
                  white();
  
                  if ($relaxed and $ch eq '}') {
                      --$depth;
                      next_chr();
                      if ($F_HOOK) {
                          return _json_object_hook($o);
                      }
                      return $o;
                  }
  
              }
  
          }
  
          $at--;
          decode_error(", or } expected while parsing object/hash");
      }
  
  
      sub bareKey { # doesn't strictly follow Standard ECMA-262 3rd Edition
          my $key;
          while($ch =~ /[^\x00-\x23\x25-\x2F\x3A-\x40\x5B-\x5E\x60\x7B-\x7F]/){
              $key .= $ch;
              next_chr();
          }
          return $key;
      }
  
  
      sub word {
          my $word =  substr($text,$at-1,4);
  
          if($word eq 'true'){
              $at += 3;
              next_chr;
              return $JSON::PP::true;
          }
          elsif($word eq 'null'){
              $at += 3;
              next_chr;
              return undef;
          }
          elsif($word eq 'fals'){
              $at += 3;
              if(substr($text,$at,1) eq 'e'){
                  $at++;
                  next_chr;
                  return $JSON::PP::false;
              }
          }
  
          $at--; # for decode_error report
  
          decode_error("'null' expected")  if ($word =~ /^n/);
          decode_error("'true' expected")  if ($word =~ /^t/);
          decode_error("'false' expected") if ($word =~ /^f/);
          decode_error("malformed JSON string, neither array, object, number, string or atom");
      }
  
  
      sub number {
          my $n    = '';
          my $v;
  
          # According to RFC4627, hex or oct digits are invalid.
          if($ch eq '0'){
              my $peek = substr($text,$at,1);
              my $hex  = $peek =~ /[xX]/; # 0 or 1
  
              if($hex){
                  decode_error("malformed number (leading zero must not be followed by another digit)");
                  ($n) = ( substr($text, $at+1) =~ /^([0-9a-fA-F]+)/);
              }
              else{ # oct
                  ($n) = ( substr($text, $at) =~ /^([0-7]+)/);
                  if (defined $n and length $n > 1) {
                      decode_error("malformed number (leading zero must not be followed by another digit)");
                  }
              }
  
              if(defined $n and length($n)){
                  if (!$hex and length($n) == 1) {
                     decode_error("malformed number (leading zero must not be followed by another digit)");
                  }
                  $at += length($n) + $hex;
                  next_chr;
                  return $hex ? hex($n) : oct($n);
              }
          }
  
          if($ch eq '-'){
              $n = '-';
              next_chr;
              if (!defined $ch or $ch !~ /\d/) {
                  decode_error("malformed number (no digits after initial minus)");
              }
          }
  
          while(defined $ch and $ch =~ /\d/){
              $n .= $ch;
              next_chr;
          }
  
          if(defined $ch and $ch eq '.'){
              $n .= '.';
  
              next_chr;
              if (!defined $ch or $ch !~ /\d/) {
                  decode_error("malformed number (no digits after decimal point)");
              }
              else {
                  $n .= $ch;
              }
  
              while(defined(next_chr) and $ch =~ /\d/){
                  $n .= $ch;
              }
          }
  
          if(defined $ch and ($ch eq 'e' or $ch eq 'E')){
              $n .= $ch;
              next_chr;
  
              if(defined($ch) and ($ch eq '+' or $ch eq '-')){
                  $n .= $ch;
                  next_chr;
                  if (!defined $ch or $ch =~ /\D/) {
                      decode_error("malformed number (no digits after exp sign)");
                  }
                  $n .= $ch;
              }
              elsif(defined($ch) and $ch =~ /\d/){
                  $n .= $ch;
              }
              else {
                  decode_error("malformed number (no digits after exp sign)");
              }
  
              while(defined(next_chr) and $ch =~ /\d/){
                  $n .= $ch;
              }
  
          }
  
          $v .= $n;
  
          if ($v !~ /[.eE]/ and length $v > $max_intsize) {
              if ($allow_bigint) { # from Adam Sussman
                  require Math::BigInt;
                  return Math::BigInt->new($v);
              }
              else {
                  return "$v";
              }
          }
          elsif ($allow_bigint) {
              require Math::BigFloat;
              return Math::BigFloat->new($v);
          }
  
          return 0+$v;
      }
  
  
      sub is_valid_utf8 {
  
          $utf8_len = $_[0] =~ /[\x00-\x7F]/  ? 1
                    : $_[0] =~ /[\xC2-\xDF]/  ? 2
                    : $_[0] =~ /[\xE0-\xEF]/  ? 3
                    : $_[0] =~ /[\xF0-\xF4]/  ? 4
                    : 0
                    ;
  
          return unless $utf8_len;
  
          my $is_valid_utf8 = substr($text, $at - 1, $utf8_len);
  
          return ( $is_valid_utf8 =~ /^(?:
               [\x00-\x7F]
              |[\xC2-\xDF][\x80-\xBF]
              |[\xE0][\xA0-\xBF][\x80-\xBF]
              |[\xE1-\xEC][\x80-\xBF][\x80-\xBF]
              |[\xED][\x80-\x9F][\x80-\xBF]
              |[\xEE-\xEF][\x80-\xBF][\x80-\xBF]
              |[\xF0][\x90-\xBF][\x80-\xBF][\x80-\xBF]
              |[\xF1-\xF3][\x80-\xBF][\x80-\xBF][\x80-\xBF]
              |[\xF4][\x80-\x8F][\x80-\xBF][\x80-\xBF]
          )$/x )  ? $is_valid_utf8 : '';
      }
  
  
      sub decode_error {
          my $error  = shift;
          my $no_rep = shift;
          my $str    = defined $text ? substr($text, $at) : '';
          my $mess   = '';
          my $type   = $] >= 5.008           ? 'U*'
                     : $] <  5.006           ? 'C*'
                     : utf8::is_utf8( $str ) ? 'U*' # 5.6
                     : 'C*'
                     ;
  
          for my $c ( unpack( $type, $str ) ) { # emulate pv_uni_display() ?
              $mess .=  $c == 0x07 ? '\a'
                      : $c == 0x09 ? '\t'
                      : $c == 0x0a ? '\n'
                      : $c == 0x0d ? '\r'
                      : $c == 0x0c ? '\f'
                      : $c <  0x20 ? sprintf('\x{%x}', $c)
                      : $c == 0x5c ? '\\\\'
                      : $c <  0x80 ? chr($c)
                      : sprintf('\x{%x}', $c)
                      ;
              if ( length $mess >= 20 ) {
                  $mess .= '...';
                  last;
              }
          }
  
          unless ( length $mess ) {
              $mess = '(end of string)';
          }
  
          Carp::croak (
              $no_rep ? "$error" : "$error, at character offset $at (before \"$mess\")"
          );
  
      }
  
  
      sub _json_object_hook {
          my $o    = $_[0];
          my @ks = keys %{$o};
  
          if ( $cb_sk_object and @ks == 1 and exists $cb_sk_object->{ $ks[0] } and ref $cb_sk_object->{ $ks[0] } ) {
              my @val = $cb_sk_object->{ $ks[0] }->( $o->{$ks[0]} );
              if (@val == 1) {
                  return $val[0];
              }
          }
  
          my @val = $cb_object->($o) if ($cb_object);
          if (@val == 0 or @val > 1) {
              return $o;
          }
          else {
              return $val[0];
          }
      }
  
  
      sub PP_decode_box {
          {
              text    => $text,
              at      => $at,
              ch      => $ch,
              len     => $len,
              depth   => $depth,
              encoding      => $encoding,
              is_valid_utf8 => $is_valid_utf8,
          };
      }
  
  } # PARSE
  
  
  sub _decode_surrogates { # from perlunicode
      my $uni = 0x10000 + (hex($_[0]) - 0xD800) * 0x400 + (hex($_[1]) - 0xDC00);
      my $un  = pack('U*', $uni);
      utf8::encode( $un );
      return $un;
  }
  
  
  sub _decode_unicode {
      my $un = pack('U', hex shift);
      utf8::encode( $un );
      return $un;
  }
  
  #
  # Setup for various Perl versions (the code from JSON::PP58)
  #
  
  BEGIN {
  
      unless ( defined &utf8::is_utf8 ) {
         require Encode;
         *utf8::is_utf8 = *Encode::is_utf8;
      }
  
      if ( $] >= 5.008 ) {
          *JSON::PP::JSON_PP_encode_ascii      = \&_encode_ascii;
          *JSON::PP::JSON_PP_encode_latin1     = \&_encode_latin1;
          *JSON::PP::JSON_PP_decode_surrogates = \&_decode_surrogates;
          *JSON::PP::JSON_PP_decode_unicode    = \&_decode_unicode;
      }
  
      if ($] >= 5.008 and $] < 5.008003) { # join() in 5.8.0 - 5.8.2 is broken.
          package # hide from PAUSE
            JSON::PP;
          require subs;
          subs->import('join');
          eval q|
              sub join {
                  return '' if (@_ < 2);
                  my $j   = shift;
                  my $str = shift;
                  for (@_) { $str .= $j . $_; }
                  return $str;
              }
          |;
      }
  
  
      sub JSON::PP::incr_parse {
          local $Carp::CarpLevel = 1;
          ( $_[0]->{_incr_parser} ||= JSON::PP::IncrParser->new )->incr_parse( @_ );
      }
  
  
      sub JSON::PP::incr_skip {
          ( $_[0]->{_incr_parser} ||= JSON::PP::IncrParser->new )->incr_skip;
      }
  
  
      sub JSON::PP::incr_reset {
          ( $_[0]->{_incr_parser} ||= JSON::PP::IncrParser->new )->incr_reset;
      }
  
      eval q{
          sub JSON::PP::incr_text : lvalue {
              $_[0]->{_incr_parser} ||= JSON::PP::IncrParser->new;
  
              if ( $_[0]->{_incr_parser}->{incr_parsing} ) {
                  Carp::croak("incr_text can not be called when the incremental parser already started parsing");
              }
              $_[0]->{_incr_parser}->{incr_text};
          }
      } if ( $] >= 5.006 );
  
  } # Setup for various Perl versions (the code from JSON::PP58)
  
  
  ###############################
  # Utilities
  #
  
  BEGIN {
      eval 'require Scalar::Util';
      unless($@){
          *JSON::PP::blessed = \&Scalar::Util::blessed;
          *JSON::PP::reftype = \&Scalar::Util::reftype;
          *JSON::PP::refaddr = \&Scalar::Util::refaddr;
      }
      else{ # This code is from Scalar::Util.
          # warn $@;
          eval 'sub UNIVERSAL::a_sub_not_likely_to_be_here { ref($_[0]) }';
          *JSON::PP::blessed = sub {
              local($@, $SIG{__DIE__}, $SIG{__WARN__});
              ref($_[0]) ? eval { $_[0]->a_sub_not_likely_to_be_here } : undef;
          };
          my %tmap = qw(
              B::NULL   SCALAR
              B::HV     HASH
              B::AV     ARRAY
              B::CV     CODE
              B::IO     IO
              B::GV     GLOB
              B::REGEXP REGEXP
          );
          *JSON::PP::reftype = sub {
              my $r = shift;
  
              return undef unless length(ref($r));
  
              my $t = ref(B::svref_2object($r));
  
              return
                  exists $tmap{$t} ? $tmap{$t}
                : length(ref($$r)) ? 'REF'
                :                    'SCALAR';
          };
          *JSON::PP::refaddr = sub {
            return undef unless length(ref($_[0]));
  
            my $addr;
            if(defined(my $pkg = blessed($_[0]))) {
              $addr .= bless $_[0], 'Scalar::Util::Fake';
              bless $_[0], $pkg;
            }
            else {
              $addr .= $_[0]
            }
  
            $addr =~ /0x(\w+)/;
            local $^W;
            #no warnings 'portable';
            hex($1);
          }
      }
  }
  
  
  # shamelessly copied and modified from JSON::XS code.
  
  $JSON::PP::true  = do { bless \(my $dummy = 1), "JSON::backportPP::Boolean" };
  $JSON::PP::false = do { bless \(my $dummy = 0), "JSON::backportPP::Boolean" };
  
  sub is_bool { defined $_[0] and UNIVERSAL::isa($_[0], "JSON::PP::Boolean"); }
  
  sub true  { $JSON::PP::true  }
  sub false { $JSON::PP::false }
  sub null  { undef; }
  
  ###############################
  
  package JSON::backportPP::Boolean;
  
  @JSON::backportPP::Boolean::ISA = ('JSON::PP::Boolean');
  use overload (
     "0+"     => sub { ${$_[0]} },
     "++"     => sub { $_[0] = ${$_[0]} + 1 },
     "--"     => sub { $_[0] = ${$_[0]} - 1 },
     fallback => 1,
  );
  
  
  ###############################
  
  package # hide from PAUSE
    JSON::PP::IncrParser;
  
  use strict;
  
  use constant INCR_M_WS   => 0; # initial whitespace skipping
  use constant INCR_M_STR  => 1; # inside string
  use constant INCR_M_BS   => 2; # inside backslash
  use constant INCR_M_JSON => 3; # outside anything, count nesting
  use constant INCR_M_C0   => 4;
  use constant INCR_M_C1   => 5;
  
  use vars qw($VERSION);
  $VERSION = '1.01';
  
  my $unpack_format = $] < 5.006 ? 'C*' : 'U*';
  
  sub new {
      my ( $class ) = @_;
  
      bless {
          incr_nest    => 0,
          incr_text    => undef,
          incr_parsing => 0,
          incr_p       => 0,
      }, $class;
  }
  
  
  sub incr_parse {
      my ( $self, $coder, $text ) = @_;
  
      $self->{incr_text} = '' unless ( defined $self->{incr_text} );
  
      if ( defined $text ) {
          if ( utf8::is_utf8( $text ) and !utf8::is_utf8( $self->{incr_text} ) ) {
              utf8::upgrade( $self->{incr_text} ) ;
              utf8::decode( $self->{incr_text} ) ;
          }
          $self->{incr_text} .= $text;
      }
  
  
      my $max_size = $coder->get_max_size;
  
      if ( defined wantarray ) {
  
          $self->{incr_mode} = INCR_M_WS unless defined $self->{incr_mode};
  
          if ( wantarray ) {
              my @ret;
  
              $self->{incr_parsing} = 1;
  
              do {
                  push @ret, $self->_incr_parse( $coder, $self->{incr_text} );
  
                  unless ( !$self->{incr_nest} and $self->{incr_mode} == INCR_M_JSON ) {
                      $self->{incr_mode} = INCR_M_WS if $self->{incr_mode} != INCR_M_STR;
                  }
  
              } until ( length $self->{incr_text} >= $self->{incr_p} );
  
              $self->{incr_parsing} = 0;
  
              return @ret;
          }
          else { # in scalar context
              $self->{incr_parsing} = 1;
              my $obj = $self->_incr_parse( $coder, $self->{incr_text} );
              $self->{incr_parsing} = 0 if defined $obj; # pointed by Martin J. Evans
              return $obj ? $obj : undef; # $obj is an empty string, parsing was completed.
          }
  
      }
  
  }
  
  
  sub _incr_parse {
      my ( $self, $coder, $text, $skip ) = @_;
      my $p = $self->{incr_p};
      my $restore = $p;
  
      my @obj;
      my $len = length $text;
  
      if ( $self->{incr_mode} == INCR_M_WS ) {
          while ( $len > $p ) {
              my $s = substr( $text, $p, 1 );
              $p++ and next if ( 0x20 >= unpack($unpack_format, $s) );
              $self->{incr_mode} = INCR_M_JSON;
              last;
         }
      }
  
      while ( $len > $p ) {
          my $s = substr( $text, $p++, 1 );
  
          if ( $s eq '"' ) {
              if (substr( $text, $p - 2, 1 ) eq '\\' ) {
                  next;
              }
  
              if ( $self->{incr_mode} != INCR_M_STR  ) {
                  $self->{incr_mode} = INCR_M_STR;
              }
              else {
                  $self->{incr_mode} = INCR_M_JSON;
                  unless ( $self->{incr_nest} ) {
                      last;
                  }
              }
          }
  
          if ( $self->{incr_mode} == INCR_M_JSON ) {
  
              if ( $s eq '[' or $s eq '{' ) {
                  if ( ++$self->{incr_nest} > $coder->get_max_depth ) {
                      Carp::croak('json text or perl structure exceeds maximum nesting level (max_depth set too low?)');
                  }
              }
              elsif ( $s eq ']' or $s eq '}' ) {
                  last if ( --$self->{incr_nest} <= 0 );
              }
              elsif ( $s eq '#' ) {
                  while ( $len > $p ) {
                      last if substr( $text, $p++, 1 ) eq "\n";
                  }
              }
  
          }
  
      }
  
      $self->{incr_p} = $p;
  
      return if ( $self->{incr_mode} == INCR_M_STR and not $self->{incr_nest} );
      return if ( $self->{incr_mode} == INCR_M_JSON and $self->{incr_nest} > 0 );
  
      return '' unless ( length substr( $self->{incr_text}, 0, $p ) );
  
      local $Carp::CarpLevel = 2;
  
      $self->{incr_p} = $restore;
      $self->{incr_c} = $p;
  
      my ( $obj, $tail ) = $coder->PP_decode_json( substr( $self->{incr_text}, 0, $p ), 0x10000001 );
  
      $self->{incr_text} = substr( $self->{incr_text}, $p );
      $self->{incr_p} = 0;
  
      return $obj or '';
  }
  
  
  sub incr_text {
      if ( $_[0]->{incr_parsing} ) {
          Carp::croak("incr_text can not be called when the incremental parser already started parsing");
      }
      $_[0]->{incr_text};
  }
  
  
  sub incr_skip {
      my $self  = shift;
      $self->{incr_text} = substr( $self->{incr_text}, $self->{incr_c} );
      $self->{incr_p} = 0;
  }
  
  
  sub incr_reset {
      my $self = shift;
      $self->{incr_text}    = undef;
      $self->{incr_p}       = 0;
      $self->{incr_mode}    = 0;
      $self->{incr_nest}    = 0;
      $self->{incr_parsing} = 0;
  }
  
  ###############################
  
  
  1;
  __END__
  =pod
  
  =head1 NAME
  
  JSON::PP - JSON::XS compatible pure-Perl module.
  
  =head1 SYNOPSIS
  
   use JSON::PP;
  
   # exported functions, they croak on error
   # and expect/generate UTF-8
  
   $utf8_encoded_json_text = encode_json $perl_hash_or_arrayref;
   $perl_hash_or_arrayref  = decode_json $utf8_encoded_json_text;
  
   # OO-interface
  
   $coder = JSON::PP->new->ascii->pretty->allow_nonref;
   
   $json_text   = $json->encode( $perl_scalar );
   $perl_scalar = $json->decode( $json_text );
   
   $pretty_printed = $json->pretty->encode( $perl_scalar ); # pretty-printing
   
   # Note that JSON version 2.0 and above will automatically use
   # JSON::XS or JSON::PP, so you should be able to just:
   
   use JSON;
  
  
  =head1 VERSION
  
      2.27200
  
  L<JSON::XS> 2.27 (~2.30) compatible.
  
  =head1 DESCRIPTION
  
  This module is L<JSON::XS> compatible pure Perl module.
  (Perl 5.8 or later is recommended)
  
  JSON::XS is the fastest and most proper JSON module on CPAN.
  It is written by Marc Lehmann in C, so must be compiled and
  installed in the used environment.
  
  JSON::PP is a pure-Perl module and has compatibility to JSON::XS.
  
  
  =head2 FEATURES
  
  =over
  
  =item * correct unicode handling
  
  This module knows how to handle Unicode (depending on Perl version).
  
  See to L<JSON::XS/A FEW NOTES ON UNICODE AND PERL> and
  L<UNICODE HANDLING ON PERLS>.
  
  
  =item * round-trip integrity
  
  When you serialise a perl data structure using only data types
  supported by JSON and Perl, the deserialised data structure is
  identical on the Perl level. (e.g. the string "2.0" doesn't suddenly
  become "2" just because it looks like a number). There I<are> minor
  exceptions to this, read the MAPPING section below to learn about
  those.
  
  
  =item * strict checking of JSON correctness
  
  There is no guessing, no generating of illegal JSON texts by default,
  and only JSON is accepted as input by default (the latter is a
  security feature). But when some options are set, loose checking
  features are available.
  
  =back
  
  =head1 FUNCTIONAL INTERFACE
  
  Some documents are copied and modified from L<JSON::XS/FUNCTIONAL INTERFACE>.
  
  =head2 encode_json
  
      $json_text = encode_json $perl_scalar
  
  Converts the given Perl data structure to a UTF-8 encoded, binary string.
  
  This function call is functionally identical to:
  
      $json_text = JSON::PP->new->utf8->encode($perl_scalar)
  
  =head2 decode_json
  
      $perl_scalar = decode_json $json_text
  
  The opposite of C<encode_json>: expects an UTF-8 (binary) string and tries
  to parse that as an UTF-8 encoded JSON text, returning the resulting
  reference.
  
  This function call is functionally identical to:
  
      $perl_scalar = JSON::PP->new->utf8->decode($json_text)
  
  =head2 JSON::PP::is_bool
  
      $is_boolean = JSON::PP::is_bool($scalar)
  
  Returns true if the passed scalar represents either JSON::PP::true or
  JSON::PP::false, two constants that act like C<1> and C<0> respectively
  and are also used to represent JSON C<true> and C<false> in Perl strings.
  
  =head2 JSON::PP::true
  
  Returns JSON true value which is blessed object.
  It C<isa> JSON::PP::Boolean object.
  
  =head2 JSON::PP::false
  
  Returns JSON false value which is blessed object.
  It C<isa> JSON::PP::Boolean object.
  
  =head2 JSON::PP::null
  
  Returns C<undef>.
  
  See L<MAPPING>, below, for more information on how JSON values are mapped to
  Perl.
  
  
  =head1 HOW DO I DECODE A DATA FROM OUTER AND ENCODE TO OUTER
  
  This section supposes that your perl version is 5.8 or later.
  
  If you know a JSON text from an outer world - a network, a file content, and so on,
  is encoded in UTF-8, you should use C<decode_json> or C<JSON> module object
  with C<utf8> enable. And the decoded result will contain UNICODE characters.
  
    # from network
    my $json        = JSON::PP->new->utf8;
    my $json_text   = CGI->new->param( 'json_data' );
    my $perl_scalar = $json->decode( $json_text );
    
    # from file content
    local $/;
    open( my $fh, '<', 'json.data' );
    $json_text   = <$fh>;
    $perl_scalar = decode_json( $json_text );
  
  If an outer data is not encoded in UTF-8, firstly you should C<decode> it.
  
    use Encode;
    local $/;
    open( my $fh, '<', 'json.data' );
    my $encoding = 'cp932';
    my $unicode_json_text = decode( $encoding, <$fh> ); # UNICODE
    
    # or you can write the below code.
    #
    # open( my $fh, "<:encoding($encoding)", 'json.data' );
    # $unicode_json_text = <$fh>;
  
  In this case, C<$unicode_json_text> is of course UNICODE string.
  So you B<cannot> use C<decode_json> nor C<JSON> module object with C<utf8> enable.
  Instead of them, you use C<JSON> module object with C<utf8> disable.
  
    $perl_scalar = $json->utf8(0)->decode( $unicode_json_text );
  
  Or C<encode 'utf8'> and C<decode_json>:
  
    $perl_scalar = decode_json( encode( 'utf8', $unicode_json_text ) );
    # this way is not efficient.
  
  And now, you want to convert your C<$perl_scalar> into JSON data and
  send it to an outer world - a network or a file content, and so on.
  
  Your data usually contains UNICODE strings and you want the converted data to be encoded
  in UTF-8, you should use C<encode_json> or C<JSON> module object with C<utf8> enable.
  
    print encode_json( $perl_scalar ); # to a network? file? or display?
    # or
    print $json->utf8->encode( $perl_scalar );
  
  If C<$perl_scalar> does not contain UNICODE but C<$encoding>-encoded strings
  for some reason, then its characters are regarded as B<latin1> for perl
  (because it does not concern with your $encoding).
  You B<cannot> use C<encode_json> nor C<JSON> module object with C<utf8> enable.
  Instead of them, you use C<JSON> module object with C<utf8> disable.
  Note that the resulted text is a UNICODE string but no problem to print it.
  
    # $perl_scalar contains $encoding encoded string values
    $unicode_json_text = $json->utf8(0)->encode( $perl_scalar );
    # $unicode_json_text consists of characters less than 0x100
    print $unicode_json_text;
  
  Or C<decode $encoding> all string values and C<encode_json>:
  
    $perl_scalar->{ foo } = decode( $encoding, $perl_scalar->{ foo } );
    # ... do it to each string values, then encode_json
    $json_text = encode_json( $perl_scalar );
  
  This method is a proper way but probably not efficient.
  
  See to L<Encode>, L<perluniintro>.
  
  
  =head1 METHODS
  
  Basically, check to L<JSON> or L<JSON::XS>.
  
  =head2 new
  
      $json = JSON::PP->new
  
  Returns a new JSON::PP object that can be used to de/encode JSON
  strings.
  
  All boolean flags described below are by default I<disabled>.
  
  The mutators for flags all return the JSON object again and thus calls can
  be chained:
  
     my $json = JSON::PP->new->utf8->space_after->encode({a => [1,2]})
     => {"a": [1, 2]}
  
  =head2 ascii
  
      $json = $json->ascii([$enable])
      
      $enabled = $json->get_ascii
  
  If $enable is true (or missing), then the encode method will not generate characters outside
  the code range 0..127. Any Unicode characters outside that range will be escaped using either
  a single \uXXXX or a double \uHHHH\uLLLLL escape sequence, as per RFC4627.
  (See to L<JSON::XS/OBJECT-ORIENTED INTERFACE>).
  
  In Perl 5.005, there is no character having high value (more than 255).
  See to L<UNICODE HANDLING ON PERLS>.
  
  If $enable is false, then the encode method will not escape Unicode characters unless
  required by the JSON syntax or other flags. This results in a faster and more compact format.
  
    JSON::PP->new->ascii(1)->encode([chr 0x10401])
    => ["\ud801\udc01"]
  
  =head2 latin1
  
      $json = $json->latin1([$enable])
      
      $enabled = $json->get_latin1
  
  If $enable is true (or missing), then the encode method will encode the resulting JSON
  text as latin1 (or iso-8859-1), escaping any characters outside the code range 0..255.
  
  If $enable is false, then the encode method will not escape Unicode characters
  unless required by the JSON syntax or other flags.
  
    JSON::XS->new->latin1->encode (["\x{89}\x{abc}"]
    => ["\x{89}\\u0abc"]    # (perl syntax, U+abc escaped, U+89 not)
  
  See to L<UNICODE HANDLING ON PERLS>.
  
  =head2 utf8
  
      $json = $json->utf8([$enable])
      
      $enabled = $json->get_utf8
  
  If $enable is true (or missing), then the encode method will encode the JSON result
  into UTF-8, as required by many protocols, while the decode method expects to be handled
  an UTF-8-encoded string. Please note that UTF-8-encoded strings do not contain any
  characters outside the range 0..255, they are thus useful for bytewise/binary I/O.
  
  (In Perl 5.005, any character outside the range 0..255 does not exist.
  See to L<UNICODE HANDLING ON PERLS>.)
  
  In future versions, enabling this option might enable autodetection of the UTF-16 and UTF-32
  encoding families, as described in RFC4627.
  
  If $enable is false, then the encode method will return the JSON string as a (non-encoded)
  Unicode string, while decode expects thus a Unicode string. Any decoding or encoding
  (e.g. to UTF-8 or UTF-16) needs to be done yourself, e.g. using the Encode module.
  
  Example, output UTF-16BE-encoded JSON:
  
    use Encode;
    $jsontext = encode "UTF-16BE", JSON::PP->new->encode ($object);
  
  Example, decode UTF-32LE-encoded JSON:
  
    use Encode;
    $object = JSON::PP->new->decode (decode "UTF-32LE", $jsontext);
  
  
  =head2 pretty
  
      $json = $json->pretty([$enable])
  
  This enables (or disables) all of the C<indent>, C<space_before> and
  C<space_after> flags in one call to generate the most readable
  (or most compact) form possible.
  
  Equivalent to:
  
     $json->indent->space_before->space_after
  
  =head2 indent
  
      $json = $json->indent([$enable])
      
      $enabled = $json->get_indent
  
  The default indent space length is three.
  You can use C<indent_length> to change the length.
  
  =head2 space_before
  
      $json = $json->space_before([$enable])
      
      $enabled = $json->get_space_before
  
  If C<$enable> is true (or missing), then the C<encode> method will add an extra
  optional space before the C<:> separating keys from values in JSON objects.
  
  If C<$enable> is false, then the C<encode> method will not add any extra
  space at those places.
  
  This setting has no effect when decoding JSON texts.
  
  Example, space_before enabled, space_after and indent disabled:
  
     {"key" :"value"}
  
  =head2 space_after
  
      $json = $json->space_after([$enable])
      
      $enabled = $json->get_space_after
  
  If C<$enable> is true (or missing), then the C<encode> method will add an extra
  optional space after the C<:> separating keys from values in JSON objects
  and extra whitespace after the C<,> separating key-value pairs and array
  members.
  
  If C<$enable> is false, then the C<encode> method will not add any extra
  space at those places.
  
  This setting has no effect when decoding JSON texts.
  
  Example, space_before and indent disabled, space_after enabled:
  
     {"key": "value"}
  
  =head2 relaxed
  
      $json = $json->relaxed([$enable])
      
      $enabled = $json->get_relaxed
  
  If C<$enable> is true (or missing), then C<decode> will accept some
  extensions to normal JSON syntax (see below). C<encode> will not be
  affected in anyway. I<Be aware that this option makes you accept invalid
  JSON texts as if they were valid!>. I suggest only to use this option to
  parse application-specific files written by humans (configuration files,
  resource files etc.)
  
  If C<$enable> is false (the default), then C<decode> will only accept
  valid JSON texts.
  
  Currently accepted extensions are:
  
  =over 4
  
  =item * list items can have an end-comma
  
  JSON I<separates> array elements and key-value pairs with commas. This
  can be annoying if you write JSON texts manually and want to be able to
  quickly append elements, so this extension accepts comma at the end of
  such items not just between them:
  
     [
        1,
        2, <- this comma not normally allowed
     ]
     {
        "k1": "v1",
        "k2": "v2", <- this comma not normally allowed
     }
  
  =item * shell-style '#'-comments
  
  Whenever JSON allows whitespace, shell-style comments are additionally
  allowed. They are terminated by the first carriage-return or line-feed
  character, after which more white-space and comments are allowed.
  
    [
       1, # this comment not allowed in JSON
          # neither this one...
    ]
  
  =back
  
  =head2 canonical
  
      $json = $json->canonical([$enable])
      
      $enabled = $json->get_canonical
  
  If C<$enable> is true (or missing), then the C<encode> method will output JSON objects
  by sorting their keys. This is adding a comparatively high overhead.
  
  If C<$enable> is false, then the C<encode> method will output key-value
  pairs in the order Perl stores them (which will likely change between runs
  of the same script).
  
  This option is useful if you want the same data structure to be encoded as
  the same JSON text (given the same overall settings). If it is disabled,
  the same hash might be encoded differently even if contains the same data,
  as key-value pairs have no inherent ordering in Perl.
  
  This setting has no effect when decoding JSON texts.
  
  If you want your own sorting routine, you can give a code reference
  or a subroutine name to C<sort_by>. See to C<JSON::PP OWN METHODS>.
  
  =head2 allow_nonref
  
      $json = $json->allow_nonref([$enable])
      
      $enabled = $json->get_allow_nonref
  
  If C<$enable> is true (or missing), then the C<encode> method can convert a
  non-reference into its corresponding string, number or null JSON value,
  which is an extension to RFC4627. Likewise, C<decode> will accept those JSON
  values instead of croaking.
  
  If C<$enable> is false, then the C<encode> method will croak if it isn't
  passed an arrayref or hashref, as JSON texts must either be an object
  or array. Likewise, C<decode> will croak if given something that is not a
  JSON object or array.
  
     JSON::PP->new->allow_nonref->encode ("Hello, World!")
     => "Hello, World!"
  
  =head2 allow_unknown
  
      $json = $json->allow_unknown ([$enable])
      
      $enabled = $json->get_allow_unknown
  
  If $enable is true (or missing), then "encode" will *not* throw an
  exception when it encounters values it cannot represent in JSON (for
  example, filehandles) but instead will encode a JSON "null" value.
  Note that blessed objects are not included here and are handled
  separately by c<allow_nonref>.
  
  If $enable is false (the default), then "encode" will throw an
  exception when it encounters anything it cannot encode as JSON.
  
  This option does not affect "decode" in any way, and it is
  recommended to leave it off unless you know your communications
  partner.
  
  =head2 allow_blessed
  
      $json = $json->allow_blessed([$enable])
      
      $enabled = $json->get_allow_blessed
  
  If C<$enable> is true (or missing), then the C<encode> method will not
  barf when it encounters a blessed reference. Instead, the value of the
  B<convert_blessed> option will decide whether C<null> (C<convert_blessed>
  disabled or no C<TO_JSON> method found) or a representation of the
  object (C<convert_blessed> enabled and C<TO_JSON> method found) is being
  encoded. Has no effect on C<decode>.
  
  If C<$enable> is false (the default), then C<encode> will throw an
  exception when it encounters a blessed object.
  
  =head2 convert_blessed
  
      $json = $json->convert_blessed([$enable])
      
      $enabled = $json->get_convert_blessed
  
  If C<$enable> is true (or missing), then C<encode>, upon encountering a
  blessed object, will check for the availability of the C<TO_JSON> method
  on the object's class. If found, it will be called in scalar context
  and the resulting scalar will be encoded instead of the object. If no
  C<TO_JSON> method is found, the value of C<allow_blessed> will decide what
  to do.
  
  The C<TO_JSON> method may safely call die if it wants. If C<TO_JSON>
  returns other blessed objects, those will be handled in the same
  way. C<TO_JSON> must take care of not causing an endless recursion cycle
  (== crash) in this case. The name of C<TO_JSON> was chosen because other
  methods called by the Perl core (== not by the user of the object) are
  usually in upper case letters and to avoid collisions with the C<to_json>
  function or method.
  
  This setting does not yet influence C<decode> in any way.
  
  If C<$enable> is false, then the C<allow_blessed> setting will decide what
  to do when a blessed object is found.
  
  =head2 filter_json_object
  
      $json = $json->filter_json_object([$coderef])
  
  When C<$coderef> is specified, it will be called from C<decode> each
  time it decodes a JSON object. The only argument passed to the coderef
  is a reference to the newly-created hash. If the code references returns
  a single scalar (which need not be a reference), this value
  (i.e. a copy of that scalar to avoid aliasing) is inserted into the
  deserialised data structure. If it returns an empty list
  (NOTE: I<not> C<undef>, which is a valid scalar), the original deserialised
  hash will be inserted. This setting can slow down decoding considerably.
  
  When C<$coderef> is omitted or undefined, any existing callback will
  be removed and C<decode> will not change the deserialised hash in any
  way.
  
  Example, convert all JSON objects into the integer 5:
  
     my $js = JSON::PP->new->filter_json_object (sub { 5 });
     # returns [5]
     $js->decode ('[{}]'); # the given subroutine takes a hash reference.
     # throw an exception because allow_nonref is not enabled
     # so a lone 5 is not allowed.
     $js->decode ('{"a":1, "b":2}');
  
  =head2 filter_json_single_key_object
  
      $json = $json->filter_json_single_key_object($key [=> $coderef])
  
  Works remotely similar to C<filter_json_object>, but is only called for
  JSON objects having a single key named C<$key>.
  
  This C<$coderef> is called before the one specified via
  C<filter_json_object>, if any. It gets passed the single value in the JSON
  object. If it returns a single value, it will be inserted into the data
  structure. If it returns nothing (not even C<undef> but the empty list),
  the callback from C<filter_json_object> will be called next, as if no
  single-key callback were specified.
  
  If C<$coderef> is omitted or undefined, the corresponding callback will be
  disabled. There can only ever be one callback for a given key.
  
  As this callback gets called less often then the C<filter_json_object>
  one, decoding speed will not usually suffer as much. Therefore, single-key
  objects make excellent targets to serialise Perl objects into, especially
  as single-key JSON objects are as close to the type-tagged value concept
  as JSON gets (it's basically an ID/VALUE tuple). Of course, JSON does not
  support this in any way, so you need to make sure your data never looks
  like a serialised Perl hash.
  
  Typical names for the single object key are C<__class_whatever__>, or
  C<$__dollars_are_rarely_used__$> or C<}ugly_brace_placement>, or even
  things like C<__class_md5sum(classname)__>, to reduce the risk of clashing
  with real hashes.
  
  Example, decode JSON objects of the form C<< { "__widget__" => <id> } >>
  into the corresponding C<< $WIDGET{<id>} >> object:
  
     # return whatever is in $WIDGET{5}:
     JSON::PP
        ->new
        ->filter_json_single_key_object (__widget__ => sub {
              $WIDGET{ $_[0] }
           })
        ->decode ('{"__widget__": 5')
  
     # this can be used with a TO_JSON method in some "widget" class
     # for serialisation to json:
     sub WidgetBase::TO_JSON {
        my ($self) = @_;
  
        unless ($self->{id}) {
           $self->{id} = ..get..some..id..;
           $WIDGET{$self->{id}} = $self;
        }
  
        { __widget__ => $self->{id} }
     }
  
  =head2 shrink
  
      $json = $json->shrink([$enable])
      
      $enabled = $json->get_shrink
  
  In JSON::XS, this flag resizes strings generated by either
  C<encode> or C<decode> to their minimum size possible.
  It will also try to downgrade any strings to octet-form if possible.
  
  In JSON::PP, it is noop about resizing strings but tries
  C<utf8::downgrade> to the returned string by C<encode>.
  See to L<utf8>.
  
  See to L<JSON::XS/OBJECT-ORIENTED INTERFACE>
  
  =head2 max_depth
  
      $json = $json->max_depth([$maximum_nesting_depth])
      
      $max_depth = $json->get_max_depth
  
  Sets the maximum nesting level (default C<512>) accepted while encoding
  or decoding. If a higher nesting level is detected in JSON text or a Perl
  data structure, then the encoder and decoder will stop and croak at that
  point.
  
  Nesting level is defined by number of hash- or arrayrefs that the encoder
  needs to traverse to reach a given point or the number of C<{> or C<[>
  characters without their matching closing parenthesis crossed to reach a
  given character in a string.
  
  If no argument is given, the highest possible setting will be used, which
  is rarely useful.
  
  See L<JSON::XS/SSECURITY CONSIDERATIONS> for more info on why this is useful.
  
  When a large value (100 or more) was set and it de/encodes a deep nested object/text,
  it may raise a warning 'Deep recursion on subroutine' at the perl runtime phase.
  
  =head2 max_size
  
      $json = $json->max_size([$maximum_string_size])
      
      $max_size = $json->get_max_size
  
  Set the maximum length a JSON text may have (in bytes) where decoding is
  being attempted. The default is C<0>, meaning no limit. When C<decode>
  is called on a string that is longer then this many bytes, it will not
  attempt to decode the string but throw an exception. This setting has no
  effect on C<encode> (yet).
  
  If no argument is given, the limit check will be deactivated (same as when
  C<0> is specified).
  
  See L<JSON::XS/SECURITY CONSIDERATIONS> for more info on why this is useful.
  
  =head2 encode
  
      $json_text = $json->encode($perl_scalar)
  
  Converts the given Perl data structure (a simple scalar or a reference
  to a hash or array) to its JSON representation. Simple scalars will be
  converted into JSON string or number sequences, while references to arrays
  become JSON arrays and references to hashes become JSON objects. Undefined
  Perl values (e.g. C<undef>) become JSON C<null> values.
  References to the integers C<0> and C<1> are converted into C<true> and C<false>.
  
  =head2 decode
  
      $perl_scalar = $json->decode($json_text)
  
  The opposite of C<encode>: expects a JSON text and tries to parse it,
  returning the resulting simple scalar or reference. Croaks on error.
  
  JSON numbers and strings become simple Perl scalars. JSON arrays become
  Perl arrayrefs and JSON objects become Perl hashrefs. C<true> becomes
  C<1> (C<JSON::true>), C<false> becomes C<0> (C<JSON::false>) and
  C<null> becomes C<undef>.
  
  =head2 decode_prefix
  
      ($perl_scalar, $characters) = $json->decode_prefix($json_text)
  
  This works like the C<decode> method, but instead of raising an exception
  when there is trailing garbage after the first JSON object, it will
  silently stop parsing there and return the number of characters consumed
  so far.
  
     JSON->new->decode_prefix ("[1] the tail")
     => ([], 3)
  
  =head1 INCREMENTAL PARSING
  
  Most of this section are copied and modified from L<JSON::XS/INCREMENTAL PARSING>.
  
  In some cases, there is the need for incremental parsing of JSON texts.
  This module does allow you to parse a JSON stream incrementally.
  It does so by accumulating text until it has a full JSON object, which
  it then can decode. This process is similar to using C<decode_prefix>
  to see if a full JSON object is available, but is much more efficient
  (and can be implemented with a minimum of method calls).
  
  This module will only attempt to parse the JSON text once it is sure it
  has enough text to get a decisive result, using a very simple but
  truly incremental parser. This means that it sometimes won't stop as
  early as the full parser, for example, it doesn't detect parenthesis
  mismatches. The only thing it guarantees is that it starts decoding as
  soon as a syntactically valid JSON text has been seen. This means you need
  to set resource limits (e.g. C<max_size>) to ensure the parser will stop
  parsing in the presence if syntax errors.
  
  The following methods implement this incremental parser.
  
  =head2 incr_parse
  
      $json->incr_parse( [$string] ) # void context
      
      $obj_or_undef = $json->incr_parse( [$string] ) # scalar context
      
      @obj_or_empty = $json->incr_parse( [$string] ) # list context
  
  This is the central parsing function. It can both append new text and
  extract objects from the stream accumulated so far (both of these
  functions are optional).
  
  If C<$string> is given, then this string is appended to the already
  existing JSON fragment stored in the C<$json> object.
  
  After that, if the function is called in void context, it will simply
  return without doing anything further. This can be used to add more text
  in as many chunks as you want.
  
  If the method is called in scalar context, then it will try to extract
  exactly I<one> JSON object. If that is successful, it will return this
  object, otherwise it will return C<undef>. If there is a parse error,
  this method will croak just as C<decode> would do (one can then use
  C<incr_skip> to skip the erroneous part). This is the most common way of
  using the method.
  
  And finally, in list context, it will try to extract as many objects
  from the stream as it can find and return them, or the empty list
  otherwise. For this to work, there must be no separators between the JSON
  objects or arrays, instead they must be concatenated back-to-back. If
  an error occurs, an exception will be raised as in the scalar context
  case. Note that in this case, any previously-parsed JSON texts will be
  lost.
  
  Example: Parse some JSON arrays/objects in a given string and return them.
  
      my @objs = JSON->new->incr_parse ("[5][7][1,2]");
  
  =head2 incr_text
  
      $lvalue_string = $json->incr_text
  
  This method returns the currently stored JSON fragment as an lvalue, that
  is, you can manipulate it. This I<only> works when a preceding call to
  C<incr_parse> in I<scalar context> successfully returned an object. Under
  all other circumstances you must not call this function (I mean it.
  although in simple tests it might actually work, it I<will> fail under
  real world conditions). As a special exception, you can also call this
  method before having parsed anything.
  
  This function is useful in two cases: a) finding the trailing text after a
  JSON object or b) parsing multiple JSON objects separated by non-JSON text
  (such as commas).
  
      $json->incr_text =~ s/\s*,\s*//;
  
  In Perl 5.005, C<lvalue> attribute is not available.
  You must write codes like the below:
  
      $string = $json->incr_text;
      $string =~ s/\s*,\s*//;
      $json->incr_text( $string );
  
  =head2 incr_skip
  
      $json->incr_skip
  
  This will reset the state of the incremental parser and will remove the
  parsed text from the input buffer. This is useful after C<incr_parse>
  died, in which case the input buffer and incremental parser state is left
  unchanged, to skip the text parsed so far and to reset the parse state.
  
  =head2 incr_reset
  
      $json->incr_reset
  
  This completely resets the incremental parser, that is, after this call,
  it will be as if the parser had never parsed anything.
  
  This is useful if you want to repeatedly parse JSON objects and want to
  ignore any trailing data, which means you have to reset the parser after
  each successful decode.
  
  See to L<JSON::XS/INCREMENTAL PARSING> for examples.
  
  
  =head1 JSON::PP OWN METHODS
  
  =head2 allow_singlequote
  
      $json = $json->allow_singlequote([$enable])
  
  If C<$enable> is true (or missing), then C<decode> will accept
  JSON strings quoted by single quotations that are invalid JSON
  format.
  
      $json->allow_singlequote->decode({"foo":'bar'});
      $json->allow_singlequote->decode({'foo':"bar"});
      $json->allow_singlequote->decode({'foo':'bar'});
  
  As same as the C<relaxed> option, this option may be used to parse
  application-specific files written by humans.
  
  
  =head2 allow_barekey
  
      $json = $json->allow_barekey([$enable])
  
  If C<$enable> is true (or missing), then C<decode> will accept
  bare keys of JSON object that are invalid JSON format.
  
  As same as the C<relaxed> option, this option may be used to parse
  application-specific files written by humans.
  
      $json->allow_barekey->decode('{foo:"bar"}');
  
  =head2 allow_bignum
  
      $json = $json->allow_bignum([$enable])
  
  If C<$enable> is true (or missing), then C<decode> will convert
  the big integer Perl cannot handle as integer into a L<Math::BigInt>
  object and convert a floating number (any) into a L<Math::BigFloat>.
  
  On the contrary, C<encode> converts C<Math::BigInt> objects and C<Math::BigFloat>
  objects into JSON numbers with C<allow_blessed> enable.
  
     $json->allow_nonref->allow_blessed->allow_bignum;
     $bigfloat = $json->decode('2.000000000000000000000000001');
     print $json->encode($bigfloat);
     # => 2.000000000000000000000000001
  
  See to L<JSON::XS/MAPPING> about the normal conversion of JSON number.
  
  =head2 loose
  
      $json = $json->loose([$enable])
  
  The unescaped [\x00-\x1f\x22\x2f\x5c] strings are invalid in JSON strings
  and the module doesn't allow to C<decode> to these (except for \x2f).
  If C<$enable> is true (or missing), then C<decode>  will accept these
  unescaped strings.
  
      $json->loose->decode(qq|["abc
                                     def"]|);
  
  See L<JSON::XS/SSECURITY CONSIDERATIONS>.
  
  =head2 escape_slash
  
      $json = $json->escape_slash([$enable])
  
  According to JSON Grammar, I<slash> (U+002F) is escaped. But default
  JSON::PP (as same as JSON::XS) encodes strings without escaping slash.
  
  If C<$enable> is true (or missing), then C<encode> will escape slashes.
  
  =head2 indent_length
  
      $json = $json->indent_length($length)
  
  JSON::XS indent space length is 3 and cannot be changed.
  JSON::PP set the indent space length with the given $length.
  The default is 3. The acceptable range is 0 to 15.
  
  =head2 sort_by
  
      $json = $json->sort_by($function_name)
      $json = $json->sort_by($subroutine_ref)
  
  If $function_name or $subroutine_ref are set, its sort routine are used
  in encoding JSON objects.
  
     $js = $pc->sort_by(sub { $JSON::PP::a cmp $JSON::PP::b })->encode($obj);
     # is($js, q|{"a":1,"b":2,"c":3,"d":4,"e":5,"f":6,"g":7,"h":8,"i":9}|);
  
     $js = $pc->sort_by('own_sort')->encode($obj);
     # is($js, q|{"a":1,"b":2,"c":3,"d":4,"e":5,"f":6,"g":7,"h":8,"i":9}|);
  
     sub JSON::PP::own_sort { $JSON::PP::a cmp $JSON::PP::b }
  
  As the sorting routine runs in the JSON::PP scope, the given
  subroutine name and the special variables C<$a>, C<$b> will begin
  'JSON::PP::'.
  
  If $integer is set, then the effect is same as C<canonical> on.
  
  =head1 INTERNAL
  
  For developers.
  
  =over
  
  =item PP_encode_box
  
  Returns
  
          {
              depth        => $depth,
              indent_count => $indent_count,
          }
  
  
  =item PP_decode_box
  
  Returns
  
          {
              text    => $text,
              at      => $at,
              ch      => $ch,
              len     => $len,
              depth   => $depth,
              encoding      => $encoding,
              is_valid_utf8 => $is_valid_utf8,
          };
  
  =back
  
  =head1 MAPPING
  
  This section is copied from JSON::XS and modified to C<JSON::PP>.
  JSON::XS and JSON::PP mapping mechanisms are almost equivalent.
  
  See to L<JSON::XS/MAPPING>.
  
  =head2 JSON -> PERL
  
  =over 4
  
  =item object
  
  A JSON object becomes a reference to a hash in Perl. No ordering of object
  keys is preserved (JSON does not preserver object key ordering itself).
  
  =item array
  
  A JSON array becomes a reference to an array in Perl.
  
  =item string
  
  A JSON string becomes a string scalar in Perl - Unicode codepoints in JSON
  are represented by the same codepoints in the Perl string, so no manual
  decoding is necessary.
  
  =item number
  
  A JSON number becomes either an integer, numeric (floating point) or
  string scalar in perl, depending on its range and any fractional parts. On
  the Perl level, there is no difference between those as Perl handles all
  the conversion details, but an integer may take slightly less memory and
  might represent more values exactly than floating point numbers.
  
  If the number consists of digits only, C<JSON> will try to represent
  it as an integer value. If that fails, it will try to represent it as
  a numeric (floating point) value if that is possible without loss of
  precision. Otherwise it will preserve the number as a string value (in
  which case you lose roundtripping ability, as the JSON number will be
  re-encoded to a JSON string).
  
  Numbers containing a fractional or exponential part will always be
  represented as numeric (floating point) values, possibly at a loss of
  precision (in which case you might lose perfect roundtripping ability, but
  the JSON number will still be re-encoded as a JSON number).
  
  Note that precision is not accuracy - binary floating point values cannot
  represent most decimal fractions exactly, and when converting from and to
  floating point, C<JSON> only guarantees precision up to but not including
  the least significant bit.
  
  When C<allow_bignum> is enable, the big integers 
  and the numeric can be optionally converted into L<Math::BigInt> and
  L<Math::BigFloat> objects.
  
  =item true, false
  
  These JSON atoms become C<JSON::PP::true> and C<JSON::PP::false>,
  respectively. They are overloaded to act almost exactly like the numbers
  C<1> and C<0>. You can check whether a scalar is a JSON boolean by using
  the C<JSON::is_bool> function.
  
     print JSON::PP::true . "\n";
      => true
     print JSON::PP::true + 1;
      => 1
  
     ok(JSON::true eq  '1');
     ok(JSON::true == 1);
  
  C<JSON> will install these missing overloading features to the backend modules.
  
  
  =item null
  
  A JSON null atom becomes C<undef> in Perl.
  
  C<JSON::PP::null> returns C<undef>.
  
  =back
  
  
  =head2 PERL -> JSON
  
  The mapping from Perl to JSON is slightly more difficult, as Perl is a
  truly typeless language, so we can only guess which JSON type is meant by
  a Perl value.
  
  =over 4
  
  =item hash references
  
  Perl hash references become JSON objects. As there is no inherent ordering
  in hash keys (or JSON objects), they will usually be encoded in a
  pseudo-random order that can change between runs of the same program but
  stays generally the same within a single run of a program. C<JSON>
  optionally sort the hash keys (determined by the I<canonical> flag), so
  the same data structure will serialise to the same JSON text (given same
  settings and version of JSON::XS), but this incurs a runtime overhead
  and is only rarely useful, e.g. when you want to compare some JSON text
  against another for equality.
  
  
  =item array references
  
  Perl array references become JSON arrays.
  
  =item other references
  
  Other unblessed references are generally not allowed and will cause an
  exception to be thrown, except for references to the integers C<0> and
  C<1>, which get turned into C<false> and C<true> atoms in JSON. You can
  also use C<JSON::false> and C<JSON::true> to improve readability.
  
     to_json [\0,JSON::PP::true]      # yields [false,true]
  
  =item JSON::PP::true, JSON::PP::false, JSON::PP::null
  
  These special values become JSON true and JSON false values,
  respectively. You can also use C<\1> and C<\0> directly if you want.
  
  JSON::PP::null returns C<undef>.
  
  =item blessed objects
  
  Blessed objects are not directly representable in JSON. See the
  C<allow_blessed> and C<convert_blessed> methods on various options on
  how to deal with this: basically, you can choose between throwing an
  exception, encoding the reference as if it weren't blessed, or provide
  your own serialiser method.
  
  See to L<convert_blessed>.
  
  =item simple scalars
  
  Simple Perl scalars (any scalar that is not a reference) are the most
  difficult objects to encode: JSON::XS and JSON::PP will encode undefined scalars as
  JSON C<null> values, scalars that have last been used in a string context
  before encoding as JSON strings, and anything else as number value:
  
     # dump as number
     encode_json [2]                      # yields [2]
     encode_json [-3.0e17]                # yields [-3e+17]
     my $value = 5; encode_json [$value]  # yields [5]
  
     # used as string, so dump as string
     print $value;
     encode_json [$value]                 # yields ["5"]
  
     # undef becomes null
     encode_json [undef]                  # yields [null]
  
  You can force the type to be a string by stringifying it:
  
     my $x = 3.1; # some variable containing a number
     "$x";        # stringified
     $x .= "";    # another, more awkward way to stringify
     print $x;    # perl does it for you, too, quite often
  
  You can force the type to be a number by numifying it:
  
     my $x = "3"; # some variable containing a string
     $x += 0;     # numify it, ensuring it will be dumped as a number
     $x *= 1;     # same thing, the choice is yours.
  
  You can not currently force the type in other, less obscure, ways.
  
  Note that numerical precision has the same meaning as under Perl (so
  binary to decimal conversion follows the same rules as in Perl, which
  can differ to other languages). Also, your perl interpreter might expose
  extensions to the floating point numbers of your platform, such as
  infinities or NaN's - these cannot be represented in JSON, and it is an
  error to pass those in.
  
  =item Big Number
  
  When C<allow_bignum> is enable, 
  C<encode> converts C<Math::BigInt> objects and C<Math::BigFloat>
  objects into JSON numbers.
  
  
  =back
  
  =head1 UNICODE HANDLING ON PERLS
  
  If you do not know about Unicode on Perl well,
  please check L<JSON::XS/A FEW NOTES ON UNICODE AND PERL>.
  
  =head2 Perl 5.8 and later
  
  Perl can handle Unicode and the JSON::PP de/encode methods also work properly.
  
      $json->allow_nonref->encode(chr hex 3042);
      $json->allow_nonref->encode(chr hex 12345);
  
  Returns C<"\u3042"> and C<"\ud808\udf45"> respectively.
  
      $json->allow_nonref->decode('"\u3042"');
      $json->allow_nonref->decode('"\ud808\udf45"');
  
  Returns UTF-8 encoded strings with UTF8 flag, regarded as C<U+3042> and C<U+12345>.
  
  Note that the versions from Perl 5.8.0 to 5.8.2, Perl built-in C<join> was broken,
  so JSON::PP wraps the C<join> with a subroutine. Thus JSON::PP works slow in the versions.
  
  
  =head2 Perl 5.6
  
  Perl can handle Unicode and the JSON::PP de/encode methods also work.
  
  =head2 Perl 5.005
  
  Perl 5.005 is a byte semantics world -- all strings are sequences of bytes.
  That means the unicode handling is not available.
  
  In encoding,
  
      $json->allow_nonref->encode(chr hex 3042);  # hex 3042 is 12354.
      $json->allow_nonref->encode(chr hex 12345); # hex 12345 is 74565.
  
  Returns C<B> and C<E>, as C<chr> takes a value more than 255, it treats
  as C<$value % 256>, so the above codes are equivalent to :
  
      $json->allow_nonref->encode(chr 66);
      $json->allow_nonref->encode(chr 69);
  
  In decoding,
  
      $json->decode('"\u00e3\u0081\u0082"');
  
  The returned is a byte sequence C<0xE3 0x81 0x82> for UTF-8 encoded
  japanese character (C<HIRAGANA LETTER A>).
  And if it is represented in Unicode code point, C<U+3042>.
  
  Next, 
  
      $json->decode('"\u3042"');
  
  We ordinary expect the returned value is a Unicode character C<U+3042>.
  But here is 5.005 world. This is C<0xE3 0x81 0x82>.
  
      $json->decode('"\ud808\udf45"');
  
  This is not a character C<U+12345> but bytes - C<0xf0 0x92 0x8d 0x85>.
  
  
  =head1 TODO
  
  =over
  
  =item speed
  
  =item memory saving
  
  =back
  
  
  =head1 SEE ALSO
  
  Most of the document are copied and modified from JSON::XS doc.
  
  L<JSON::XS>
  
  RFC4627 (L<http://www.ietf.org/rfc/rfc4627.txt>)
  
  =head1 AUTHOR
  
  Makamaka Hannyaharamitu, E<lt>makamaka[at]cpan.orgE<gt>
  
  
  =head1 COPYRIGHT AND LICENSE
  
  Copyright 2007-2012 by Makamaka Hannyaharamitu
  
  This library is free software; you can redistribute it and/or modify
  it under the same terms as Perl itself. 
  
  =cut
JSON_BACKPORTPP

$fatpacked{"JSON/backportPP/Boolean.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'JSON_BACKPORTPP_BOOLEAN';
  =head1 NAME
  
  JSON::PP::Boolean - dummy module providing JSON::PP::Boolean
  
  =head1 SYNOPSIS
  
   # do not "use" yourself
  
  =head1 DESCRIPTION
  
  This module exists only to provide overload resolution for Storable
  and similar modules. See L<JSON::PP> for more info about this class.
  
  =cut
  
  use JSON::backportPP ();
  use strict;
  
  1;
  
  =head1 AUTHOR
  
  This idea is from L<JSON::XS::Boolean> written by
  Marc Lehmann <schmorp[at]schmorp.de>
  
  =cut
  
JSON_BACKPORTPP_BOOLEAN

$fatpacked{"JSON/backportPP/Compat5005.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'JSON_BACKPORTPP_COMPAT5005';
  package # This is JSON::backportPP
      JSON::backportPP5005;
  
  use 5.005;
  use strict;
  
  my @properties;
  
  $JSON::PP5005::VERSION = '1.10';
  
  BEGIN {
  
      sub utf8::is_utf8 {
          0; # It is considered that UTF8 flag off for Perl 5.005.
      }
  
      sub utf8::upgrade {
      }
  
      sub utf8::downgrade {
          1; # must always return true.
      }
  
      sub utf8::encode  {
      }
  
      sub utf8::decode {
      }
  
      *JSON::PP::JSON_PP_encode_ascii      = \&_encode_ascii;
      *JSON::PP::JSON_PP_encode_latin1     = \&_encode_latin1;
      *JSON::PP::JSON_PP_decode_surrogates = \&_decode_surrogates;
      *JSON::PP::JSON_PP_decode_unicode    = \&_decode_unicode;
  
      # missing in B module.
      sub B::SVp_IOK () { 0x01000000; }
      sub B::SVp_NOK () { 0x02000000; }
      sub B::SVp_POK () { 0x04000000; }
  
      $INC{'bytes.pm'} = 1; # dummy
  }
  
  
  
  sub _encode_ascii {
      join('', map { $_ <= 127 ? chr($_) : sprintf('\u%04x', $_) } unpack('C*', $_[0]) );
  }
  
  
  sub _encode_latin1 {
      join('', map { chr($_) } unpack('C*', $_[0]) );
  }
  
  
  sub _decode_surrogates { # from http://homepage1.nifty.com/nomenclator/unicode/ucs_utf.htm
      my $uni = 0x10000 + (hex($_[0]) - 0xD800) * 0x400 + (hex($_[1]) - 0xDC00); # from perlunicode
      my $bit = unpack('B32', pack('N', $uni));
  
      if ( $bit =~ /^00000000000(...)(......)(......)(......)$/ ) {
          my ($w, $x, $y, $z) = ($1, $2, $3, $4);
          return pack('B*', sprintf('11110%s10%s10%s10%s', $w, $x, $y, $z));
      }
      else {
          Carp::croak("Invalid surrogate pair");
      }
  }
  
  
  sub _decode_unicode {
      my ($u) = @_;
      my ($utf8bit);
  
      if ( $u =~ /^00([89a-f][0-9a-f])$/i ) { # 0x80-0xff
           return pack( 'H2', $1 );
      }
  
      my $bit = unpack("B*", pack("H*", $u));
  
      if ( $bit =~ /^00000(.....)(......)$/ ) {
          $utf8bit = sprintf('110%s10%s', $1, $2);
      }
      elsif ( $bit =~ /^(....)(......)(......)$/ ) {
          $utf8bit = sprintf('1110%s10%s10%s', $1, $2, $3);
      }
      else {
          Carp::croak("Invalid escaped unicode");
      }
  
      return pack('B*', $utf8bit);
  }
  
  
  sub JSON::PP::incr_text {
      $_[0]->{_incr_parser} ||= JSON::PP::IncrParser->new;
  
      if ( $_[0]->{_incr_parser}->{incr_parsing} ) {
          Carp::croak("incr_text can not be called when the incremental parser already started parsing");
      }
  
      $_[0]->{_incr_parser}->{incr_text} = $_[1] if ( @_ > 1 );
      $_[0]->{_incr_parser}->{incr_text};
  }
  
  
  1;
  __END__
  
  =pod
  
  =head1 NAME
  
  JSON::PP5005 - Helper module in using JSON::PP in Perl 5.005
  
  =head1 DESCRIPTION
  
  JSON::PP calls internally.
  
  =head1 AUTHOR
  
  Makamaka Hannyaharamitu, E<lt>makamaka[at]cpan.orgE<gt>
  
  
  =head1 COPYRIGHT AND LICENSE
  
  Copyright 2007-2012 by Makamaka Hannyaharamitu
  
  This library is free software; you can redistribute it and/or modify
  it under the same terms as Perl itself. 
  
  =cut
  
JSON_BACKPORTPP_COMPAT5005

$fatpacked{"JSON/backportPP/Compat5006.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'JSON_BACKPORTPP_COMPAT5006';
  package # This is JSON::backportPP
      JSON::backportPP56;
  
  use 5.006;
  use strict;
  
  my @properties;
  
  $JSON::PP56::VERSION = '1.08';
  
  BEGIN {
  
      sub utf8::is_utf8 {
          my $len =  length $_[0]; # char length
          {
              use bytes; #  byte length;
              return $len != length $_[0]; # if !=, UTF8-flagged on.
          }
      }
  
  
      sub utf8::upgrade {
          ; # noop;
      }
  
  
      sub utf8::downgrade ($;$) {
          return 1 unless ( utf8::is_utf8( $_[0] ) );
  
          if ( _is_valid_utf8( $_[0] ) ) {
              my $downgrade;
              for my $c ( unpack( "U*", $_[0] ) ) {
                  if ( $c < 256 ) {
                      $downgrade .= pack("C", $c);
                  }
                  else {
                      $downgrade .= pack("U", $c);
                  }
              }
              $_[0] = $downgrade;
              return 1;
          }
          else {
              Carp::croak("Wide character in subroutine entry") unless ( $_[1] );
              0;
          }
      }
  
  
      sub utf8::encode ($) { # UTF8 flag off
          if ( utf8::is_utf8( $_[0] ) ) {
              $_[0] = pack( "C*", unpack( "C*", $_[0] ) );
          }
          else {
              $_[0] = pack( "U*", unpack( "C*", $_[0] ) );
              $_[0] = pack( "C*", unpack( "C*", $_[0] ) );
          }
      }
  
  
      sub utf8::decode ($) { # UTF8 flag on
          if ( _is_valid_utf8( $_[0] ) ) {
              utf8::downgrade( $_[0] );
              $_[0] = pack( "U*", unpack( "U*", $_[0] ) );
          }
      }
  
  
      *JSON::PP::JSON_PP_encode_ascii      = \&_encode_ascii;
      *JSON::PP::JSON_PP_encode_latin1     = \&_encode_latin1;
      *JSON::PP::JSON_PP_decode_surrogates = \&JSON::PP::_decode_surrogates;
      *JSON::PP::JSON_PP_decode_unicode    = \&JSON::PP::_decode_unicode;
  
      unless ( defined &B::SVp_NOK ) { # missing in B module.
          eval q{ sub B::SVp_NOK () { 0x02000000; } };
      }
  
  }
  
  
  
  sub _encode_ascii {
      join('',
          map {
              $_ <= 127 ?
                  chr($_) :
              $_ <= 65535 ?
                  sprintf('\u%04x', $_) : sprintf('\u%x\u%x', JSON::PP::_encode_surrogates($_));
          } _unpack_emu($_[0])
      );
  }
  
  
  sub _encode_latin1 {
      join('',
          map {
              $_ <= 255 ?
                  chr($_) :
              $_ <= 65535 ?
                  sprintf('\u%04x', $_) : sprintf('\u%x\u%x', JSON::PP::_encode_surrogates($_));
          } _unpack_emu($_[0])
      );
  }
  
  
  sub _unpack_emu { # for Perl 5.6 unpack warnings
      return   !utf8::is_utf8($_[0]) ? unpack('C*', $_[0]) 
             : _is_valid_utf8($_[0]) ? unpack('U*', $_[0])
             : unpack('C*', $_[0]);
  }
  
  
  sub _is_valid_utf8 {
      my $str = $_[0];
      my $is_utf8;
  
      while ($str =~ /(?:
            (
               [\x00-\x7F]
              |[\xC2-\xDF][\x80-\xBF]
              |[\xE0][\xA0-\xBF][\x80-\xBF]
              |[\xE1-\xEC][\x80-\xBF][\x80-\xBF]
              |[\xED][\x80-\x9F][\x80-\xBF]
              |[\xEE-\xEF][\x80-\xBF][\x80-\xBF]
              |[\xF0][\x90-\xBF][\x80-\xBF][\x80-\xBF]
              |[\xF1-\xF3][\x80-\xBF][\x80-\xBF][\x80-\xBF]
              |[\xF4][\x80-\x8F][\x80-\xBF][\x80-\xBF]
            )
          | (.)
      )/xg)
      {
          if (defined $1) {
              $is_utf8 = 1 if (!defined $is_utf8);
          }
          else {
              $is_utf8 = 0 if (!defined $is_utf8);
              if ($is_utf8) { # eventually, not utf8
                  return;
              }
          }
      }
  
      return $is_utf8;
  }
  
  
  1;
  __END__
  
  =pod
  
  =head1 NAME
  
  JSON::PP56 - Helper module in using JSON::PP in Perl 5.6
  
  =head1 DESCRIPTION
  
  JSON::PP calls internally.
  
  =head1 AUTHOR
  
  Makamaka Hannyaharamitu, E<lt>makamaka[at]cpan.orgE<gt>
  
  
  =head1 COPYRIGHT AND LICENSE
  
  Copyright 2007-2012 by Makamaka Hannyaharamitu
  
  This library is free software; you can redistribute it and/or modify
  it under the same terms as Perl itself. 
  
  =cut
  
JSON_BACKPORTPP_COMPAT5006

$fatpacked{"Method/Generate/Accessor.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'METHOD_GENERATE_ACCESSOR';
  package Method::Generate::Accessor;
  
  use strictures 1;
  use Moo::_Utils;
  use base qw(Moo::Object);
  use Sub::Quote qw(quote_sub quoted_from_sub quotify);
  use Scalar::Util 'blessed';
  use overload ();
  use Module::Runtime qw(use_module);
  BEGIN {
    our $CAN_HAZ_XS =
      !$ENV{MOO_XS_DISABLE}
        &&
      _maybe_load_module('Class::XSAccessor')
        &&
      (eval { Class::XSAccessor->VERSION('1.07') })
    ;
    our $CAN_HAZ_XS_PRED =
      $CAN_HAZ_XS &&
      (eval { Class::XSAccessor->VERSION('1.17') })
    ;
  }
  
  my $module_name_only = qr/\A$Module::Runtime::module_name_rx\z/;
  
  sub _die_overwrite
  {
    my ($pkg, $method, $type) = @_;
    die "You cannot overwrite a locally defined method ($method) with "
      . ( $type || 'an accessor' );
  }
  
  sub generate_method {
    my ($self, $into, $name, $spec, $quote_opts) = @_;
    $spec->{allow_overwrite}++ if $name =~ s/^\+//;
    die "Must have an is" unless my $is = $spec->{is};
    if ($is eq 'ro') {
      $spec->{reader} = $name unless exists $spec->{reader};
    } elsif ($is eq 'rw') {
      $spec->{accessor} = $name unless exists $spec->{accessor}
        or ( $spec->{reader} and $spec->{writer} );
    } elsif ($is eq 'lazy') {
      $spec->{reader} = $name unless exists $spec->{reader};
      $spec->{lazy} = 1;
      $spec->{builder} ||= '_build_'.$name unless exists $spec->{default};
    } elsif ($is eq 'rwp') {
      $spec->{reader} = $name unless exists $spec->{reader};
      $spec->{writer} = "_set_${name}" unless exists $spec->{writer};
    } elsif ($is ne 'bare') {
      die "Unknown is ${is}";
    }
    if (exists $spec->{builder}) {
      if(ref $spec->{builder}) {
        $self->_validate_codulatable('builder', $spec->{builder},
          "$into->$name", 'or a method name');
        $spec->{builder_sub} = $spec->{builder};
        $spec->{builder} = 1;
      }
      $spec->{builder} = '_build_'.$name if ($spec->{builder}||0) eq 1;
      die "Invalid builder for $into->$name - not a valid method name"
        if $spec->{builder} !~ $module_name_only;
    }
    if (($spec->{predicate}||0) eq 1) {
      $spec->{predicate} = $name =~ /^_/ ? "_has${name}" : "has_${name}";
    }
    if (($spec->{clearer}||0) eq 1) {
      $spec->{clearer} = $name =~ /^_/ ? "_clear${name}" : "clear_${name}";
    }
    if (($spec->{trigger}||0) eq 1) {
      $spec->{trigger} = quote_sub('shift->_trigger_'.$name.'(@_)');
    }
    if (($spec->{coerce}||0) eq 1) {
      my $isa = $spec->{isa};
      if (blessed $isa and $isa->can('coercion')) {
        $spec->{coerce} = $isa->coercion;
      } elsif (blessed $isa and $isa->can('coerce')) {
        $spec->{coerce} = sub { $isa->coerce(@_) };
      } else {
        die "Invalid coercion for $into->$name - no appropriate type constraint";
      }
    }
  
    for my $setting (qw( isa coerce )) {
      next if !exists $spec->{$setting};
      $self->_validate_codulatable($setting, $spec->{$setting}, "$into->$name");
    }
  
    if (exists $spec->{default}) {
      if (ref $spec->{default}) {
        $self->_validate_codulatable('default', $spec->{default}, "$into->$name",
          'or a non-ref');
      }
    }
  
    if (exists $spec->{moosify}) {
      if (ref $spec->{moosify} ne 'ARRAY') {
        $spec->{moosify} = [$spec->{moosify}];
      }
  
      for my $spec (@{$spec->{moosify}}) {
        $self->_validate_codulatable('moosify', $spec, "$into->$name");
      }
    }
  
    my %methods;
    if (my $reader = $spec->{reader}) {
      _die_overwrite($into, $reader, 'a reader')
        if !$spec->{allow_overwrite} && *{_getglob("${into}::${reader}")}{CODE};
      if (our $CAN_HAZ_XS && $self->is_simple_get($name, $spec)) {
        $methods{$reader} = $self->_generate_xs(
          getters => $into, $reader, $name, $spec
        );
      } else {
        $self->{captures} = {};
        $methods{$reader} =
          quote_sub "${into}::${reader}"
            => '    die "'.$reader.' is a read-only accessor" if @_ > 1;'."\n"
               .$self->_generate_get($name, $spec)
            => delete $self->{captures}
          ;
      }
    }
    if (my $accessor = $spec->{accessor}) {
      _die_overwrite($into, $accessor, 'an accessor')
        if !$spec->{allow_overwrite} && *{_getglob("${into}::${accessor}")}{CODE};
      if (
        our $CAN_HAZ_XS
        && $self->is_simple_get($name, $spec)
        && $self->is_simple_set($name, $spec)
      ) {
        $methods{$accessor} = $self->_generate_xs(
          accessors => $into, $accessor, $name, $spec
        );
      } else {
        $self->{captures} = {};
        $methods{$accessor} =
          quote_sub "${into}::${accessor}"
            => $self->_generate_getset($name, $spec)
            => delete $self->{captures}
          ;
      }
    }
    if (my $writer = $spec->{writer}) {
      _die_overwrite($into, $writer, 'a writer')
        if !$spec->{allow_overwrite} && *{_getglob("${into}::${writer}")}{CODE};
      if (
        our $CAN_HAZ_XS
        && $self->is_simple_set($name, $spec)
      ) {
        $methods{$writer} = $self->_generate_xs(
          setters => $into, $writer, $name, $spec
        );
      } else {
        $self->{captures} = {};
        $methods{$writer} =
          quote_sub "${into}::${writer}"
            => $self->_generate_set($name, $spec)
            => delete $self->{captures}
          ;
      }
    }
    if (my $pred = $spec->{predicate}) {
      _die_overwrite($into, $pred, 'a predicate')
        if !$spec->{allow_overwrite} && *{_getglob("${into}::${pred}")}{CODE};
      if (our $CAN_HAZ_XS && our $CAN_HAZ_XS_PRED) {
        $methods{$pred} = $self->_generate_xs(
          exists_predicates => $into, $pred, $name, $spec
        );
      } else {
        $methods{$pred} =
          quote_sub "${into}::${pred}" =>
            '    '.$self->_generate_simple_has('$_[0]', $name, $spec)."\n"
          ;
      }
    }
    if (my $pred = $spec->{builder_sub}) {
      _install_coderef( "${into}::$spec->{builder}" => $spec->{builder_sub} );
    }
    if (my $cl = $spec->{clearer}) {
      _die_overwrite($into, $cl, 'a clearer')
        if !$spec->{allow_overwrite} && *{_getglob("${into}::${cl}")}{CODE};
      $methods{$cl} =
        quote_sub "${into}::${cl}" =>
          $self->_generate_simple_clear('$_[0]', $name, $spec)."\n"
        ;
    }
    if (my $hspec = $spec->{handles}) {
      my $asserter = $spec->{asserter} ||= '_assert_'.$name;
      my @specs = do {
        if (ref($hspec) eq 'ARRAY') {
          map [ $_ => $_ ], @$hspec;
        } elsif (ref($hspec) eq 'HASH') {
          map [ $_ => ref($hspec->{$_}) ? @{$hspec->{$_}} : $hspec->{$_} ],
            keys %$hspec;
        } elsif (!ref($hspec)) {
          map [ $_ => $_ ], use_module('Moo::Role')->methods_provided_by(use_module($hspec))
        } else {
          die "You gave me a handles of ${hspec} and I have no idea why";
        }
      };
      foreach my $delegation_spec (@specs) {
        my ($proxy, $target, @args) = @$delegation_spec;
        _die_overwrite($into, $proxy, 'a delegation')
          if !$spec->{allow_overwrite} && *{_getglob("${into}::${proxy}")}{CODE};
        $self->{captures} = {};
        $methods{$proxy} =
          quote_sub "${into}::${proxy}" =>
            $self->_generate_delegation($asserter, $target, \@args),
            delete $self->{captures}
          ;
      }
    }
    if (my $asserter = $spec->{asserter}) {
      $self->{captures} = {};
  
  
      $methods{$asserter} =
        quote_sub "${into}::${asserter}" =>
          $self->_generate_asserter($name, $spec),
          delete $self->{captures};
    }
    \%methods;
  }
  
  sub is_simple_attribute {
    my ($self, $name, $spec) = @_;
    # clearer doesn't have to be listed because it doesn't
    # affect whether defined/exists makes a difference
    !grep $spec->{$_},
      qw(lazy default builder coerce isa trigger predicate weak_ref);
  }
  
  sub is_simple_get {
    my ($self, $name, $spec) = @_;
    !($spec->{lazy} and (exists $spec->{default} or $spec->{builder}));
  }
  
  sub is_simple_set {
    my ($self, $name, $spec) = @_;
    !grep $spec->{$_}, qw(coerce isa trigger weak_ref);
  }
  
  sub has_eager_default {
    my ($self, $name, $spec) = @_;
    (!$spec->{lazy} and (exists $spec->{default} or $spec->{builder}));
  }
  
  sub _generate_get {
    my ($self, $name, $spec) = @_;
    my $simple = $self->_generate_simple_get('$_[0]', $name, $spec);
    if ($self->is_simple_get($name, $spec)) {
      $simple;
    } else {
      $self->_generate_use_default(
        '$_[0]', $name, $spec,
        $self->_generate_simple_has('$_[0]', $name, $spec),
      );
    }
  }
  
  sub generate_simple_has {
    my $self = shift;
    $self->{captures} = {};
    my $code = $self->_generate_simple_has(@_);
    ($code, delete $self->{captures});
  }
  
  sub _generate_simple_has {
    my ($self, $me, $name) = @_;
    "exists ${me}->{${\quotify $name}}";
  }
  
  sub _generate_simple_clear {
    my ($self, $me, $name) = @_;
    "    delete ${me}->{${\quotify $name}}\n"
  }
  
  sub generate_get_default {
    my $self = shift;
    $self->{captures} = {};
    my $code = $self->_generate_get_default(@_);
    ($code, delete $self->{captures});
  }
  
  sub generate_use_default {
    my $self = shift;
    $self->{captures} = {};
    my $code = $self->_generate_use_default(@_);
    ($code, delete $self->{captures});
  }
  
  sub _generate_use_default {
    my ($self, $me, $name, $spec, $test) = @_;
    my $get_value = $self->_generate_get_default($me, $name, $spec);
    if ($spec->{coerce}) {
      $get_value = $self->_generate_coerce(
        $name, $get_value,
        $spec->{coerce}
      )
    }
    $test." ? \n"
    .$self->_generate_simple_get($me, $name, $spec)."\n:"
    .($spec->{isa} ?
         "    do {\n      my \$value = ".$get_value.";\n"
        ."      ".$self->_generate_isa_check($name, '$value', $spec->{isa}).";\n"
        ."      ".$self->_generate_simple_set($me, $name, $spec, '$value')."\n"
        ."    }\n"
      : '    ('.$self->_generate_simple_set($me, $name, $spec, $get_value).")\n"
    );
  }
  
  sub _generate_get_default {
    my ($self, $me, $name, $spec) = @_;
    if (exists $spec->{default}) {
      ref $spec->{default}
        ? $self->_generate_call_code($name, 'default', $me, $spec->{default})
      : quotify $spec->{default};
    }
    else {
      "${me}->${\$spec->{builder}}"
    }
  }
  
  sub generate_simple_get {
    my ($self, @args) = @_;
    $self->{captures} = {};
    my $code = $self->_generate_simple_get(@args);
    ($code, delete $self->{captures});
  }
  
  sub _generate_simple_get {
    my ($self, $me, $name) = @_;
    my $name_str = quotify $name;
    "${me}->{${name_str}}";
  }
  
  sub _generate_set {
    my ($self, $name, $spec) = @_;
    if ($self->is_simple_set($name, $spec)) {
      $self->_generate_simple_set('$_[0]', $name, $spec, '$_[1]');
    } else {
      my ($coerce, $trigger, $isa_check) = @{$spec}{qw(coerce trigger isa)};
      my $value_store = '$_[0]';
      my $code;
      if ($coerce) {
        $value_store = '$value';
        $code = "do { my (\$self, \$value) = \@_;\n"
          ."        \$value = "
          .$self->_generate_coerce($name, $value_store, $coerce).";\n";
      }
      else {
        $code = "do { my \$self = shift;\n";
      }
      if ($isa_check) {
        $code .=
          "        ".$self->_generate_isa_check($name, $value_store, $isa_check).";\n";
      }
      my $simple = $self->_generate_simple_set('$self', $name, $spec, $value_store);
      if ($trigger) {
        my $fire = $self->_generate_trigger($name, '$self', $value_store, $trigger);
        $code .=
          "        ".$simple.";\n        ".$fire.";\n"
          ."        $value_store;\n";
      } else {
        $code .= "        ".$simple.";\n";
      }
      $code .= "      }";
      $code;
    }
  }
  
  sub generate_coerce {
    my $self = shift;
    $self->{captures} = {};
    my $code = $self->_generate_coerce(@_);
    ($code, delete $self->{captures});
  }
  
  sub _attr_desc {
    my ($name, $init_arg) = @_;
    return quotify($name) if !defined($init_arg) or $init_arg eq $name;
    return quotify($name).' (constructor argument: '.quotify($init_arg).')';
  }
  
  sub _generate_coerce {
    my ($self, $name, $value, $coerce, $init_arg) = @_;
    $self->_wrap_attr_exception(
      $name,
      "coercion",
      $init_arg,
      $self->_generate_call_code($name, 'coerce', "${value}", $coerce),
      1,
    );
  }
  
  sub generate_trigger {
    my $self = shift;
    $self->{captures} = {};
    my $code = $self->_generate_trigger(@_);
    ($code, delete $self->{captures});
  }
  
  sub _generate_trigger {
    my ($self, $name, $obj, $value, $trigger) = @_;
    $self->_generate_call_code($name, 'trigger', "${obj}, ${value}", $trigger);
  }
  
  sub generate_isa_check {
    my ($self, @args) = @_;
    $self->{captures} = {};
    my $code = $self->_generate_isa_check(@args);
    ($code, delete $self->{captures});
  }
  
  sub _wrap_attr_exception {
    my ($self, $name, $step, $arg, $code, $want_return) = @_;
    my $prefix = quotify("${step} for "._attr_desc($name, $arg).' failed: ');
    "do {\n"
    .'  local $Method::Generate::Accessor::CurrentAttribute = {'."\n"
    .'    init_arg => '.quotify($arg).",\n"
    .'    name     => '.quotify($name).",\n"
    .'    step     => '.quotify($step).",\n"
    ."  };\n"
    .($want_return ? '  my $_return;'."\n" : '')
    .'  my $_error;'."\n"
    ."  {\n"
    .'    my $_old_error = $@;'."\n"
    ."    if (!eval {\n"
    .'      $@ = $_old_error;'."\n"
    .($want_return ? '      $_return ='."\n" : '')
    .'      '.$code.";\n"
    ."      1;\n"
    ."    }) {\n"
    .'      $_error = $@;'."\n"
    .'      if (!ref $_error) {'."\n"
    .'        $_error = '.$prefix.'.$_error;'."\n"
    ."      }\n"
    ."    }\n"
    .'    $@ = $_old_error;'."\n"
    ."  }\n"
    .'  die $_error if $_error;'."\n"
    .($want_return ? '  $_return;'."\n" : '')
    ."}\n"
  }
  
  sub _generate_isa_check {
    my ($self, $name, $value, $check, $init_arg) = @_;
    $self->_wrap_attr_exception(
      $name,
      "isa check",
      $init_arg,
      $self->_generate_call_code($name, 'isa_check', $value, $check)
    );
  }
  
  sub _generate_call_code {
    my ($self, $name, $type, $values, $sub) = @_;
    $sub = \&{$sub} if blessed($sub);  # coderef if blessed
    if (my $quoted = quoted_from_sub($sub)) {
      my $local = 1;
      if ($values eq '@_' || $values eq '$_[0]') {
        $local = 0;
        $values = '@_';
      }
      my $code = $quoted->[1];
      if (my $captures = $quoted->[2]) {
        my $cap_name = qq{\$${type}_captures_for_}.$self->_sanitize_name($name);
        $self->{captures}->{$cap_name} = \$captures;
        Sub::Quote::inlinify($code, $values,
          Sub::Quote::capture_unroll($cap_name, $captures, 6), $local);
      } else {
        Sub::Quote::inlinify($code, $values, undef, $local);
      }
    } else {
      my $cap_name = qq{\$${type}_for_}.$self->_sanitize_name($name);
      $self->{captures}->{$cap_name} = \$sub;
      "${cap_name}->(${values})";
    }
  }
  
  sub _sanitize_name {
    my ($self, $name) = @_;
    $name =~ s/([_\W])/sprintf('_%x', ord($1))/ge;
    $name;
  }
  
  sub generate_populate_set {
    my $self = shift;
    $self->{captures} = {};
    my $code = $self->_generate_populate_set(@_);
    ($code, delete $self->{captures});
  }
  
  sub _generate_populate_set {
    my ($self, $me, $name, $spec, $source, $test, $init_arg) = @_;
    if ($self->has_eager_default($name, $spec)) {
      my $get_indent = ' ' x ($spec->{isa} ? 6 : 4);
      my $get_default = $self->_generate_get_default(
                          '$new', $name, $spec
                        );
      my $get_value =
        defined($spec->{init_arg})
          ? "(\n${get_indent}  ${test}\n"
              ."${get_indent}   ? ${source}\n${get_indent}   : "
              .$get_default
              ."\n${get_indent})"
          : $get_default;
      if ($spec->{coerce}) {
        $get_value = $self->_generate_coerce(
          $name, $get_value,
          $spec->{coerce}, $init_arg
        )
      }
      ($spec->{isa}
        ? "    {\n      my \$value = ".$get_value.";\n      "
          .$self->_generate_isa_check(
            $name, '$value', $spec->{isa}, $init_arg
          ).";\n"
          .'      '.$self->_generate_simple_set($me, $name, $spec, '$value').";\n"
          ."    }\n"
        : '    '.$self->_generate_simple_set($me, $name, $spec, $get_value).";\n"
      )
      .($spec->{trigger}
        ? '    '
          .$self->_generate_trigger(
            $name, $me, $self->_generate_simple_get($me, $name, $spec),
            $spec->{trigger}
          )." if ${test};\n"
        : ''
      );
    } else {
      "    if (${test}) {\n"
        .($spec->{coerce}
          ? "      $source = "
            .$self->_generate_coerce(
              $name, $source,
              $spec->{coerce}, $init_arg
            ).";\n"
          : ""
        )
        .($spec->{isa}
          ? "      "
            .$self->_generate_isa_check(
              $name, $source, $spec->{isa}, $init_arg
            ).";\n"
          : ""
        )
        ."      ".$self->_generate_simple_set($me, $name, $spec, $source).";\n"
        .($spec->{trigger}
          ? "      "
            .$self->_generate_trigger(
              $name, $me, $self->_generate_simple_get($me, $name, $spec),
              $spec->{trigger}
            ).";\n"
          : ""
        )
        ."    }\n";
    }
  }
  
  sub _generate_core_set {
    my ($self, $me, $name, $spec, $value) = @_;
    my $name_str = quotify $name;
    "${me}->{${name_str}} = ${value}";
  }
  
  sub _generate_simple_set {
    my ($self, $me, $name, $spec, $value) = @_;
    my $name_str = quotify $name;
    my $simple = $self->_generate_core_set($me, $name, $spec, $value);
  
    if ($spec->{weak_ref}) {
      require Scalar::Util;
      my $get = $self->_generate_simple_get($me, $name, $spec);
  
      # Perl < 5.8.3 can't weaken refs to readonly vars
      # (e.g. string constants). This *can* be solved by:
      #
      # &Internals::SvREADONLY($foo, 0);
      # Scalar::Util::weaken($foo);
      # &Internals::SvREADONLY($foo, 1);
      #
      # but requires Internal functions and is just too damn crazy
      # so simply throw a better exception
      my $weak_simple = "do { Scalar::Util::weaken(${simple}); no warnings 'void'; $get }";
      Moo::_Utils::lt_5_8_3() ? <<"EOC" : $weak_simple;
        eval { Scalar::Util::weaken($simple); 1 }
          ? do { no warnings 'void'; $get }
          : do {
            if( \$@ =~ /Modification of a read-only value attempted/) {
              require Carp;
              Carp::croak( sprintf (
                'Reference to readonly value in "%s" can not be weakened on Perl < 5.8.3',
                $name_str,
              ) );
            } else {
              die \$@;
            }
          }
  EOC
    } else {
      $simple;
    }
  }
  
  sub _generate_getset {
    my ($self, $name, $spec) = @_;
    q{(@_ > 1}."\n      ? ".$self->_generate_set($name, $spec)
      ."\n      : ".$self->_generate_get($name, $spec)."\n    )";
  }
  
  sub _generate_asserter {
    my ($self, $name, $spec) = @_;
  
    "do {\n"
     ."  my \$val = ".$self->_generate_get($name, $spec).";\n"
     ."  unless (".$self->_generate_simple_has('$_[0]', $name, $spec).") {\n"
     .qq!    die "Attempted to access '${name}' but it is not set";\n!
     ."  }\n"
     ."  \$val;\n"
     ."}\n";
  }
  sub _generate_delegation {
    my ($self, $asserter, $target, $args) = @_;
    my $arg_string = do {
      if (@$args) {
        # I could, I reckon, linearise out non-refs here using quotify
        # plus something to check for numbers but I'm unsure if it's worth it
        $self->{captures}{'@curries'} = $args;
        '@curries, @_';
      } else {
        '@_';
      }
    };
    "shift->${asserter}->${target}(${arg_string});";
  }
  
  sub _generate_xs {
    my ($self, $type, $into, $name, $slot) = @_;
    Class::XSAccessor->import(
      class => $into,
      $type => { $name => $slot },
      replace => 1,
    );
    $into->can($name);
  }
  
  sub default_construction_string { '{}' }
  
  sub _validate_codulatable {
    my ($self, $setting, $value, $into, $appended) = @_;
    my $invalid = "Invalid $setting '" . overload::StrVal($value)
      . "' for $into not a coderef";
    $invalid .= " $appended" if $appended;
  
    unless (ref $value and (ref $value eq 'CODE' or blessed($value))) {
      die "$invalid or code-convertible object";
    }
  
    unless (eval { \&$value }) {
      die "$invalid and could not be converted to a coderef: $@";
    }
  
    1;
  }
  
  1;
METHOD_GENERATE_ACCESSOR

$fatpacked{"Method/Generate/BuildAll.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'METHOD_GENERATE_BUILDALL';
  package Method::Generate::BuildAll;
  
  use strictures 1;
  use base qw(Moo::Object);
  use Sub::Quote qw(quote_sub quotify);
  use Moo::_Utils;
  
  sub generate_method {
    my ($self, $into) = @_;
    quote_sub "${into}::BUILDALL", join '',
      $self->_handle_subbuild($into),
      qq{    my \$self = shift;\n},
      $self->buildall_body_for($into, '$self', '@_'),
      qq{    return \$self\n};
  }
  
  sub _handle_subbuild {
    my ($self, $into) = @_;
    '    if (ref($_[0]) ne '.quotify($into).') {'."\n".
    '      return shift->Moo::Object::BUILDALL(@_)'.";\n".
    '    }'."\n";
  }
  
  sub buildall_body_for {
    my ($self, $into, $me, $args) = @_;
    my @builds =
      grep *{_getglob($_)}{CODE},
      map "${_}::BUILD",
      reverse @{Moo::_Utils::_get_linear_isa($into)};
    join '', map qq{    ${me}->${_}(${args});\n}, @builds;
  }
  
  1;
METHOD_GENERATE_BUILDALL

$fatpacked{"Method/Generate/Constructor.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'METHOD_GENERATE_CONSTRUCTOR';
  package Method::Generate::Constructor;
  
  use strictures 1;
  use Sub::Quote qw(quote_sub unquote_sub quotify);
  use Sub::Defer;
  use Moo::_Utils qw(_getstash);
  
  sub register_attribute_specs {
    my ($self, @new_specs) = @_;
    my $specs = $self->{attribute_specs}||={};
    while (my ($name, $new_spec) = splice @new_specs, 0, 2) {
      if ($name =~ s/^\+//) {
        die "has '+${name}' given but no ${name} attribute already exists"
          unless my $old_spec = $specs->{$name};
        foreach my $key (keys %$old_spec) {
          if (!exists $new_spec->{$key}) {
            $new_spec->{$key} = $old_spec->{$key}
              unless $key eq 'handles';
          }
          elsif ($key eq 'moosify') {
            $new_spec->{$key} = [
              map { ref $_ eq 'ARRAY' ? @$_ : $_ }
                ($old_spec->{$key}, $new_spec->{$key})
            ];
          }
        }
      }
      if ($new_spec->{required}
        && !(
          exists $new_spec->{default}
          || $new_spec->{builder}
          || !exists $new_spec->{init_arg}
          || defined $new_spec->{init_arg}
        )
      ) {
        die "You cannot have a required attribute (${name})"
          . " without a default, builder, or an init_arg";
      }
      $new_spec->{index} = scalar keys %$specs
        unless defined $new_spec->{index};
      $specs->{$name} = $new_spec;
    }
    $self;
  }
  
  sub all_attribute_specs {
    $_[0]->{attribute_specs}
  }
  
  sub accessor_generator {
    $_[0]->{accessor_generator}
  }
  
  sub construction_string {
    my ($self) = @_;
    $self->{construction_string}
      ||= $self->_build_construction_string;
  }
  
  sub buildall_generator {
    require Method::Generate::BuildAll;
    Method::Generate::BuildAll->new;
  }
  
  sub _build_construction_string {
    my ($self) = @_;
    my $builder = $self->{construction_builder};
    $builder ? $self->$builder
      : 'bless('
      .$self->accessor_generator->default_construction_string
      .', $class);'
  }
  
  sub install_delayed {
    my ($self) = @_;
    my $package = $self->{package};
    defer_sub "${package}::new" => sub {
      unquote_sub $self->generate_method(
        $package, 'new', $self->{attribute_specs}, { no_install => 1 }
      )
    };
    $self;
  }
  
  sub generate_method {
    my ($self, $into, $name, $spec, $quote_opts) = @_;
    foreach my $no_init (grep !exists($spec->{$_}{init_arg}), keys %$spec) {
      $spec->{$no_init}{init_arg} = $no_init;
    }
    local $self->{captures} = {};
    my $body = '    my $class = shift;'."\n"
              .'    $class = ref($class) if ref($class);'."\n";
    $body .= $self->_handle_subconstructor($into, $name);
    my $into_buildargs = $into->can('BUILDARGS');
    if ( $into_buildargs && $into_buildargs != \&Moo::Object::BUILDARGS ) {
        $body .= $self->_generate_args_via_buildargs;
    } else {
        $body .= $self->_generate_args;
    }
    $body .= $self->_check_required($spec);
    $body .= '    my $new = '.$self->construction_string.";\n";
    $body .= $self->_assign_new($spec);
    if ($into->can('BUILD')) {
      $body .= $self->buildall_generator->buildall_body_for(
        $into, '$new', '$args'
      );
    }
    $body .= '    return $new;'."\n";
    if ($into->can('DEMOLISH')) {
      require Method::Generate::DemolishAll;
      Method::Generate::DemolishAll->new->generate_method($into);
    }
    quote_sub
      "${into}::${name}" => $body,
      $self->{captures}, $quote_opts||{}
    ;
  }
  
  sub _handle_subconstructor {
    my ($self, $into, $name) = @_;
    if (my $gen = $self->{subconstructor_handler}) {
      '    if ($class ne '.quotify($into).') {'."\n".
      $gen.
      '    }'."\n";
    } else {
      ''
    }
  }
  
  sub _cap_call {
    my ($self, $code, $captures) = @_;
    @{$self->{captures}}{keys %$captures} = values %$captures if $captures;
    $code;
  }
  
  sub _generate_args_via_buildargs {
    my ($self) = @_;
    q{    my $args = $class->BUILDARGS(@_);}."\n"
    .q{    die "BUILDARGS did not return a hashref" unless ref($args) eq 'HASH';}
    ."\n";
  }
  
  # inlined from Moo::Object - update that first.
  sub _generate_args {
    my ($self) = @_;
    return <<'_EOA';
      my $args;
      if ( scalar @_ == 1 ) {
          unless ( defined $_[0] && ref $_[0] eq 'HASH' ) {
              die "Single parameters to new() must be a HASH ref"
                  ." data => ". $_[0] ."\n";
          }
          $args = { %{ $_[0] } };
      }
      elsif ( @_ % 2 ) {
          die "The new() method for $class expects a hash reference or a"
            . " key/value list. You passed an odd number of arguments\n";
      }
      else {
          $args = {@_};
      }
  _EOA
  
  }
  
  sub _assign_new {
    my ($self, $spec) = @_;
    my $ag = $self->accessor_generator;
    my %test;
    NAME: foreach my $name (sort keys %$spec) {
      my $attr_spec = $spec->{$name};
      next NAME unless defined($attr_spec->{init_arg})
                         or $ag->has_eager_default($name, $attr_spec);
      $test{$name} = $attr_spec->{init_arg};
    }
    join '', map {
      my $arg_key = quotify($test{$_});
      my $test = "exists \$args->{$arg_key}";
      my $source = "\$args->{$arg_key}";
      my $attr_spec = $spec->{$_};
      $self->_cap_call($ag->generate_populate_set(
        '$new', $_, $attr_spec, $source, $test, $test{$_},
      ));
    } sort keys %test;
  }
  
  sub _check_required {
    my ($self, $spec) = @_;
    my @required_init =
      map $spec->{$_}{init_arg},
        grep {
          my %s = %{$spec->{$_}}; # ignore required if default or builder set
          $s{required} and not($s{builder} or $s{default})
        } sort keys %$spec;
    return '' unless @required_init;
    '    if (my @missing = grep !exists $args->{$_}, qw('
      .join(' ',@required_init).')) {'."\n"
      .q{      die "Missing required arguments: ".join(', ', sort @missing);}."\n"
      ."    }\n";
  }
  
  use Moo;
  # bootstrap our own constructor
  sub new {
    my $class = shift;
    bless $class->BUILDARGS(@_), $class;
  }
  Moo->_constructor_maker_for(__PACKAGE__)
  ->register_attribute_specs(
    attribute_specs => {
      is => 'ro',
      reader => 'all_attribute_specs',
    },
    accessor_generator => { is => 'ro' },
    construction_string => { is => 'lazy' },
    construction_builder => { is => 'bare' },
    subconstructor_handler => { is => 'ro' },
    package => { is => 'bare' },
  );
  
  1;
METHOD_GENERATE_CONSTRUCTOR

$fatpacked{"Method/Generate/DemolishAll.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'METHOD_GENERATE_DEMOLISHALL';
  package Method::Generate::DemolishAll;
  
  use strictures 1;
  use base qw(Moo::Object);
  use Sub::Quote qw(quote_sub quotify);
  use Moo::_Utils;
  
  sub generate_method {
    my ($self, $into) = @_;
    quote_sub "${into}::DEMOLISHALL", join '',
      $self->_handle_subdemolish($into),
      qq{    my \$self = shift;\n},
      $self->demolishall_body_for($into, '$self', '@_'),
      qq{    return \$self\n};
    quote_sub "${into}::DESTROY", join '',
      q!    my $self = shift;
      my $e = do {
        local $?;
        local $@;
        require Moo::_Utils;
        eval {
          $self->DEMOLISHALL(Moo::_Utils::_in_global_destruction);
        };
        $@;
      };
  
      no warnings 'misc';
      die $e if $e; # rethrow
    !;
  }
  
  sub demolishall_body_for {
    my ($self, $into, $me, $args) = @_;
    my @demolishers =
      grep *{_getglob($_)}{CODE},
      map "${_}::DEMOLISH",
      @{Moo::_Utils::_get_linear_isa($into)};
    join '', map qq{    ${me}->${_}(${args});\n}, @demolishers;
  }
  
  sub _handle_subdemolish {
    my ($self, $into) = @_;
    '    if (ref($_[0]) ne '.quotify($into).') {'."\n".
    '      return shift->Moo::Object::DEMOLISHALL(@_)'.";\n".
    '    }'."\n";
  }
  
  1;
METHOD_GENERATE_DEMOLISHALL

$fatpacked{"Method/Inliner.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'METHOD_INLINER';
  package Method::Inliner;
  
  use strictures 1;
  use Text::Balanced qw(extract_bracketed);
  use Sub::Quote ();
  
  sub slurp { do { local (@ARGV, $/) = $_[0]; <> } }
  sub splat {
    open my $out, '>', $_[1] or die "can't open $_[1]: $!";
    print $out $_[0] or die "couldn't write to $_[1]: $!";
  }
  
  sub inlinify {
    my $file = $_[0];
    my @chunks = split /(^sub.*?^}$)/sm, slurp $file;
    warn join "\n--\n", @chunks;
    my %code;
    foreach my $chunk (@chunks) {
      if (my ($name, $body) =
        $chunk =~ /^sub (\S+) {\n(.*)\n}$/s
      ) {
        $code{$name} = $body;
      }
    }
    foreach my $chunk (@chunks) {
      my ($me) = $chunk =~ /^sub.*{\n  my \((\$\w+).*\) = \@_;\n/ or next;
      my $meq = quotemeta $me;
      #warn $meq, $chunk;
      my $copy = $chunk;
      my ($fixed, $rest);
      while ($copy =~ s/^(.*?)${meq}->(\S+)(?=\()//s) {
        my ($front, $name) = ($1, $2);
        ((my $body), $rest) = extract_bracketed($copy, '()');
        warn "spotted ${name} - ${body}";
        if ($code{$name}) {
        warn "replacing";
          s/^\(//, s/\)$// for $body;
          $body = "${me}, ".$body;
          $fixed .= $front.Sub::Quote::inlinify($code{$name}, $body);
        } else {
  	$fixed .= $front.$me.'->'.$name.$body;
        }
        #warn $fixed; warn $rest;
        $copy = $rest;
      }
      $fixed .= $rest if $fixed;
      warn $fixed if $fixed;
      $chunk = $fixed if $fixed;
    }
    print join '', @chunks;
  }
  
  1;
METHOD_INLINER

$fatpacked{"Module/CPANfile.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MODULE_CPANFILE';
  package Module::CPANfile;
  use strict;
  use warnings;
  use Cwd;
  use Carp ();
  use Module::CPANfile::Environment;
  use Module::CPANfile::Requirement;
  
  our $VERSION = '1.1000';
  
  sub new {
      my($class, $file) = @_;
      bless {}, $class;
  }
  
  sub load {
      my($proto, $file) = @_;
  
      my $self = ref $proto ? $proto : $proto->new;
      $self->parse($file || Cwd::abs_path('cpanfile'));
      $self;
  }
  
  sub save {
      my($self, $path) = @_;
  
      open my $out, ">", $path or die "$path: $!";
      print {$out} $self->to_string;
  }
  
  sub parse {
      my($self, $file) = @_;
  
      my $code = do {
          open my $fh, "<", $file or die "$file: $!";
          join '', <$fh>;
      };
  
      my $env = Module::CPANfile::Environment->new($file);
      $env->parse($code) or die $@;
  
      $self->{_mirrors} = $env->mirrors;
      $self->{_prereqs} = $env->prereqs;
  }
  
  sub from_prereqs {
      my($proto, $prereqs) = @_;
  
      my $self = $proto->new;
      $self->{_prereqs} = Module::CPANfile::Prereqs->from_cpan_meta($prereqs);
  
      $self;
  }
  
  sub mirrors {
      my $self = shift;
      $self->{_mirrors} || [];
  }
  
  sub features {
      my $self = shift;
      map $self->feature($_), $self->{_prereqs}->identifiers;
  }
  
  sub feature {
      my($self, $identifier) = @_;
      $self->{_prereqs}->feature($identifier);
  }
  
  sub prereq { shift->prereqs }
  
  sub prereqs {
      my $self = shift;
      $self->{_prereqs}->as_cpan_meta;
  }
  
  sub merged_requirements {
      my $self = shift;
      $self->{_prereqs}->merged_requirements;
  }
  
  sub effective_prereqs {
      my($self, $features) = @_;
      $self->prereqs_with(@{$features || []});
  }
  
  sub prereqs_with {
      my($self, @feature_identifiers) = @_;
  
      my $prereqs = $self->prereqs;
      my @others = map { $self->feature($_)->prereqs } @feature_identifiers;
  
      $prereqs->with_merged_prereqs(\@others);
  }
  
  sub prereq_specs {
      my $self = shift;
      $self->prereqs->as_string_hash;
  }
  
  sub prereq_for_module {
      my($self, $module) = @_;
      $self->{_prereqs}->find($module);
  }
  
  sub options_for_module {
      my($self, $module) = @_;
      my $prereq = $self->prereq_for_module($module) or return;
      $prereq->requirement->options;
  }
  
  sub merge_meta {
      my($self, $file, $version) = @_;
  
      require CPAN::Meta;
  
      $version ||= $file =~ /\.yml$/ ? '1.4' : '2';
  
      my $prereq = $self->prereqs;
  
      my $meta = CPAN::Meta->load_file($file);
      my $prereqs_hash = $prereq->with_merged_prereqs($meta->effective_prereqs)->as_string_hash;
      my $struct = { %{$meta->as_struct}, prereqs => $prereqs_hash };
  
      CPAN::Meta->new($struct)->save($file, { version => $version });
  }
  
  sub _dump {
      my $str = shift;
      require Data::Dumper;
      chomp(my $value = Data::Dumper->new([$str])->Terse(1)->Dump);
      $value;
  }
  
  sub to_string {
      my($self, $include_empty) = @_;
  
      my $mirrors = $self->mirrors;
      my $prereqs = $self->prereq_specs;
  
      my $code = '';
      $code .= $self->_dump_mirrors($mirrors);
      $code .= $self->_dump_prereqs($prereqs, $include_empty);
  
      for my $feature ($self->features) {
          $code .= sprintf "feature %s, %s => sub {\n", _dump($feature->{identifier}), _dump($feature->{description});
          $code .= $self->_dump_prereqs($feature->{spec}, $include_empty, 4);
          $code .= "}\n\n";
      }
  
      $code =~ s/\n+$/\n/s;
      $code;
  }
  
  sub _dump_mirrors {
      my($self, $mirrors) = @_;
  
      my $code = "";
  
      for my $url (@$mirrors) {
          $code .= "mirror '$url';\n";
      }
  
      $code =~ s/\n+$/\n/s;
      $code;
  }
  
  sub _dump_prereqs {
      my($self, $prereqs, $include_empty, $base_indent) = @_;
  
      my $code = '';
      for my $phase (qw(runtime configure build test develop)) {
          my $indent = $phase eq 'runtime' ? '' : '    ';
          $indent = (' ' x ($base_indent || 0)) . $indent;
  
          my($phase_code, $requirements);
          $phase_code .= "on $phase => sub {\n" unless $phase eq 'runtime';
  
          for my $type (qw(requires recommends suggests conflicts)) {
              for my $mod (sort keys %{$prereqs->{$phase}{$type}}) {
                  my $ver = $prereqs->{$phase}{$type}{$mod};
                  $phase_code .= $ver eq '0'
                               ? "${indent}$type '$mod';\n"
                               : "${indent}$type '$mod', '$ver';\n";
                  $requirements++;
              }
          }
  
          $phase_code .= "\n" unless $requirements;
          $phase_code .= "};\n" unless $phase eq 'runtime';
  
          $code .= $phase_code . "\n" if $requirements or $include_empty;
      }
  
      $code =~ s/\n+$/\n/s;
      $code;
  }
  
  1;
  
  __END__
  
  =head1 NAME
  
  Module::CPANfile - Parse cpanfile
  
  =head1 SYNOPSIS
  
    use Module::CPANfile;
  
    my $file = Module::CPANfile->load("cpanfile");
    my $prereqs = $file->prereqs; # CPAN::Meta::Prereqs object
  
    my @features = $file->features; # CPAN::Meta::Feature objects
    my $merged_prereqs = $file->prereqs_with(@identifiers); # CPAN::Meta::Prereqs
  
    $file->merge_meta('MYMETA.json');
  
  =head1 DESCRIPTION
  
  Module::CPANfile is a tool to handle L<cpanfile> format to load application
  specific dependencies, not just for CPAN distributions.
  
  =head1 METHODS
  
  =over 4
  
  =item load
  
    $file = Module::CPANfile->load;
    $file = Module::CPANfile->load('cpanfile');
  
  Load and parse a cpanfile. By default it tries to load C<cpanfile> in
  the current directory, unless you pass the path to its argument.
  
  =item from_prereqs
  
    $file = Module::CPANfile->from_prereqs({
      runtime => { requires => { DBI => '1.000' } },
    });
  
  Creates a new Module::CPANfile object from prereqs hash you can get
  via L<CPAN::Meta>'s C<prereqs>, or L<CPAN::Meta::Prereqs>'
  C<as_string_hash>.
  
    # read MYMETA, then feed the prereqs to create Module::CPANfile
    my $meta = CPAN::Meta->load_file('MYMETA.json');
    my $file = Module::CPANfile->from_prereqs($meta->prereqs);
  
    # load cpanfile, then recreate it with round-trip
    my $file = Module::CPANfile->load('cpanfile');
    $file = Module::CPANfile->from_prereqs($file->prereq_specs);
                                      # or $file->prereqs->as_string_hash
  
  =item prereqs
  
  Returns L<CPAN::Meta::Prereqs> object out of the parsed cpanfile.
  
  =item prereq_specs
  
  Returns a hash reference that should be passed to C<< CPAN::Meta::Prereqs->new >>.
  
  =item features
  
  Returns a list of features available in the cpanfile as L<CPAN::Meta::Feature>.
  
  =item prereqs_with(@identifiers), effective_prereqs(\@identifiers)
  
  Returns L<CPAN::Meta::Prereqs> object, with merged prereqs for
  features identified with the C<@identifiers>.
  
  =item to_string($include_empty)
  
    $file->to_string;
    $file->to_string(1);
  
  Returns a canonical string (code) representation for cpanfile. Useful
  if you want to convert L<CPAN::Meta::Prereqs> to a new cpanfile.
  
    # read MYMETA's prereqs and print cpanfile representation of it
    my $meta = CPAN::Meta->load_file('MYMETA.json');
    my $file = Module::CPANfile->from_prereqs($meta->prereqs);
    print $file->to_string;
  
  By default, it omits the phase where there're no modules
  registered. If you pass the argument of a true value, it will print
  them as well.
  
  =item save
  
    $file->save('cpanfile');
  
  Saves the currently loaded prereqs as a new C<cpanfile> by calling
  C<to_string>. Beware B<this method will overwrite the existing
  cpanfile without any warning or backup>. Taking a backup or giving
  warnings to users is a caller's responsibility.
  
    # Read MYMETA.json and creates a new cpanfile
    my $meta = CPAN::Meta->load_file('MYMETA.json');
    my $file = Module::CPANfile->from_prereqs($meta->prereqs);
    $file->save('cpanfile');
  
  =item merge_meta
  
    $file->merge_meta('META.yml');
    $file->merge_meta('MYMETA.json', '2.0');
  
  Merge the effective prereqs with Meta specification loaded from the
  given META file, using CPAN::Meta. You can specify the META spec
  version in the second argument, which defaults to 1.4 in case the
  given file is YAML, and 2 if it is JSON.
  
  =back
  
  =head1 AUTHOR
  
  Tatsuhiko Miyagawa
  
  =head1 SEE ALSO
  
  L<cpanfile>, L<CPAN::Meta>, L<CPAN::Meta::Spec>
  
  =cut
MODULE_CPANFILE

$fatpacked{"Module/CPANfile/Environment.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MODULE_CPANFILE_ENVIRONMENT';
  package Module::CPANfile::Environment;
  use strict;
  use warnings;
  use Module::CPANfile::Prereqs;
  use Carp ();
  
  my @bindings = qw(
      on requires recommends suggests conflicts
      feature
      osname
      mirror
      configure_requires build_requires test_requires author_requires
  );
  
  my $file_id = 1;
  
  sub new {
      my($class, $file) = @_;
      bless {
          file     => $file,
          phase    => 'runtime', # default phase
          feature  => undef,
          features => {},
          prereqs  => Module::CPANfile::Prereqs->new,
          mirrors  => [],
      }, $class;
  }
  
  sub bind {
      my $self = shift;
      my $pkg = caller;
  
      for my $binding (@bindings) {
          no strict 'refs';
          *{"$pkg\::$binding"} = sub { $self->$binding(@_) };
      }
  }
  
  sub parse {
      my($self, $code) = @_;
  
      my $err;
      {
          local $@;
          $file_id++;
          $self->_evaluate(<<EVAL);
  package Module::CPANfile::Sandbox$file_id;
  no warnings;
  BEGIN { \$_environment->bind }
  
  # line 1 "$self->{file}"
  $code;
  EVAL
          $err = $@;
      }
  
      if ($err) { die "Parsing $self->{file} failed: $err" };
  
      return 1;
  }
  
  sub _evaluate {
      my $_environment = $_[0];
      eval $_[1];
  }
  
  sub prereqs { $_[0]->{prereqs} }
  
  sub mirrors { $_[0]->{mirrors} }
  
  # DSL goes from here
  
  sub on {
      my($self, $phase, $code) = @_;
      local $self->{phase} = $phase;
      $code->();
  }
  
  sub feature {
      my($self, $identifier, $description, $code) = @_;
  
      # shortcut: feature identifier => sub { ... }
      if (@_ == 3 && ref($description) eq 'CODE') {
          $code = $description;
          $description = $identifier;
      }
  
      unless (ref $description eq '' && ref $code eq 'CODE') {
          Carp::croak("Usage: feature 'identifier', 'Description' => sub { ... }");
      }
  
      local $self->{feature} = $identifier;
      $self->prereqs->add_feature($identifier, $description);
  
      $code->();
  }
  
  sub osname { die "TODO" }
  
  sub mirror {
      my($self, $url) = @_;
      push @{$self->{mirrors}}, $url;
  }
  
  sub requirement_for {
      my($self, $module, @args) = @_;
  
      my $requirement = 0;
      $requirement = shift @args if @args % 2;
  
      return Module::CPANfile::Requirement->new(
          name    => $module,
          version => $requirement,
          @args,
      );
  }
  
  sub requires {
      my $self = shift;
      $self->add_prereq(requires => @_);
  }
  
  sub recommends {
      my $self = shift;
      $self->add_prereq(recommends => @_);
  }
  
  sub suggests {
      my $self = shift;
      $self->add_prereq(suggests => @_);
  }
  
  sub conflicts {
      my $self = shift;
      $self->add_prereq(conflicts => @_);
  }
  
  sub add_prereq {
      my($self, $type, $module, @args) = @_;
  
      $self->prereqs->add_prereq(
          feature => $self->{feature},
          phase   => $self->{phase},
          type    => $type,
          module  => $module,
          requirement => $self->requirement_for($module, @args),
      );
  }
  
  # Module::Install compatible shortcuts
  
  sub configure_requires {
      my($self, @args) = @_;
      $self->on(configure => sub { $self->requires(@args) });
  }
  
  sub build_requires {
      my($self, @args) = @_;
      $self->on(build => sub { $self->requires(@args) });
  }
  
  sub test_requires {
      my($self, @args) = @_;
      $self->on(test => sub { $self->requires(@args) });
  }
  
  sub author_requires {
      my($self, @args) = @_;
      $self->on(develop => sub { $self->requires(@args) });
  }
  
  1;
  
MODULE_CPANFILE_ENVIRONMENT

$fatpacked{"Module/CPANfile/Prereq.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MODULE_CPANFILE_PREREQ';
  package Module::CPANfile::Prereq;
  use strict;
  
  sub new {
      my($class, %options) = @_;
      bless \%options, $class;
  }
  
  sub feature { $_[0]->{feature} }
  sub phase   { $_[0]->{phase} }
  sub type    { $_[0]->{type} }
  sub module  { $_[0]->{module} }
  sub requirement { $_[0]->{requirement} }
  
  sub match_feature {
      my($self, $identifier) = @_;
      no warnings 'uninitialized';
      $self->feature eq $identifier;
  }
  
  1;
MODULE_CPANFILE_PREREQ

$fatpacked{"Module/CPANfile/Prereqs.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MODULE_CPANFILE_PREREQS';
  package Module::CPANfile::Prereqs;
  use strict;
  use Carp ();
  use CPAN::Meta::Feature;
  use Module::CPANfile::Prereq;
  
  sub from_cpan_meta {
      my($class, $prereqs) = @_;
  
      my $self = $class->new;
  
      for my $phase (keys %$prereqs) {
          for my $type (keys %{ $prereqs->{$phase} }) {
              while (my($module, $requirement) = each %{ $prereqs->{$phase}{$type} }) {
                  $self->add_prereq(
                      phase => $phase,
                      type  => $type,
                      module => $module,
                      requirement => Module::CPANfile::Requirement->new(name => $module, version => $requirement),
                  );
              }
          }
      }
  
      $self;
  }
  
  sub new {
      my $class = shift;
      bless {
          prereqs => [],
          features => {},
      }, $class;
  }
  
  sub add_feature {
      my($self, $identifier, $description) = @_;
      $self->{features}{$identifier} = { description => $description };
  }
  
  sub add_prereq {
      my($self, %args) = @_;
      $self->add( Module::CPANfile::Prereq->new(%args) );
  }
  
  sub add {
      my($self, $prereq) = @_;
      push @{$self->{prereqs}}, $prereq;
  }
  
  sub as_cpan_meta {
      my $self = shift;
      $self->{cpanmeta} ||= $self->build_cpan_meta;
  }
  
  sub build_cpan_meta {
      my($self, $identifier) = @_;
  
      my $prereq_spec = {};
      $self->prereq_each($identifier, sub {
          my $prereq = shift;
          $prereq_spec->{$prereq->phase}{$prereq->type}{$prereq->module} = $prereq->requirement->version;
      });
  
      CPAN::Meta::Prereqs->new($prereq_spec);
  }
  
  sub prereq_each {
      my($self, $identifier, $code) = @_;
  
      for my $prereq (@{$self->{prereqs}}) {
          next unless $prereq->match_feature($identifier);
          $code->($prereq);
      }
  }
  
  sub merged_requirements {
      my $self = shift;
  
      my $reqs = CPAN::Meta::Requirements->new;
      for my $prereq (@{$self->{prereqs}}) {
          $reqs->add_string_requirement($prereq->module, $prereq->requirement->version);
      }
  
      $reqs;
  }
  
  sub find {
      my($self, $module) = @_;
  
      for my $prereq (@{$self->{prereqs}}) {
          return $prereq if $prereq->module eq $module;
      }
  
      return;
  }
  
  sub identifiers {
      my $self = shift;
      keys %{$self->{features}};
  }
  
  sub feature {
      my($self, $identifier) = @_;
  
      my $data = $self->{features}{$identifier}
        or Carp::croak("Unknown feature '$identifier'");
  
      my $prereqs = $self->build_cpan_meta($identifier);
  
      CPAN::Meta::Feature->new($identifier, {
          description => $data->{description},
          prereqs => $prereqs->as_string_hash,
      });
  }
  
  1;
MODULE_CPANFILE_PREREQS

$fatpacked{"Module/CPANfile/Requirement.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MODULE_CPANFILE_REQUIREMENT';
  package Module::CPANfile::Requirement;
  use strict;
  
  sub new {
      my ($class, %args) = @_;
  
      $args{version} ||= 0;
  
      bless +{
          name    => delete $args{name},
          version => delete $args{version},
          options => \%args,
      }, $class;
  }
  
  sub name    { $_[0]->{name} }
  sub version { $_[0]->{version} }
  
  sub options { $_[0]->{options} }
  
  sub has_options {
      keys %{$_[0]->{options}} > 0;
  }
  
  1;
MODULE_CPANFILE_REQUIREMENT

$fatpacked{"Module/CoreList.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MODULE_CORELIST';
  package Module::CoreList;
  use strict;
  use vars qw/$VERSION %released %version %families %upstream
  	    %bug_tracker %deprecated %delta/;
  use Module::CoreList::TieHashDelta;
  use version;
  $VERSION = '5.20150620';
  
  sub _released_order {   # Sort helper, to make '?' sort after everything else
      (substr($released{$a}, 0, 1) eq "?")
      ? ((substr($released{$b}, 0, 1) eq "?")
          ? 0
          : 1)
      : ((substr($released{$b}, 0, 1) eq "?")
          ? -1
          : $released{$a} cmp $released{$b} )
  }
  
  my $dumpinc = 0;
  sub import {
      my $self = shift;
      my $what = shift || '';
      if ($what eq 'dumpinc') {
          $dumpinc = 1;
      }
  }
  
  END {
      print "---INC---\n", join "\n" => keys %INC
        if $dumpinc;
  }
  
  
  sub first_release_raw {
      my $module = shift;
      $module = shift if eval { $module->isa(__PACKAGE__) }
        and scalar @_ and $_[0] =~ m#\A[a-zA-Z_][0-9a-zA-Z_]*(?:(::|')[0-9a-zA-Z_]+)*\z#;
      my $version = shift;
  
      my @perls = $version
          ? grep { defined $version{$_}{ $module } &&
                          $version{$_}{ $module } ge $version } keys %version
          : grep { exists $version{$_}{ $module }             } keys %version;
  
      return @perls;
  }
  
  sub first_release_by_date {
      my @perls = &first_release_raw;
      return unless @perls;
      return (sort _released_order @perls)[0];
  }
  
  sub first_release {
      my @perls = &first_release_raw;
      return unless @perls;
      return (sort { $a cmp $b } @perls)[0];
  }
  
  sub find_modules {
      my $regex = shift;
      $regex = shift if eval { $regex->isa(__PACKAGE__) };
      my @perls = @_;
      @perls = keys %version unless @perls;
  
      my %mods;
      foreach (@perls) {
          while (my ($k, $v) = each %{$version{$_}}) {
              $mods{$k}++ if $k =~ $regex;
          }
      }
      return sort keys %mods
  }
  
  sub find_version {
      my $v = shift;
      $v = shift if eval { $v->isa(__PACKAGE__) };
      return $version{$v} if defined $version{$v};
      return undef;
  }
  
  sub is_deprecated {
      my $module = shift;
      $module = shift if eval { $module->isa(__PACKAGE__) }
        and scalar @_ and $_[0] =~ m#\A[a-zA-Z_][0-9a-zA-Z_]*(?:(::|')[0-9a-zA-Z_]+)*\z#;
      my $perl_version = shift;
      $perl_version ||= $];
      return unless $module && exists $deprecated{$perl_version}{$module};
      return $deprecated{$perl_version}{$module};
  }
  
  sub deprecated_in {
      my $module = shift;
      $module = shift if eval { $module->isa(__PACKAGE__) }
        and scalar @_ and $_[0] =~ m#\A[a-zA-Z_][0-9a-zA-Z_]*(?:(::|')[0-9a-zA-Z_]+)*\z#;
      return unless $module;
      my @perls = grep { exists $deprecated{$_}{$module} } keys %deprecated;
      return unless @perls;
      require List::Util;
      return List::Util::minstr(@perls);
  }
  
  sub removed_from {
    my @perls = &removed_raw;
    return shift @perls;
  }
  
  sub removed_from_by_date {
    my @perls = sort _released_order &removed_raw;
    return shift @perls;
  }
  
  sub removed_raw {
    my $mod = shift;
    $mod = shift if eval { $mod->isa(__PACKAGE__) }
        and scalar @_ and $_[0] =~ m#\A[a-zA-Z_][0-9a-zA-Z_]*(?:(::|')[0-9a-zA-Z_]+)*\z#;
    return unless my @perls = sort { $a cmp $b } first_release_raw($mod);
    my $last = pop @perls;
    my @removed = grep { $_ > $last } sort { $a cmp $b } keys %version;
    return @removed;
  }
  
  sub changes_between {
    my $left_ver = shift;
    $left_ver = shift if eval { $left_ver->isa(__PACKAGE__) };
    my $right_ver = shift;
  
    my $left  = $version{ $left_ver };
    my $right = $version{ $right_ver };
  
    my %uniq = (%$left, %$right);
  
    my %changes;
    for my $lib (keys %uniq) {
        my $lhs = exists $left->{ $lib }
                ? (defined $left->{ $lib } ? $left->{ $lib } : '(undef)')
                : '(absent)';
        my $rhs = exists $right->{ $lib }
                ? (defined $right->{ $lib } ? $right->{ $lib } : '(undef)')
                : '(absent)';
  
        next if $lhs eq $rhs;
  
        my $change = {
          (exists $left->{$lib}  ? (left  => $left->{$lib})  : ()),
          (exists $right->{$lib} ? (right => $right->{$lib}) : ()),
        };
  
        $changes{$lib} = $change;
    }
  
    return %changes;
  }
  
  # When things escaped.
  # NB. If you put version numbers with trailing zeroes here, you
  # should also add an alias for the numerical ($]) version; see
  # just before the __END__ of this module.
  %released = (
      5.000    => '1994-10-17',
      5.001    => '1995-03-14',
      5.002    => '1996-02-29',
      5.00307  => '1996-10-10',
      5.004    => '1997-05-15',
      5.005    => '1998-07-22',
      5.00503  => '1999-03-28',
      5.00405  => '1999-04-29',
      5.006    => '2000-03-22',
      5.006001 => '2001-04-08',
      5.007003 => '2002-03-05',
      5.008    => '2002-07-19',
      5.008001 => '2003-09-25',
      5.009    => '2003-10-27',
      5.008002 => '2003-11-05',
      5.006002 => '2003-11-15',
      5.008003 => '2004-01-14',
      5.00504  => '2004-02-23',
      5.009001 => '2004-03-16',
      5.008004 => '2004-04-21',
      5.008005 => '2004-07-19',
      5.008006 => '2004-11-27',
      5.009002 => '2005-04-01',
      5.008007 => '2005-05-30',
      5.009003 => '2006-01-28',
      5.008008 => '2006-01-31',
      5.009004 => '2006-08-15',
      5.009005 => '2007-07-07',
      5.010000 => '2007-12-18',
      5.008009 => '2008-12-14',
      5.010001 => '2009-08-22',
      5.011000 => '2009-10-02',
      5.011001 => '2009-10-20',
      5.011002 => '2009-11-20',
      5.011003 => '2009-12-20',
      5.011004 => '2010-01-20',
      5.011005 => '2010-02-20',
      5.012000 => '2010-04-12',
      5.013000 => '2010-04-20',
      5.012001 => '2010-05-16',
      5.013001 => '2010-05-20',
      5.013002 => '2010-06-22',
      5.013003 => '2010-07-20',
      5.013004 => '2010-08-20',
      5.012002 => '2010-09-06',
      5.013005 => '2010-09-19',
      5.013006 => '2010-10-20',
      5.013007 => '2010-11-20',
      5.013008 => '2010-12-20',
      5.012003 => '2011-01-21',
      5.013009 => '2011-01-20',
      5.013010 => '2011-02-20',
      5.013011 => '2011-03-20',
      5.014000 => '2011-05-14',
      5.012004 => '2011-06-20',
      5.012005 => '2012-11-10',
      5.014001 => '2011-06-16',
      5.015000 => '2011-06-20',
      5.015001 => '2011-07-20',
      5.015002 => '2011-08-20',
      5.014002 => '2011-09-26',
      5.015003 => '2011-09-20',
      5.015004 => '2011-10-20',
      5.015005 => '2011-11-20',
      5.015006 => '2011-12-20',
      5.015007 => '2012-01-20',
      5.015008 => '2012-02-20',
      5.015009 => '2012-03-20',
      5.016000 => '2012-05-20',
      5.016001 => '2012-08-08',
      5.016002 => '2012-11-01',
      5.017000 => '2012-05-26',
      5.017001 => '2012-06-20',
      5.017002 => '2012-07-20',
      5.017003 => '2012-08-20',
      5.017004 => '2012-09-20',
      5.014003 => '2012-10-12',
      5.017005 => '2012-10-20',
      5.017006 => '2012-11-20',
      5.017007 => '2012-12-18',
      5.017008 => '2013-01-20',
      5.017009 => '2013-02-20',
      5.014004 => '2013-03-10',
      5.016003 => '2013-03-11',
      5.017010 => '2013-03-21',
      5.017011 => '2013-04-20',
      5.018000 => '2013-05-18',
      5.019000 => '2013-05-20',
      5.019001 => '2013-06-21',
      5.019002 => '2013-07-22',
      5.018001 => '2013-08-12',
      5.019003 => '2013-08-20',
      5.019004 => '2013-09-20',
      5.019005 => '2013-10-20',
      5.019006 => '2013-11-20',
      5.019007 => '2013-12-20',
      5.018002 => '2014-01-06',
      5.018003 => '2014-10-01',
      5.018004 => '2014-10-01',
      5.019008 => '2014-01-20',
      5.019009 => '2014-02-20',
      5.01901  => '2014-03-20',
      5.019011 => '2014-04-20',
      5.020000 => '2014-05-27',
      5.021000 => '2014-05-27',
      5.021001 => '2014-06-20',
      5.021002 => '2014-07-20',
      5.021003 => '2014-08-20',
      5.020001 => '2014-09-14',
      5.021004 => '2014-09-20',
      5.021005 => '2014-10-20',
      5.021006 => '2014-11-20',
      5.021007 => '2014-12-20',
      5.021008 => '2015-01-20',
      5.020002 => '2015-02-14',
      5.021009 => '2015-02-21',
      5.021010 => '2015-03-20',
      5.021011 => '2015-04-20',
      5.022000 => '2015-06-01',
      5.023000 => '2015-06-20',
    );
  
  for my $version ( sort { $a <=> $b } keys %released ) {
      my $family = int ($version * 1000) / 1000;
      push @{ $families{ $family }} , $version;
  }
  
  %delta = (
      5 => {
          changed => {
              'AnyDBM_File'           => undef,
              'AutoLoader'            => undef,
              'AutoSplit'             => undef,
              'Benchmark'             => undef,
              'Carp'                  => undef,
              'Cwd'                   => undef,
              'DB_File'               => undef,
              'DynaLoader'            => undef,
              'English'               => undef,
              'Env'                   => undef,
              'Exporter'              => undef,
              'ExtUtils::MakeMaker'   => undef,
              'Fcntl'                 => undef,
              'File::Basename'        => undef,
              'File::CheckTree'       => undef,
              'File::Find'            => undef,
              'FileHandle'            => undef,
              'GDBM_File'             => undef,
              'Getopt::Long'          => undef,
              'Getopt::Std'           => undef,
              'I18N::Collate'         => undef,
              'IPC::Open2'            => undef,
              'IPC::Open3'            => undef,
              'Math::BigFloat'        => undef,
              'Math::BigInt'          => undef,
              'Math::Complex'         => undef,
              'NDBM_File'             => undef,
              'Net::Ping'             => undef,
              'ODBM_File'             => undef,
              'POSIX'                 => undef,
              'SDBM_File'             => undef,
              'Search::Dict'          => undef,
              'Shell'                 => undef,
              'Socket'                => undef,
              'Sys::Hostname'         => undef,
              'Sys::Syslog'           => undef,
              'Term::Cap'             => undef,
              'Term::Complete'        => undef,
              'Test::Harness'         => undef,
              'Text::Abbrev'          => undef,
              'Text::ParseWords'      => undef,
              'Text::Soundex'         => undef,
              'Text::Tabs'            => undef,
              'TieHash'               => undef,
              'Time::Local'           => undef,
              'integer'               => undef,
              'less'                  => undef,
              'sigtrap'               => undef,
              'strict'                => undef,
              'subs'                  => undef,
          },
          removed => {
          }
      },
      5.001 => {
          delta_from => 5,
          changed => {
              'ExtUtils::Liblist'     => undef,
              'ExtUtils::Manifest'    => undef,
              'ExtUtils::Mkbootstrap' => undef,
              'File::Path'            => undef,
              'SubstrHash'            => undef,
              'lib'                   => undef,
          },
          removed => {
          }
      },
      5.002 => {
          delta_from => 5.001,
          changed => {
              'DB_File'               => '1.01',
              'Devel::SelfStubber'    => '1.01',
              'DirHandle'             => undef,
              'DynaLoader'            => '1.00',
              'ExtUtils::Install'     => undef,
              'ExtUtils::MM_OS2'      => undef,
              'ExtUtils::MM_Unix'     => undef,
              'ExtUtils::MM_VMS'      => undef,
              'ExtUtils::MakeMaker'   => '5.21',
              'ExtUtils::Manifest'    => '1.22',
              'ExtUtils::Mksymlists'  => '1.00',
              'Fcntl'                 => '1.00',
              'File::Copy'            => '1.5',
              'File::Path'            => '1.01',
              'FileCache'             => undef,
              'FileHandle'            => '1.00',
              'GDBM_File'             => '1.00',
              'Getopt::Long'          => '2.01',
              'NDBM_File'             => '1.00',
              'Net::Ping'             => '1',
              'ODBM_File'             => '1.00',
              'POSIX'                 => '1.00',
              'Pod::Functions'        => undef,
              'Pod::Text'             => undef,
              'SDBM_File'             => '1.00',
              'Safe'                  => '1.00',
              'SelectSaver'           => undef,
              'SelfLoader'            => '1.06',
              'Socket'                => '1.5',
              'Symbol'                => undef,
              'Term::ReadLine'        => undef,
              'Test::Harness'         => '1.07',
              'Text::Wrap'            => undef,
              'Tie::Hash'             => undef,
              'Tie::Scalar'           => undef,
              'Tie::SubstrHash'       => undef,
              'diagnostics'           => undef,
              'overload'              => undef,
              'vars'                  => undef,
          },
          removed => {
              'SubstrHash'            => 1,
              'TieHash'               => 1,
          }
      },
      5.00307 => {
          delta_from => 5.002,
          changed => {
              'Config'                => undef,
              'DB_File'               => '1.03',
              'ExtUtils::Embed'       => '1.18',
              'ExtUtils::Install'     => '1.15',
              'ExtUtils::Liblist'     => '1.20',
              'ExtUtils::MM_Unix'     => '1.107',
              'ExtUtils::MakeMaker'   => '5.38',
              'ExtUtils::Manifest'    => '1.27',
              'ExtUtils::Mkbootstrap' => '1.13',
              'ExtUtils::Mksymlists'  => '1.12',
              'ExtUtils::testlib'     => '1.11',
              'Fatal'                 => undef,
              'File::Basename'        => '2.4',
              'FindBin'               => '1.04',
              'Getopt::Long'          => '2.04',
              'IO'                    => undef,
              'IO::File'              => '1.05',
              'IO::Handle'            => '1.12',
              'IO::Pipe'              => '1.07',
              'IO::Seekable'          => '1.05',
              'IO::Select'            => '1.09',
              'IO::Socket'            => '1.13',
              'Net::Ping'             => '1.01',
              'OS2::ExtAttr'          => '0.01',
              'OS2::PrfDB'            => '0.02',
              'OS2::Process'          => undef,
              'OS2::REXX'             => undef,
              'Opcode'                => '1.01',
              'Safe'                  => '2.06',
              'Test::Harness'         => '1.13',
              'Text::Tabs'            => '96.051501',
              'Text::Wrap'            => '96.041801',
              'UNIVERSAL'             => undef,
              'VMS::Filespec'         => undef,
              'VMS::Stdio'            => '2.0',
              'ops'                   => undef,
              'sigtrap'               => '1.01',
          },
          removed => {
          }
      },
      5.004 => {
          delta_from => 5.00307,
          changed => {
              'Bundle::CPAN'          => '0.02',
              'CGI'                   => '2.36',
              'CGI::Apache'           => '1.01',
              'CGI::Carp'             => '1.06',
              'CGI::Fast'             => '1.00a',
              'CGI::Push'             => '1.00',
              'CGI::Switch'           => '0.05',
              'CPAN'                  => '1.2401',
              'CPAN::FirstTime'       => '1.18',
              'CPAN::Nox'             => undef,
              'Class::Struct'         => undef,
              'Cwd'                   => '2.00',
              'DB_File'               => '1.14',
              'DynaLoader'            => '1.02',
              'ExtUtils::Command'     => '1.00',
              'ExtUtils::Embed'       => '1.2501',
              'ExtUtils::Install'     => '1.16',
              'ExtUtils::Liblist'     => '1.2201',
              'ExtUtils::MM_Unix'     => '1.114',
              'ExtUtils::MM_Win32'    => undef,
              'ExtUtils::MakeMaker'   => '5.4002',
              'ExtUtils::Manifest'    => '1.33',
              'ExtUtils::Mksymlists'  => '1.13',
              'ExtUtils::XSSymSet'    => '1.0',
              'Fcntl'                 => '1.03',
              'File::Basename'        => '2.5',
              'File::Compare'         => '1.1001',
              'File::Copy'            => '2.02',
              'File::Path'            => '1.04',
              'File::stat'            => undef,
              'FileHandle'            => '2.00',
              'Getopt::Long'          => '2.10',
              'IO::File'              => '1.0602',
              'IO::Handle'            => '1.1504',
              'IO::Pipe'              => '1.0901',
              'IO::Seekable'          => '1.06',
              'IO::Select'            => '1.10',
              'IO::Socket'            => '1.1602',
              'IPC::Open2'            => '1.01',
              'IPC::Open3'            => '1.0101',
              'Math::Complex'         => '1.01',
              'Math::Trig'            => '1',
              'Net::Ping'             => '2.02',
              'Net::hostent'          => undef,
              'Net::netent'           => undef,
              'Net::protoent'         => undef,
              'Net::servent'          => undef,
              'Opcode'                => '1.04',
              'POSIX'                 => '1.02',
              'Pod::Html'             => undef,
              'Pod::Text'             => '1.0203',
              'SelfLoader'            => '1.07',
              'Socket'                => '1.6',
              'Symbol'                => '1.02',
              'Test::Harness'         => '1.1502',
              'Text::Tabs'            => '96.121201',
              'Text::Wrap'            => '97.011701',
              'Tie::RefHash'          => undef,
              'Time::gmtime'          => '1.01',
              'Time::localtime'       => '1.01',
              'Time::tm'              => undef,
              'User::grent'           => undef,
              'User::pwent'           => undef,
              'VMS::DCLsym'           => '1.01',
              'VMS::Stdio'            => '2.02',
              'autouse'               => '1.01',
              'blib'                  => undef,
              'constant'              => '1.00',
              'locale'                => undef,
              'sigtrap'               => '1.02',
              'vmsish'                => undef,
          },
          removed => {
              'Fatal'                 => 1,
          }
      },
      5.00405 => {
          delta_from => 5.004,
          changed => {
              'AutoLoader'            => '5.56',
              'AutoSplit'             => '1.0303',
              'Bundle::CPAN'          => '0.03',
              'CGI'                   => '2.42',
              'CGI::Apache'           => '1.1',
              'CGI::Carp'             => '1.10',
              'CGI::Cookie'           => '1.06',
              'CGI::Push'             => '1.01',
              'CGI::Switch'           => '0.06',
              'CPAN'                  => '1.40',
              'CPAN::FirstTime'       => '1.30',
              'Cwd'                   => '2.01',
              'DB_File'               => '1.15',
              'DynaLoader'            => '1.03',
              'ExtUtils::Command'     => '1.01',
              'ExtUtils::Embed'       => '1.2505',
              'ExtUtils::Install'     => '1.28',
              'ExtUtils::Liblist'     => '1.25',
              'ExtUtils::MM_Unix'     => '1.118',
              'ExtUtils::MakeMaker'   => '5.42',
              'ExtUtils::Mkbootstrap' => '1.14',
              'ExtUtils::Mksymlists'  => '1.16',
              'File::Basename'        => '2.6',
              'File::DosGlob'         => undef,
              'File::Path'            => '1.0402',
              'File::Spec'            => '0.6',
              'File::Spec::Mac'       => '1.0',
              'File::Spec::OS2'       => undef,
              'File::Spec::Unix'      => undef,
              'File::Spec::VMS'       => undef,
              'File::Spec::Win32'     => undef,
              'FindBin'               => '1.41',
              'Getopt::Long'          => '2.19',
              'IO::File'              => '1.06021',
              'IO::Socket'            => '1.1603',
              'IPC::Open3'            => '1.0103',
              'Math::Complex'         => '1.25',
              'NDBM_File'             => '1.01',
              'Pod::Html'             => '1.0101',
              'Pod::Text'             => '1.0204',
              'SelfLoader'            => '1.08',
              'Socket'                => '1.7',
              'Test'                  => '1.04',
              'Test::Harness'         => '1.1602',
              'Text::ParseWords'      => '3.1001',
              'Text::Wrap'            => '98.112902',
              'Tie::Handle'           => undef,
              'attrs'                 => '0.1',
              'base'                  => undef,
              'blib'                  => '1.00',
              're'                    => undef,
              'strict'                => '1.01',
          },
          removed => {
          }
      },
      5.005 => {
          delta_from => 5.00405,
          changed => {
              'AutoLoader'            => undef,
              'AutoSplit'             => '1.0302',
              'B'                     => undef,
              'B::Asmdata'            => undef,
              'B::Assembler'          => undef,
              'B::Bblock'             => undef,
              'B::Bytecode'           => undef,
              'B::C'                  => undef,
              'B::CC'                 => undef,
              'B::Debug'              => undef,
              'B::Deparse'            => '0.56',
              'B::Disassembler'       => undef,
              'B::Lint'               => undef,
              'B::Showlex'            => undef,
              'B::Stackobj'           => undef,
              'B::Terse'              => undef,
              'B::Xref'               => undef,
              'CGI::Carp'             => '1.101',
              'CPAN'                  => '1.3901',
              'CPAN::FirstTime'       => '1.29',
              'DB_File'               => '1.60',
              'Data::Dumper'          => '2.09',
              'Errno'                 => '1.09',
              'ExtUtils::Installed'   => '0.02',
              'ExtUtils::MM_Unix'     => '1.12601',
              'ExtUtils::MakeMaker'   => '5.4301',
              'ExtUtils::Mkbootstrap' => '1.13',
              'ExtUtils::Mksymlists'  => '1.17',
              'ExtUtils::Packlist'    => '0.03',
              'Fatal'                 => '1.02',
              'File::Path'            => '1.0401',
              'Getopt::Long'          => '2.17',
              'IO::Handle'            => '1.1505',
              'IPC::Msg'              => '1.00',
              'IPC::Open3'            => '1.0102',
              'IPC::Semaphore'        => '1.00',
              'IPC::SysV'             => '1.03',
              'O'                     => undef,
              'OS2::Process'          => '0.2',
              'Pod::Html'             => '1.01',
              'Pod::Text'             => '1.0203',
              'Text::ParseWords'      => '3.1',
              'Text::Wrap'            => '97.02',
              'Thread'                => '1.0',
              'Thread::Queue'         => undef,
              'Thread::Semaphore'     => undef,
              'Thread::Signal'        => undef,
              'Thread::Specific'      => undef,
              'Tie::Array'            => '1.00',
              'VMS::Stdio'            => '2.1',
              'attrs'                 => '1.0',
              'fields'                => '0.02',
              're'                    => '0.02',
          },
          removed => {
              'Bundle::CPAN'          => 1,
          }
      },
      5.00503 => {
          delta_from => 5.005,
          changed => {
              'AutoSplit'             => '1.0303',
              'CGI'                   => '2.46',
              'CGI::Carp'             => '1.13',
              'CGI::Fast'             => '1.01',
              'CPAN'                  => '1.48',
              'CPAN::FirstTime'       => '1.36',
              'CPAN::Nox'             => '1.00',
              'DB_File'               => '1.65',
              'Data::Dumper'          => '2.101',
              'Dumpvalue'             => undef,
              'Errno'                 => '1.111',
              'ExtUtils::Install'     => '1.28',
              'ExtUtils::Liblist'     => '1.25',
              'ExtUtils::MM_Unix'     => '1.12602',
              'ExtUtils::MakeMaker'   => '5.4302',
              'ExtUtils::Manifest'    => '1.33',
              'ExtUtils::Mkbootstrap' => '1.14',
              'ExtUtils::Mksymlists'  => '1.17',
              'ExtUtils::testlib'     => '1.11',
              'FindBin'               => '1.42',
              'Getopt::Long'          => '2.19',
              'Getopt::Std'           => '1.01',
              'IO::Pipe'              => '1.0902',
              'IPC::Open3'            => '1.0103',
              'Math::Complex'         => '1.26',
              'Test'                  => '1.122',
              'Text::Wrap'            => '98.112902',
          },
          removed => {
          }
      },
      5.00504 => {
          delta_from => 5.00503,
          changed => {
              'CPAN::FirstTime'       => '1.36',
              'DB_File'               => '1.807',
              'ExtUtils::Install'     => '1.28',
              'ExtUtils::Liblist'     => '1.25',
              'ExtUtils::MM_Unix'     => '1.12602',
              'ExtUtils::Manifest'    => '1.33',
              'ExtUtils::Miniperl'    => undef,
              'ExtUtils::Mkbootstrap' => '1.14',
              'ExtUtils::Mksymlists'  => '1.17',
              'ExtUtils::testlib'     => '1.11',
              'File::Compare'         => '1.1002',
              'File::Spec'            => '0.8',
              'File::Spec::Functions' => undef,
              'File::Spec::Mac'       => undef,
              'Getopt::Long'          => '2.20',
              'Pod::Html'             => '1.02',
          },
          removed => {
          }
      },
      5.006 => {
          delta_from => 5.00504,
          changed => {
              'AutoLoader'            => '5.57',
              'AutoSplit'             => '1.0305',
              'B::Deparse'            => '0.59',
              'B::Stash'              => undef,
              'Benchmark'             => '1',
              'ByteLoader'            => '0.03',
              'CGI'                   => '2.56',
              'CGI::Apache'           => undef,
              'CGI::Carp'             => '1.14',
              'CGI::Cookie'           => '1.12',
              'CGI::Fast'             => '1.02',
              'CGI::Pretty'           => '1.03',
              'CGI::Switch'           => undef,
              'CPAN'                  => '1.52',
              'CPAN::FirstTime'       => '1.38',
              'Carp::Heavy'           => undef,
              'Class::Struct'         => '0.58',
              'Cwd'                   => '2.02',
              'DB'                    => '1.0',
              'DB_File'               => '1.72',
              'Devel::DProf'          => '20000000.00_00',
              'Devel::Peek'           => '1.00_01',
              'DynaLoader'            => '1.04',
              'Exporter'              => '5.562',
              'Exporter::Heavy'       => undef,
              'ExtUtils::MM_Cygwin'   => undef,
              'ExtUtils::MM_Unix'     => '1.12603',
              'ExtUtils::MakeMaker'   => '5.45',
              'File::Copy'            => '2.03',
              'File::Glob'            => '0.991',
              'File::Path'            => '1.0403',
              'GDBM_File'             => '1.03',
              'Getopt::Long'          => '2.23',
              'Getopt::Std'           => '1.02',
              'IO'                    => '1.20',
              'IO::Dir'               => '1.03',
              'IO::File'              => '1.08',
              'IO::Handle'            => '1.21',
              'IO::Pipe'              => '1.121',
              'IO::Poll'              => '0.01',
              'IO::Seekable'          => '1.08',
              'IO::Select'            => '1.14',
              'IO::Socket'            => '1.26',
              'IO::Socket::INET'      => '1.25',
              'IO::Socket::UNIX'      => '1.20',
              'JNI'                   => '0.01',
              'JPL::AutoLoader'       => undef,
              'JPL::Class'            => undef,
              'JPL::Compile'          => undef,
              'NDBM_File'             => '1.03',
              'ODBM_File'             => '1.02',
              'OS2::DLL'              => undef,
              'POSIX'                 => '1.03',
              'Pod::Checker'          => '1.098',
              'Pod::Find'             => '0.12',
              'Pod::Html'             => '1.03',
              'Pod::InputObjects'     => '1.12',
              'Pod::Man'              => '1.02',
              'Pod::ParseUtils'       => '0.2',
              'Pod::Parser'           => '1.12',
              'Pod::Plainer'          => '0.01',
              'Pod::Select'           => '1.12',
              'Pod::Text'             => '2.03',
              'Pod::Text::Color'      => '0.05',
              'Pod::Text::Termcap'    => '0.04',
              'Pod::Usage'            => '1.12',
              'SDBM_File'             => '1.02',
              'SelfLoader'            => '1.0901',
              'Shell'                 => '0.2',
              'Socket'                => '1.72',
              'Sys::Hostname'         => '1.1',
              'Sys::Syslog'           => '0.01',
              'Term::ANSIColor'       => '1.01',
              'Test'                  => '1.13',
              'Test::Harness'         => '1.1604',
              'Text::ParseWords'      => '3.2',
              'Text::Soundex'         => '1.0',
              'Text::Tabs'            => '98.112801',
              'Tie::Array'            => '1.01',
              'Tie::Handle'           => '1.0',
              'VMS::Stdio'            => '2.2',
              'XSLoader'              => '0.01',
              'attributes'            => '0.03',
              'autouse'               => '1.02',
              'base'                  => '1.01',
              'bytes'                 => undef,
              'charnames'             => undef,
              'constant'              => '1.02',
              'diagnostics'           => '1.0',
              'fields'                => '1.01',
              'filetest'              => undef,
              'lib'                   => '0.5564',
              'open'                  => undef,
              'utf8'                  => undef,
              'warnings'              => undef,
              'warnings::register'    => undef,
          },
          removed => {
          }
      },
      5.006001 => {
          delta_from => 5.006,
          changed => {
              'AutoLoader'            => '5.58',
              'B::Assembler'          => '0.02',
              'B::Concise'            => '0.51',
              'B::Deparse'            => '0.6',
              'ByteLoader'            => '0.04',
              'CGI'                   => '2.752',
              'CGI::Carp'             => '1.20',
              'CGI::Cookie'           => '1.18',
              'CGI::Pretty'           => '1.05',
              'CGI::Push'             => '1.04',
              'CGI::Util'             => '1.1',
              'CPAN'                  => '1.59_54',
              'CPAN::FirstTime'       => '1.53',
              'Class::Struct'         => '0.59',
              'Cwd'                   => '2.04',
              'DB_File'               => '1.75',
              'Data::Dumper'          => '2.102',
              'ExtUtils::Install'     => '1.28',
              'ExtUtils::Liblist'     => '1.26',
              'ExtUtils::MM_Unix'     => '1.12603',
              'ExtUtils::Manifest'    => '1.33',
              'ExtUtils::Mkbootstrap' => '1.14',
              'ExtUtils::Mksymlists'  => '1.17',
              'ExtUtils::testlib'     => '1.11',
              'File::Path'            => '1.0404',
              'File::Spec'            => '0.82',
              'File::Spec::Epoc'      => undef,
              'File::Spec::Functions' => '1.1',
              'File::Spec::Mac'       => '1.2',
              'File::Spec::OS2'       => '1.1',
              'File::Spec::Unix'      => '1.2',
              'File::Spec::VMS'       => '1.1',
              'File::Spec::Win32'     => '1.2',
              'File::Temp'            => '0.12',
              'GDBM_File'             => '1.05',
              'Getopt::Long'          => '2.25',
              'IO::Poll'              => '0.05',
              'JNI'                   => '0.1',
              'Math::BigFloat'        => '0.02',
              'Math::BigInt'          => '0.01',
              'Math::Complex'         => '1.31',
              'NDBM_File'             => '1.04',
              'ODBM_File'             => '1.03',
              'OS2::REXX'             => '1.00',
              'Pod::Checker'          => '1.2',
              'Pod::Find'             => '0.21',
              'Pod::InputObjects'     => '1.13',
              'Pod::LaTeX'            => '0.53',
              'Pod::Man'              => '1.15',
              'Pod::ParseUtils'       => '0.22',
              'Pod::Parser'           => '1.13',
              'Pod::Select'           => '1.13',
              'Pod::Text'             => '2.08',
              'Pod::Text::Color'      => '0.06',
              'Pod::Text::Overstrike' => '1.01',
              'Pod::Text::Termcap'    => '1',
              'Pod::Usage'            => '1.14',
              'SDBM_File'             => '1.03',
              'SelfLoader'            => '1.0902',
              'Shell'                 => '0.3',
              'Term::ANSIColor'       => '1.03',
              'Test'                  => '1.15',
              'Text::Wrap'            => '2001.0131',
              'Tie::Handle'           => '4.0',
              'Tie::RefHash'          => '1.3',
          },
          removed => {
          }
      },
      5.006002 => {
          delta_from => 5.006001,
          changed => {
              'CPAN::FirstTime'       => '1.53',
              'DB_File'               => '1.806',
              'Data::Dumper'          => '2.121',
              'ExtUtils::Command'     => '1.05',
              'ExtUtils::Command::MM' => '0.03',
              'ExtUtils::Install'     => '1.32',
              'ExtUtils::Installed'   => '0.08',
              'ExtUtils::Liblist'     => '1.01',
              'ExtUtils::Liblist::Kid'=> '1.3',
              'ExtUtils::MM'          => '0.04',
              'ExtUtils::MM_Any'      => '0.07',
              'ExtUtils::MM_BeOS'     => '1.04',
              'ExtUtils::MM_Cygwin'   => '1.06',
              'ExtUtils::MM_DOS'      => '0.02',
              'ExtUtils::MM_MacOS'    => '1.07',
              'ExtUtils::MM_NW5'      => '2.06',
              'ExtUtils::MM_OS2'      => '1.04',
              'ExtUtils::MM_UWIN'     => '0.02',
              'ExtUtils::MM_Unix'     => '1.42',
              'ExtUtils::MM_VMS'      => '5.70',
              'ExtUtils::MM_Win32'    => '1.09',
              'ExtUtils::MM_Win95'    => '0.03',
              'ExtUtils::MY'          => '0.01',
              'ExtUtils::MakeMaker'   => '6.17',
              'ExtUtils::MakeMaker::bytes'=> '0.01',
              'ExtUtils::MakeMaker::vmsish'=> '0.01',
              'ExtUtils::Manifest'    => '1.42',
              'ExtUtils::Mkbootstrap' => '1.15',
              'ExtUtils::Mksymlists'  => '1.19',
              'ExtUtils::Packlist'    => '0.04',
              'ExtUtils::testlib'     => '1.15',
              'File::Spec'            => '0.86',
              'File::Spec::Cygwin'    => '1.1',
              'File::Spec::Epoc'      => '1.1',
              'File::Spec::Functions' => '1.3',
              'File::Spec::Mac'       => '1.4',
              'File::Spec::OS2'       => '1.2',
              'File::Spec::Unix'      => '1.5',
              'File::Spec::VMS'       => '1.4',
              'File::Spec::Win32'     => '1.4',
              'File::Temp'            => '0.14',
              'Safe'                  => '2.10',
              'Test'                  => '1.24',
              'Test::Builder'         => '0.17',
              'Test::Harness'         => '2.30',
              'Test::Harness::Assert' => '0.01',
              'Test::Harness::Iterator'=> '0.01',
              'Test::Harness::Straps' => '0.15',
              'Test::More'            => '0.47',
              'Test::Simple'          => '0.47',
              'Unicode'               => '3.0.1',
              'if'                    => '0.03',
              'ops'                   => '1.00',
          },
          removed => {
          }
      },
      5.007003 => {
          delta_from => 5.006001,
          changed => {
              'AnyDBM_File'           => '1.00',
              'Attribute::Handlers'   => '0.76',
              'AutoLoader'            => '5.59',
              'AutoSplit'             => '1.0307',
              'B'                     => '1.00',
              'B::Asmdata'            => '1.00',
              'B::Assembler'          => '0.04',
              'B::Bblock'             => '1.00',
              'B::Bytecode'           => '1.00',
              'B::C'                  => '1.01',
              'B::CC'                 => '1.00',
              'B::Concise'            => '0.52',
              'B::Debug'              => '1.00',
              'B::Deparse'            => '0.63',
              'B::Disassembler'       => '1.01',
              'B::Lint'               => '1.00',
              'B::Showlex'            => '1.00',
              'B::Stackobj'           => '1.00',
              'B::Stash'              => '1.00',
              'B::Terse'              => '1.00',
              'B::Xref'               => '1.00',
              'Benchmark'             => '1.04',
              'CGI'                   => '2.80',
              'CGI::Apache'           => '1.00',
              'CGI::Carp'             => '1.22',
              'CGI::Cookie'           => '1.20',
              'CGI::Fast'             => '1.04',
              'CGI::Pretty'           => '1.05_00',
              'CGI::Switch'           => '1.00',
              'CGI::Util'             => '1.3',
              'CPAN'                  => '1.59_56',
              'CPAN::FirstTime'       => '1.54',
              'CPAN::Nox'             => '1.00_01',
              'Carp'                  => '1.01',
              'Carp::Heavy'           => '1.01',
              'Class::ISA'            => '0.32',
              'Class::Struct'         => '0.61',
              'Cwd'                   => '2.06',
              'DB_File'               => '1.804',
              'Data::Dumper'          => '2.12',
              'Devel::DProf'          => '20000000.00_01',
              'Devel::PPPort'         => '2.0002',
              'Devel::Peek'           => '1.00_03',
              'Devel::SelfStubber'    => '1.03',
              'Digest'                => '1.00',
              'Digest::MD5'           => '2.16',
              'DirHandle'             => '1.00',
              'Dumpvalue'             => '1.10',
              'Encode'                => '0.40',
              'Encode::CN'            => '0.02',
              'Encode::CN::HZ'        => undef,
              'Encode::Encoding'      => '0.02',
              'Encode::Internal'      => '0.30',
              'Encode::JP'            => '0.02',
              'Encode::JP::Constants' => '1.02',
              'Encode::JP::H2Z'       => '0.77',
              'Encode::JP::ISO_2022_JP'=> undef,
              'Encode::JP::JIS'       => undef,
              'Encode::JP::Tr'        => '0.77',
              'Encode::KR'            => '0.02',
              'Encode::TW'            => '0.02',
              'Encode::Tcl'           => '1.01',
              'Encode::Tcl::Escape'   => '1.01',
              'Encode::Tcl::Extended' => '1.01',
              'Encode::Tcl::HanZi'    => '1.01',
              'Encode::Tcl::Table'    => '1.01',
              'Encode::Unicode'       => '0.30',
              'Encode::XS'            => '0.40',
              'Encode::iso10646_1'    => '0.30',
              'Encode::usc2_le'       => '0.30',
              'Encode::utf8'          => '0.30',
              'English'               => '1.00',
              'Env'                   => '1.00',
              'Exporter'              => '5.566',
              'Exporter::Heavy'       => '5.562',
              'ExtUtils::Command'     => '1.02',
              'ExtUtils::Constant'    => '0.11',
              'ExtUtils::Embed'       => '1.250601',
              'ExtUtils::Install'     => '1.29',
              'ExtUtils::Installed'   => '0.04',
              'ExtUtils::Liblist'     => '1.2701',
              'ExtUtils::MM_BeOS'     => '1.00',
              'ExtUtils::MM_Cygwin'   => '1.00',
              'ExtUtils::MM_OS2'      => '1.00',
              'ExtUtils::MM_Unix'     => '1.12607',
              'ExtUtils::MM_VMS'      => '5.56',
              'ExtUtils::MM_Win32'    => '1.00_02',
              'ExtUtils::MakeMaker'   => '5.48_03',
              'ExtUtils::Manifest'    => '1.35',
              'ExtUtils::Mkbootstrap' => '1.1401',
              'ExtUtils::Mksymlists'  => '1.18',
              'ExtUtils::Packlist'    => '0.04',
              'ExtUtils::testlib'     => '1.1201',
              'Fatal'                 => '1.03',
              'Fcntl'                 => '1.04',
              'File::Basename'        => '2.71',
              'File::CheckTree'       => '4.1',
              'File::Compare'         => '1.1003',
              'File::Copy'            => '2.05',
              'File::DosGlob'         => '1.00',
              'File::Find'            => '1.04',
              'File::Glob'            => '1.01',
              'File::Path'            => '1.05',
              'File::Spec'            => '0.83',
              'File::Spec::Cygwin'    => '1.0',
              'File::Spec::Epoc'      => '1.00',
              'File::Spec::Functions' => '1.2',
              'File::Spec::Mac'       => '1.3',
              'File::Spec::Unix'      => '1.4',
              'File::Spec::VMS'       => '1.2',
              'File::Spec::Win32'     => '1.3',
              'File::Temp'            => '0.13',
              'File::stat'            => '1.00',
              'FileCache'             => '1.00',
              'FileHandle'            => '2.01',
              'Filter::Simple'        => '0.77',
              'Filter::Util::Call'    => '1.06',
              'FindBin'               => '1.43',
              'GDBM_File'             => '1.06',
              'Getopt::Long'          => '2.28',
              'Getopt::Std'           => '1.03',
              'I18N::Collate'         => '1.00',
              'I18N::LangTags'        => '0.27',
              'I18N::LangTags::List'  => '0.25',
              'I18N::Langinfo'        => '0.01',
              'IO::Dir'               => '1.03_00',
              'IO::File'              => '1.09',
              'IO::Handle'            => '1.21_00',
              'IO::Pipe'              => '1.122',
              'IO::Poll'              => '0.06',
              'IO::Seekable'          => '1.08_00',
              'IO::Select'            => '1.15',
              'IO::Socket'            => '1.27',
              'IO::Socket::INET'      => '1.26',
              'IO::Socket::UNIX'      => '1.20_00',
              'IPC::Msg'              => '1.00_00',
              'IPC::Open3'            => '1.0104',
              'IPC::Semaphore'        => '1.00_00',
              'IPC::SysV'             => '1.03_00',
              'List::Util'            => '1.06_00',
              'Locale::Constants'     => '2.01',
              'Locale::Country'       => '2.01',
              'Locale::Currency'      => '2.01',
              'Locale::Language'      => '2.01',
              'Locale::Maketext'      => '1.03',
              'Locale::Script'        => '2.01',
              'MIME::Base64'          => '2.12',
              'MIME::QuotedPrint'     => '2.03',
              'Math::BigFloat'        => '1.30',
              'Math::BigInt'          => '1.54',
              'Math::BigInt::Calc'    => '0.25',
              'Math::Complex'         => '1.34',
              'Math::Trig'            => '1.01',
              'Memoize'               => '0.66',
              'Memoize::AnyDBM_File'  => '0.65',
              'Memoize::Expire'       => '0.66',
              'Memoize::ExpireFile'   => '0.65',
              'Memoize::ExpireTest'   => '0.65',
              'Memoize::NDBM_File'    => '0.65',
              'Memoize::SDBM_File'    => '0.65',
              'Memoize::Storable'     => '0.65',
              'NEXT'                  => '0.50',
              'Net::Cmd'              => '2.21',
              'Net::Config'           => '1.10',
              'Net::Domain'           => '2.17',
              'Net::FTP'              => '2.64',
              'Net::FTP::A'           => '1.15',
              'Net::FTP::E'           => '0.01',
              'Net::FTP::I'           => '1.12',
              'Net::FTP::L'           => '0.01',
              'Net::FTP::dataconn'    => '0.10',
              'Net::NNTP'             => '2.21',
              'Net::Netrc'            => '2.12',
              'Net::POP3'             => '2.23',
              'Net::Ping'             => '2.12',
              'Net::SMTP'             => '2.21',
              'Net::Time'             => '2.09',
              'Net::hostent'          => '1.00',
              'Net::netent'           => '1.00',
              'Net::protoent'         => '1.00',
              'Net::servent'          => '1.00',
              'O'                     => '1.00',
              'OS2::DLL'              => '1.00',
              'OS2::Process'          => '1.0',
              'OS2::REXX'             => '1.01',
              'Opcode'                => '1.05',
              'POSIX'                 => '1.05',
              'PerlIO'                => '1.00',
              'PerlIO::Scalar'        => '0.01',
              'PerlIO::Via'           => '0.01',
              'Pod::Checker'          => '1.3',
              'Pod::Find'             => '0.22',
              'Pod::Functions'        => '1.01',
              'Pod::Html'             => '1.04',
              'Pod::LaTeX'            => '0.54',
              'Pod::Man'              => '1.32',
              'Pod::ParseLink'        => '1.05',
              'Pod::Text'             => '2.18',
              'Pod::Text::Color'      => '1.03',
              'Pod::Text::Overstrike' => '1.08',
              'Pod::Text::Termcap'    => '1.09',
              'Safe'                  => '2.07',
              'Scalar::Util'          => '1.06_00',
              'Search::Dict'          => '1.02',
              'SelectSaver'           => '1.00',
              'SelfLoader'            => '1.0903',
              'Shell'                 => '0.4',
              'Socket'                => '1.75',
              'Storable'              => '1.015',
              'Switch'                => '2.06',
              'Symbol'                => '1.04',
              'Sys::Syslog'           => '0.02',
              'Term::ANSIColor'       => '1.04',
              'Term::Cap'             => '1.07',
              'Term::Complete'        => '1.4',
              'Term::ReadLine'        => '1.00',
              'Test'                  => '1.18',
              'Test::Builder'         => '0.11',
              'Test::Harness'         => '2.01',
              'Test::Harness::Assert' => '0.01',
              'Test::Harness::Iterator'=> '0.01',
              'Test::Harness::Straps' => '0.08',
              'Test::More'            => '0.41',
              'Test::Simple'          => '0.41',
              'Text::Abbrev'          => '1.00',
              'Text::Balanced'        => '1.89',
              'Text::ParseWords'      => '3.21',
              'Text::Soundex'         => '1.01',
              'Text::Wrap'            => '2001.0929',
              'Thread'                => '2.00',
              'Thread::Queue'         => '1.00',
              'Thread::Semaphore'     => '1.00',
              'Thread::Signal'        => '1.00',
              'Thread::Specific'      => '1.00',
              'Tie::Array'            => '1.02',
              'Tie::File'             => '0.17',
              'Tie::Handle'           => '4.1',
              'Tie::Hash'             => '1.00',
              'Tie::Memoize'          => '1.0',
              'Tie::RefHash'          => '1.3_00',
              'Tie::Scalar'           => '1.00',
              'Tie::SubstrHash'       => '1.00',
              'Time::HiRes'           => '1.20_00',
              'Time::Local'           => '1.04',
              'Time::gmtime'          => '1.02',
              'Time::localtime'       => '1.02',
              'Time::tm'              => '1.00',
              'UNIVERSAL'             => '1.00',
              'Unicode::Collate'      => '0.10',
              'Unicode::Normalize'    => '0.14',
              'Unicode::UCD'          => '0.2',
              'User::grent'           => '1.00',
              'User::pwent'           => '1.00',
              'VMS::DCLsym'           => '1.02',
              'VMS::Filespec'         => '1.1',
              'VMS::Stdio'            => '2.3',
              'XS::Typemap'           => '0.01',
              'attributes'            => '0.04_01',
              'attrs'                 => '1.01',
              'autouse'               => '1.03',
              'base'                  => '1.02',
              'blib'                  => '1.01',
              'bytes'                 => '1.00',
              'charnames'             => '1.01',
              'constant'              => '1.04',
              'diagnostics'           => '1.1',
              'encoding'              => '1.00',
              'fields'                => '1.02',
              'filetest'              => '1.00',
              'if'                    => '0.01',
              'integer'               => '1.00',
              'less'                  => '0.01',
              'locale'                => '1.00',
              'open'                  => '1.01',
              'ops'                   => '1.00',
              'overload'              => '1.00',
              're'                    => '0.03',
              'sort'                  => '1.00',
              'strict'                => '1.02',
              'subs'                  => '1.00',
              'threads'               => '0.05',
              'threads::shared'       => '0.90',
              'utf8'                  => '1.00',
              'vars'                  => '1.01',
              'vmsish'                => '1.00',
              'warnings'              => '1.00',
              'warnings::register'    => '1.00',
          },
          removed => {
          }
      },
      5.008 => {
          delta_from => 5.007003,
          changed => {
              'Attribute::Handlers'   => '0.77',
              'B'                     => '1.01',
              'B::Lint'               => '1.01',
              'B::Xref'               => '1.01',
              'CGI'                   => '2.81',
              'CGI::Carp'             => '1.23',
              'CPAN'                  => '1.61',
              'CPAN::FirstTime'       => '1.56',
              'CPAN::Nox'             => '1.02',
              'Digest::MD5'           => '2.20',
              'Dumpvalue'             => '1.11',
              'Encode'                => '1.75',
              'Encode::Alias'         => '1.32',
              'Encode::Byte'          => '1.22',
              'Encode::CJKConstants'  => '1.00',
              'Encode::CN'            => '1.24',
              'Encode::CN::HZ'        => '1.04',
              'Encode::Config'        => '1.06',
              'Encode::EBCDIC'        => '1.21',
              'Encode::Encoder'       => '0.05',
              'Encode::Encoding'      => '1.30',
              'Encode::Guess'         => '1.06',
              'Encode::JP'            => '1.25',
              'Encode::JP::H2Z'       => '1.02',
              'Encode::JP::JIS7'      => '1.08',
              'Encode::KR'            => '1.22',
              'Encode::KR::2022_KR'   => '1.05',
              'Encode::MIME::Header'  => '1.05',
              'Encode::Symbol'        => '1.22',
              'Encode::TW'            => '1.26',
              'Encode::Unicode'       => '1.37',
              'Exporter::Heavy'       => '5.566',
              'ExtUtils::Command'     => '1.04',
              'ExtUtils::Command::MM' => '0.01',
              'ExtUtils::Constant'    => '0.12',
              'ExtUtils::Installed'   => '0.06',
              'ExtUtils::Liblist'     => '1.00',
              'ExtUtils::Liblist::Kid'=> '1.29',
              'ExtUtils::MM'          => '0.04',
              'ExtUtils::MM_Any'      => '0.04',
              'ExtUtils::MM_BeOS'     => '1.03',
              'ExtUtils::MM_Cygwin'   => '1.04',
              'ExtUtils::MM_DOS'      => '0.01',
              'ExtUtils::MM_MacOS'    => '1.03',
              'ExtUtils::MM_NW5'      => '2.05',
              'ExtUtils::MM_OS2'      => '1.03',
              'ExtUtils::MM_UWIN'     => '0.01',
              'ExtUtils::MM_Unix'     => '1.33',
              'ExtUtils::MM_VMS'      => '5.65',
              'ExtUtils::MM_Win32'    => '1.05',
              'ExtUtils::MM_Win95'    => '0.02',
              'ExtUtils::MY'          => '0.01',
              'ExtUtils::MakeMaker'   => '6.03',
              'ExtUtils::Manifest'    => '1.38',
              'ExtUtils::Mkbootstrap' => '1.15',
              'ExtUtils::Mksymlists'  => '1.19',
              'ExtUtils::testlib'     => '1.15',
              'File::CheckTree'       => '4.2',
              'FileCache'             => '1.021',
              'Filter::Simple'        => '0.78',
              'Getopt::Long'          => '2.32',
              'Hash::Util'            => '0.04',
              'List::Util'            => '1.07_00',
              'Locale::Country'       => '2.04',
              'Math::BigFloat'        => '1.35',
              'Math::BigFloat::Trace' => '0.01',
              'Math::BigInt'          => '1.60',
              'Math::BigInt::Calc'    => '0.30',
              'Math::BigInt::Trace'   => '0.01',
              'Math::BigRat'          => '0.07',
              'Memoize'               => '1.01',
              'Memoize::Expire'       => '1.00',
              'Memoize::ExpireFile'   => '1.01',
              'Net::FTP'              => '2.65',
              'Net::FTP::dataconn'    => '0.11',
              'Net::Ping'             => '2.19',
              'Net::SMTP'             => '2.24',
              'PerlIO'                => '1.01',
              'PerlIO::encoding'      => '0.06',
              'PerlIO::scalar'        => '0.01',
              'PerlIO::via'           => '0.01',
              'PerlIO::via::QuotedPrint'=> '0.04',
              'Pod::Man'              => '1.33',
              'Pod::Text'             => '2.19',
              'Scalar::Util'          => '1.07_00',
              'Storable'              => '2.04',
              'Switch'                => '2.09',
              'Sys::Syslog'           => '0.03',
              'Test'                  => '1.20',
              'Test::Builder'         => '0.15',
              'Test::Harness'         => '2.26',
              'Test::Harness::Straps' => '0.14',
              'Test::More'            => '0.45',
              'Test::Simple'          => '0.45',
              'Thread::Queue'         => '2.00',
              'Thread::Semaphore'     => '2.00',
              'Tie::File'             => '0.93',
              'Tie::RefHash'          => '1.30',
              'Unicode'               => '3.2.0',
              'Unicode::Collate'      => '0.12',
              'Unicode::Normalize'    => '0.17',
              'XS::APItest'           => '0.01',
              'attributes'            => '0.05',
              'base'                  => '1.03',
              'bigint'                => '0.02',
              'bignum'                => '0.11',
              'bigrat'                => '0.04',
              'blib'                  => '1.02',
              'encoding'              => '1.35',
              'sort'                  => '1.01',
              'threads'               => '0.99',
          },
          removed => {
              'Encode::Internal'      => 1,
              'Encode::JP::Constants' => 1,
              'Encode::JP::ISO_2022_JP'=> 1,
              'Encode::JP::JIS'       => 1,
              'Encode::JP::Tr'        => 1,
              'Encode::Tcl'           => 1,
              'Encode::Tcl::Escape'   => 1,
              'Encode::Tcl::Extended' => 1,
              'Encode::Tcl::HanZi'    => 1,
              'Encode::Tcl::Table'    => 1,
              'Encode::XS'            => 1,
              'Encode::iso10646_1'    => 1,
              'Encode::usc2_le'       => 1,
              'Encode::utf8'          => 1,
              'PerlIO::Scalar'        => 1,
              'PerlIO::Via'           => 1,
          }
      },
      5.008001 => {
          delta_from => 5.008,
          changed => {
              'Attribute::Handlers'   => '0.78',
              'AutoLoader'            => '5.60',
              'AutoSplit'             => '1.04',
              'B'                     => '1.02',
              'B::Asmdata'            => '1.01',
              'B::Assembler'          => '0.06',
              'B::Bblock'             => '1.02',
              'B::Bytecode'           => '1.01',
              'B::C'                  => '1.02',
              'B::Concise'            => '0.56',
              'B::Debug'              => '1.01',
              'B::Deparse'            => '0.64',
              'B::Disassembler'       => '1.03',
              'B::Lint'               => '1.02',
              'B::Terse'              => '1.02',
              'Benchmark'             => '1.051',
              'ByteLoader'            => '0.05',
              'CGI'                   => '3.00',
              'CGI::Carp'             => '1.26',
              'CGI::Cookie'           => '1.24',
              'CGI::Fast'             => '1.041',
              'CGI::Pretty'           => '1.07_00',
              'CGI::Util'             => '1.31',
              'CPAN'                  => '1.76_01',
              'CPAN::FirstTime'       => '1.60',
              'CPAN::Nox'             => '1.03',
              'Class::Struct'         => '0.63',
              'Cwd'                   => '2.08',
              'DB_File'               => '1.806',
              'Data::Dumper'          => '2.121',
              'Devel::DProf'          => '20030813.00',
              'Devel::PPPort'         => '2.007',
              'Devel::Peek'           => '1.01',
              'Digest'                => '1.02',
              'Digest::MD5'           => '2.27',
              'Encode'                => '1.9801',
              'Encode::Alias'         => '1.38',
              'Encode::Byte'          => '1.23',
              'Encode::CJKConstants'  => '1.02',
              'Encode::CN::HZ'        => '1.05',
              'Encode::Config'        => '1.07',
              'Encode::Encoder'       => '0.07',
              'Encode::Encoding'      => '1.33',
              'Encode::Guess'         => '1.09',
              'Encode::JP::JIS7'      => '1.12',
              'Encode::KR'            => '1.23',
              'Encode::KR::2022_KR'   => '1.06',
              'Encode::MIME::Header'  => '1.09',
              'Encode::Unicode'       => '1.40',
              'Encode::Unicode::UTF7' => '0.02',
              'English'               => '1.01',
              'Errno'                 => '1.09_00',
              'Exporter'              => '5.567',
              'Exporter::Heavy'       => '5.567',
              'ExtUtils::Command'     => '1.05',
              'ExtUtils::Command::MM' => '0.03',
              'ExtUtils::Constant'    => '0.14',
              'ExtUtils::Install'     => '1.32',
              'ExtUtils::Installed'   => '0.08',
              'ExtUtils::Liblist'     => '1.01',
              'ExtUtils::Liblist::Kid'=> '1.3',
              'ExtUtils::MM_Any'      => '0.07',
              'ExtUtils::MM_BeOS'     => '1.04',
              'ExtUtils::MM_Cygwin'   => '1.06',
              'ExtUtils::MM_DOS'      => '0.02',
              'ExtUtils::MM_MacOS'    => '1.07',
              'ExtUtils::MM_NW5'      => '2.06',
              'ExtUtils::MM_OS2'      => '1.04',
              'ExtUtils::MM_UWIN'     => '0.02',
              'ExtUtils::MM_Unix'     => '1.42',
              'ExtUtils::MM_VMS'      => '5.70',
              'ExtUtils::MM_Win32'    => '1.09',
              'ExtUtils::MM_Win95'    => '0.03',
              'ExtUtils::MakeMaker'   => '6.17',
              'ExtUtils::MakeMaker::bytes'=> '0.01',
              'ExtUtils::MakeMaker::vmsish'=> '0.01',
              'ExtUtils::Manifest'    => '1.42',
              'Fcntl'                 => '1.05',
              'File::Basename'        => '2.72',
              'File::Copy'            => '2.06',
              'File::Find'            => '1.05',
              'File::Glob'            => '1.02',
              'File::Path'            => '1.06',
              'File::Spec'            => '0.86',
              'File::Spec::Cygwin'    => '1.1',
              'File::Spec::Epoc'      => '1.1',
              'File::Spec::Functions' => '1.3',
              'File::Spec::Mac'       => '1.4',
              'File::Spec::OS2'       => '1.2',
              'File::Spec::Unix'      => '1.5',
              'File::Spec::VMS'       => '1.4',
              'File::Spec::Win32'     => '1.4',
              'File::Temp'            => '0.14',
              'FileCache'             => '1.03',
              'Filter::Util::Call'    => '1.0601',
              'GDBM_File'             => '1.07',
              'Getopt::Long'          => '2.34',
              'Getopt::Std'           => '1.04',
              'Hash::Util'            => '0.05',
              'I18N::LangTags'        => '0.28',
              'I18N::LangTags::List'  => '0.26',
              'I18N::Langinfo'        => '0.02',
              'IO'                    => '1.21',
              'IO::Dir'               => '1.04',
              'IO::File'              => '1.10',
              'IO::Handle'            => '1.23',
              'IO::Seekable'          => '1.09',
              'IO::Select'            => '1.16',
              'IO::Socket'            => '1.28',
              'IO::Socket::INET'      => '1.27',
              'IO::Socket::UNIX'      => '1.21',
              'IPC::Msg'              => '1.02',
              'IPC::Open3'            => '1.0105',
              'IPC::Semaphore'        => '1.02',
              'IPC::SysV'             => '1.04',
              'JNI'                   => '0.2',
              'List::Util'            => '1.13',
              'Locale::Country'       => '2.61',
              'Locale::Currency'      => '2.21',
              'Locale::Language'      => '2.21',
              'Locale::Maketext'      => '1.06',
              'Locale::Maketext::Guts'=> undef,
              'Locale::Maketext::GutsLoader'=> undef,
              'Locale::Script'        => '2.21',
              'MIME::Base64'          => '2.20',
              'MIME::QuotedPrint'     => '2.20',
              'Math::BigFloat'        => '1.40',
              'Math::BigInt'          => '1.66',
              'Math::BigInt::Calc'    => '0.36',
              'Math::BigInt::Scalar'  => '0.11',
              'Math::BigRat'          => '0.10',
              'Math::Trig'            => '1.02',
              'NDBM_File'             => '1.05',
              'NEXT'                  => '0.60',
              'Net::Cmd'              => '2.24',
              'Net::Domain'           => '2.18',
              'Net::FTP'              => '2.71',
              'Net::FTP::A'           => '1.16',
              'Net::NNTP'             => '2.22',
              'Net::POP3'             => '2.24',
              'Net::Ping'             => '2.31',
              'Net::SMTP'             => '2.26',
              'Net::hostent'          => '1.01',
              'Net::servent'          => '1.01',
              'ODBM_File'             => '1.04',
              'OS2::DLL'              => '1.01',
              'OS2::ExtAttr'          => '0.02',
              'OS2::PrfDB'            => '0.03',
              'OS2::Process'          => '1.01',
              'OS2::REXX'             => '1.02',
              'POSIX'                 => '1.06',
              'PerlIO'                => '1.02',
              'PerlIO::encoding'      => '0.07',
              'PerlIO::scalar'        => '0.02',
              'PerlIO::via'           => '0.02',
              'PerlIO::via::QuotedPrint'=> '0.05',
              'Pod::Checker'          => '1.41',
              'Pod::Find'             => '0.24',
              'Pod::Functions'        => '1.02',
              'Pod::Html'             => '1.0501',
              'Pod::InputObjects'     => '1.14',
              'Pod::LaTeX'            => '0.55',
              'Pod::Man'              => '1.37',
              'Pod::ParseLink'        => '1.06',
              'Pod::ParseUtils'       => '0.3',
              'Pod::Perldoc'          => '3.10',
              'Pod::Perldoc::BaseTo'  => undef,
              'Pod::Perldoc::GetOptsOO'=> undef,
              'Pod::Perldoc::ToChecker'=> undef,
              'Pod::Perldoc::ToMan'   => undef,
              'Pod::Perldoc::ToNroff' => undef,
              'Pod::Perldoc::ToPod'   => undef,
              'Pod::Perldoc::ToRtf'   => undef,
              'Pod::Perldoc::ToText'  => undef,
              'Pod::Perldoc::ToTk'    => undef,
              'Pod::Perldoc::ToXml'   => undef,
              'Pod::PlainText'        => '2.01',
              'Pod::Text'             => '2.21',
              'Pod::Text::Color'      => '1.04',
              'Pod::Text::Overstrike' => '1.1',
              'Pod::Text::Termcap'    => '1.11',
              'Pod::Usage'            => '1.16',
              'SDBM_File'             => '1.04',
              'Safe'                  => '2.10',
              'Scalar::Util'          => '1.13',
              'SelfLoader'            => '1.0904',
              'Shell'                 => '0.5',
              'Socket'                => '1.76',
              'Storable'              => '2.08',
              'Switch'                => '2.10',
              'Symbol'                => '1.05',
              'Sys::Hostname'         => '1.11',
              'Sys::Syslog'           => '0.04',
              'Term::ANSIColor'       => '1.07',
              'Term::Cap'             => '1.08',
              'Term::Complete'        => '1.401',
              'Term::ReadLine'        => '1.01',
              'Test'                  => '1.24',
              'Test::Builder'         => '0.17',
              'Test::Harness'         => '2.30',
              'Test::Harness::Straps' => '0.15',
              'Test::More'            => '0.47',
              'Test::Simple'          => '0.47',
              'Text::Abbrev'          => '1.01',
              'Text::Balanced'        => '1.95',
              'Text::Wrap'            => '2001.09291',
              'Thread::Semaphore'     => '2.01',
              'Tie::Array'            => '1.03',
              'Tie::File'             => '0.97',
              'Tie::RefHash'          => '1.31',
              'Time::HiRes'           => '1.51',
              'Time::Local'           => '1.07',
              'UNIVERSAL'             => '1.01',
              'Unicode'               => '4.0.0',
              'Unicode::Collate'      => '0.28',
              'Unicode::Normalize'    => '0.23',
              'Unicode::UCD'          => '0.21',
              'VMS::Filespec'         => '1.11',
              'XS::APItest'           => '0.02',
              'XSLoader'              => '0.02',
              'attributes'            => '0.06',
              'base'                  => '2.03',
              'bigint'                => '0.04',
              'bignum'                => '0.14',
              'bigrat'                => '0.06',
              'bytes'                 => '1.01',
              'charnames'             => '1.02',
              'diagnostics'           => '1.11',
              'encoding'              => '1.47',
              'fields'                => '2.03',
              'filetest'              => '1.01',
              'if'                    => '0.03',
              'lib'                   => '0.5565',
              'open'                  => '1.02',
              'overload'              => '1.01',
              're'                    => '0.04',
              'sort'                  => '1.02',
              'strict'                => '1.03',
              'threads'               => '1.00',
              'threads::shared'       => '0.91',
              'utf8'                  => '1.02',
              'vmsish'                => '1.01',
              'warnings'              => '1.03',
          },
          removed => {
          }
      },
      5.008002 => {
          delta_from => 5.008001,
          changed => {
              'DB_File'               => '1.807',
              'Devel::PPPort'         => '2.009',
              'Digest::MD5'           => '2.30',
              'I18N::LangTags'        => '0.29',
              'I18N::LangTags::List'  => '0.29',
              'MIME::Base64'          => '2.21',
              'MIME::QuotedPrint'     => '2.21',
              'Net::Domain'           => '2.19',
              'Net::FTP'              => '2.72',
              'Pod::Perldoc'          => '3.11',
              'Time::HiRes'           => '1.52',
              'Unicode::Collate'      => '0.30',
              'Unicode::Normalize'    => '0.25',
          },
          removed => {
          }
      },
      5.008003 => {
          delta_from => 5.008002,
          changed => {
              'Benchmark'             => '1.052',
              'CGI'                   => '3.01',
              'CGI::Carp'             => '1.27',
              'CGI::Fast'             => '1.05',
              'CGI::Pretty'           => '1.08',
              'CGI::Util'             => '1.4',
              'Cwd'                   => '2.12',
              'DB_File'               => '1.808',
              'Devel::PPPort'         => '2.011',
              'Digest'                => '1.05',
              'Digest::MD5'           => '2.33',
              'Digest::base'          => '1.00',
              'Encode'                => '1.99',
              'Exporter'              => '5.57',
              'File::CheckTree'       => '4.3',
              'File::Copy'            => '2.07',
              'File::Find'            => '1.06',
              'File::Spec'            => '0.87',
              'FindBin'               => '1.44',
              'Getopt::Std'           => '1.05',
              'Math::BigFloat'        => '1.42',
              'Math::BigInt'          => '1.68',
              'Math::BigInt::Calc'    => '0.38',
              'Math::BigInt::CalcEmu' => '0.02',
              'OS2::DLL'              => '1.02',
              'POSIX'                 => '1.07',
              'PerlIO'                => '1.03',
              'PerlIO::via::QuotedPrint'=> '0.06',
              'Pod::Html'             => '1.0502',
              'Pod::Parser'           => '1.14',
              'Pod::Perldoc'          => '3.12',
              'Pod::PlainText'        => '2.02',
              'Storable'              => '2.09',
              'Test::Harness'         => '2.40',
              'Test::Harness::Assert' => '0.02',
              'Test::Harness::Iterator'=> '0.02',
              'Test::Harness::Straps' => '0.19',
              'Tie::Hash'             => '1.01',
              'Unicode::Collate'      => '0.33',
              'Unicode::Normalize'    => '0.28',
              'XS::APItest'           => '0.03',
              'base'                  => '2.04',
              'diagnostics'           => '1.12',
              'encoding'              => '1.48',
              'threads'               => '1.01',
              'threads::shared'       => '0.92',
          },
          removed => {
              'Math::BigInt::Scalar'  => 1,
          }
      },
      5.008004 => {
          delta_from => 5.008003,
          changed => {
              'Attribute::Handlers'   => '0.78_01',
              'B::Assembler'          => '0.07',
              'B::Concise'            => '0.60',
              'B::Deparse'            => '0.66',
              'Benchmark'             => '1.06',
              'CGI'                   => '3.04',
              'Carp'                  => '1.02',
              'Cwd'                   => '2.17',
              'DBM_Filter'            => '0.01',
              'DBM_Filter::compress'  => '0.01',
              'DBM_Filter::encode'    => '0.01',
              'DBM_Filter::int32'     => '0.01',
              'DBM_Filter::null'      => '0.01',
              'DBM_Filter::utf8'      => '0.01',
              'Digest'                => '1.06',
              'DynaLoader'            => '1.05',
              'Encode'                => '1.99_01',
              'Encode::CN::HZ'        => '1.0501',
              'Exporter'              => '5.58',
              'Exporter::Heavy'       => '5.57',
              'ExtUtils::Liblist::Kid'=> '1.3001',
              'ExtUtils::MM_NW5'      => '2.07_02',
              'ExtUtils::MM_Win95'    => '0.0301',
              'File::Find'            => '1.07',
              'IO::Handle'            => '1.24',
              'IO::Pipe'              => '1.123',
              'IPC::Open3'            => '1.0106',
              'Locale::Maketext'      => '1.08',
              'MIME::Base64'          => '3.01',
              'MIME::QuotedPrint'     => '3.01',
              'Math::BigFloat'        => '1.44',
              'Math::BigInt'          => '1.70',
              'Math::BigInt::Calc'    => '0.40',
              'Math::BigInt::CalcEmu' => '0.04',
              'Math::BigRat'          => '0.12',
              'ODBM_File'             => '1.05',
              'POSIX'                 => '1.08',
              'Shell'                 => '0.5.2',
              'Socket'                => '1.77',
              'Storable'              => '2.12',
              'Sys::Syslog'           => '0.05',
              'Term::ANSIColor'       => '1.08',
              'Time::HiRes'           => '1.59',
              'Unicode'               => '4.0.1',
              'Unicode::UCD'          => '0.22',
              'Win32'                 => '0.23',
              'base'                  => '2.05',
              'bigint'                => '0.05',
              'bignum'                => '0.15',
              'charnames'             => '1.03',
              'open'                  => '1.03',
              'threads'               => '1.03',
              'utf8'                  => '1.03',
          },
          removed => {
          }
      },
      5.008005 => {
          delta_from => 5.008004,
          changed => {
              'B::Concise'            => '0.61',
              'B::Deparse'            => '0.67',
              'CGI'                   => '3.05',
              'CGI::Carp'             => '1.28',
              'CGI::Util'             => '1.5',
              'Carp'                  => '1.03',
              'Carp::Heavy'           => '1.03',
              'Cwd'                   => '2.19',
              'DB_File'               => '1.809',
              'Digest'                => '1.08',
              'Encode'                => '2.01',
              'Encode::Alias'         => '2.00',
              'Encode::Byte'          => '2.00',
              'Encode::CJKConstants'  => '2.00',
              'Encode::CN'            => '2.00',
              'Encode::CN::HZ'        => '2.01',
              'Encode::Config'        => '2.00',
              'Encode::EBCDIC'        => '2.00',
              'Encode::Encoder'       => '2.00',
              'Encode::Encoding'      => '2.00',
              'Encode::Guess'         => '2.00',
              'Encode::JP'            => '2.00',
              'Encode::JP::H2Z'       => '2.00',
              'Encode::JP::JIS7'      => '2.00',
              'Encode::KR'            => '2.00',
              'Encode::KR::2022_KR'   => '2.00',
              'Encode::MIME::Header'  => '2.00',
              'Encode::Symbol'        => '2.00',
              'Encode::TW'            => '2.00',
              'Encode::Unicode'       => '2.00',
              'Encode::Unicode::UTF7' => '2.01',
              'File::Basename'        => '2.73',
              'File::Copy'            => '2.08',
              'File::Glob'            => '1.03',
              'FileCache'             => '1.04_01',
              'I18N::LangTags'        => '0.33',
              'I18N::LangTags::Detect'=> '1.03',
              'List::Util'            => '1.14',
              'Locale::Constants'     => '2.07',
              'Locale::Country'       => '2.07',
              'Locale::Currency'      => '2.07',
              'Locale::Language'      => '2.07',
              'Locale::Maketext'      => '1.09',
              'Locale::Script'        => '2.07',
              'Net::Cmd'              => '2.26',
              'Net::FTP'              => '2.75',
              'Net::NNTP'             => '2.23',
              'Net::POP3'             => '2.28',
              'Net::SMTP'             => '2.29',
              'Net::Time'             => '2.10',
              'Pod::Checker'          => '1.42',
              'Pod::Find'             => '0.2401',
              'Pod::LaTeX'            => '0.56',
              'Pod::ParseUtils'       => '1.2',
              'Pod::Perldoc'          => '3.13',
              'Safe'                  => '2.11',
              'Scalar::Util'          => '1.14',
              'Shell'                 => '0.6',
              'Storable'              => '2.13',
              'Term::Cap'             => '1.09',
              'Test'                  => '1.25',
              'Test::Harness'         => '2.42',
              'Text::ParseWords'      => '3.22',
              'Text::Wrap'            => '2001.09292',
              'Time::Local'           => '1.10',
              'Unicode::Collate'      => '0.40',
              'Unicode::Normalize'    => '0.30',
              'XS::APItest'           => '0.04',
              'autouse'               => '1.04',
              'base'                  => '2.06',
              'charnames'             => '1.04',
              'diagnostics'           => '1.13',
              'encoding'              => '2.00',
              'threads'               => '1.05',
              'utf8'                  => '1.04',
          },
          removed => {
          }
      },
      5.008006 => {
          delta_from => 5.008005,
          changed => {
              'B'                     => '1.07',
              'B::C'                  => '1.04',
              'B::Concise'            => '0.64',
              'B::Debug'              => '1.02',
              'B::Deparse'            => '0.69',
              'B::Lint'               => '1.03',
              'B::Showlex'            => '1.02',
              'Cwd'                   => '3.01',
              'DB_File'               => '1.810',
              'Data::Dumper'          => '2.121_02',
              'Devel::PPPort'         => '3.03',
              'Devel::Peek'           => '1.02',
              'Encode'                => '2.08',
              'Encode::Alias'         => '2.02',
              'Encode::Encoding'      => '2.02',
              'Encode::JP'            => '2.01',
              'Encode::Unicode'       => '2.02',
              'Exporter::Heavy'       => '5.58',
              'ExtUtils::Constant'    => '0.1401',
              'File::Spec'            => '3.01',
              'File::Spec::Win32'     => '1.5',
              'I18N::LangTags'        => '0.35',
              'I18N::LangTags::List'  => '0.35',
              'MIME::Base64'          => '3.05',
              'MIME::QuotedPrint'     => '3.03',
              'Math::BigFloat'        => '1.47',
              'Math::BigInt'          => '1.73',
              'Math::BigInt::Calc'    => '0.43',
              'Math::BigRat'          => '0.13',
              'Text::ParseWords'      => '3.23',
              'Time::HiRes'           => '1.65',
              'XS::APItest'           => '0.05',
              'diagnostics'           => '1.14',
              'encoding'              => '2.01',
              'open'                  => '1.04',
              'overload'              => '1.02',
          },
          removed => {
          }
      },
      5.008007 => {
          delta_from => 5.008006,
          changed => {
              'B'                     => '1.09',
              'B::Concise'            => '0.65',
              'B::Deparse'            => '0.7',
              'B::Disassembler'       => '1.04',
              'B::Terse'              => '1.03',
              'Benchmark'             => '1.07',
              'CGI'                   => '3.10',
              'CGI::Carp'             => '1.29',
              'CGI::Cookie'           => '1.25',
              'Carp'                  => '1.04',
              'Carp::Heavy'           => '1.04',
              'Class::ISA'            => '0.33',
              'Cwd'                   => '3.05',
              'DB_File'               => '1.811',
              'Data::Dumper'          => '2.121_04',
              'Devel::DProf'          => '20050310.00',
              'Devel::PPPort'         => '3.06',
              'Digest'                => '1.10',
              'Digest::file'          => '0.01',
              'Encode'                => '2.10',
              'Encode::Alias'         => '2.03',
              'Errno'                 => '1.09_01',
              'ExtUtils::Constant'    => '0.16',
              'ExtUtils::Constant::Base'=> '0.01',
              'ExtUtils::Constant::Utils'=> '0.01',
              'ExtUtils::Constant::XS'=> '0.01',
              'File::Find'            => '1.09',
              'File::Glob'            => '1.04',
              'File::Path'            => '1.07',
              'File::Spec'            => '3.05',
              'File::Temp'            => '0.16',
              'FileCache'             => '1.05',
              'IO::File'              => '1.11',
              'IO::Socket::INET'      => '1.28',
              'Math::BigFloat'        => '1.51',
              'Math::BigInt'          => '1.77',
              'Math::BigInt::Calc'    => '0.47',
              'Math::BigInt::CalcEmu' => '0.05',
              'Math::BigRat'          => '0.15',
              'Pod::Find'             => '1.3',
              'Pod::Html'             => '1.0503',
              'Pod::InputObjects'     => '1.3',
              'Pod::LaTeX'            => '0.58',
              'Pod::ParseUtils'       => '1.3',
              'Pod::Parser'           => '1.3',
              'Pod::Perldoc'          => '3.14',
              'Pod::Select'           => '1.3',
              'Pod::Usage'            => '1.3',
              'SelectSaver'           => '1.01',
              'Symbol'                => '1.06',
              'Sys::Syslog'           => '0.06',
              'Term::ANSIColor'       => '1.09',
              'Term::Complete'        => '1.402',
              'Test::Builder'         => '0.22',
              'Test::Harness'         => '2.48',
              'Test::Harness::Point'  => '0.01',
              'Test::Harness::Straps' => '0.23',
              'Test::More'            => '0.54',
              'Test::Simple'          => '0.54',
              'Text::ParseWords'      => '3.24',
              'Text::Wrap'            => '2001.09293',
              'Tie::RefHash'          => '1.32',
              'Time::HiRes'           => '1.66',
              'Time::Local'           => '1.11',
              'Unicode'               => '4.1.0',
              'Unicode::Normalize'    => '0.32',
              'Unicode::UCD'          => '0.23',
              'Win32'                 => '0.24',
              'XS::APItest'           => '0.06',
              'base'                  => '2.07',
              'bigint'                => '0.07',
              'bignum'                => '0.17',
              'bigrat'                => '0.08',
              'bytes'                 => '1.02',
              'constant'              => '1.05',
              'overload'              => '1.03',
              'threads::shared'       => '0.93',
              'utf8'                  => '1.05',
          },
          removed => {
              'JNI'                   => 1,
              'JPL::AutoLoader'       => 1,
              'JPL::Class'            => 1,
              'JPL::Compile'          => 1,
          }
      },
      5.008008 => {
          delta_from => 5.008007,
          changed => {
              'Attribute::Handlers'   => '0.78_02',
              'B'                     => '1.09_01',
              'B::Bblock'             => '1.02_01',
              'B::Bytecode'           => '1.01_01',
              'B::C'                  => '1.04_01',
              'B::CC'                 => '1.00_01',
              'B::Concise'            => '0.66',
              'B::Debug'              => '1.02_01',
              'B::Deparse'            => '0.71',
              'B::Disassembler'       => '1.05',
              'B::Terse'              => '1.03_01',
              'ByteLoader'            => '0.06',
              'CGI'                   => '3.15',
              'CGI::Cookie'           => '1.26',
              'CPAN'                  => '1.76_02',
              'Cwd'                   => '3.12',
              'DB'                    => '1.01',
              'DB_File'               => '1.814',
              'Data::Dumper'          => '2.121_08',
              'Devel::DProf'          => '20050603.00',
              'Devel::PPPort'         => '3.06_01',
              'Devel::Peek'           => '1.03',
              'Digest'                => '1.14',
              'Digest::MD5'           => '2.36',
              'Digest::file'          => '1.00',
              'Dumpvalue'             => '1.12',
              'Encode'                => '2.12',
              'Encode::Alias'         => '2.04',
              'Encode::Config'        => '2.01',
              'Encode::MIME::Header'  => '2.01',
              'Encode::MIME::Header::ISO_2022_JP'=> '1.01',
              'English'               => '1.02',
              'ExtUtils::Command'     => '1.09',
              'ExtUtils::Command::MM' => '0.05',
              'ExtUtils::Constant'    => '0.17',
              'ExtUtils::Embed'       => '1.26',
              'ExtUtils::Install'     => '1.33',
              'ExtUtils::Liblist::Kid'=> '1.3',
              'ExtUtils::MM'          => '0.05',
              'ExtUtils::MM_AIX'      => '0.03',
              'ExtUtils::MM_Any'      => '0.13',
              'ExtUtils::MM_BeOS'     => '1.05',
              'ExtUtils::MM_Cygwin'   => '1.08',
              'ExtUtils::MM_MacOS'    => '1.08',
              'ExtUtils::MM_NW5'      => '2.08',
              'ExtUtils::MM_OS2'      => '1.05',
              'ExtUtils::MM_QNX'      => '0.02',
              'ExtUtils::MM_Unix'     => '1.50',
              'ExtUtils::MM_VMS'      => '5.73',
              'ExtUtils::MM_VOS'      => '0.02',
              'ExtUtils::MM_Win32'    => '1.12',
              'ExtUtils::MM_Win95'    => '0.04',
              'ExtUtils::MakeMaker'   => '6.30',
              'ExtUtils::MakeMaker::Config'=> '0.02',
              'ExtUtils::Manifest'    => '1.46',
              'File::Basename'        => '2.74',
              'File::Copy'            => '2.09',
              'File::Find'            => '1.10',
              'File::Glob'            => '1.05',
              'File::Path'            => '1.08',
              'File::Spec'            => '3.12',
              'File::Spec::Win32'     => '1.6',
              'FileCache'             => '1.06',
              'Filter::Simple'        => '0.82',
              'FindBin'               => '1.47',
              'GDBM_File'             => '1.08',
              'Getopt::Long'          => '2.35',
              'IO'                    => '1.22',
              'IO::Dir'               => '1.05',
              'IO::File'              => '1.13',
              'IO::Handle'            => '1.25',
              'IO::Pipe'              => '1.13',
              'IO::Poll'              => '0.07',
              'IO::Seekable'          => '1.10',
              'IO::Select'            => '1.17',
              'IO::Socket'            => '1.29',
              'IO::Socket::INET'      => '1.29',
              'IO::Socket::UNIX'      => '1.22',
              'IPC::Open2'            => '1.02',
              'IPC::Open3'            => '1.02',
              'List::Util'            => '1.18',
              'MIME::Base64'          => '3.07',
              'MIME::QuotedPrint'     => '3.07',
              'Math::Complex'         => '1.35',
              'Math::Trig'            => '1.03',
              'NDBM_File'             => '1.06',
              'ODBM_File'             => '1.06',
              'OS2::PrfDB'            => '0.04',
              'OS2::Process'          => '1.02',
              'OS2::REXX'             => '1.03',
              'Opcode'                => '1.06',
              'POSIX'                 => '1.09',
              'PerlIO'                => '1.04',
              'PerlIO::encoding'      => '0.09',
              'PerlIO::scalar'        => '0.04',
              'PerlIO::via'           => '0.03',
              'Pod::Checker'          => '1.43',
              'Pod::Find'             => '1.34',
              'Pod::Functions'        => '1.03',
              'Pod::Html'             => '1.0504',
              'Pod::ParseUtils'       => '1.33',
              'Pod::Parser'           => '1.32',
              'Pod::Usage'            => '1.33',
              'SDBM_File'             => '1.05',
              'Safe'                  => '2.12',
              'Scalar::Util'          => '1.18',
              'Socket'                => '1.78',
              'Storable'              => '2.15',
              'Switch'                => '2.10_01',
              'Sys::Syslog'           => '0.13',
              'Term::ANSIColor'       => '1.10',
              'Term::ReadLine'        => '1.02',
              'Test::Builder'         => '0.32',
              'Test::Builder::Module' => '0.02',
              'Test::Builder::Tester' => '1.02',
              'Test::Builder::Tester::Color'=> undef,
              'Test::Harness'         => '2.56',
              'Test::Harness::Straps' => '0.26',
              'Test::More'            => '0.62',
              'Test::Simple'          => '0.62',
              'Text::Tabs'            => '2005.0824',
              'Text::Wrap'            => '2005.082401',
              'Tie::Hash'             => '1.02',
              'Time::HiRes'           => '1.86',
              'Unicode::Collate'      => '0.52',
              'Unicode::UCD'          => '0.24',
              'User::grent'           => '1.01',
              'Win32'                 => '0.2601',
              'XS::APItest'           => '0.08',
              'XS::Typemap'           => '0.02',
              'XSLoader'              => '0.06',
              'attrs'                 => '1.02',
              'autouse'               => '1.05',
              'blib'                  => '1.03',
              'charnames'             => '1.05',
              'diagnostics'           => '1.15',
              'encoding'              => '2.02',
              'if'                    => '0.05',
              'open'                  => '1.05',
              'ops'                   => '1.01',
              'overload'              => '1.04',
              're'                    => '0.05',
              'threads'               => '1.07',
              'threads::shared'       => '0.94',
              'utf8'                  => '1.06',
              'vmsish'                => '1.02',
              'warnings'              => '1.05',
              'warnings::register'    => '1.01',
          },
          removed => {
          }
      },
      5.008009 => {
          delta_from => 5.008008,
          changed => {
              'Attribute::Handlers'   => '0.78_03',
              'AutoLoader'            => '5.67',
              'AutoSplit'             => '1.06',
              'B'                     => '1.19',
              'B::Asmdata'            => '1.02',
              'B::Assembler'          => '0.08',
              'B::C'                  => '1.05',
              'B::Concise'            => '0.76',
              'B::Debug'              => '1.05',
              'B::Deparse'            => '0.87',
              'B::Lint'               => '1.11',
              'B::Lint::Debug'        => undef,
              'B::Terse'              => '1.05',
              'Benchmark'             => '1.1',
              'CGI'                   => '3.42',
              'CGI::Carp'             => '1.30_01',
              'CGI::Cookie'           => '1.29',
              'CGI::Fast'             => '1.07',
              'CGI::Util'             => '1.5_01',
              'CPAN'                  => '1.9301',
              'CPAN::Debug'           => '5.5',
              'CPAN::DeferedCode'     => '5.50',
              'CPAN::Distroprefs'     => '6',
              'CPAN::FirstTime'       => '5.5_01',
              'CPAN::HandleConfig'    => '5.5',
              'CPAN::Kwalify'         => '5.50',
              'CPAN::Nox'             => '5.50',
              'CPAN::Queue'           => '5.5',
              'CPAN::Tarzip'          => '5.5',
              'CPAN::Version'         => '5.5',
              'Carp'                  => '1.10',
              'Carp::Heavy'           => '1.10',
              'Cwd'                   => '3.29',
              'DBM_Filter'            => '0.02',
              'DBM_Filter::compress'  => '0.02',
              'DBM_Filter::encode'    => '0.02',
              'DBM_Filter::int32'     => '0.02',
              'DBM_Filter::null'      => '0.02',
              'DBM_Filter::utf8'      => '0.02',
              'DB_File'               => '1.817',
              'Data::Dumper'          => '2.121_17',
              'Devel::DProf'          => '20080331.00',
              'Devel::InnerPackage'   => '0.3',
              'Devel::PPPort'         => '3.14',
              'Devel::Peek'           => '1.04',
              'Digest'                => '1.15',
              'Digest::MD5'           => '2.37',
              'DirHandle'             => '1.02',
              'DynaLoader'            => '1.09',
              'Encode'                => '2.26',
              'Encode::Alias'         => '2.10',
              'Encode::Byte'          => '2.03',
              'Encode::CJKConstants'  => '2.02',
              'Encode::CN'            => '2.02',
              'Encode::CN::HZ'        => '2.05',
              'Encode::Config'        => '2.05',
              'Encode::EBCDIC'        => '2.02',
              'Encode::Encoder'       => '2.01',
              'Encode::Encoding'      => '2.05',
              'Encode::GSM0338'       => '2.01',
              'Encode::Guess'         => '2.02',
              'Encode::JP'            => '2.03',
              'Encode::JP::H2Z'       => '2.02',
              'Encode::JP::JIS7'      => '2.04',
              'Encode::KR'            => '2.02',
              'Encode::KR::2022_KR'   => '2.02',
              'Encode::MIME::Header'  => '2.05',
              'Encode::MIME::Header::ISO_2022_JP'=> '1.03',
              'Encode::MIME::Name'    => '1.01',
              'Encode::Symbol'        => '2.02',
              'Encode::TW'            => '2.02',
              'Encode::Unicode'       => '2.05',
              'Encode::Unicode::UTF7' => '2.04',
              'English'               => '1.03',
              'Errno'                 => '1.10',
              'Exporter'              => '5.63',
              'Exporter::Heavy'       => '5.63',
              'ExtUtils::Command'     => '1.15',
              'ExtUtils::Command::MM' => '6.48',
              'ExtUtils::Constant'    => '0.21',
              'ExtUtils::Constant::Base'=> '0.04',
              'ExtUtils::Constant::ProxySubs'=> '0.06',
              'ExtUtils::Constant::Utils'=> '0.02',
              'ExtUtils::Constant::XS'=> '0.02',
              'ExtUtils::Embed'       => '1.28',
              'ExtUtils::Install'     => '1.50_01',
              'ExtUtils::Installed'   => '1.43',
              'ExtUtils::Liblist'     => '6.48',
              'ExtUtils::Liblist::Kid'=> '6.48',
              'ExtUtils::MM'          => '6.48',
              'ExtUtils::MM_AIX'      => '6.48',
              'ExtUtils::MM_Any'      => '6.48',
              'ExtUtils::MM_BeOS'     => '6.48',
              'ExtUtils::MM_Cygwin'   => '6.48',
              'ExtUtils::MM_DOS'      => '6.48',
              'ExtUtils::MM_Darwin'   => '6.48',
              'ExtUtils::MM_MacOS'    => '6.48',
              'ExtUtils::MM_NW5'      => '6.48',
              'ExtUtils::MM_OS2'      => '6.48',
              'ExtUtils::MM_QNX'      => '6.48',
              'ExtUtils::MM_UWIN'     => '6.48',
              'ExtUtils::MM_Unix'     => '6.48',
              'ExtUtils::MM_VMS'      => '6.48',
              'ExtUtils::MM_VOS'      => '6.48',
              'ExtUtils::MM_Win32'    => '6.48',
              'ExtUtils::MM_Win95'    => '6.48',
              'ExtUtils::MY'          => '6.48',
              'ExtUtils::MakeMaker'   => '6.48',
              'ExtUtils::MakeMaker::Config'=> '6.48',
              'ExtUtils::MakeMaker::bytes'=> '6.48',
              'ExtUtils::MakeMaker::vmsish'=> '6.48',
              'ExtUtils::Manifest'    => '1.55',
              'ExtUtils::Mkbootstrap' => '6.48',
              'ExtUtils::Mksymlists'  => '6.48',
              'ExtUtils::Packlist'    => '1.43',
              'ExtUtils::ParseXS'     => '2.19',
              'ExtUtils::XSSymSet'    => '1.1',
              'ExtUtils::testlib'     => '6.48',
              'Fatal'                 => '1.06',
              'Fcntl'                 => '1.06',
              'File::Basename'        => '2.77',
              'File::CheckTree'       => '4.4',
              'File::Compare'         => '1.1005',
              'File::Copy'            => '2.13',
              'File::DosGlob'         => '1.01',
              'File::Find'            => '1.13',
              'File::Glob'            => '1.06',
              'File::Path'            => '2.07_02',
              'File::Spec'            => '3.29',
              'File::Spec::Cygwin'    => '3.29',
              'File::Spec::Epoc'      => '3.29',
              'File::Spec::Functions' => '3.29',
              'File::Spec::Mac'       => '3.29',
              'File::Spec::OS2'       => '3.29',
              'File::Spec::Unix'      => '3.29',
              'File::Spec::VMS'       => '3.29',
              'File::Spec::Win32'     => '3.29',
              'File::Temp'            => '0.20',
              'File::stat'            => '1.01',
              'FileCache'             => '1.07',
              'Filter::Simple'        => '0.83',
              'Filter::Util::Call'    => '1.07',
              'FindBin'               => '1.49',
              'GDBM_File'             => '1.09',
              'Getopt::Long'          => '2.37',
              'Getopt::Std'           => '1.06',
              'Hash::Util'            => '0.06',
              'IO'                    => '1.23',
              'IO::Dir'               => '1.06',
              'IO::File'              => '1.14',
              'IO::Handle'            => '1.27',
              'IO::Socket'            => '1.30',
              'IO::Socket::INET'      => '1.31',
              'IO::Socket::UNIX'      => '1.23',
              'IPC::Msg'              => '2.00',
              'IPC::Open2'            => '1.03',
              'IPC::Open3'            => '1.03',
              'IPC::Semaphore'        => '2.00',
              'IPC::SharedMem'        => '2.00',
              'IPC::SysV'             => '2.00',
              'List::Util'            => '1.19',
              'Locale::Maketext'      => '1.13',
              'Locale::Maketext::Guts'=> '1.13',
              'Locale::Maketext::GutsLoader'=> '1.13',
              'Math::BigFloat'        => '1.60',
              'Math::BigInt'          => '1.89',
              'Math::BigInt::Calc'    => '0.52',
              'Math::BigRat'          => '0.22',
              'Math::Complex'         => '1.54',
              'Math::Trig'            => '1.18',
              'Module::CoreList'      => '2.17',
              'Module::Pluggable'     => '3.8',
              'Module::Pluggable::Object'=> '3.6',
              'NDBM_File'             => '1.07',
              'NEXT'                  => '0.61',
              'Net::Cmd'              => '2.29',
              'Net::Config'           => '1.11',
              'Net::Domain'           => '2.20',
              'Net::FTP'              => '2.77',
              'Net::FTP::A'           => '1.18',
              'Net::NNTP'             => '2.24',
              'Net::POP3'             => '2.29',
              'Net::Ping'             => '2.35',
              'Net::SMTP'             => '2.31',
              'O'                     => '1.01',
              'ODBM_File'             => '1.07',
              'OS2::DLL'              => '1.03',
              'OS2::Process'          => '1.03',
              'Opcode'                => '1.0601',
              'POSIX'                 => '1.15',
              'PerlIO'                => '1.05',
              'PerlIO::encoding'      => '0.11',
              'PerlIO::scalar'        => '0.06',
              'PerlIO::via'           => '0.05',
              'Pod::Html'             => '1.09',
              'Pod::ParseUtils'       => '1.35',
              'Pod::Parser'           => '1.35',
              'Pod::Select'           => '1.35',
              'Pod::Usage'            => '1.35',
              'SDBM_File'             => '1.06',
              'Safe'                  => '2.16',
              'Scalar::Util'          => '1.19',
              'SelfLoader'            => '1.17',
              'Shell'                 => '0.72',
              'Socket'                => '1.81',
              'Storable'              => '2.19',
              'Switch'                => '2.13',
              'Sys::Syslog'           => '0.27',
              'Sys::Syslog::win32::Win32'=> undef,
              'Term::ANSIColor'       => '1.12',
              'Term::Cap'             => '1.12',
              'Term::ReadLine'        => '1.03',
              'Test::Builder'         => '0.80',
              'Test::Builder::Module' => '0.80',
              'Test::Builder::Tester' => '1.13',
              'Test::Harness'         => '2.64',
              'Test::Harness::Results'=> '0.01_01',
              'Test::Harness::Straps' => '0.26_01',
              'Test::Harness::Util'   => '0.01',
              'Test::More'            => '0.80',
              'Test::Simple'          => '0.80',
              'Text::Balanced'        => '1.98',
              'Text::ParseWords'      => '3.27',
              'Text::Soundex'         => '3.03',
              'Text::Tabs'            => '2007.1117',
              'Text::Wrap'            => '2006.1117',
              'Thread'                => '2.01',
              'Thread::Queue'         => '2.11',
              'Thread::Semaphore'     => '2.09',
              'Tie::Handle'           => '4.2',
              'Tie::Hash'             => '1.03',
              'Tie::Memoize'          => '1.1',
              'Tie::RefHash'          => '1.38',
              'Tie::Scalar'           => '1.01',
              'Tie::StdHandle'        => '4.2',
              'Time::HiRes'           => '1.9715',
              'Time::Local'           => '1.1901',
              'Time::gmtime'          => '1.03',
              'Unicode'               => '5.1.0',
              'Unicode::Normalize'    => '1.02',
              'Unicode::UCD'          => '0.25',
              'VMS::DCLsym'           => '1.03',
              'VMS::Stdio'            => '2.4',
              'Win32'                 => '0.38',
              'Win32API::File'        => '0.1001_01',
              'Win32API::File::ExtUtils::Myconst2perl'=> '1',
              'Win32CORE'             => '0.02',
              'XS::APItest'           => '0.15',
              'XS::Typemap'           => '0.03',
              'XSLoader'              => '0.10',
              'attributes'            => '0.09',
              'autouse'               => '1.06',
              'base'                  => '2.13',
              'bigint'                => '0.23',
              'bignum'                => '0.23',
              'bigrat'                => '0.23',
              'blib'                  => '1.04',
              'charnames'             => '1.06',
              'constant'              => '1.17',
              'diagnostics'           => '1.16',
              'encoding'              => '2.6_01',
              'fields'                => '2.12',
              'filetest'              => '1.02',
              'lib'                   => '0.61',
              'open'                  => '1.06',
              'ops'                   => '1.02',
              'overload'              => '1.06',
              're'                    => '0.0601',
              'sigtrap'               => '1.04',
              'threads'               => '1.71',
              'threads::shared'       => '1.27',
              'utf8'                  => '1.07',
              'warnings'              => '1.05_01',
          },
          removed => {
          }
      },
      5.009 => {
          delta_from => 5.008002,
          changed => {
              'B'                     => '1.03',
              'B::C'                  => '1.03',
              'B::Concise'            => '0.57',
              'B::Deparse'            => '0.65',
              'DB_File'               => '1.806',
              'Devel::PPPort'         => '2.008',
              'English'               => '1.02',
              'Fatal'                 => '1.04',
              'OS2::DLL'              => '1.02',
              'Opcode'                => '1.06',
              'Time::HiRes'           => '1.51',
              'Unicode::Collate'      => '0.28',
              'Unicode::Normalize'    => '0.23',
              'XSLoader'              => '0.03',
              'assertions'            => '0.01',
              'assertions::activate'  => '0.01',
              'overload'              => '1.02',
              'version'               => '0.29',
          },
          removed => {
          }
      },
      5.009001 => {
          delta_from => 5.008004,
          changed => {
              'B'                     => '1.05',
              'B::Assembler'          => '0.06',
              'B::C'                  => '1.04',
              'B::Concise'            => '0.59',
              'B::Debug'              => '1.02',
              'B::Deparse'            => '0.65',
              'DB_File'               => '1.808_01',
              'Devel::PPPort'         => '2.011_01',
              'Digest'                => '1.05',
              'DynaLoader'            => '1.04',
              'English'               => '1.02',
              'Exporter::Heavy'       => '5.567',
              'ExtUtils::Command'     => '1.07',
              'ExtUtils::Liblist::Kid'=> '1.3',
              'ExtUtils::MM_Any'      => '0.0901',
              'ExtUtils::MM_Cygwin'   => '1.07',
              'ExtUtils::MM_NW5'      => '2.07_01',
              'ExtUtils::MM_Unix'     => '1.45_01',
              'ExtUtils::MM_VMS'      => '5.71_01',
              'ExtUtils::MM_Win32'    => '1.10_01',
              'ExtUtils::MM_Win95'    => '0.03',
              'ExtUtils::MakeMaker'   => '6.21_02',
              'ExtUtils::Manifest'    => '1.43',
              'Fatal'                 => '1.04',
              'Getopt::Long'          => '2.3401',
              'IO::Handle'            => '1.23',
              'IO::Pipe'              => '1.122',
              'IPC::Open3'            => '1.0105',
              'MIME::Base64'          => '3.00_01',
              'MIME::QuotedPrint'     => '3.00',
              'Memoize'               => '1.01_01',
              'ODBM_File'             => '1.04',
              'Opcode'                => '1.06',
              'POSIX'                 => '1.07',
              'Storable'              => '2.11',
              'Time::HiRes'           => '1.56',
              'Time::Local'           => '1.07_94',
              'UNIVERSAL'             => '1.02',
              'Unicode'               => '4.0.0',
              'Unicode::UCD'          => '0.21',
              'XSLoader'              => '0.03',
              'assertions'            => '0.01',
              'assertions::activate'  => '0.01',
              'base'                  => '2.04',
              'if'                    => '0.0401',
              'open'                  => '1.02',
              'overload'              => '1.02',
              'threads'               => '1.02',
              'utf8'                  => '1.02',
              'version'               => '0.36',
          },
          removed => {
          }
      },
      5.009002 => {
          delta_from => 5.008007,
          changed => {
              'B'                     => '1.07',
              'B::Concise'            => '0.64',
              'B::Deparse'            => '0.69',
              'B::Disassembler'       => '1.03',
              'B::Terse'              => '1.02',
              'CGI'                   => '3.07',
              'Config::Extensions'    => '0.01',
              'Devel::DProf'          => '20030813.00',
              'DynaLoader'            => '1.07',
              'Encode'                => '2.09',
              'Encode::Alias'         => '2.02',
              'English'               => '1.03',
              'Exporter'              => '5.59',
              'Exporter::Heavy'       => '5.59',
              'ExtUtils::Command'     => '1.07',
              'ExtUtils::Command::MM' => '0.03_01',
              'ExtUtils::Embed'       => '1.26',
              'ExtUtils::Liblist::Kid'=> '1.3',
              'ExtUtils::MM_Any'      => '0.10',
              'ExtUtils::MM_Cygwin'   => '1.07',
              'ExtUtils::MM_MacOS'    => '1.08',
              'ExtUtils::MM_NW5'      => '2.07',
              'ExtUtils::MM_Unix'     => '1.46_01',
              'ExtUtils::MM_VMS'      => '5.71',
              'ExtUtils::MM_Win32'    => '1.10',
              'ExtUtils::MM_Win95'    => '0.03',
              'ExtUtils::MakeMaker'   => '6.25',
              'ExtUtils::Manifest'    => '1.44',
              'Fatal'                 => '1.04',
              'File::Path'            => '1.06',
              'FileCache'             => '1.04_01',
              'Getopt::Long'          => '2.3401',
              'IO::File'              => '1.10',
              'IO::Socket::INET'      => '1.27',
              'Math::BigFloat'        => '1.49',
              'Math::BigInt'          => '1.75',
              'Math::BigInt::Calc'    => '0.45',
              'Math::BigRat'          => '0.14',
              'Memoize'               => '1.01_01',
              'Module::CoreList'      => '1.99',
              'NEXT'                  => '0.60_01',
              'Opcode'                => '1.06',
              'Pod::Html'             => '1.0502',
              'Scalar::Util'          => '1.14_1',
              'Storable'              => '2.14',
              'Symbol'                => '1.05',
              'Test::Harness'         => '2.46',
              'Test::Harness::Straps' => '0.20_01',
              'Text::Balanced'        => '1.95_01',
              'Text::Wrap'            => '2001.09292',
              'UNIVERSAL'             => '1.02',
              'Unicode'               => '4.0.1',
              'Unicode::Normalize'    => '0.30',
              'Unicode::UCD'          => '0.22',
              'Win32'                 => '0.23',
              'XS::APItest'           => '0.05',
              'XSLoader'              => '0.03',
              'assertions'            => '0.01',
              'assertions::activate'  => '0.01',
              'base'                  => '2.06',
              'bigint'                => '0.06',
              'bignum'                => '0.16',
              'bigrat'                => '0.07',
              'bytes'                 => '1.01',
              'encoding::warnings'    => '0.05',
              'if'                    => '0.0401',
              're'                    => '0.05',
              'threads::shared'       => '0.92',
              'utf8'                  => '1.04',
              'version'               => '0.42',
              'warnings'              => '1.04',
          },
          removed => {
              'Test::Harness::Point'  => 1,
          }
      },
      5.009003 => {
          delta_from => 5.008008,
          changed => {
              'Archive::Tar'          => '1.26_01',
              'Archive::Tar::Constant'=> '0.02',
              'Archive::Tar::File'    => '0.02',
              'AutoSplit'             => '1.04_01',
              'B'                     => '1.10',
              'B::Bblock'             => '1.02',
              'B::Bytecode'           => '1.01',
              'B::C'                  => '1.04',
              'B::CC'                 => '1.00',
              'B::Concise'            => '0.67',
              'B::Debug'              => '1.02',
              'B::Deparse'            => '0.73',
              'B::Lint'               => '1.04',
              'B::Terse'              => '1.03',
              'CGI'                   => '3.15_01',
              'CPAN'                  => '1.83_58',
              'CPAN::Debug'           => '4.44',
              'CPAN::FirstTime'       => '4.50',
              'CPAN::HandleConfig'    => '4.31',
              'CPAN::Nox'             => '2.31',
              'CPAN::Tarzip'          => '3.36',
              'CPAN::Version'         => '2.55',
              'Carp'                  => '1.05',
              'Carp::Heavy'           => '1.05',
              'Compress::Zlib'        => '2.000_07',
              'Compress::Zlib::Common'=> '2.000_07',
              'Compress::Zlib::Compress::Gzip::Constants'=> '2.000_07',
              'Compress::Zlib::Compress::Zip::Constants'=> '1.00',
              'Compress::Zlib::CompressPlugin::Deflate'=> '2.000_05',
              'Compress::Zlib::CompressPlugin::Identity'=> '2.000_05',
              'Compress::Zlib::File::GlobMapper'=> '0.000_02',
              'Compress::Zlib::FileConstants'=> '2.000_07',
              'Compress::Zlib::IO::Compress::Base'=> '2.000_05',
              'Compress::Zlib::IO::Compress::Deflate'=> '2.000_07',
              'Compress::Zlib::IO::Compress::Gzip'=> '2.000_07',
              'Compress::Zlib::IO::Compress::RawDeflate'=> '2.000_07',
              'Compress::Zlib::IO::Compress::Zip'=> '2.000_04',
              'Compress::Zlib::IO::Uncompress::AnyInflate'=> '2.000_07',
              'Compress::Zlib::IO::Uncompress::AnyUncompress'=> '2.000_05',
              'Compress::Zlib::IO::Uncompress::Base'=> '2.000_05',
              'Compress::Zlib::IO::Uncompress::Gunzip'=> '2.000_07',
              'Compress::Zlib::IO::Uncompress::Inflate'=> '2.000_07',
              'Compress::Zlib::IO::Uncompress::RawInflate'=> '2.000_07',
              'Compress::Zlib::IO::Uncompress::Unzip'=> '2.000_05',
              'Compress::Zlib::ParseParameters'=> '2.000_07',
              'Compress::Zlib::UncompressPlugin::Identity'=> '2.000_05',
              'Compress::Zlib::UncompressPlugin::Inflate'=> '2.000_05',
              'Config::Extensions'    => '0.01',
              'Cwd'                   => '3.15',
              'Devel::PPPort'         => '3.08',
              'Digest::SHA'           => '5.32',
              'DirHandle'             => '1.01',
              'DynaLoader'            => '1.07',
              'Encode'                => '2.14',
              'Encode::CN::HZ'        => '2.02',
              'Encode::MIME::Header'  => '2.02',
              'English'               => '1.04',
              'Exporter'              => '5.59',
              'Exporter::Heavy'       => '5.59',
              'ExtUtils::CBuilder'    => '0.15',
              'ExtUtils::CBuilder::Base'=> '0.12',
              'ExtUtils::CBuilder::Platform::Unix'=> '0.12',
              'ExtUtils::CBuilder::Platform::VMS'=> '0.12',
              'ExtUtils::CBuilder::Platform::Windows'=> '0.12',
              'ExtUtils::CBuilder::Platform::aix'=> '0.12',
              'ExtUtils::CBuilder::Platform::cygwin'=> '0.12',
              'ExtUtils::CBuilder::Platform::darwin'=> '0.12',
              'ExtUtils::CBuilder::Platform::dec_osf'=> '0.01',
              'ExtUtils::CBuilder::Platform::os2'=> '0.13',
              'ExtUtils::Command::MM' => '0.05_01',
              'ExtUtils::Constant'    => '0.2',
              'ExtUtils::Constant::Base'=> '0.02',
              'ExtUtils::Constant::ProxySubs'=> '0.01',
              'ExtUtils::Constant::XS'=> '0.02',
              'ExtUtils::MM_Any'      => '0.13_01',
              'ExtUtils::MM_Unix'     => '1.50_01',
              'ExtUtils::MakeMaker'   => '6.30_01',
              'ExtUtils::ParseXS'     => '2.15_02',
              'Fatal'                 => '1.04',
              'File::Compare'         => '1.1005',
              'File::Spec'            => '3.15',
              'File::Temp'            => '0.16_01',
              'IO::File'              => '1.13_01',
              'IO::Handle'            => '1.26',
              'IO::Socket'            => '1.29_01',
              'IO::Socket::INET'      => '1.29_02',
              'IO::Socket::UNIX'      => '1.22_01',
              'IO::Zlib'              => '1.04_02',
              'Locale::Maketext'      => '1.10_01',
              'Math::BigInt::FastCalc'=> '0.10',
              'Memoize'               => '1.01_01',
              'Module::CoreList'      => '2.02',
              'Moped::Msg'            => '0.01',
              'NEXT'                  => '0.60_01',
              'Net::Cmd'              => '2.26_01',
              'Net::Domain'           => '2.19_01',
              'Net::Ping'             => '2.31_04',
              'Opcode'                => '1.08',
              'POSIX'                 => '1.10',
              'Pod::Escapes'          => '1.04',
              'Pod::Man'              => '2.04',
              'Pod::Perldoc'          => '3.14_01',
              'Pod::Simple'           => '3.04',
              'Pod::Simple::BlackBox' => undef,
              'Pod::Simple::Checker'  => '2.02',
              'Pod::Simple::Debug'    => undef,
              'Pod::Simple::DumpAsText'=> '2.02',
              'Pod::Simple::DumpAsXML'=> '2.02',
              'Pod::Simple::HTML'     => '3.03',
              'Pod::Simple::HTMLBatch'=> '3.02',
              'Pod::Simple::HTMLLegacy'=> '5.01',
              'Pod::Simple::LinkSection'=> undef,
              'Pod::Simple::Methody'  => '2.02',
              'Pod::Simple::Progress' => '1.01',
              'Pod::Simple::PullParser'=> '2.02',
              'Pod::Simple::PullParserEndToken'=> undef,
              'Pod::Simple::PullParserStartToken'=> undef,
              'Pod::Simple::PullParserTextToken'=> undef,
              'Pod::Simple::PullParserToken'=> '2.02',
              'Pod::Simple::RTF'      => '2.02',
              'Pod::Simple::Search'   => '3.04',
              'Pod::Simple::SimpleTree'=> '2.02',
              'Pod::Simple::Text'     => '2.02',
              'Pod::Simple::TextContent'=> '2.02',
              'Pod::Simple::TiedOutFH'=> undef,
              'Pod::Simple::Transcode'=> undef,
              'Pod::Simple::TranscodeDumb'=> '2.02',
              'Pod::Simple::TranscodeSmart'=> undef,
              'Pod::Simple::XMLOutStream'=> '2.02',
              'Pod::Text'             => '3.01',
              'Pod::Text::Color'      => '2.01',
              'Pod::Text::Overstrike' => '2',
              'Pod::Text::Termcap'    => '2.01',
              'Pod::Usage'            => '1.33_01',
              'SelfLoader'            => '1.0905',
              'Storable'              => '2.15_02',
              'Test::Builder::Module' => '0.03',
              'Text::Balanced'        => '1.95_01',
              'Tie::File'             => '0.97_01',
              'UNIVERSAL'             => '1.03',
              'XS::APItest'           => '0.09',
              'assertions'            => '0.02',
              'assertions::activate'  => '0.02',
              'assertions::compat'    => undef,
              'constant'              => '1.07',
              'encoding::warnings'    => '0.05',
              'feature'               => '1.00',
              're'                    => '0.06',
              'sort'                  => '2.00',
              'version'               => '0.53',
          },
          removed => {
          }
      },
      5.009004 => {
          delta_from => 5.009003,
          changed => {
              'Archive::Tar'          => '1.30_01',
              'AutoLoader'            => '5.61',
              'B'                     => '1.11',
              'B::Bytecode'           => '1.02',
              'B::C'                  => '1.05',
              'B::Concise'            => '0.69',
              'B::Deparse'            => '0.76',
              'B::Lint'               => '1.08',
              'Benchmark'             => '1.08',
              'CGI'                   => '3.20',
              'CGI::Cookie'           => '1.27',
              'CGI::Fast'             => '1.07',
              'CPAN'                  => '1.87_55',
              'CPAN::Debug'           => '5.400561',
              'CPAN::FirstTime'       => '5.400742',
              'CPAN::HandleConfig'    => '5.400740',
              'CPAN::Nox'             => '5.400561',
              'CPAN::Tarzip'          => '5.400714',
              'CPAN::Version'         => '5.400561',
              'Compress::Raw::Zlib'   => '2.000_13',
              'Compress::Zlib'        => '2.000_13',
              'Cwd'                   => '3.19',
              'Devel::PPPort'         => '3.10',
              'Digest'                => '1.15',
              'Digest::SHA'           => '5.43',
              'Encode'                => '2.18_01',
              'Encode::Alias'         => '2.06',
              'Encode::Byte'          => '2.02',
              'Encode::CJKConstants'  => '2.02',
              'Encode::CN'            => '2.02',
              'Encode::CN::HZ'        => '2.04',
              'Encode::Config'        => '2.03',
              'Encode::EBCDIC'        => '2.02',
              'Encode::Encoder'       => '2.01',
              'Encode::Encoding'      => '2.04',
              'Encode::Guess'         => '2.02',
              'Encode::JP'            => '2.03',
              'Encode::JP::H2Z'       => '2.02',
              'Encode::JP::JIS7'      => '2.02',
              'Encode::KR'            => '2.02',
              'Encode::KR::2022_KR'   => '2.02',
              'Encode::MIME::Header'  => '2.04',
              'Encode::MIME::Header::ISO_2022_JP'=> '1.03',
              'Encode::Symbol'        => '2.02',
              'Encode::TW'            => '2.02',
              'Encode::Unicode'       => '2.03',
              'Encode::Unicode::UTF7' => '2.04',
              'ExtUtils::CBuilder'    => '0.18',
              'ExtUtils::CBuilder::Platform::Windows'=> '0.12_01',
              'ExtUtils::Constant::Base'=> '0.03',
              'ExtUtils::Constant::ProxySubs'=> '0.03',
              'ExtUtils::Install'     => '1.41',
              'ExtUtils::Installed'   => '1.41',
              'ExtUtils::MM_Any'      => '0.13_02',
              'ExtUtils::MM_NW5'      => '2.08_01',
              'ExtUtils::MM_Unix'     => '1.5003',
              'ExtUtils::MM_VMS'      => '5.73_03',
              'ExtUtils::MM_Win32'    => '1.12_02',
              'ExtUtils::MM_Win95'    => '0.04_01',
              'ExtUtils::MakeMaker'   => '6.30_02',
              'ExtUtils::Manifest'    => '1.46_01',
              'ExtUtils::Mkbootstrap' => '1.15_01',
              'ExtUtils::Mksymlists'  => '1.19_01',
              'ExtUtils::Packlist'    => '1.41',
              'File::Basename'        => '2.75',
              'File::Find'            => '1.11',
              'File::GlobMapper'      => '0.000_02',
              'File::Spec'            => '3.19',
              'FileCache'             => '1.07',
              'Getopt::Long'          => '2.3501',
              'Hash::Util'            => '0.07',
              'Hash::Util::FieldHash' => '0.01',
              'IO'                    => '1.23_01',
              'IO::Compress::Adapter::Deflate'=> '2.000_13',
              'IO::Compress::Adapter::Identity'=> '2.000_13',
              'IO::Compress::Base'    => '2.000_13',
              'IO::Compress::Base::Common'=> '2.000_13',
              'IO::Compress::Deflate' => '2.000_13',
              'IO::Compress::Gzip'    => '2.000_13',
              'IO::Compress::Gzip::Constants'=> '2.000_13',
              'IO::Compress::RawDeflate'=> '2.000_13',
              'IO::Compress::Zip'     => '2.000_13',
              'IO::Compress::Zip::Constants'=> '2.000_13',
              'IO::Compress::Zlib::Constants'=> '2.000_13',
              'IO::Compress::Zlib::Extra'=> '2.000_13',
              'IO::Dir'               => '1.06',
              'IO::File'              => '1.14',
              'IO::Handle'            => '1.27',
              'IO::Socket'            => '1.30_01',
              'IO::Socket::INET'      => '1.31',
              'IO::Socket::UNIX'      => '1.23',
              'IO::Uncompress::Adapter::Identity'=> '2.000_13',
              'IO::Uncompress::Adapter::Inflate'=> '2.000_13',
              'IO::Uncompress::AnyInflate'=> '2.000_13',
              'IO::Uncompress::AnyUncompress'=> '2.000_13',
              'IO::Uncompress::Base'  => '2.000_13',
              'IO::Uncompress::Gunzip'=> '2.000_13',
              'IO::Uncompress::Inflate'=> '2.000_13',
              'IO::Uncompress::RawInflate'=> '2.000_13',
              'IO::Uncompress::Unzip' => '2.000_13',
              'MIME::Base64'          => '3.07_01',
              'Math::Complex'         => '1.36',
              'Math::Trig'            => '1.04',
              'Module::Build'         => '0.2805',
              'Module::Build::Base'   => undef,
              'Module::Build::Compat' => '0.03',
              'Module::Build::ConfigData'=> undef,
              'Module::Build::Cookbook'=> undef,
              'Module::Build::ModuleInfo'=> undef,
              'Module::Build::Notes'  => undef,
              'Module::Build::PPMMaker'=> undef,
              'Module::Build::Platform::Amiga'=> undef,
              'Module::Build::Platform::Default'=> undef,
              'Module::Build::Platform::EBCDIC'=> undef,
              'Module::Build::Platform::MPEiX'=> undef,
              'Module::Build::Platform::MacOS'=> undef,
              'Module::Build::Platform::RiscOS'=> undef,
              'Module::Build::Platform::Unix'=> undef,
              'Module::Build::Platform::VMS'=> undef,
              'Module::Build::Platform::VOS'=> undef,
              'Module::Build::Platform::Windows'=> undef,
              'Module::Build::Platform::aix'=> undef,
              'Module::Build::Platform::cygwin'=> undef,
              'Module::Build::Platform::darwin'=> undef,
              'Module::Build::Platform::os2'=> undef,
              'Module::Build::PodParser'=> undef,
              'Module::Build::Version'=> '0',
              'Module::Build::YAML'   => '0.50',
              'Module::CoreList'      => '2.08',
              'Module::Load'          => '0.10',
              'Module::Loaded'        => '0.01',
              'Package::Constants'    => '0.01',
              'Pod::Html'             => '1.07',
              'Pod::Man'              => '2.09',
              'Pod::Text'             => '3.07',
              'Pod::Text::Color'      => '2.03',
              'Pod::Text::Termcap'    => '2.03',
              'SDBM_File'             => '1.06',
              'Shell'                 => '0.7',
              'Sys::Syslog'           => '0.17',
              'Term::ANSIColor'       => '1.11',
              'Test::Builder'         => '0.33',
              'Test::Builder::Tester' => '1.04',
              'Test::Harness'         => '2.62',
              'Test::Harness::Util'   => '0.01',
              'Test::More'            => '0.64',
              'Test::Simple'          => '0.64',
              'Text::Balanced'        => '1.98_01',
              'Text::ParseWords'      => '3.25',
              'Text::Tabs'            => '2007.071101',
              'Text::Wrap'            => '2006.0711',
              'Tie::RefHash'          => '1.34_01',
              'Time::HiRes'           => '1.87',
              'Time::Local'           => '1.13',
              'Time::gmtime'          => '1.03',
              'UNIVERSAL'             => '1.04',
              'Unicode::Normalize'    => '1.01',
              'Win32API::File'        => '0.1001',
              'Win32API::File::ExtUtils::Myconst2perl'=> '1',
              'assertions'            => '0.03',
              'assertions::compat'    => '0.02',
              'autouse'               => '1.06',
              'diagnostics'           => '1.16',
              'encoding'              => '2.04',
              'encoding::warnings'    => '0.10',
              'feature'               => '1.01',
              're'                    => '0.0601',
              'threads'               => '1.38',
              'threads::shared'       => '0.94_01',
              'version'               => '0.67',
          },
          removed => {
              'Compress::Zlib::Common'=> 1,
              'Compress::Zlib::Compress::Gzip::Constants'=> 1,
              'Compress::Zlib::Compress::Zip::Constants'=> 1,
              'Compress::Zlib::CompressPlugin::Deflate'=> 1,
              'Compress::Zlib::CompressPlugin::Identity'=> 1,
              'Compress::Zlib::File::GlobMapper'=> 1,
              'Compress::Zlib::FileConstants'=> 1,
              'Compress::Zlib::IO::Compress::Base'=> 1,
              'Compress::Zlib::IO::Compress::Deflate'=> 1,
              'Compress::Zlib::IO::Compress::Gzip'=> 1,
              'Compress::Zlib::IO::Compress::RawDeflate'=> 1,
              'Compress::Zlib::IO::Compress::Zip'=> 1,
              'Compress::Zlib::IO::Uncompress::AnyInflate'=> 1,
              'Compress::Zlib::IO::Uncompress::AnyUncompress'=> 1,
              'Compress::Zlib::IO::Uncompress::Base'=> 1,
              'Compress::Zlib::IO::Uncompress::Gunzip'=> 1,
              'Compress::Zlib::IO::Uncompress::Inflate'=> 1,
              'Compress::Zlib::IO::Uncompress::RawInflate'=> 1,
              'Compress::Zlib::IO::Uncompress::Unzip'=> 1,
              'Compress::Zlib::ParseParameters'=> 1,
              'Compress::Zlib::UncompressPlugin::Identity'=> 1,
              'Compress::Zlib::UncompressPlugin::Inflate'=> 1,
          }
      },
      5.009005 => {
          delta_from => 5.009004,
          changed => {
              'Archive::Extract'      => '0.22_01',
              'Archive::Tar'          => '1.32',
              'Attribute::Handlers'   => '0.78_06',
              'AutoLoader'            => '5.63',
              'AutoSplit'             => '1.05',
              'B'                     => '1.16',
              'B::Concise'            => '0.72',
              'B::Debug'              => '1.05',
              'B::Deparse'            => '0.82',
              'B::Lint'               => '1.09',
              'B::Terse'              => '1.05',
              'Benchmark'             => '1.1',
              'CGI'                   => '3.29',
              'CGI::Cookie'           => '1.28',
              'CGI::Util'             => '1.5_01',
              'CPAN'                  => '1.9102',
              'CPAN::Debug'           => '5.400955',
              'CPAN::FirstTime'       => '5.401669',
              'CPAN::HandleConfig'    => '5.401744',
              'CPAN::Kwalify'         => '5.401418',
              'CPAN::Nox'             => '5.400844',
              'CPAN::Queue'           => '5.401704',
              'CPAN::Tarzip'          => '5.401717',
              'CPAN::Version'         => '5.401387',
              'CPANPLUS'              => '0.81_01',
              'CPANPLUS::Backend'     => undef,
              'CPANPLUS::Backend::RV' => undef,
              'CPANPLUS::Config'      => undef,
              'CPANPLUS::Configure'   => undef,
              'CPANPLUS::Configure::Setup'=> undef,
              'CPANPLUS::Dist'        => undef,
              'CPANPLUS::Dist::Base'  => '0.01',
              'CPANPLUS::Dist::Build' => '0.06_01',
              'CPANPLUS::Dist::Build::Constants'=> '0.01',
              'CPANPLUS::Dist::MM'    => undef,
              'CPANPLUS::Dist::Sample'=> undef,
              'CPANPLUS::Error'       => undef,
              'CPANPLUS::Internals'   => '0.81_01',
              'CPANPLUS::Internals::Constants'=> '0.01',
              'CPANPLUS::Internals::Constants::Report'=> '0.01',
              'CPANPLUS::Internals::Extract'=> undef,
              'CPANPLUS::Internals::Fetch'=> undef,
              'CPANPLUS::Internals::Report'=> undef,
              'CPANPLUS::Internals::Search'=> undef,
              'CPANPLUS::Internals::Source'=> undef,
              'CPANPLUS::Internals::Utils'=> undef,
              'CPANPLUS::Internals::Utils::Autoflush'=> undef,
              'CPANPLUS::Module'      => undef,
              'CPANPLUS::Module::Author'=> undef,
              'CPANPLUS::Module::Author::Fake'=> undef,
              'CPANPLUS::Module::Checksums'=> undef,
              'CPANPLUS::Module::Fake'=> undef,
              'CPANPLUS::Module::Signature'=> undef,
              'CPANPLUS::Selfupdate'  => undef,
              'CPANPLUS::Shell'       => undef,
              'CPANPLUS::Shell::Classic'=> '0.0562',
              'CPANPLUS::Shell::Default'=> '0.81_01',
              'CPANPLUS::Shell::Default::Plugins::Remote'=> undef,
              'CPANPLUS::Shell::Default::Plugins::Source'=> undef,
              'CPANPLUS::inc'         => undef,
              'Carp'                  => '1.07',
              'Carp::Heavy'           => '1.07',
              'Compress::Raw::Zlib'   => '2.005',
              'Compress::Zlib'        => '2.005',
              'Cwd'                   => '3.25',
              'DBM_Filter'            => '0.02',
              'DB_File'               => '1.815',
              'Data::Dumper'          => '2.121_13',
              'Devel::InnerPackage'   => '0.3',
              'Devel::PPPort'         => '3.11_01',
              'Digest::MD5'           => '2.36_01',
              'Digest::SHA'           => '5.44',
              'DynaLoader'            => '1.08',
              'Encode'                => '2.23',
              'Encode::Alias'         => '2.07',
              'Encode::Byte'          => '2.03',
              'Encode::Config'        => '2.04',
              'Encode::Encoding'      => '2.05',
              'Encode::GSM0338'       => '2.00',
              'Encode::JP::JIS7'      => '2.03',
              'Encode::MIME::Header'  => '2.05',
              'Encode::MIME::Name'    => '1.01',
              'Encode::Unicode'       => '2.05',
              'Errno'                 => '1.10',
              'Exporter'              => '5.60',
              'Exporter::Heavy'       => '5.60',
              'ExtUtils::CBuilder'    => '0.19',
              'ExtUtils::CBuilder::Platform::Windows'=> '0.13',
              'ExtUtils::Command'     => '1.13',
              'ExtUtils::Command::MM' => '0.07',
              'ExtUtils::Constant::Base'=> '0.04',
              'ExtUtils::Install'     => '1.41_01',
              'ExtUtils::Liblist'     => '1.03',
              'ExtUtils::Liblist::Kid'=> '1.33',
              'ExtUtils::MM'          => '0.07',
              'ExtUtils::MM_AIX'      => '0.05',
              'ExtUtils::MM_Any'      => '0.15',
              'ExtUtils::MM_BeOS'     => '1.07',
              'ExtUtils::MM_Cygwin'   => '1.1',
              'ExtUtils::MM_DOS'      => '0.04',
              'ExtUtils::MM_MacOS'    => '1.1',
              'ExtUtils::MM_NW5'      => '2.1',
              'ExtUtils::MM_OS2'      => '1.07',
              'ExtUtils::MM_QNX'      => '0.04',
              'ExtUtils::MM_UWIN'     => '0.04',
              'ExtUtils::MM_Unix'     => '1.54_01',
              'ExtUtils::MM_VMS'      => '5.76',
              'ExtUtils::MM_VOS'      => '0.04',
              'ExtUtils::MM_Win32'    => '1.15',
              'ExtUtils::MM_Win95'    => '0.06',
              'ExtUtils::MY'          => '0.03',
              'ExtUtils::MakeMaker'   => '6.36',
              'ExtUtils::MakeMaker::Config'=> '0.04',
              'ExtUtils::MakeMaker::bytes'=> '0.03',
              'ExtUtils::MakeMaker::vmsish'=> '0.03',
              'ExtUtils::Manifest'    => '1.51_01',
              'ExtUtils::Mkbootstrap' => '1.17',
              'ExtUtils::Mksymlists'  => '1.21',
              'ExtUtils::ParseXS'     => '2.18',
              'ExtUtils::XSSymSet'    => '1.1',
              'ExtUtils::testlib'     => '1.17',
              'Fatal'                 => '1.05',
              'Fcntl'                 => '1.06',
              'File::Basename'        => '2.76',
              'File::Copy'            => '2.10',
              'File::Fetch'           => '0.10',
              'File::Glob'            => '1.06',
              'File::Path'            => '2.01',
              'File::Spec'            => '3.25',
              'File::Spec::Cygwin'    => '1.1_01',
              'File::Spec::VMS'       => '1.4_01',
              'File::Temp'            => '0.18',
              'Filter::Util::Call'    => '1.0602',
              'FindBin'               => '1.49',
              'Getopt::Long'          => '2.36',
              'Hash::Util::FieldHash' => '1.01',
              'IO::Compress::Adapter::Deflate'=> '2.005',
              'IO::Compress::Adapter::Identity'=> '2.005',
              'IO::Compress::Base'    => '2.005',
              'IO::Compress::Base::Common'=> '2.005',
              'IO::Compress::Deflate' => '2.005',
              'IO::Compress::Gzip'    => '2.005',
              'IO::Compress::Gzip::Constants'=> '2.005',
              'IO::Compress::RawDeflate'=> '2.005',
              'IO::Compress::Zip'     => '2.005',
              'IO::Compress::Zip::Constants'=> '2.005',
              'IO::Compress::Zlib::Constants'=> '2.005',
              'IO::Compress::Zlib::Extra'=> '2.005',
              'IO::Uncompress::Adapter::Identity'=> '2.005',
              'IO::Uncompress::Adapter::Inflate'=> '2.005',
              'IO::Uncompress::AnyInflate'=> '2.005',
              'IO::Uncompress::AnyUncompress'=> '2.005',
              'IO::Uncompress::Base'  => '2.005',
              'IO::Uncompress::Gunzip'=> '2.005',
              'IO::Uncompress::Inflate'=> '2.005',
              'IO::Uncompress::RawInflate'=> '2.005',
              'IO::Uncompress::Unzip' => '2.005',
              'IO::Zlib'              => '1.05_01',
              'IPC::Cmd'              => '0.36_01',
              'List::Util'            => '1.19',
              'Locale::Maketext::Simple'=> '0.18',
              'Log::Message'          => '0.01',
              'Log::Message::Config'  => '0.01',
              'Log::Message::Handlers'=> undef,
              'Log::Message::Item'    => undef,
              'Log::Message::Simple'  => '0.0201',
              'Math::BigFloat'        => '1.58',
              'Math::BigInt'          => '1.87',
              'Math::BigInt::Calc'    => '0.51',
              'Math::BigInt::FastCalc'=> '0.15_01',
              'Math::BigRat'          => '0.19',
              'Math::Complex'         => '1.37',
              'Memoize'               => '1.01_02',
              'Module::Build'         => '0.2808',
              'Module::Build::Config' => undef,
              'Module::Build::Version'=> '0.7203',
              'Module::CoreList'      => '2.12',
              'Module::Load::Conditional'=> '0.16',
              'Module::Pluggable'     => '3.6',
              'Module::Pluggable::Object'=> '3.6',
              'NDBM_File'             => '1.07',
              'Net::Cmd'              => '2.28',
              'Net::Config'           => '1.11',
              'Net::Domain'           => '2.20',
              'Net::FTP'              => '2.77',
              'Net::FTP::A'           => '1.18',
              'Net::NNTP'             => '2.24',
              'Net::POP3'             => '2.29',
              'Net::SMTP'             => '2.31',
              'ODBM_File'             => '1.07',
              'OS2::DLL'              => '1.03',
              'Object::Accessor'      => '0.32',
              'Opcode'                => '1.09',
              'POSIX'                 => '1.13',
              'Params::Check'         => '0.26',
              'PerlIO::encoding'      => '0.10',
              'PerlIO::scalar'        => '0.05',
              'PerlIO::via'           => '0.04',
              'Pod::Html'             => '1.08',
              'Pod::Man'              => '2.12',
              'Pod::ParseUtils'       => '1.35',
              'Pod::Parser'           => '1.35',
              'Pod::Select'           => '1.35',
              'Pod::Simple'           => '3.05',
              'Pod::Text'             => '3.08',
              'Pod::Usage'            => '1.35',
              'Scalar::Util'          => '1.19',
              'SelfLoader'            => '1.11',
              'Shell'                 => '0.72_01',
              'Socket'                => '1.79',
              'Storable'              => '2.16',
              'Switch'                => '2.13',
              'Sys::Syslog'           => '0.18_01',
              'Term::ANSIColor'       => '1.12',
              'Term::UI'              => '0.14_01',
              'Term::UI::History'     => undef,
              'Test::Builder'         => '0.70',
              'Test::Builder::Module' => '0.68',
              'Test::Builder::Tester' => '1.07',
              'Test::Harness'         => '2.64',
              'Test::Harness::Results'=> '0.01',
              'Test::More'            => '0.70',
              'Test::Simple'          => '0.70',
              'Text::Balanced'        => '2.0.0',
              'Text::Soundex'         => '3.02',
              'Text::Tabs'            => '2007.1117',
              'Text::Wrap'            => '2006.1117',
              'Thread'                => '3.02',
              'Tie::File'             => '0.97_02',
              'Tie::Hash::NamedCapture'=> '0.06',
              'Tie::Memoize'          => '1.1',
              'Tie::RefHash'          => '1.37',
              'Time::HiRes'           => '1.9707',
              'Time::Local'           => '1.17',
              'Time::Piece'           => '1.11_02',
              'Time::Seconds'         => undef,
              'Unicode'               => '5.0.0',
              'Unicode::Normalize'    => '1.02',
              'Unicode::UCD'          => '0.25',
              'VMS::DCLsym'           => '1.03',
              'Win32'                 => '0.30',
              'Win32API::File'        => '0.1001_01',
              'Win32CORE'             => '0.02',
              'XS::APItest'           => '0.12',
              'XSLoader'              => '0.08',
              'attributes'            => '0.08',
              'base'                  => '2.12',
              'bigint'                => '0.22',
              'bignum'                => '0.22',
              'bigrat'                => '0.22',
              'bytes'                 => '1.03',
              'charnames'             => '1.06',
              'constant'              => '1.10',
              'diagnostics'           => '1.17',
              'encoding'              => '2.06',
              'encoding::warnings'    => '0.11',
              'feature'               => '1.10',
              'fields'                => '2.12',
              'less'                  => '0.02',
              'mro'                   => '1.00',
              'overload'              => '1.06',
              're'                    => '0.08',
              'sigtrap'               => '1.04',
              'sort'                  => '2.01',
              'strict'                => '1.04',
              'threads'               => '1.63',
              'threads::shared'       => '1.12',
              'utf8'                  => '1.07',
              'version'               => '0.7203',
              'warnings'              => '1.06',
          },
          removed => {
              'B::Asmdata'            => 1,
              'B::Assembler'          => 1,
              'B::Bblock'             => 1,
              'B::Bytecode'           => 1,
              'B::C'                  => 1,
              'B::CC'                 => 1,
              'B::Disassembler'       => 1,
              'B::Stackobj'           => 1,
              'B::Stash'              => 1,
              'ByteLoader'            => 1,
              'Thread::Signal'        => 1,
              'Thread::Specific'      => 1,
              'assertions'            => 1,
              'assertions::activate'  => 1,
              'assertions::compat'    => 1,
          }
      },
      5.01 => {
          delta_from => 5.009005,
          changed => {
              'Archive::Extract'      => '0.24',
              'Archive::Tar'          => '1.38',
              'Attribute::Handlers'   => '0.79',
              'B'                     => '1.17',
              'B::Concise'            => '0.74',
              'B::Deparse'            => '0.83',
              'CPAN'                  => '1.9205',
              'CPAN::API::HOWTO'      => undef,
              'CPAN::Debug'           => '5.402212',
              'CPAN::DeferedCode'     => '5.50',
              'CPAN::FirstTime'       => '5.402229',
              'CPAN::HandleConfig'    => '5.402212',
              'CPAN::Nox'             => '5.402411',
              'CPAN::Queue'           => '5.402212',
              'CPAN::Tarzip'          => '5.402213',
              'CPAN::Version'         => '5.5',
              'CPANPLUS'              => '0.84',
              'CPANPLUS::Dist::Build' => '0.06_02',
              'CPANPLUS::Internals'   => '0.84',
              'CPANPLUS::Shell::Default'=> '0.84',
              'CPANPLUS::Shell::Default::Plugins::CustomSource'=> undef,
              'Carp'                  => '1.08',
              'Carp::Heavy'           => '1.08',
              'Compress::Raw::Zlib'   => '2.008',
              'Compress::Zlib'        => '2.008',
              'Cwd'                   => '3.2501',
              'DB_File'               => '1.816_1',
              'Data::Dumper'          => '2.121_14',
              'Devel::PPPort'         => '3.13',
              'Digest::SHA'           => '5.45',
              'Exporter'              => '5.62',
              'Exporter::Heavy'       => '5.62',
              'ExtUtils::CBuilder'    => '0.21',
              'ExtUtils::CBuilder::Base'=> '0.21',
              'ExtUtils::CBuilder::Platform::Unix'=> '0.21',
              'ExtUtils::CBuilder::Platform::VMS'=> '0.22',
              'ExtUtils::CBuilder::Platform::Windows'=> '0.21',
              'ExtUtils::CBuilder::Platform::aix'=> '0.21',
              'ExtUtils::CBuilder::Platform::cygwin'=> '0.21',
              'ExtUtils::CBuilder::Platform::darwin'=> '0.21',
              'ExtUtils::CBuilder::Platform::dec_osf'=> '0.21',
              'ExtUtils::CBuilder::Platform::os2'=> '0.21',
              'ExtUtils::Command::MM' => '6.42',
              'ExtUtils::Constant::ProxySubs'=> '0.05',
              'ExtUtils::Embed'       => '1.27',
              'ExtUtils::Install'     => '1.44',
              'ExtUtils::Installed'   => '1.43',
              'ExtUtils::Liblist'     => '6.42',
              'ExtUtils::Liblist::Kid'=> '6.42',
              'ExtUtils::MM'          => '6.42',
              'ExtUtils::MM_AIX'      => '6.42',
              'ExtUtils::MM_Any'      => '6.42',
              'ExtUtils::MM_BeOS'     => '6.42',
              'ExtUtils::MM_Cygwin'   => '6.42',
              'ExtUtils::MM_DOS'      => '6.42',
              'ExtUtils::MM_MacOS'    => '6.42',
              'ExtUtils::MM_NW5'      => '6.42',
              'ExtUtils::MM_OS2'      => '6.42',
              'ExtUtils::MM_QNX'      => '6.42',
              'ExtUtils::MM_UWIN'     => '6.42',
              'ExtUtils::MM_Unix'     => '6.42',
              'ExtUtils::MM_VMS'      => '6.42',
              'ExtUtils::MM_VOS'      => '6.42',
              'ExtUtils::MM_Win32'    => '6.42',
              'ExtUtils::MM_Win95'    => '6.42',
              'ExtUtils::MY'          => '6.42',
              'ExtUtils::MakeMaker'   => '6.42',
              'ExtUtils::MakeMaker::Config'=> '6.42',
              'ExtUtils::MakeMaker::bytes'=> '6.42',
              'ExtUtils::MakeMaker::vmsish'=> '6.42',
              'ExtUtils::Mkbootstrap' => '6.42',
              'ExtUtils::Mksymlists'  => '6.42',
              'ExtUtils::Packlist'    => '1.43',
              'ExtUtils::ParseXS'     => '2.18_02',
              'ExtUtils::testlib'     => '6.42',
              'File::Copy'            => '2.11',
              'File::Fetch'           => '0.14',
              'File::Find'            => '1.12',
              'File::Path'            => '2.04',
              'File::Spec'            => '3.2501',
              'File::Spec::Cygwin'    => '3.2501',
              'File::Spec::Epoc'      => '3.2501',
              'File::Spec::Functions' => '3.2501',
              'File::Spec::Mac'       => '3.2501',
              'File::Spec::OS2'       => '3.2501',
              'File::Spec::Unix'      => '3.2501',
              'File::Spec::VMS'       => '3.2501',
              'File::Spec::Win32'     => '3.2501',
              'Filter::Util::Call'    => '1.07',
              'Getopt::Long'          => '2.37',
              'Hash::Util::FieldHash' => '1.03',
              'IO::Compress::Adapter::Deflate'=> '2.008',
              'IO::Compress::Adapter::Identity'=> '2.008',
              'IO::Compress::Base'    => '2.008',
              'IO::Compress::Base::Common'=> '2.008',
              'IO::Compress::Deflate' => '2.008',
              'IO::Compress::Gzip'    => '2.008',
              'IO::Compress::Gzip::Constants'=> '2.008',
              'IO::Compress::RawDeflate'=> '2.008',
              'IO::Compress::Zip'     => '2.008',
              'IO::Compress::Zip::Constants'=> '2.008',
              'IO::Compress::Zlib::Constants'=> '2.008',
              'IO::Compress::Zlib::Extra'=> '2.008',
              'IO::Uncompress::Adapter::Identity'=> '2.008',
              'IO::Uncompress::Adapter::Inflate'=> '2.008',
              'IO::Uncompress::AnyInflate'=> '2.008',
              'IO::Uncompress::AnyUncompress'=> '2.008',
              'IO::Uncompress::Base'  => '2.008',
              'IO::Uncompress::Gunzip'=> '2.008',
              'IO::Uncompress::Inflate'=> '2.008',
              'IO::Uncompress::RawInflate'=> '2.008',
              'IO::Uncompress::Unzip' => '2.008',
              'IO::Zlib'              => '1.07',
              'IPC::Cmd'              => '0.40_1',
              'IPC::SysV'             => '1.05',
              'Locale::Maketext'      => '1.12',
              'Log::Message::Simple'  => '0.04',
              'Math::BigFloat'        => '1.59',
              'Math::BigInt'          => '1.88',
              'Math::BigInt::Calc'    => '0.52',
              'Math::BigInt::FastCalc'=> '0.16',
              'Math::BigRat'          => '0.21',
              'Module::Build'         => '0.2808_01',
              'Module::Build::Base'   => '0.2808_01',
              'Module::Build::Compat' => '0.2808_01',
              'Module::Build::Config' => '0.2808_01',
              'Module::Build::Dumper' => undef,
              'Module::Build::ModuleInfo'=> '0.2808_01',
              'Module::Build::Notes'  => '0.2808_01',
              'Module::Build::PPMMaker'=> '0.2808_01',
              'Module::Build::Platform::Amiga'=> '0.2808_01',
              'Module::Build::Platform::Default'=> '0.2808_01',
              'Module::Build::Platform::EBCDIC'=> '0.2808_01',
              'Module::Build::Platform::MPEiX'=> '0.2808_01',
              'Module::Build::Platform::MacOS'=> '0.2808_01',
              'Module::Build::Platform::RiscOS'=> '0.2808_01',
              'Module::Build::Platform::Unix'=> '0.2808_01',
              'Module::Build::Platform::VMS'=> '0.2808_01',
              'Module::Build::Platform::VOS'=> '0.2808_01',
              'Module::Build::Platform::Windows'=> '0.2808_01',
              'Module::Build::Platform::aix'=> '0.2808_01',
              'Module::Build::Platform::cygwin'=> '0.2808_01',
              'Module::Build::Platform::darwin'=> '0.2808_01',
              'Module::Build::Platform::os2'=> '0.2808_01',
              'Module::Build::PodParser'=> '0.2808_01',
              'Module::CoreList'      => '2.13',
              'Module::Load'          => '0.12',
              'Module::Load::Conditional'=> '0.22',
              'Net::Cmd'              => '2.29',
              'Net::Ping'             => '2.33',
              'Opcode'                => '1.11',
              'Pod::Checker'          => '1.43_01',
              'Pod::Man'              => '2.16',
              'Pod::Perldoc'          => '3.14_02',
              'Socket'                => '1.80',
              'Storable'              => '2.18',
              'Sys::Syslog'           => '0.22',
              'Sys::Syslog::win32::Win32'=> undef,
              'Term::Cap'             => '1.12',
              'Term::ReadLine'        => '1.03',
              'Term::UI'              => '0.18',
              'Test::Builder'         => '0.72',
              'Test::Builder::Module' => '0.72',
              'Test::Builder::Tester' => '1.09',
              'Test::Harness::Straps' => '0.26_01',
              'Test::More'            => '0.72',
              'Test::Simple'          => '0.72',
              'Text::ParseWords'      => '3.26',
              'Text::Soundex'         => '3.03',
              'Tie::StdHandle'        => undef,
              'Time::HiRes'           => '1.9711',
              'Time::Local'           => '1.18',
              'Time::Piece'           => '1.12',
              'VMS::Filespec'         => '1.12',
              'Win32'                 => '0.34',
              'base'                  => '2.13',
              'constant'              => '1.13',
              'feature'               => '1.11',
              'fields'                => '2.13',
              'filetest'              => '1.02',
              'open'                  => '1.06',
              'threads'               => '1.67',
              'threads::shared'       => '1.14',
              'version'               => '0.74',
          },
          removed => {
          }
      },
      5.010001 => {
          delta_from => 5.01,
          changed => {
              'App::Prove'            => '3.17',
              'App::Prove::State'     => '3.17',
              'App::Prove::State::Result'=> '3.17',
              'App::Prove::State::Result::Test'=> '3.17',
              'Archive::Extract'      => '0.34',
              'Archive::Tar'          => '1.52',
              'Attribute::Handlers'   => '0.85',
              'AutoLoader'            => '5.68',
              'AutoSplit'             => '1.06',
              'B'                     => '1.22',
              'B::Concise'            => '0.76',
              'B::Debug'              => '1.11',
              'B::Deparse'            => '0.89',
              'B::Lint'               => '1.11',
              'B::Lint::Debug'        => undef,
              'B::Xref'               => '1.02',
              'Benchmark'             => '1.11',
              'CGI'                   => '3.43',
              'CGI::Carp'             => '1.30_01',
              'CGI::Cookie'           => '1.29',
              'CPAN'                  => '1.9402',
              'CPAN::Author'          => '5.5',
              'CPAN::Bundle'          => '5.5',
              'CPAN::CacheMgr'        => '5.5',
              'CPAN::Complete'        => '5.5',
              'CPAN::Debug'           => '5.5',
              'CPAN::DeferredCode'    => '5.50',
              'CPAN::Distribution'    => '1.93',
              'CPAN::Distroprefs'     => '6',
              'CPAN::Distrostatus'    => '5.5',
              'CPAN::Exception::RecursiveDependency'=> '5.5',
              'CPAN::Exception::blocked_urllist'=> '1.0',
              'CPAN::Exception::yaml_not_installed'=> '5.5',
              'CPAN::FTP'             => '5.5001',
              'CPAN::FTP::netrc'      => '1.00',
              'CPAN::FirstTime'       => '5.53',
              'CPAN::HandleConfig'    => '5.5',
              'CPAN::Index'           => '1.93',
              'CPAN::InfoObj'         => '5.5',
              'CPAN::Kwalify'         => '5.50',
              'CPAN::LWP::UserAgent'  => '1.00',
              'CPAN::Module'          => '5.5',
              'CPAN::Nox'             => '5.50',
              'CPAN::Prompt'          => '5.5',
              'CPAN::Queue'           => '5.5',
              'CPAN::Shell'           => '5.5',
              'CPAN::Tarzip'          => '5.501',
              'CPAN::URL'             => '5.5',
              'CPANPLUS'              => '0.88',
              'CPANPLUS::Dist::Autobundle'=> undef,
              'CPANPLUS::Dist::Base'  => undef,
              'CPANPLUS::Dist::Build' => '0.36',
              'CPANPLUS::Dist::Build::Constants'=> '0.36',
              'CPANPLUS::Internals'   => '0.88',
              'CPANPLUS::Internals::Constants'=> undef,
              'CPANPLUS::Internals::Constants::Report'=> undef,
              'CPANPLUS::Internals::Source::Memory'=> undef,
              'CPANPLUS::Internals::Source::SQLite'=> undef,
              'CPANPLUS::Internals::Source::SQLite::Tie'=> undef,
              'CPANPLUS::Shell::Default'=> '0.88',
              'Carp'                  => '1.11',
              'Carp::Heavy'           => '1.11',
              'Compress::Raw::Bzip2'  => '2.020',
              'Compress::Raw::Zlib'   => '2.020',
              'Compress::Zlib'        => '2.020',
              'Cwd'                   => '3.30',
              'DB'                    => '1.02',
              'DBM_Filter::compress'  => '0.02',
              'DBM_Filter::encode'    => '0.02',
              'DBM_Filter::int32'     => '0.02',
              'DBM_Filter::null'      => '0.02',
              'DBM_Filter::utf8'      => '0.02',
              'DB_File'               => '1.820',
              'Data::Dumper'          => '2.124',
              'Devel::DProf'          => '20080331.00',
              'Devel::PPPort'         => '3.19',
              'Devel::Peek'           => '1.04',
              'Digest'                => '1.16',
              'Digest::MD5'           => '2.39',
              'Digest::SHA'           => '5.47',
              'Digest::base'          => '1.16',
              'Digest::file'          => '1.16',
              'DirHandle'             => '1.03',
              'Dumpvalue'             => '1.13',
              'DynaLoader'            => '1.10',
              'Encode'                => '2.35',
              'Encode::Alias'         => '2.12',
              'Encode::CN::HZ'        => '2.05',
              'Encode::Config'        => '2.05',
              'Encode::GSM0338'       => '2.01',
              'Encode::Guess'         => '2.03',
              'Encode::JP::JIS7'      => '2.04',
              'Encode::MIME::Header'  => '2.11',
              'Encode::Unicode'       => '2.06',
              'Errno'                 => '1.11',
              'Exporter'              => '5.63',
              'Exporter::Heavy'       => '5.63',
              'ExtUtils::CBuilder'    => '0.2602',
              'ExtUtils::CBuilder::Base'=> '0.2602',
              'ExtUtils::CBuilder::Platform::Unix'=> '0.2602',
              'ExtUtils::CBuilder::Platform::VMS'=> '0.2602',
              'ExtUtils::CBuilder::Platform::Windows'=> '0.2602',
              'ExtUtils::CBuilder::Platform::aix'=> '0.2602',
              'ExtUtils::CBuilder::Platform::cygwin'=> '0.2602',
              'ExtUtils::CBuilder::Platform::darwin'=> '0.2602',
              'ExtUtils::CBuilder::Platform::dec_osf'=> '0.2602',
              'ExtUtils::CBuilder::Platform::os2'=> '0.2602',
              'ExtUtils::Command'     => '1.16',
              'ExtUtils::Command::MM' => '6.55_02',
              'ExtUtils::Constant'    => '0.22',
              'ExtUtils::Constant::ProxySubs'=> '0.06',
              'ExtUtils::Constant::Utils'=> '0.02',
              'ExtUtils::Constant::XS'=> '0.03',
              'ExtUtils::Embed'       => '1.28',
              'ExtUtils::Install'     => '1.54',
              'ExtUtils::Installed'   => '1.999_001',
              'ExtUtils::Liblist'     => '6.55_02',
              'ExtUtils::Liblist::Kid'=> '6.5502',
              'ExtUtils::MM'          => '6.55_02',
              'ExtUtils::MM_AIX'      => '6.55_02',
              'ExtUtils::MM_Any'      => '6.55_02',
              'ExtUtils::MM_BeOS'     => '6.55_02',
              'ExtUtils::MM_Cygwin'   => '6.55_02',
              'ExtUtils::MM_DOS'      => '6.5502',
              'ExtUtils::MM_Darwin'   => '6.55_02',
              'ExtUtils::MM_MacOS'    => '6.5502',
              'ExtUtils::MM_NW5'      => '6.55_02',
              'ExtUtils::MM_OS2'      => '6.55_02',
              'ExtUtils::MM_QNX'      => '6.55_02',
              'ExtUtils::MM_UWIN'     => '6.5502',
              'ExtUtils::MM_Unix'     => '6.55_02',
              'ExtUtils::MM_VMS'      => '6.55_02',
              'ExtUtils::MM_VOS'      => '6.55_02',
              'ExtUtils::MM_Win32'    => '6.55_02',
              'ExtUtils::MM_Win95'    => '6.55_02',
              'ExtUtils::MY'          => '6.5502',
              'ExtUtils::MakeMaker'   => '6.55_02',
              'ExtUtils::MakeMaker::Config'=> '6.55_02',
              'ExtUtils::Manifest'    => '1.56',
              'ExtUtils::Mkbootstrap' => '6.55_02',
              'ExtUtils::Mksymlists'  => '6.55_02',
              'ExtUtils::ParseXS'     => '2.2002',
              'ExtUtils::testlib'     => '6.5502',
              'Fatal'                 => '2.06_01',
              'File::Basename'        => '2.77',
              'File::CheckTree'       => '4.4',
              'File::Compare'         => '1.1006',
              'File::Copy'            => '2.14',
              'File::DosGlob'         => '1.01',
              'File::Fetch'           => '0.20',
              'File::Find'            => '1.14',
              'File::GlobMapper'      => '1.000',
              'File::Path'            => '2.07_03',
              'File::Spec'            => '3.30',
              'File::Spec::Cygwin'    => '3.30',
              'File::Spec::Epoc'      => '3.30',
              'File::Spec::Functions' => '3.30',
              'File::Spec::Mac'       => '3.30',
              'File::Spec::OS2'       => '3.30',
              'File::Spec::Unix'      => '3.30',
              'File::Spec::VMS'       => '3.30',
              'File::Spec::Win32'     => '3.30',
              'File::Temp'            => '0.22',
              'File::stat'            => '1.01',
              'FileCache'             => '1.08',
              'FileHandle'            => '2.02',
              'Filter::Simple'        => '0.84',
              'Filter::Util::Call'    => '1.08',
              'FindBin'               => '1.50',
              'GDBM_File'             => '1.09',
              'Getopt::Long'          => '2.38',
              'Getopt::Std'           => '1.06',
              'Hash::Util::FieldHash' => '1.04',
              'I18N::Collate'         => '1.01',
              'IO'                    => '1.25',
              'IO::Compress::Adapter::Bzip2'=> '2.020',
              'IO::Compress::Adapter::Deflate'=> '2.020',
              'IO::Compress::Adapter::Identity'=> '2.020',
              'IO::Compress::Base'    => '2.020',
              'IO::Compress::Base::Common'=> '2.020',
              'IO::Compress::Bzip2'   => '2.020',
              'IO::Compress::Deflate' => '2.020',
              'IO::Compress::Gzip'    => '2.020',
              'IO::Compress::Gzip::Constants'=> '2.020',
              'IO::Compress::RawDeflate'=> '2.020',
              'IO::Compress::Zip'     => '2.020',
              'IO::Compress::Zip::Constants'=> '2.020',
              'IO::Compress::Zlib::Constants'=> '2.020',
              'IO::Compress::Zlib::Extra'=> '2.020',
              'IO::Dir'               => '1.07',
              'IO::Handle'            => '1.28',
              'IO::Socket'            => '1.31',
              'IO::Uncompress::Adapter::Bunzip2'=> '2.020',
              'IO::Uncompress::Adapter::Identity'=> '2.020',
              'IO::Uncompress::Adapter::Inflate'=> '2.020',
              'IO::Uncompress::AnyInflate'=> '2.020',
              'IO::Uncompress::AnyUncompress'=> '2.020',
              'IO::Uncompress::Base'  => '2.020',
              'IO::Uncompress::Bunzip2'=> '2.020',
              'IO::Uncompress::Gunzip'=> '2.020',
              'IO::Uncompress::Inflate'=> '2.020',
              'IO::Uncompress::RawInflate'=> '2.020',
              'IO::Uncompress::Unzip' => '2.020',
              'IO::Zlib'              => '1.09',
              'IPC::Cmd'              => '0.46',
              'IPC::Msg'              => '2.01',
              'IPC::Open2'            => '1.03',
              'IPC::Open3'            => '1.04',
              'IPC::Semaphore'        => '2.01',
              'IPC::SharedMem'        => '2.01',
              'IPC::SysV'             => '2.01',
              'List::Util'            => '1.21',
              'List::Util::PP'        => '1.21',
              'List::Util::XS'        => '1.21',
              'Locale::Maketext'      => '1.13',
              'Locale::Maketext::Guts'=> '1.13',
              'Locale::Maketext::GutsLoader'=> '1.13',
              'Log::Message'          => '0.02',
              'MIME::Base64'          => '3.08',
              'MIME::QuotedPrint'     => '3.08',
              'Math::BigFloat'        => '1.60',
              'Math::BigInt'          => '1.89',
              'Math::BigInt::FastCalc'=> '0.19',
              'Math::BigRat'          => '0.22',
              'Math::Complex'         => '1.56',
              'Math::Trig'            => '1.2',
              'Memoize'               => '1.01_03',
              'Module::Build'         => '0.340201',
              'Module::Build::Base'   => '0.340201',
              'Module::Build::Compat' => '0.340201',
              'Module::Build::Config' => '0.340201',
              'Module::Build::Cookbook'=> '0.340201',
              'Module::Build::Dumper' => '0.340201',
              'Module::Build::ModuleInfo'=> '0.340201',
              'Module::Build::Notes'  => '0.340201',
              'Module::Build::PPMMaker'=> '0.340201',
              'Module::Build::Platform::Amiga'=> '0.340201',
              'Module::Build::Platform::Default'=> '0.340201',
              'Module::Build::Platform::EBCDIC'=> '0.340201',
              'Module::Build::Platform::MPEiX'=> '0.340201',
              'Module::Build::Platform::MacOS'=> '0.340201',
              'Module::Build::Platform::RiscOS'=> '0.340201',
              'Module::Build::Platform::Unix'=> '0.340201',
              'Module::Build::Platform::VMS'=> '0.340201',
              'Module::Build::Platform::VOS'=> '0.340201',
              'Module::Build::Platform::Windows'=> '0.340201',
              'Module::Build::Platform::aix'=> '0.340201',
              'Module::Build::Platform::cygwin'=> '0.340201',
              'Module::Build::Platform::darwin'=> '0.340201',
              'Module::Build::Platform::os2'=> '0.340201',
              'Module::Build::PodParser'=> '0.340201',
              'Module::Build::Version'=> '0.77',
              'Module::CoreList'      => '2.18',
              'Module::Load'          => '0.16',
              'Module::Load::Conditional'=> '0.30',
              'Module::Loaded'        => '0.02',
              'Module::Pluggable'     => '3.9',
              'Module::Pluggable::Object'=> '3.9',
              'NDBM_File'             => '1.08',
              'NEXT'                  => '0.64',
              'Net::Ping'             => '2.36',
              'O'                     => '1.01',
              'OS2::Process'          => '1.03',
              'OS2::REXX'             => '1.04',
              'Object::Accessor'      => '0.34',
              'POSIX'                 => '1.17',
              'Package::Constants'    => '0.02',
              'Parse::CPAN::Meta'     => '1.39',
              'PerlIO'                => '1.06',
              'PerlIO::encoding'      => '0.11',
              'PerlIO::scalar'        => '0.07',
              'PerlIO::via'           => '0.07',
              'Pod::Checker'          => '1.45',
              'Pod::Find'             => '1.35',
              'Pod::Html'             => '1.09',
              'Pod::InputObjects'     => '1.31',
              'Pod::Man'              => '2.22',
              'Pod::ParseLink'        => '1.09',
              'Pod::ParseUtils'       => '1.36',
              'Pod::Parser'           => '1.37',
              'Pod::Perldoc'          => '3.14_04',
              'Pod::PlainText'        => '2.04',
              'Pod::Select'           => '1.36',
              'Pod::Simple'           => '3.07',
              'Pod::Simple::XHTML'    => '3.04',
              'Pod::Text'             => '3.13',
              'Pod::Text::Color'      => '2.05',
              'Pod::Text::Overstrike' => '2.03',
              'Pod::Text::Termcap'    => '2.05',
              'Pod::Usage'            => '1.36',
              'Safe'                  => '2.18',
              'Scalar::Util'          => '1.21',
              'Scalar::Util::PP'      => '1.21',
              'SelectSaver'           => '1.02',
              'SelfLoader'            => '1.17',
              'Socket'                => '1.82',
              'Storable'              => '2.20',
              'Switch'                => '2.14',
              'Symbol'                => '1.07',
              'Sys::Syslog'           => '0.27',
              'TAP::Base'             => '3.17',
              'TAP::Formatter::Base'  => '3.17',
              'TAP::Formatter::Color' => '3.17',
              'TAP::Formatter::Console'=> '3.17',
              'TAP::Formatter::Console::ParallelSession'=> '3.17',
              'TAP::Formatter::Console::Session'=> '3.17',
              'TAP::Formatter::File'  => '3.17',
              'TAP::Formatter::File::Session'=> '3.17',
              'TAP::Formatter::Session'=> '3.17',
              'TAP::Harness'          => '3.17',
              'TAP::Object'           => '3.17',
              'TAP::Parser'           => '3.17',
              'TAP::Parser::Aggregator'=> '3.17',
              'TAP::Parser::Grammar'  => '3.17',
              'TAP::Parser::Iterator' => '3.17',
              'TAP::Parser::Iterator::Array'=> '3.17',
              'TAP::Parser::Iterator::Process'=> '3.17',
              'TAP::Parser::Iterator::Stream'=> '3.17',
              'TAP::Parser::IteratorFactory'=> '3.17',
              'TAP::Parser::Multiplexer'=> '3.17',
              'TAP::Parser::Result'   => '3.17',
              'TAP::Parser::Result::Bailout'=> '3.17',
              'TAP::Parser::Result::Comment'=> '3.17',
              'TAP::Parser::Result::Plan'=> '3.17',
              'TAP::Parser::Result::Pragma'=> '3.17',
              'TAP::Parser::Result::Test'=> '3.17',
              'TAP::Parser::Result::Unknown'=> '3.17',
              'TAP::Parser::Result::Version'=> '3.17',
              'TAP::Parser::Result::YAML'=> '3.17',
              'TAP::Parser::ResultFactory'=> '3.17',
              'TAP::Parser::Scheduler'=> '3.17',
              'TAP::Parser::Scheduler::Job'=> '3.17',
              'TAP::Parser::Scheduler::Spinner'=> '3.17',
              'TAP::Parser::Source'   => '3.17',
              'TAP::Parser::Source::Perl'=> '3.17',
              'TAP::Parser::Utils'    => '3.17',
              'TAP::Parser::YAMLish::Reader'=> '3.17',
              'TAP::Parser::YAMLish::Writer'=> '3.17',
              'Term::ANSIColor'       => '2.00',
              'Term::ReadLine'        => '1.04',
              'Term::UI'              => '0.20',
              'Test'                  => '1.25_02',
              'Test::Builder'         => '0.92',
              'Test::Builder::Module' => '0.92',
              'Test::Builder::Tester' => '1.18',
              'Test::Builder::Tester::Color'=> '1.18',
              'Test::Harness'         => '3.17',
              'Test::More'            => '0.92',
              'Test::Simple'          => '0.92',
              'Text::ParseWords'      => '3.27',
              'Text::Tabs'            => '2009.0305',
              'Text::Wrap'            => '2009.0305',
              'Thread::Queue'         => '2.11',
              'Thread::Semaphore'     => '2.09',
              'Tie::Handle'           => '4.2',
              'Tie::Hash'             => '1.03',
              'Tie::RefHash'          => '1.38',
              'Tie::Scalar'           => '1.01',
              'Tie::StdHandle'        => '4.2',
              'Time::HiRes'           => '1.9719',
              'Time::Local'           => '1.1901',
              'Time::Piece'           => '1.15',
              'UNIVERSAL'             => '1.05',
              'Unicode'               => '5.1.0',
              'Unicode::Normalize'    => '1.03',
              'Unicode::UCD'          => '0.27',
              'VMS::Stdio'            => '2.4',
              'Win32'                 => '0.39',
              'Win32API::File'        => '0.1101',
              'XS::APItest'           => '0.15',
              'XS::Typemap'           => '0.03',
              'XSLoader'              => '0.10',
              'attributes'            => '0.09',
              'attrs'                 => '1.03',
              'autodie'               => '2.06_01',
              'autodie::exception'    => '2.06_01',
              'autodie::exception::system'=> '2.06_01',
              'autodie::hints'        => '2.06_01',
              'base'                  => '2.14',
              'bigint'                => '0.23',
              'bignum'                => '0.23',
              'bigrat'                => '0.23',
              'blib'                  => '1.04',
              'charnames'             => '1.07',
              'constant'              => '1.17',
              'encoding'              => '2.6_01',
              'feature'               => '1.13',
              'fields'                => '2.14',
              'lib'                   => '0.62',
              'mro'                   => '1.01',
              'open'                  => '1.07',
              'ops'                   => '1.02',
              'overload'              => '1.07',
              'overload::numbers'     => undef,
              'overloading'           => '0.01',
              'parent'                => '0.221',
              're'                    => '0.09',
              'threads'               => '1.72',
              'threads::shared'       => '1.29',
              'version'               => '0.77',
          },
          removed => {
              'CPAN::API::HOWTO'      => 1,
              'CPAN::DeferedCode'     => 1,
              'CPANPLUS::inc'         => 1,
              'ExtUtils::MakeMaker::bytes'=> 1,
              'ExtUtils::MakeMaker::vmsish'=> 1,
              'Test::Harness::Assert' => 1,
              'Test::Harness::Iterator'=> 1,
              'Test::Harness::Point'  => 1,
              'Test::Harness::Results'=> 1,
              'Test::Harness::Straps' => 1,
              'Test::Harness::Util'   => 1,
          }
      },
      5.011 => {
          delta_from => 5.010001,
          changed => {
              'Archive::Tar'          => '1.54',
              'Attribute::Handlers'   => '0.87',
              'AutoLoader'            => '5.70',
              'B::Deparse'            => '0.91',
              'B::Lint'               => '1.11_01',
              'B::Lint::Debug'        => '0.01',
              'CGI'                   => '3.45',
              'CGI::Apache'           => '1.01',
              'CGI::Carp'             => '3.45',
              'CGI::Pretty'           => '3.44',
              'CGI::Switch'           => '1.01',
              'CGI::Util'             => '3.45',
              'CPAN'                  => '1.94_51',
              'CPAN::Distribution'    => '1.94',
              'CPAN::FTP'             => '5.5002',
              'CPAN::Index'           => '1.94',
              'CPAN::LWP::UserAgent'  => '1.94',
              'CPANPLUS::Dist::Build' => '0.40',
              'CPANPLUS::Dist::Build::Constants'=> '0.40',
              'Carp'                  => '1.12',
              'Carp::Heavy'           => '1.12',
              'Class::ISA'            => '0.36',
              'Compress::Raw::Bzip2'  => '2.021',
              'Compress::Raw::Zlib'   => '2.021',
              'Compress::Zlib'        => '2.021',
              'Cwd'                   => '3.3002',
              'Data::Dumper'          => '2.125',
              'Encode'                => '2.37',
              'Exporter'              => '5.64',
              'Exporter::Heavy'       => '5.64',
              'ExtUtils::ParseXS'     => '2.200403',
              'File::Basename'        => '2.78',
              'File::Copy'            => '2.16',
              'File::stat'            => '1.02',
              'IO'                    => '1.25_01',
              'IO::Compress::Adapter::Bzip2'=> '2.021',
              'IO::Compress::Adapter::Deflate'=> '2.021',
              'IO::Compress::Adapter::Identity'=> '2.021',
              'IO::Compress::Base'    => '2.021',
              'IO::Compress::Base::Common'=> '2.021',
              'IO::Compress::Bzip2'   => '2.021',
              'IO::Compress::Deflate' => '2.021',
              'IO::Compress::Gzip'    => '2.021',
              'IO::Compress::Gzip::Constants'=> '2.021',
              'IO::Compress::RawDeflate'=> '2.021',
              'IO::Compress::Zip'     => '2.021',
              'IO::Compress::Zip::Constants'=> '2.021',
              'IO::Compress::Zlib::Constants'=> '2.021',
              'IO::Compress::Zlib::Extra'=> '2.021',
              'IO::Uncompress::Adapter::Bunzip2'=> '2.021',
              'IO::Uncompress::Adapter::Identity'=> '2.021',
              'IO::Uncompress::Adapter::Inflate'=> '2.021',
              'IO::Uncompress::AnyInflate'=> '2.021',
              'IO::Uncompress::AnyUncompress'=> '2.021',
              'IO::Uncompress::Base'  => '2.021',
              'IO::Uncompress::Bunzip2'=> '2.021',
              'IO::Uncompress::Gunzip'=> '2.021',
              'IO::Uncompress::Inflate'=> '2.021',
              'IO::Uncompress::RawInflate'=> '2.021',
              'IO::Uncompress::Unzip' => '2.021',
              'IO::Zlib'              => '1.10',
              'IPC::Cmd'              => '0.50',
              'IPC::Open3'            => '1.05',
              'Locale::Maketext::Simple'=> '0.21',
              'Log::Message::Simple'  => '0.06',
              'Math::BigInt'          => '1.89_01',
              'Math::BigRat'          => '0.24',
              'Module::Build'         => '0.35',
              'Module::Build::Base'   => '0.35',
              'Module::Build::Compat' => '0.35',
              'Module::Build::Config' => '0.35',
              'Module::Build::Cookbook'=> '0.35',
              'Module::Build::Dumper' => '0.35',
              'Module::Build::ModuleInfo'=> '0.35',
              'Module::Build::Notes'  => '0.35',
              'Module::Build::PPMMaker'=> '0.35',
              'Module::Build::Platform::Amiga'=> '0.35',
              'Module::Build::Platform::Default'=> '0.35',
              'Module::Build::Platform::EBCDIC'=> '0.35',
              'Module::Build::Platform::MPEiX'=> '0.35',
              'Module::Build::Platform::MacOS'=> '0.35',
              'Module::Build::Platform::RiscOS'=> '0.35',
              'Module::Build::Platform::Unix'=> '0.35',
              'Module::Build::Platform::VMS'=> '0.35',
              'Module::Build::Platform::VOS'=> '0.35',
              'Module::Build::Platform::Windows'=> '0.35',
              'Module::Build::Platform::aix'=> '0.35',
              'Module::Build::Platform::cygwin'=> '0.35',
              'Module::Build::Platform::darwin'=> '0.35',
              'Module::Build::Platform::os2'=> '0.35',
              'Module::Build::PodParser'=> '0.35',
              'Module::CoreList'      => '2.19',
              'Module::Loaded'        => '0.06',
              'Opcode'                => '1.13',
              'PerlIO::via'           => '0.08',
              'Pod::Perldoc'          => '3.15_01',
              'Pod::Plainer'          => '1.01',
              'Safe'                  => '2.19',
              'Socket'                => '1.84',
              'Switch'                => '2.14_01',
              'Term::ANSIColor'       => '2.02',
              'Term::ReadLine'        => '1.05',
              'Text::Balanced'        => '2.02',
              'Text::Soundex'         => '3.03_01',
              'Time::Local'           => '1.1901_01',
              'Unicode::Collate'      => '0.52_01',
              'attributes'            => '0.12',
              'constant'              => '1.19',
              'deprecate'             => '0.01',
              'overload'              => '1.08',
              'parent'                => '0.223',
              're'                    => '0.10',
              'threads'               => '1.74',
              'threads::shared'       => '1.31',
              'warnings'              => '1.07',
          },
          removed => {
              'attrs'                 => 1,
          }
      },
      5.011001 => {
          delta_from => 5.011,
          changed => {
              'B'                     => '1.23',
              'B::Concise'            => '0.77',
              'B::Deparse'            => '0.92',
              'CGI'                   => '3.48',
              'CGI::Pretty'           => '3.46',
              'CGI::Util'             => '3.48',
              'CPANPLUS'              => '0.89_03',
              'CPANPLUS::Internals'   => '0.89_03',
              'CPANPLUS::Shell::Default'=> '0.89_03',
              'Carp'                  => '1.13',
              'Carp::Heavy'           => '1.13',
              'ExtUtils::CBuilder'    => '0.260301',
              'ExtUtils::CBuilder::Base'=> '0.260301',
              'ExtUtils::CBuilder::Platform::Unix'=> '0.260301',
              'ExtUtils::CBuilder::Platform::VMS'=> '0.260301',
              'ExtUtils::CBuilder::Platform::Windows'=> '0.260301',
              'ExtUtils::CBuilder::Platform::aix'=> '0.260301',
              'ExtUtils::CBuilder::Platform::cygwin'=> '0.260301',
              'ExtUtils::CBuilder::Platform::darwin'=> '0.260301',
              'ExtUtils::CBuilder::Platform::dec_osf'=> '0.260301',
              'ExtUtils::CBuilder::Platform::os2'=> '0.260301',
              'ExtUtils::Install'     => '1.55',
              'ExtUtils::Manifest'    => '1.57',
              'ExtUtils::Packlist'    => '1.44',
              'ExtUtils::ParseXS'     => '2.21',
              'File::Glob'            => '1.07',
              'File::Path'            => '2.08',
              'IO'                    => '1.25_02',
              'Module::CoreList'      => '2.21',
              'OS2::DLL'              => '1.04',
              'OS2::Process'          => '1.04',
              'Object::Accessor'      => '0.36',
              'Opcode'                => '1.15',
              'POSIX'                 => '1.18',
              'Parse::CPAN::Meta'     => '1.40',
              'PerlIO::via'           => '0.09',
              'Pod::Simple'           => '3.08',
              'Socket'                => '1.85',
              'Storable'              => '2.22',
              'Switch'                => '2.15',
              'Test::Builder'         => '0.94',
              'Test::Builder::Module' => '0.94',
              'Test::More'            => '0.94',
              'Test::Simple'          => '0.94',
              'XS::APItest'           => '0.16',
              'mro'                   => '1.02',
              'overload'              => '1.09',
              'threads::shared'       => '1.32',
          },
          removed => {
          }
      },
      5.011002 => {
          delta_from => 5.011001,
          changed => {
              'B::Concise'            => '0.78',
              'B::Deparse'            => '0.93',
              'CPANPLUS'              => '0.89_09',
              'CPANPLUS::Dist::Build' => '0.44',
              'CPANPLUS::Dist::Build::Constants'=> '0.44',
              'CPANPLUS::Internals'   => '0.89_09',
              'CPANPLUS::Shell::Default'=> '0.89_09',
              'Carp'                  => '1.14',
              'Carp::Heavy'           => '1.14',
              'Compress::Zlib'        => '2.022',
              'DBM_Filter'            => '0.03',
              'Encode'                => '2.38',
              'Encode::Byte'          => '2.04',
              'Encode::CN'            => '2.03',
              'Encode::JP'            => '2.04',
              'Encode::KR'            => '2.03',
              'Encode::TW'            => '2.03',
              'Encode::Unicode'       => '2.07',
              'Env'                   => '1.01',
              'Exporter'              => '5.64_01',
              'Exporter::Heavy'       => '5.64_01',
              'ExtUtils::CBuilder'    => '0.27',
              'ExtUtils::CBuilder::Base'=> '0.27',
              'ExtUtils::CBuilder::Platform::Unix'=> '0.27',
              'ExtUtils::CBuilder::Platform::VMS'=> '0.27',
              'ExtUtils::CBuilder::Platform::Windows'=> '0.27',
              'ExtUtils::CBuilder::Platform::Windows::BCC'=> '0.27',
              'ExtUtils::CBuilder::Platform::Windows::GCC'=> '0.27',
              'ExtUtils::CBuilder::Platform::Windows::MSVC'=> '0.27',
              'ExtUtils::CBuilder::Platform::aix'=> '0.27',
              'ExtUtils::CBuilder::Platform::cygwin'=> '0.27',
              'ExtUtils::CBuilder::Platform::darwin'=> '0.27',
              'ExtUtils::CBuilder::Platform::dec_osf'=> '0.27',
              'ExtUtils::CBuilder::Platform::os2'=> '0.27',
              'File::Fetch'           => '0.22',
              'I18N::LangTags::Detect'=> '1.04',
              'I18N::Langinfo'        => '0.03',
              'IO::Compress::Adapter::Bzip2'=> '2.022',
              'IO::Compress::Adapter::Deflate'=> '2.022',
              'IO::Compress::Adapter::Identity'=> '2.022',
              'IO::Compress::Base'    => '2.022',
              'IO::Compress::Base::Common'=> '2.022',
              'IO::Compress::Bzip2'   => '2.022',
              'IO::Compress::Deflate' => '2.022',
              'IO::Compress::Gzip'    => '2.022',
              'IO::Compress::Gzip::Constants'=> '2.022',
              'IO::Compress::RawDeflate'=> '2.022',
              'IO::Compress::Zip'     => '2.022',
              'IO::Compress::Zip::Constants'=> '2.022',
              'IO::Compress::Zlib::Constants'=> '2.022',
              'IO::Compress::Zlib::Extra'=> '2.022',
              'IO::Uncompress::Adapter::Bunzip2'=> '2.022',
              'IO::Uncompress::Adapter::Identity'=> '2.022',
              'IO::Uncompress::Adapter::Inflate'=> '2.022',
              'IO::Uncompress::AnyInflate'=> '2.022',
              'IO::Uncompress::AnyUncompress'=> '2.022',
              'IO::Uncompress::Base'  => '2.022',
              'IO::Uncompress::Bunzip2'=> '2.022',
              'IO::Uncompress::Gunzip'=> '2.022',
              'IO::Uncompress::Inflate'=> '2.022',
              'IO::Uncompress::RawInflate'=> '2.022',
              'IO::Uncompress::Unzip' => '2.022',
              'IPC::Cmd'              => '0.54',
              'List::Util'            => '1.22',
              'List::Util::PP'        => '1.22',
              'List::Util::XS'        => '1.22',
              'Locale::Maketext'      => '1.14',
              'Module::Build'         => '0.35_09',
              'Module::Build::Base'   => '0.35_09',
              'Module::Build::Compat' => '0.35_09',
              'Module::Build::Config' => '0.35_09',
              'Module::Build::Cookbook'=> '0.35_09',
              'Module::Build::Dumper' => '0.35_09',
              'Module::Build::ModuleInfo'=> '0.35_09',
              'Module::Build::Notes'  => '0.35_09',
              'Module::Build::PPMMaker'=> '0.35_09',
              'Module::Build::Platform::Amiga'=> '0.35_09',
              'Module::Build::Platform::Default'=> '0.35_09',
              'Module::Build::Platform::EBCDIC'=> '0.35_09',
              'Module::Build::Platform::MPEiX'=> '0.35_09',
              'Module::Build::Platform::MacOS'=> '0.35_09',
              'Module::Build::Platform::RiscOS'=> '0.35_09',
              'Module::Build::Platform::Unix'=> '0.35_09',
              'Module::Build::Platform::VMS'=> '0.35_09',
              'Module::Build::Platform::VOS'=> '0.35_09',
              'Module::Build::Platform::Windows'=> '0.35_09',
              'Module::Build::Platform::aix'=> '0.35_09',
              'Module::Build::Platform::cygwin'=> '0.35_09',
              'Module::Build::Platform::darwin'=> '0.35_09',
              'Module::Build::Platform::os2'=> '0.35_09',
              'Module::Build::PodParser'=> '0.35_09',
              'Module::Build::YAML'   => '1.40',
              'Module::CoreList'      => '2.23',
              'Module::Load::Conditional'=> '0.34',
              'Pod::Simple'           => '3.10',
              'Pod::Simple::XHTML'    => '3.10',
              'Scalar::Util'          => '1.22',
              'Scalar::Util::PP'      => '1.22',
              'Switch'                => '2.16',
              'XS::APItest'           => '0.17',
              'XS::APItest::KeywordRPN'=> '0.003',
              'base'                  => '2.15',
              'diagnostics'           => '1.18',
              'fields'                => '2.15',
              'inc::latest'           => '0.35_09',
              'legacy'                => '1.00',
              'overload'              => '1.10',
          },
          removed => {
          }
      },
      5.011003 => {
          delta_from => 5.011002,
          changed => {
              'App::Cpan'             => '1.570001',
              'Archive::Extract'      => '0.36',
              'CPAN'                  => '1.94_5301',
              'CPAN::FTP'             => '5.5004',
              'CPAN::FirstTime'       => '5.530001',
              'CPAN::Mirrors'         => '1.770001',
              'CPANPLUS'              => '0.90',
              'CPANPLUS::Internals'   => '0.90',
              'CPANPLUS::Shell::Default'=> '0.90',
              'Cwd'                   => '3.31',
              'Encode'                => '2.39',
              'ExtUtils::Command::MM' => '6.56',
              'ExtUtils::Liblist'     => '6.56',
              'ExtUtils::Liblist::Kid'=> '6.56',
              'ExtUtils::MM'          => '6.56',
              'ExtUtils::MM_AIX'      => '6.56',
              'ExtUtils::MM_Any'      => '6.56',
              'ExtUtils::MM_BeOS'     => '6.56',
              'ExtUtils::MM_Cygwin'   => '6.56',
              'ExtUtils::MM_DOS'      => '6.56',
              'ExtUtils::MM_Darwin'   => '6.56',
              'ExtUtils::MM_MacOS'    => '6.56',
              'ExtUtils::MM_NW5'      => '6.56',
              'ExtUtils::MM_OS2'      => '6.56',
              'ExtUtils::MM_QNX'      => '6.56',
              'ExtUtils::MM_UWIN'     => '6.56',
              'ExtUtils::MM_Unix'     => '6.56',
              'ExtUtils::MM_VMS'      => '6.56',
              'ExtUtils::MM_VOS'      => '6.56',
              'ExtUtils::MM_Win32'    => '6.56',
              'ExtUtils::MM_Win95'    => '6.56',
              'ExtUtils::MY'          => '6.56',
              'ExtUtils::MakeMaker'   => '6.56',
              'ExtUtils::MakeMaker::Config'=> '6.56',
              'ExtUtils::Mkbootstrap' => '6.56',
              'ExtUtils::Mksymlists'  => '6.56',
              'ExtUtils::testlib'     => '6.56',
              'File::Find'            => '1.15',
              'File::Path'            => '2.08_01',
              'File::Spec'            => '3.31',
              'Module::Build'         => '0.36',
              'Module::Build::Base'   => '0.36',
              'Module::Build::Compat' => '0.36',
              'Module::Build::Config' => '0.36',
              'Module::Build::Cookbook'=> '0.36',
              'Module::Build::Dumper' => '0.36',
              'Module::Build::ModuleInfo'=> '0.36',
              'Module::Build::Notes'  => '0.36',
              'Module::Build::PPMMaker'=> '0.36',
              'Module::Build::Platform::Amiga'=> '0.36',
              'Module::Build::Platform::Default'=> '0.36',
              'Module::Build::Platform::EBCDIC'=> '0.36',
              'Module::Build::Platform::MPEiX'=> '0.36',
              'Module::Build::Platform::MacOS'=> '0.36',
              'Module::Build::Platform::RiscOS'=> '0.36',
              'Module::Build::Platform::Unix'=> '0.36',
              'Module::Build::Platform::VMS'=> '0.36',
              'Module::Build::Platform::VOS'=> '0.36',
              'Module::Build::Platform::Windows'=> '0.36',
              'Module::Build::Platform::aix'=> '0.36',
              'Module::Build::Platform::cygwin'=> '0.36',
              'Module::Build::Platform::darwin'=> '0.36',
              'Module::Build::Platform::os2'=> '0.36',
              'Module::Build::PodParser'=> '0.36',
              'Module::CoreList'      => '2.24',
              'POSIX'                 => '1.19',
              'Pod::Simple'           => '3.13',
              'Pod::Simple::BlackBox' => '3.13',
              'Pod::Simple::Checker'  => '3.13',
              'Pod::Simple::Debug'    => '3.13',
              'Pod::Simple::DumpAsText'=> '3.13',
              'Pod::Simple::DumpAsXML'=> '3.13',
              'Pod::Simple::HTML'     => '3.13',
              'Pod::Simple::HTMLBatch'=> '3.13',
              'Pod::Simple::LinkSection'=> '3.13',
              'Pod::Simple::Methody'  => '3.13',
              'Pod::Simple::Progress' => '3.13',
              'Pod::Simple::PullParser'=> '3.13',
              'Pod::Simple::PullParserEndToken'=> '3.13',
              'Pod::Simple::PullParserStartToken'=> '3.13',
              'Pod::Simple::PullParserTextToken'=> '3.13',
              'Pod::Simple::PullParserToken'=> '3.13',
              'Pod::Simple::RTF'      => '3.13',
              'Pod::Simple::Search'   => '3.13',
              'Pod::Simple::SimpleTree'=> '3.13',
              'Pod::Simple::Text'     => '3.13',
              'Pod::Simple::TextContent'=> '3.13',
              'Pod::Simple::TiedOutFH'=> '3.13',
              'Pod::Simple::Transcode'=> '3.13',
              'Pod::Simple::TranscodeDumb'=> '3.13',
              'Pod::Simple::TranscodeSmart'=> '3.13',
              'Pod::Simple::XHTML'    => '3.13',
              'Pod::Simple::XMLOutStream'=> '3.13',
              'Safe'                  => '2.20',
              'Unicode'               => '5.2.0',
              'constant'              => '1.20',
              'diagnostics'           => '1.19',
              'feature'               => '1.14',
              'inc::latest'           => '0.36',
              'threads'               => '1.75',
              'warnings'              => '1.08',
          },
          removed => {
              'legacy'                => 1,
          }
      },
      5.011004 => {
          delta_from => 5.011003,
          changed => {
              'App::Cpan'             => '1.5701',
              'Archive::Extract'      => '0.38',
              'B::Deparse'            => '0.94',
              'CPAN'                  => '1.94_54',
              'CPAN::FirstTime'       => '5.53',
              'CPAN::Mirrors'         => '1.77',
              'Carp'                  => '1.15',
              'Carp::Heavy'           => '1.15',
              'Compress::Raw::Bzip2'  => '2.024',
              'Compress::Raw::Zlib'   => '2.024',
              'Compress::Zlib'        => '2.024',
              'File::Copy'            => '2.17',
              'File::Fetch'           => '0.24',
              'GDBM_File'             => '1.10',
              'IO::Compress::Adapter::Bzip2'=> '2.024',
              'IO::Compress::Adapter::Deflate'=> '2.024',
              'IO::Compress::Adapter::Identity'=> '2.024',
              'IO::Compress::Base'    => '2.024',
              'IO::Compress::Base::Common'=> '2.024',
              'IO::Compress::Bzip2'   => '2.024',
              'IO::Compress::Deflate' => '2.024',
              'IO::Compress::Gzip'    => '2.024',
              'IO::Compress::Gzip::Constants'=> '2.024',
              'IO::Compress::RawDeflate'=> '2.024',
              'IO::Compress::Zip'     => '2.024',
              'IO::Compress::Zip::Constants'=> '2.024',
              'IO::Compress::Zlib::Constants'=> '2.024',
              'IO::Compress::Zlib::Extra'=> '2.024',
              'IO::Uncompress::Adapter::Bunzip2'=> '2.024',
              'IO::Uncompress::Adapter::Identity'=> '2.024',
              'IO::Uncompress::Adapter::Inflate'=> '2.024',
              'IO::Uncompress::AnyInflate'=> '2.024',
              'IO::Uncompress::AnyUncompress'=> '2.024',
              'IO::Uncompress::Base'  => '2.024',
              'IO::Uncompress::Bunzip2'=> '2.024',
              'IO::Uncompress::Gunzip'=> '2.024',
              'IO::Uncompress::Inflate'=> '2.024',
              'IO::Uncompress::RawInflate'=> '2.024',
              'IO::Uncompress::Unzip' => '2.024',
              'Module::Build'         => '0.3603',
              'Module::Build::Base'   => '0.3603',
              'Module::Build::Compat' => '0.3603',
              'Module::Build::Config' => '0.3603',
              'Module::Build::Cookbook'=> '0.3603',
              'Module::Build::Dumper' => '0.3603',
              'Module::Build::ModuleInfo'=> '0.3603',
              'Module::Build::Notes'  => '0.3603',
              'Module::Build::PPMMaker'=> '0.3603',
              'Module::Build::Platform::Amiga'=> '0.3603',
              'Module::Build::Platform::Default'=> '0.3603',
              'Module::Build::Platform::EBCDIC'=> '0.3603',
              'Module::Build::Platform::MPEiX'=> '0.3603',
              'Module::Build::Platform::MacOS'=> '0.3603',
              'Module::Build::Platform::RiscOS'=> '0.3603',
              'Module::Build::Platform::Unix'=> '0.3603',
              'Module::Build::Platform::VMS'=> '0.3603',
              'Module::Build::Platform::VOS'=> '0.3603',
              'Module::Build::Platform::Windows'=> '0.3603',
              'Module::Build::Platform::aix'=> '0.3603',
              'Module::Build::Platform::cygwin'=> '0.3603',
              'Module::Build::Platform::darwin'=> '0.3603',
              'Module::Build::Platform::os2'=> '0.3603',
              'Module::Build::PodParser'=> '0.3603',
              'Module::CoreList'      => '2.25',
              'PerlIO::encoding'      => '0.12',
              'Safe'                  => '2.21',
              'UNIVERSAL'             => '1.06',
              'feature'               => '1.15',
              'inc::latest'           => '0.3603',
              'less'                  => '0.03',
              're'                    => '0.11',
              'version'               => '0.81',
              'warnings'              => '1.09',
          },
          removed => {
          }
      },
      5.011005 => {
          delta_from => 5.011004,
          changed => {
              'B::Debug'              => '1.12',
              'CPAN'                  => '1.94_56',
              'CPAN::Debug'           => '5.5001',
              'CPAN::Distribution'    => '1.9456',
              'CPAN::FirstTime'       => '5.5301',
              'CPAN::HandleConfig'    => '5.5001',
              'CPAN::Shell'           => '5.5001',
              'CPAN::Tarzip'          => '5.5011',
              'CPANPLUS::Dist::Build' => '0.46',
              'CPANPLUS::Dist::Build::Constants'=> '0.46',
              'Module::CoreList'      => '2.26',
              'Pod::Man'              => '2.23',
              'Pod::ParseLink'        => '1.10',
              'Pod::Perldoc'          => '3.15_02',
              'Pod::Plainer'          => '1.02',
              'Pod::Text'             => '3.14',
              'Pod::Text::Color'      => '2.06',
              'Pod::Text::Overstrike' => '2.04',
              'Pod::Text::Termcap'    => '2.06',
              'Safe'                  => '2.22',
              'Socket'                => '1.86',
              'version'               => '0.82',
          },
          removed => {
          }
      },
      5.012 => {
          delta_from => 5.011005,
          changed => {
              'B::Deparse'            => '0.96',
              'CPAN::Distribution'    => '1.9456_01',
              'Module::CoreList'      => '2.29',
              'Safe'                  => '2.25',
              'Socket'                => '1.87',
              'Tie::Scalar'           => '1.02',
              'Time::Piece'           => '1.15_01',
              'bytes'                 => '1.04',
              'feature'               => '1.16',
              'utf8'                  => '1.08',
          },
          removed => {
          }
      },
      5.012001 => {
          delta_from => 5.012,
          changed => {
              'B::Deparse'            => '0.97',
              'CGI'                   => '3.49',
              'CGI::Fast'             => '1.08',
              'Carp'                  => '1.16',
              'Carp::Heavy'           => '1.16',
              'File::Copy'            => '2.18',
              'Module::CoreList'      => '2.32',
              'Pod::Functions'        => '1.04',
              'Pod::Simple'           => '3.14',
              'Pod::Simple::BlackBox' => '3.14',
              'Pod::Simple::Checker'  => '3.14',
              'Pod::Simple::Debug'    => '3.14',
              'Pod::Simple::DumpAsText'=> '3.14',
              'Pod::Simple::DumpAsXML'=> '3.14',
              'Pod::Simple::HTML'     => '3.14',
              'Pod::Simple::HTMLBatch'=> '3.14',
              'Pod::Simple::LinkSection'=> '3.14',
              'Pod::Simple::Methody'  => '3.14',
              'Pod::Simple::Progress' => '3.14',
              'Pod::Simple::PullParser'=> '3.14',
              'Pod::Simple::PullParserEndToken'=> '3.14',
              'Pod::Simple::PullParserStartToken'=> '3.14',
              'Pod::Simple::PullParserTextToken'=> '3.14',
              'Pod::Simple::PullParserToken'=> '3.14',
              'Pod::Simple::RTF'      => '3.14',
              'Pod::Simple::Search'   => '3.14',
              'Pod::Simple::SimpleTree'=> '3.14',
              'Pod::Simple::Text'     => '3.14',
              'Pod::Simple::TextContent'=> '3.14',
              'Pod::Simple::TiedOutFH'=> '3.14',
              'Pod::Simple::Transcode'=> '3.14',
              'Pod::Simple::TranscodeDumb'=> '3.14',
              'Pod::Simple::TranscodeSmart'=> '3.14',
              'Pod::Simple::XHTML'    => '3.14',
              'Pod::Simple::XMLOutStream'=> '3.14',
              'Safe'                  => '2.27',
          },
          removed => {
          }
      },
      5.012002 => {
          delta_from => 5.012001,
          changed => {
              'Carp'                  => '1.17',
              'Carp::Heavy'           => '1.17',
              'File::Spec'            => '3.31_01',
              'Module::CoreList'      => '2.38',
              'Module::Load::Conditional'=> '0.38',
              'PerlIO::scalar'        => '0.08',
          },
          removed => {
          }
      },
      5.012003 => {
          delta_from => 5.012002,
          changed => {
              'B::Deparse'            => '0.9701',
              'Module::Build::Platform::cygwin'=> '0.360301',
              'Module::CoreList'      => '2.43',
              'Socket'                => '1.87_01',
          },
          removed => {
          }
      },
      5.012004 => {
          delta_from => 5.012003,
          changed => {
              'Module::CoreList'      => '2.50',
          },
          removed => {
          }
      },
      5.012005 => {
          delta_from => 5.012004,
          changed => {
              'B::Concise'            => '0.78_01',
              'Encode'                => '2.39_01',
              'File::Glob'            => '1.07_01',
              'Module::CoreList'      => '2.50_02',
              'Unicode::UCD'          => '0.29',
              'charnames'             => '1.07_01',
          },
          removed => {
          }
      },
      5.013 => {
          delta_from => 5.012,
          changed => {
              'CGI'                   => '3.49',
              'CGI::Fast'             => '1.08',
              'Data::Dumper'          => '2.126',
              'ExtUtils::MM_Unix'     => '6.5601',
              'ExtUtils::MakeMaker'   => '6.5601',
              'File::Copy'            => '2.18',
              'IPC::Open3'            => '1.06',
              'MIME::Base64'          => '3.09',
              'MIME::QuotedPrint'     => '3.09',
              'Module::CoreList'      => '2.31',
              'Pod::Functions'        => '1.04',
              'XS::APItest'           => '0.18',
              'XS::APItest::KeywordRPN'=> '0.004',
              'feature'               => '1.17',
              'threads'               => '1.77_01',
              'threads::shared'       => '1.33',
          },
          removed => {
          }
      },
      5.013001 => {
          delta_from => 5.012001,
          changed => {
              'Data::Dumper'          => '2.126',
              'Dumpvalue'             => '1.14',
              'Errno'                 => '1.12',
              'ExtUtils::MM_Unix'     => '6.5601',
              'ExtUtils::MakeMaker'   => '6.5601',
              'ExtUtils::ParseXS'     => '2.2205',
              'File::Find'            => '1.16',
              'IPC::Cmd'              => '0.58',
              'IPC::Open3'            => '1.06',
              'List::Util'            => '1.23',
              'List::Util::PP'        => '1.23',
              'List::Util::XS'        => '1.23',
              'Locale::Codes'         => '3.12',
              'Locale::Codes::Country'=> '3.12',
              'Locale::Codes::Currency'=> '3.12',
              'Locale::Codes::Language'=> '3.12',
              'Locale::Codes::Script' => '3.12',
              'Locale::Constants'     => '3.12',
              'Locale::Country'       => '3.12',
              'Locale::Currency'      => '3.12',
              'Locale::Language'      => '3.12',
              'Locale::Script'        => '3.12',
              'MIME::Base64'          => '3.09',
              'MIME::QuotedPrint'     => '3.09',
              'Module::Build::Platform::cygwin'=> '0.360301',
              'Module::CoreList'      => '2.34',
              'Module::Load::Conditional'=> '0.38',
              'PerlIO::scalar'        => '0.08',
              'Scalar::Util'          => '1.23',
              'Scalar::Util::PP'      => '1.23',
              'Socket'                => '1.88',
              'Term::ReadLine'        => '1.06',
              'Unicode::UCD'          => '0.28',
              'XS::APItest'           => '0.19',
              'XS::APItest::KeywordRPN'=> '0.004',
              'charnames'             => '1.08',
              'feature'               => '1.17',
              'threads'               => '1.77_01',
              'threads::shared'       => '1.33',
          },
          removed => {
              'Class::ISA'            => 1,
              'Pod::Plainer'          => 1,
              'Switch'                => 1,
          }
      },
      5.013002 => {
          delta_from => 5.013001,
          changed => {
              'B::Concise'            => '0.79',
              'B::Deparse'            => '0.98',
              'CPAN'                  => '1.94_57',
              'CPAN::Distribution'    => '1.9600',
              'Exporter'              => '5.64_02',
              'Exporter::Heavy'       => '5.64_02',
              'File::Copy'            => '2.19',
              'Hash::Util'            => '0.08',
              'IO::Socket'            => '1.32',
              'Locale::Codes'         => '3.13',
              'Locale::Codes::Country'=> '3.13',
              'Locale::Codes::Currency'=> '3.13',
              'Locale::Codes::Language'=> '3.13',
              'Locale::Codes::Script' => '3.13',
              'Locale::Constants'     => '3.13',
              'Locale::Country'       => '3.13',
              'Locale::Currency'      => '3.13',
              'Locale::Language'      => '3.13',
              'Locale::Script'        => '3.13',
              'Search::Dict'          => '1.03',
              'Socket'                => '1.89',
              'Thread::Semaphore'     => '2.11',
              'UNIVERSAL'             => '1.07',
              'VMS::DCLsym'           => '1.04',
              'mro'                   => '1.03',
              'threads'               => '1.77_02',
              'threads::shared'       => '1.33_01',
          },
          removed => {
          }
      },
      5.013003 => {
          delta_from => 5.013002,
          changed => {
              'App::Prove'            => '3.21',
              'App::Prove::State'     => '3.21',
              'App::Prove::State::Result'=> '3.21',
              'App::Prove::State::Result::Test'=> '3.21',
              'Archive::Extract'      => '0.42',
              'Archive::Tar'          => '1.64',
              'Archive::Tar::Constant'=> '1.64',
              'Archive::Tar::File'    => '1.64',
              'Attribute::Handlers'   => '0.88',
              'CPANPLUS'              => '0.9007',
              'CPANPLUS::Internals'   => '0.9007',
              'CPANPLUS::Shell::Default'=> '0.9007',
              'Compress::Raw::Bzip2'  => '2.027',
              'Compress::Raw::Zlib'   => '2.027_01',
              'Compress::Zlib'        => '2.027',
              'DB'                    => '1.03',
              'Digest::MD5'           => '2.40',
              'Digest::SHA'           => '5.48',
              'Exporter'              => '5.64_03',
              'Exporter::Heavy'       => '5.64_03',
              'ExtUtils::CBuilder'    => '0.2703',
              'ExtUtils::CBuilder::Base'=> '0.2703_01',
              'ExtUtils::CBuilder::Platform::Unix'=> '0.2703',
              'ExtUtils::CBuilder::Platform::VMS'=> '0.2703',
              'ExtUtils::CBuilder::Platform::Windows'=> '0.2703',
              'ExtUtils::CBuilder::Platform::Windows::BCC'=> '0.2703',
              'ExtUtils::CBuilder::Platform::Windows::GCC'=> '0.2703',
              'ExtUtils::CBuilder::Platform::Windows::MSVC'=> '0.2703',
              'ExtUtils::CBuilder::Platform::aix'=> '0.2703',
              'ExtUtils::CBuilder::Platform::cygwin'=> '0.2703',
              'ExtUtils::CBuilder::Platform::darwin'=> '0.2703',
              'ExtUtils::CBuilder::Platform::dec_osf'=> '0.2703',
              'ExtUtils::CBuilder::Platform::os2'=> '0.2703',
              'ExtUtils::Manifest'    => '1.58',
              'ExtUtils::ParseXS'     => '2.2206',
              'Fatal'                 => '2.10',
              'File::Basename'        => '2.79',
              'File::Copy'            => '2.20',
              'File::DosGlob'         => '1.02',
              'File::Find'            => '1.17',
              'File::Glob'            => '1.08',
              'File::stat'            => '1.03',
              'I18N::LangTags'        => '0.35_01',
              'I18N::LangTags::List'  => '0.35_01',
              'IO::Compress::Adapter::Bzip2'=> '2.027',
              'IO::Compress::Adapter::Deflate'=> '2.027',
              'IO::Compress::Adapter::Identity'=> '2.027',
              'IO::Compress::Base'    => '2.027',
              'IO::Compress::Base::Common'=> '2.027',
              'IO::Compress::Bzip2'   => '2.027',
              'IO::Compress::Deflate' => '2.027',
              'IO::Compress::Gzip'    => '2.027',
              'IO::Compress::Gzip::Constants'=> '2.027',
              'IO::Compress::RawDeflate'=> '2.027',
              'IO::Compress::Zip'     => '2.027',
              'IO::Compress::Zip::Constants'=> '2.027',
              'IO::Compress::Zlib::Constants'=> '2.027',
              'IO::Compress::Zlib::Extra'=> '2.027',
              'IO::Uncompress::Adapter::Bunzip2'=> '2.027',
              'IO::Uncompress::Adapter::Identity'=> '2.027',
              'IO::Uncompress::Adapter::Inflate'=> '2.027',
              'IO::Uncompress::AnyInflate'=> '2.027',
              'IO::Uncompress::AnyUncompress'=> '2.027',
              'IO::Uncompress::Base'  => '2.027',
              'IO::Uncompress::Bunzip2'=> '2.027',
              'IO::Uncompress::Gunzip'=> '2.027',
              'IO::Uncompress::Inflate'=> '2.027',
              'IO::Uncompress::RawInflate'=> '2.027',
              'IO::Uncompress::Unzip' => '2.027',
              'IPC::Cmd'              => '0.60',
              'IPC::Msg'              => '2.03',
              'IPC::Semaphore'        => '2.03',
              'IPC::SharedMem'        => '2.03',
              'IPC::SysV'             => '2.03',
              'Locale::Maketext'      => '1.15',
              'Locale::Maketext::Guts'=> undef,
              'Locale::Maketext::GutsLoader'=> undef,
              'Module::Build'         => '0.3607',
              'Module::Build::Base'   => '0.3607',
              'Module::Build::Compat' => '0.3607',
              'Module::Build::Config' => '0.3607',
              'Module::Build::Cookbook'=> '0.3607',
              'Module::Build::Dumper' => '0.3607',
              'Module::Build::ModuleInfo'=> '0.3607',
              'Module::Build::Notes'  => '0.3607',
              'Module::Build::PPMMaker'=> '0.3607',
              'Module::Build::Platform::Amiga'=> '0.3607',
              'Module::Build::Platform::Default'=> '0.3607',
              'Module::Build::Platform::EBCDIC'=> '0.3607',
              'Module::Build::Platform::MPEiX'=> '0.3607',
              'Module::Build::Platform::MacOS'=> '0.3607',
              'Module::Build::Platform::RiscOS'=> '0.3607',
              'Module::Build::Platform::Unix'=> '0.3607',
              'Module::Build::Platform::VMS'=> '0.3607',
              'Module::Build::Platform::VOS'=> '0.3607',
              'Module::Build::Platform::Windows'=> '0.3607',
              'Module::Build::Platform::aix'=> '0.3607',
              'Module::Build::Platform::cygwin'=> '0.3607',
              'Module::Build::Platform::darwin'=> '0.3607',
              'Module::Build::Platform::os2'=> '0.3607',
              'Module::Build::PodParser'=> '0.3607',
              'Module::CoreList'      => '2.36',
              'Module::Load'          => '0.18',
              'TAP::Base'             => '3.21',
              'TAP::Formatter::Base'  => '3.21',
              'TAP::Formatter::Color' => '3.21',
              'TAP::Formatter::Console'=> '3.21',
              'TAP::Formatter::Console::ParallelSession'=> '3.21',
              'TAP::Formatter::Console::Session'=> '3.21',
              'TAP::Formatter::File'  => '3.21',
              'TAP::Formatter::File::Session'=> '3.21',
              'TAP::Formatter::Session'=> '3.21',
              'TAP::Harness'          => '3.21',
              'TAP::Object'           => '3.21',
              'TAP::Parser'           => '3.21',
              'TAP::Parser::Aggregator'=> '3.21',
              'TAP::Parser::Grammar'  => '3.21',
              'TAP::Parser::Iterator' => '3.21',
              'TAP::Parser::Iterator::Array'=> '3.21',
              'TAP::Parser::Iterator::Process'=> '3.21',
              'TAP::Parser::Iterator::Stream'=> '3.21',
              'TAP::Parser::IteratorFactory'=> '3.21',
              'TAP::Parser::Multiplexer'=> '3.21',
              'TAP::Parser::Result'   => '3.21',
              'TAP::Parser::Result::Bailout'=> '3.21',
              'TAP::Parser::Result::Comment'=> '3.21',
              'TAP::Parser::Result::Plan'=> '3.21',
              'TAP::Parser::Result::Pragma'=> '3.21',
              'TAP::Parser::Result::Test'=> '3.21',
              'TAP::Parser::Result::Unknown'=> '3.21',
              'TAP::Parser::Result::Version'=> '3.21',
              'TAP::Parser::Result::YAML'=> '3.21',
              'TAP::Parser::ResultFactory'=> '3.21',
              'TAP::Parser::Scheduler'=> '3.21',
              'TAP::Parser::Scheduler::Job'=> '3.21',
              'TAP::Parser::Scheduler::Spinner'=> '3.21',
              'TAP::Parser::Source'   => '3.21',
              'TAP::Parser::SourceHandler'=> '3.21',
              'TAP::Parser::SourceHandler::Executable'=> '3.21',
              'TAP::Parser::SourceHandler::File'=> '3.21',
              'TAP::Parser::SourceHandler::Handle'=> '3.21',
              'TAP::Parser::SourceHandler::Perl'=> '3.21',
              'TAP::Parser::SourceHandler::RawTAP'=> '3.21',
              'TAP::Parser::SourceHandler::pgTAP'=> '3.21',
              'TAP::Parser::Utils'    => '3.21',
              'TAP::Parser::YAMLish::Reader'=> '3.21',
              'TAP::Parser::YAMLish::Writer'=> '3.21',
              'Term::ANSIColor'       => '3.00',
              'Term::ReadLine'        => '1.07',
              'Test::Harness'         => '3.21',
              'Tie::Array'            => '1.04',
              'Time::HiRes'           => '1.9721',
              'Time::Piece'           => '1.20_01',
              'Unicode::Collate'      => '0.53',
              'Unicode::Normalize'    => '1.06',
              'Unicode::UCD'          => '0.29',
              'autodie'               => '2.10',
              'autodie::exception'    => '2.10',
              'autodie::exception::system'=> '2.10',
              'autodie::hints'        => '2.10',
              'blib'                  => '1.05',
              'charnames'             => '1.11',
              'diagnostics'           => '1.20',
              'inc::latest'           => '0.3607',
              'lib'                   => '0.63',
              're'                    => '0.12',
              'threads'               => '1.77_03',
              'threads::shared'       => '1.33_02',
              'vars'                  => '1.02',
              'warnings'              => '1.10',
          },
          removed => {
              'TAP::Parser::Source::Perl'=> 1,
          }
      },
      5.013004 => {
          delta_from => 5.013003,
          changed => {
              'App::Prove'            => '3.22',
              'App::Prove::State'     => '3.22',
              'App::Prove::State::Result'=> '3.22',
              'App::Prove::State::Result::Test'=> '3.22',
              'Archive::Tar'          => '1.68',
              'Archive::Tar::Constant'=> '1.68',
              'Archive::Tar::File'    => '1.68',
              'B::Lint'               => '1.12',
              'B::Lint::Debug'        => '1.12',
              'Carp'                  => '1.18',
              'Carp::Heavy'           => '1.18',
              'Compress::Raw::Bzip2'  => '2.030',
              'Compress::Raw::Zlib'   => '2.030',
              'Compress::Zlib'        => '2.030',
              'ExtUtils::ParseXS'     => '2.2207',
              'File::Spec'            => '3.31_01',
              'I18N::Langinfo'        => '0.04',
              'IO::Compress::Adapter::Bzip2'=> '2.030',
              'IO::Compress::Adapter::Deflate'=> '2.030',
              'IO::Compress::Adapter::Identity'=> '2.030',
              'IO::Compress::Base'    => '2.030',
              'IO::Compress::Base::Common'=> '2.030',
              'IO::Compress::Bzip2'   => '2.030',
              'IO::Compress::Deflate' => '2.030',
              'IO::Compress::Gzip'    => '2.030',
              'IO::Compress::Gzip::Constants'=> '2.030',
              'IO::Compress::RawDeflate'=> '2.030',
              'IO::Compress::Zip'     => '2.030',
              'IO::Compress::Zip::Constants'=> '2.030',
              'IO::Compress::Zlib::Constants'=> '2.030',
              'IO::Compress::Zlib::Extra'=> '2.030',
              'IO::Uncompress::Adapter::Bunzip2'=> '2.030',
              'IO::Uncompress::Adapter::Identity'=> '2.030',
              'IO::Uncompress::Adapter::Inflate'=> '2.030',
              'IO::Uncompress::AnyInflate'=> '2.030',
              'IO::Uncompress::AnyUncompress'=> '2.030',
              'IO::Uncompress::Base'  => '2.030',
              'IO::Uncompress::Bunzip2'=> '2.030',
              'IO::Uncompress::Gunzip'=> '2.030',
              'IO::Uncompress::Inflate'=> '2.030',
              'IO::Uncompress::RawInflate'=> '2.030',
              'IO::Uncompress::Unzip' => '2.030',
              'Module::CoreList'      => '2.37',
              'TAP::Base'             => '3.22',
              'TAP::Formatter::Base'  => '3.22',
              'TAP::Formatter::Color' => '3.22',
              'TAP::Formatter::Console'=> '3.22',
              'TAP::Formatter::Console::ParallelSession'=> '3.22',
              'TAP::Formatter::Console::Session'=> '3.22',
              'TAP::Formatter::File'  => '3.22',
              'TAP::Formatter::File::Session'=> '3.22',
              'TAP::Formatter::Session'=> '3.22',
              'TAP::Harness'          => '3.22',
              'TAP::Object'           => '3.22',
              'TAP::Parser'           => '3.22',
              'TAP::Parser::Aggregator'=> '3.22',
              'TAP::Parser::Grammar'  => '3.22',
              'TAP::Parser::Iterator' => '3.22',
              'TAP::Parser::Iterator::Array'=> '3.22',
              'TAP::Parser::Iterator::Process'=> '3.22',
              'TAP::Parser::Iterator::Stream'=> '3.22',
              'TAP::Parser::IteratorFactory'=> '3.22',
              'TAP::Parser::Multiplexer'=> '3.22',
              'TAP::Parser::Result'   => '3.22',
              'TAP::Parser::Result::Bailout'=> '3.22',
              'TAP::Parser::Result::Comment'=> '3.22',
              'TAP::Parser::Result::Plan'=> '3.22',
              'TAP::Parser::Result::Pragma'=> '3.22',
              'TAP::Parser::Result::Test'=> '3.22',
              'TAP::Parser::Result::Unknown'=> '3.22',
              'TAP::Parser::Result::Version'=> '3.22',
              'TAP::Parser::Result::YAML'=> '3.22',
              'TAP::Parser::ResultFactory'=> '3.22',
              'TAP::Parser::Scheduler'=> '3.22',
              'TAP::Parser::Scheduler::Job'=> '3.22',
              'TAP::Parser::Scheduler::Spinner'=> '3.22',
              'TAP::Parser::Source'   => '3.22',
              'TAP::Parser::SourceHandler'=> '3.22',
              'TAP::Parser::SourceHandler::Executable'=> '3.22',
              'TAP::Parser::SourceHandler::File'=> '3.22',
              'TAP::Parser::SourceHandler::Handle'=> '3.22',
              'TAP::Parser::SourceHandler::Perl'=> '3.22',
              'TAP::Parser::SourceHandler::RawTAP'=> '3.22',
              'TAP::Parser::Utils'    => '3.22',
              'TAP::Parser::YAMLish::Reader'=> '3.22',
              'TAP::Parser::YAMLish::Writer'=> '3.22',
              'Test::Builder'         => '0.96',
              'Test::Builder::Module' => '0.96',
              'Test::Builder::Tester' => '1.20',
              'Test::Builder::Tester::Color'=> '1.20',
              'Test::Harness'         => '3.22',
              'Test::More'            => '0.96',
              'Test::Simple'          => '0.96',
              'Unicode::Collate'      => '0.56',
              'Unicode::Collate::Locale'=> '0.56',
              'XS::APItest'           => '0.20',
              'charnames'             => '1.15',
              'feature'               => '1.18',
          },
          removed => {
              'TAP::Parser::SourceHandler::pgTAP'=> 1,
          }
      },
      5.013005 => {
          delta_from => 5.013004,
          changed => {
              'B::Debug'              => '1.16',
              'CPANPLUS::Dist::Build' => '0.48',
              'CPANPLUS::Dist::Build::Constants'=> '0.48',
              'Data::Dumper'          => '2.128',
              'Encode'                => '2.40',
              'Encode::Guess'         => '2.04',
              'Encode::MIME::Header'  => '2.12',
              'Encode::Unicode::UTF7' => '2.05',
              'Errno'                 => '1.13',
              'ExtUtils::Command::MM' => '6.57_05',
              'ExtUtils::Liblist'     => '6.57_05',
              'ExtUtils::Liblist::Kid'=> '6.5705',
              'ExtUtils::MM'          => '6.57_05',
              'ExtUtils::MM_AIX'      => '6.57_05',
              'ExtUtils::MM_Any'      => '6.57_05',
              'ExtUtils::MM_BeOS'     => '6.57_05',
              'ExtUtils::MM_Cygwin'   => '6.57_05',
              'ExtUtils::MM_DOS'      => '6.5705',
              'ExtUtils::MM_Darwin'   => '6.57_05',
              'ExtUtils::MM_MacOS'    => '6.5705',
              'ExtUtils::MM_NW5'      => '6.57_05',
              'ExtUtils::MM_OS2'      => '6.57_05',
              'ExtUtils::MM_QNX'      => '6.57_05',
              'ExtUtils::MM_UWIN'     => '6.5705',
              'ExtUtils::MM_Unix'     => '6.57_05',
              'ExtUtils::MM_VMS'      => '6.57_05',
              'ExtUtils::MM_VOS'      => '6.57_05',
              'ExtUtils::MM_Win32'    => '6.57_05',
              'ExtUtils::MM_Win95'    => '6.57_05',
              'ExtUtils::MY'          => '6.5705',
              'ExtUtils::MakeMaker'   => '6.57_05',
              'ExtUtils::MakeMaker::Config'=> '6.57_05',
              'ExtUtils::MakeMaker::YAML'=> '1.44',
              'ExtUtils::Mkbootstrap' => '6.57_05',
              'ExtUtils::Mksymlists'  => '6.57_05',
              'ExtUtils::testlib'     => '6.5705',
              'Filter::Simple'        => '0.85',
              'Hash::Util'            => '0.09',
              'Math::BigFloat'        => '1.62',
              'Math::BigInt'          => '1.95',
              'Math::BigInt::Calc'    => '0.54',
              'Math::BigInt::CalcEmu' => '0.06',
              'Math::BigInt::FastCalc'=> '0.22',
              'Math::BigRat'          => '0.26',
              'Module::CoreList'      => '2.39',
              'POSIX'                 => '1.20',
              'PerlIO::scalar'        => '0.09',
              'Safe'                  => '2.28',
              'Test::Builder'         => '0.97_01',
              'Test::Builder::Module' => '0.97_01',
              'Test::Builder::Tester' => '1.21_01',
              'Test::Builder::Tester::Color'=> '1.21_01',
              'Test::More'            => '0.97_01',
              'Test::Simple'          => '0.97_01',
              'Tie::Hash'             => '1.04',
              'Unicode::Collate'      => '0.59',
              'Unicode::Collate::Locale'=> '0.59',
              'XS::APItest'           => '0.21',
              'XS::APItest::KeywordRPN'=> '0.005',
              'XSLoader'              => '0.11',
              'bigint'                => '0.25',
              'bignum'                => '0.25',
              'bigrat'                => '0.25',
              'blib'                  => '1.06',
              'open'                  => '1.08',
              'threads::shared'       => '1.33_03',
              'warnings'              => '1.11',
              'warnings::register'    => '1.02',
          },
          removed => {
          }
      },
      5.013006 => {
          delta_from => 5.013005,
          changed => {
              'Archive::Extract'      => '0.44',
              'B'                     => '1.24',
              'B::Deparse'            => '0.99',
              'CPAN'                  => '1.94_61',
              'CPAN::FTP'             => '5.5005',
              'CPAN::Queue'           => '5.5001',
              'CPAN::Version'         => '5.5001',
              'Carp'                  => '1.19',
              'Carp::Heavy'           => '1.19',
              'Compress::Raw::Bzip2'  => '2.031',
              'Cwd'                   => '3.34',
              'Data::Dumper'          => '2.129',
              'Devel::Peek'           => '1.05',
              'Digest::MD5'           => '2.51',
              'ExtUtils::Constant::Base'=> '0.05',
              'ExtUtils::Constant::ProxySubs'=> '0.07',
              'ExtUtils::Embed'       => '1.29',
              'ExtUtils::XSSymSet'    => '1.2',
              'Fcntl'                 => '1.09',
              'File::DosGlob'         => '1.03',
              'File::Find'            => '1.18',
              'File::Glob'            => '1.09',
              'File::Spec'            => '3.33',
              'File::Spec::Cygwin'    => '3.33',
              'File::Spec::Epoc'      => '3.33',
              'File::Spec::Functions' => '3.33',
              'File::Spec::Mac'       => '3.33',
              'File::Spec::OS2'       => '3.33',
              'File::Spec::Unix'      => '3.33',
              'File::Spec::VMS'       => '3.33',
              'File::Spec::Win32'     => '3.33',
              'GDBM_File'             => '1.11',
              'Hash::Util::FieldHash' => '1.05',
              'I18N::Langinfo'        => '0.06',
              'IPC::Cmd'              => '0.64',
              'IPC::Open3'            => '1.07',
              'Locale::Codes'         => '3.14',
              'Locale::Codes::Country'=> '3.14',
              'Locale::Codes::Currency'=> '3.14',
              'Locale::Codes::Language'=> '3.14',
              'Locale::Codes::Script' => '3.14',
              'Locale::Constants'     => '3.14',
              'Locale::Country'       => '3.14',
              'Locale::Currency'      => '3.14',
              'Locale::Language'      => '3.14',
              'Locale::Maketext'      => '1.16',
              'Locale::Script'        => '3.14',
              'Math::BigFloat'        => '1.63',
              'Math::BigInt'          => '1.97',
              'Math::BigInt::Calc'    => '0.55',
              'Math::BigInt::CalcEmu' => '0.07',
              'Module::CoreList'      => '2.40',
              'NDBM_File'             => '1.09',
              'NEXT'                  => '0.65',
              'ODBM_File'             => '1.08',
              'Opcode'                => '1.16',
              'POSIX'                 => '1.21',
              'PerlIO::encoding'      => '0.13',
              'PerlIO::scalar'        => '0.10',
              'PerlIO::via'           => '0.10',
              'Pod::Man'              => '2.25',
              'Pod::Text'             => '3.15',
              'SDBM_File'             => '1.07',
              'Socket'                => '1.90',
              'Sys::Hostname'         => '1.13',
              'Tie::Hash::NamedCapture'=> '0.07',
              'Unicode::Collate'      => '0.63',
              'Unicode::Collate::Locale'=> '0.63',
              'Unicode::Normalize'    => '1.07',
              'XS::APItest'           => '0.23',
              'XSLoader'              => '0.13',
              'attributes'            => '0.13',
              'charnames'             => '1.16',
              'if'                    => '0.06',
              'mro'                   => '1.04',
              'overload'              => '1.11',
              're'                    => '0.13',
              'sigtrap'               => '1.05',
              'threads'               => '1.81_01',
              'threads::shared'       => '1.34',
          },
          removed => {
              'XS::APItest::KeywordRPN'=> 1,
          }
      },
      5.013007 => {
          delta_from => 5.013006,
          changed => {
              'Archive::Extract'      => '0.46',
              'Archive::Tar'          => '1.72',
              'Archive::Tar::Constant'=> '1.72',
              'Archive::Tar::File'    => '1.72',
              'AutoLoader'            => '5.71',
              'B'                     => '1.26',
              'B::Concise'            => '0.81',
              'B::Deparse'            => '1.01',
              'CGI'                   => '3.50',
              'CPAN'                  => '1.94_62',
              'CPANPLUS'              => '0.9010',
              'CPANPLUS::Dist::Build' => '0.50',
              'CPANPLUS::Dist::Build::Constants'=> '0.50',
              'CPANPLUS::Internals'   => '0.9010',
              'CPANPLUS::Shell::Default'=> '0.9010',
              'Data::Dumper'          => '2.130_01',
              'DynaLoader'            => '1.11',
              'ExtUtils::Constant'    => '0.23',
              'ExtUtils::Constant::ProxySubs'=> '0.08',
              'Fcntl'                 => '1.10',
              'File::Fetch'           => '0.28',
              'File::Glob'            => '1.10',
              'File::stat'            => '1.04',
              'GDBM_File'             => '1.12',
              'Hash::Util'            => '0.10',
              'Hash::Util::FieldHash' => '1.06',
              'I18N::Langinfo'        => '0.07',
              'Locale::Maketext'      => '1.17',
              'Locale::Maketext::Guts'=> '1.17',
              'Locale::Maketext::GutsLoader'=> '1.17',
              'MIME::Base64'          => '3.10',
              'MIME::QuotedPrint'     => '3.10',
              'Math::BigFloat'        => '1.99_01',
              'Math::BigInt'          => '1.99_01',
              'Math::BigInt::Calc'    => '1.99_01',
              'Math::BigInt::CalcEmu' => '1.99_01',
              'Math::BigInt::FastCalc'=> '0.24_01',
              'Math::BigRat'          => '0.26_01',
              'Module::CoreList'      => '2.41',
              'NDBM_File'             => '1.10',
              'ODBM_File'             => '1.09',
              'Opcode'                => '1.17',
              'POSIX'                 => '1.22',
              'Pod::Simple'           => '3.15',
              'Pod::Simple::BlackBox' => '3.15',
              'Pod::Simple::Checker'  => '3.15',
              'Pod::Simple::Debug'    => '3.15',
              'Pod::Simple::DumpAsText'=> '3.15',
              'Pod::Simple::DumpAsXML'=> '3.15',
              'Pod::Simple::HTML'     => '3.15',
              'Pod::Simple::HTMLBatch'=> '3.15',
              'Pod::Simple::LinkSection'=> '3.15',
              'Pod::Simple::Methody'  => '3.15',
              'Pod::Simple::Progress' => '3.15',
              'Pod::Simple::PullParser'=> '3.15',
              'Pod::Simple::PullParserEndToken'=> '3.15',
              'Pod::Simple::PullParserStartToken'=> '3.15',
              'Pod::Simple::PullParserTextToken'=> '3.15',
              'Pod::Simple::PullParserToken'=> '3.15',
              'Pod::Simple::RTF'      => '3.15',
              'Pod::Simple::Search'   => '3.15',
              'Pod::Simple::SimpleTree'=> '3.15',
              'Pod::Simple::Text'     => '3.15',
              'Pod::Simple::TextContent'=> '3.15',
              'Pod::Simple::TiedOutFH'=> '3.15',
              'Pod::Simple::Transcode'=> '3.15',
              'Pod::Simple::TranscodeDumb'=> '3.15',
              'Pod::Simple::TranscodeSmart'=> '3.15',
              'Pod::Simple::XHTML'    => '3.15',
              'Pod::Simple::XMLOutStream'=> '3.15',
              'SDBM_File'             => '1.08',
              'Safe'                  => '2.29',
              'SelfLoader'            => '1.18',
              'Socket'                => '1.91',
              'Storable'              => '2.24',
              'Sys::Hostname'         => '1.14',
              'Unicode'               => '6.0.0',
              'Unicode::Collate'      => '0.67',
              'Unicode::Collate::CJK::Big5'=> '0.65',
              'Unicode::Collate::CJK::GB2312'=> '0.65',
              'Unicode::Collate::CJK::JISX0208'=> '0.64',
              'Unicode::Collate::CJK::Korean'=> '0.66',
              'Unicode::Collate::CJK::Pinyin'=> '0.65',
              'Unicode::Collate::CJK::Stroke'=> '0.65',
              'Unicode::Collate::Locale'=> '0.67',
              'XS::APItest'           => '0.26',
              'XS::Typemap'           => '0.04',
              'charnames'             => '1.17',
              'mro'                   => '1.05',
              'parent'                => '0.224',
              're'                    => '0.14',
              'threads'               => '1.81_02',
          },
          removed => {
          }
      },
      5.013008 => {
          delta_from => 5.013007,
          changed => {
              'Archive::Tar'          => '1.74',
              'Archive::Tar::Constant'=> '1.74',
              'Archive::Tar::File'    => '1.74',
              'B'                     => '1.27',
              'B::Concise'            => '0.82',
              'B::Deparse'            => '1.02',
              'Carp::Heavy'           => '1.17',
              'Cwd'                   => '3.35',
              'Data::Dumper'          => '2.130_02',
              'Devel::Peek'           => '1.06',
              'Devel::SelfStubber'    => '1.05',
              'Digest::SHA'           => '5.50',
              'Dumpvalue'             => '1.15',
              'DynaLoader'            => '1.12',
              'Env'                   => '1.02',
              'Exporter::Heavy'       => '5.64_01',
              'ExtUtils::CBuilder'    => '0.280201',
              'ExtUtils::CBuilder::Base'=> '0.280201',
              'ExtUtils::CBuilder::Platform::Unix'=> '0.280201',
              'ExtUtils::CBuilder::Platform::VMS'=> '0.280201',
              'ExtUtils::CBuilder::Platform::Windows'=> '0.280201',
              'ExtUtils::CBuilder::Platform::Windows::BCC'=> '0.280201',
              'ExtUtils::CBuilder::Platform::Windows::GCC'=> '0.280201',
              'ExtUtils::CBuilder::Platform::Windows::MSVC'=> '0.280201',
              'ExtUtils::CBuilder::Platform::aix'=> '0.280201',
              'ExtUtils::CBuilder::Platform::cygwin'=> '0.280201',
              'ExtUtils::CBuilder::Platform::darwin'=> '0.280201',
              'ExtUtils::CBuilder::Platform::dec_osf'=> '0.280201',
              'ExtUtils::CBuilder::Platform::os2'=> '0.280201',
              'ExtUtils::Constant::Utils'=> '0.03',
              'ExtUtils::Embed'       => '1.30',
              'ExtUtils::ParseXS'     => '2.2208',
              'Fatal'                 => '2.1001',
              'Fcntl'                 => '1.11',
              'File::CheckTree'       => '4.41',
              'File::Glob'            => '1.11',
              'GDBM_File'             => '1.13',
              'Hash::Util::FieldHash' => '1.07',
              'I18N::Collate'         => '1.02',
              'IO'                    => '1.25_03',
              'IPC::Cmd'              => '0.66',
              'IPC::Open3'            => '1.08',
              'Locale::Codes'         => '3.15',
              'Locale::Codes::Country'=> '3.15',
              'Locale::Codes::Currency'=> '3.15',
              'Locale::Codes::Language'=> '3.15',
              'Locale::Codes::Script' => '3.15',
              'Locale::Constants'     => '3.15',
              'Locale::Country'       => '3.15',
              'Locale::Currency'      => '3.15',
              'Locale::Language'      => '3.15',
              'Locale::Script'        => '3.15',
              'MIME::Base64'          => '3.13',
              'MIME::QuotedPrint'     => '3.13',
              'Math::BigFloat'        => '1.99_02',
              'Math::BigInt'          => '1.99_02',
              'Math::BigInt::Calc'    => '1.99_02',
              'Math::BigInt::CalcEmu' => '1.99_02',
              'Memoize'               => '1.02',
              'Memoize::AnyDBM_File'  => '1.02',
              'Memoize::Expire'       => '1.02',
              'Memoize::ExpireFile'   => '1.02',
              'Memoize::ExpireTest'   => '1.02',
              'Memoize::NDBM_File'    => '1.02',
              'Memoize::SDBM_File'    => '1.02',
              'Memoize::Storable'     => '1.02',
              'Module::CoreList'      => '2.43',
              'NDBM_File'             => '1.11',
              'Net::Ping'             => '2.37',
              'ODBM_File'             => '1.10',
              'Opcode'                => '1.18',
              'POSIX'                 => '1.23',
              'PerlIO::encoding'      => '0.14',
              'PerlIO::scalar'        => '0.11',
              'PerlIO::via'           => '0.11',
              'SDBM_File'             => '1.09',
              'Socket'                => '1.92',
              'Storable'              => '2.25',
              'Time::HiRes'           => '1.9721_01',
              'Unicode::Collate'      => '0.6801',
              'Unicode::Collate::Locale'=> '0.68',
              'Unicode::Normalize'    => '1.08',
              'Unicode::UCD'          => '0.30',
              'Win32'                 => '0.41',
              'XS::APItest'           => '0.27',
              'autodie'               => '2.1001',
              'autodie::exception'    => '2.1001',
              'autodie::exception::system'=> '2.1001',
              'autodie::hints'        => '2.1001',
              'feature'               => '1.19',
              'if'                    => '0.0601',
              'mro'                   => '1.06',
              'overload'              => '1.12',
              're'                    => '0.15',
              'threads'               => '1.81_03',
              'threads::shared'       => '1.35',
              'version'               => '0.86',
          },
          removed => {
          }
      },
      5.013009 => {
          delta_from => 5.013008,
          changed => {
              'Archive::Extract'      => '0.48',
              'Archive::Tar'          => '1.76',
              'Archive::Tar::Constant'=> '1.76',
              'Archive::Tar::File'    => '1.76',
              'B::Concise'            => '0.83',
              'B::Deparse'            => '1.03',
              'B::Lint'               => '1.13',
              'Benchmark'             => '1.12',
              'CGI'                   => '3.51',
              'CGI::Carp'             => '3.51',
              'CGI::Cookie'           => '1.30',
              'CGI::Push'             => '1.05',
              'CGI::Util'             => '3.51',
              'CPAN'                  => '1.94_63',
              'CPAN::HTTP::Client'    => '1.94',
              'CPAN::HTTP::Credentials'=> '1.94',
              'CPAN::Meta::YAML'      => '0.003',
              'CPANPLUS'              => '0.9011',
              'CPANPLUS::Dist::Build' => '0.52',
              'CPANPLUS::Dist::Build::Constants'=> '0.52',
              'CPANPLUS::Internals'   => '0.9011',
              'CPANPLUS::Shell::Default'=> '0.9011',
              'Carp::Heavy'           => '1.19',
              'Compress::Raw::Bzip2'  => '2.033',
              'Compress::Raw::Zlib'   => '2.033',
              'Compress::Zlib'        => '2.033',
              'Cwd'                   => '3.36',
              'DBM_Filter'            => '0.04',
              'DB_File'               => '1.821',
              'Devel::Peek'           => '1.07',
              'DirHandle'             => '1.04',
              'Dumpvalue'             => '1.16',
              'Encode'                => '2.42',
              'Encode::Alias'         => '2.13',
              'Encode::MIME::Header'  => '2.13',
              'Exporter::Heavy'       => '5.64_03',
              'ExtUtils::Install'     => '1.56',
              'ExtUtils::ParseXS'     => '2.2209',
              'File::Basename'        => '2.80',
              'File::Copy'            => '2.21',
              'File::DosGlob'         => '1.04',
              'File::Fetch'           => '0.32',
              'File::Find'            => '1.19',
              'File::Spec::Mac'       => '3.34',
              'File::Spec::VMS'       => '3.34',
              'File::stat'            => '1.05',
              'HTTP::Tiny'            => '0.009',
              'Hash::Util::FieldHash' => '1.08',
              'IO::Compress::Adapter::Bzip2'=> '2.033',
              'IO::Compress::Adapter::Deflate'=> '2.033',
              'IO::Compress::Adapter::Identity'=> '2.033',
              'IO::Compress::Base'    => '2.033',
              'IO::Compress::Base::Common'=> '2.033',
              'IO::Compress::Bzip2'   => '2.033',
              'IO::Compress::Deflate' => '2.033',
              'IO::Compress::Gzip'    => '2.033',
              'IO::Compress::Gzip::Constants'=> '2.033',
              'IO::Compress::RawDeflate'=> '2.033',
              'IO::Compress::Zip'     => '2.033',
              'IO::Compress::Zip::Constants'=> '2.033',
              'IO::Compress::Zlib::Constants'=> '2.033',
              'IO::Compress::Zlib::Extra'=> '2.033',
              'IO::Handle'            => '1.29',
              'IO::Uncompress::Adapter::Bunzip2'=> '2.033',
              'IO::Uncompress::Adapter::Identity'=> '2.033',
              'IO::Uncompress::Adapter::Inflate'=> '2.033',
              'IO::Uncompress::AnyInflate'=> '2.033',
              'IO::Uncompress::AnyUncompress'=> '2.033',
              'IO::Uncompress::Base'  => '2.033',
              'IO::Uncompress::Bunzip2'=> '2.033',
              'IO::Uncompress::Gunzip'=> '2.033',
              'IO::Uncompress::Inflate'=> '2.033',
              'IO::Uncompress::RawInflate'=> '2.033',
              'IO::Uncompress::Unzip' => '2.033',
              'IPC::Cmd'              => '0.68',
              'IPC::Open3'            => '1.09',
              'JSON::PP'              => '2.27103',
              'JSON::PP::Boolean'     => undef,
              'Locale::Maketext'      => '1.18',
              'Log::Message'          => '0.04',
              'Log::Message::Config'  => '0.04',
              'Log::Message::Handlers'=> '0.04',
              'Log::Message::Item'    => '0.04',
              'Log::Message::Simple'  => '0.08',
              'Math::BigFloat'        => '1.99_03',
              'Math::BigInt'          => '1.99_03',
              'Math::BigInt::Calc'    => '1.99_03',
              'Math::BigInt::FastCalc'=> '0.24_02',
              'Math::BigRat'          => '0.26_02',
              'Module::CoreList'      => '2.42_01',
              'Module::Load::Conditional'=> '0.40',
              'Module::Metadata'      => '1.000003',
              'Net::Ping'             => '2.38',
              'OS2::Process'          => '1.05',
              'Object::Accessor'      => '0.38',
              'POSIX'                 => '1.24',
              'Params::Check'         => '0.28',
              'Perl::OSType'          => '1.002',
              'Pod::LaTeX'            => '0.59',
              'Pod::Perldoc'          => '3.15_03',
              'Socket'                => '1.93',
              'Storable'              => '2.26',
              'Sys::Hostname'         => '1.15',
              'Term::UI'              => '0.24',
              'Thread::Queue'         => '2.12',
              'Thread::Semaphore'     => '2.12',
              'Time::Local'           => '1.2000',
              'UNIVERSAL'             => '1.08',
              'Unicode::Normalize'    => '1.10',
              'Win32'                 => '0.44',
              'bigint'                => '0.26',
              'bignum'                => '0.26',
              'bigrat'                => '0.26',
              'charnames'             => '1.18',
              'diagnostics'           => '1.21',
              're'                    => '0.16',
              'threads'               => '1.83',
              'threads::shared'       => '1.36',
              'version'               => '0.88',
          },
          removed => {
          }
      },
      5.01301 => {
          delta_from => 5.013009,
          changed => {
              'Attribute::Handlers'   => '0.89',
              'B'                     => '1.28',
              'B::Showlex'            => '1.03',
              'CGI'                   => '3.52',
              'CPAN'                  => '1.94_65',
              'CPAN::Distribution'    => '1.9601',
              'CPAN::FTP::netrc'      => '1.01',
              'CPAN::FirstTime'       => '5.5303',
              'CPAN::HandleConfig'    => '5.5003',
              'CPAN::Meta'            => '2.110440',
              'CPAN::Meta::Converter' => '2.110440',
              'CPAN::Meta::Feature'   => '2.110440',
              'CPAN::Meta::History'   => '2.110440',
              'CPAN::Meta::Prereqs'   => '2.110440',
              'CPAN::Meta::Spec'      => '2.110440',
              'CPAN::Meta::Validator' => '2.110440',
              'CPAN::Shell'           => '5.5002',
              'CPANPLUS'              => '0.9101',
              'CPANPLUS::Internals'   => '0.9101',
              'CPANPLUS::Shell::Default'=> '0.9101',
              'Carp'                  => '1.20',
              'Carp::Heavy'           => '1.20',
              'Cwd'                   => '3.37',
              'Devel::DProf'          => '20110217.00',
              'DynaLoader'            => '1.13',
              'ExtUtils::CBuilder'    => '0.280202',
              'ExtUtils::CBuilder::Base'=> '0.280202',
              'ExtUtils::CBuilder::Platform::Unix'=> '0.280202',
              'ExtUtils::CBuilder::Platform::VMS'=> '0.280202',
              'ExtUtils::CBuilder::Platform::Windows'=> '0.280202',
              'ExtUtils::CBuilder::Platform::Windows::BCC'=> '0.280202',
              'ExtUtils::CBuilder::Platform::Windows::GCC'=> '0.280202',
              'ExtUtils::CBuilder::Platform::Windows::MSVC'=> '0.280202',
              'ExtUtils::CBuilder::Platform::aix'=> '0.280202',
              'ExtUtils::CBuilder::Platform::cygwin'=> '0.280202',
              'ExtUtils::CBuilder::Platform::darwin'=> '0.280202',
              'ExtUtils::CBuilder::Platform::dec_osf'=> '0.280202',
              'ExtUtils::CBuilder::Platform::os2'=> '0.280202',
              'File::Copy'            => '2.22',
              'Filter::Simple'        => '0.86',
              'HTTP::Tiny'            => '0.010',
              'I18N::LangTags::Detect'=> '1.05',
              'IO::Select'            => '1.18',
              'IPC::Cmd'              => '0.70',
              'Locale::Maketext'      => '1.19',
              'Math::BigFloat'        => '1.992',
              'Math::BigInt'          => '1.992',
              'Math::BigInt::Calc'    => '1.992',
              'Math::BigInt::CalcEmu' => '1.992',
              'Module::Build'         => '0.37_05',
              'Module::Build::Base'   => '0.37_05',
              'Module::Build::Compat' => '0.37_05',
              'Module::Build::Config' => '0.37_05',
              'Module::Build::Cookbook'=> '0.37_05',
              'Module::Build::Dumper' => '0.37_05',
              'Module::Build::ModuleInfo'=> '0.37_05',
              'Module::Build::Notes'  => '0.37_05',
              'Module::Build::PPMMaker'=> '0.37_05',
              'Module::Build::Platform::Amiga'=> '0.37_05',
              'Module::Build::Platform::Default'=> '0.37_05',
              'Module::Build::Platform::EBCDIC'=> '0.37_05',
              'Module::Build::Platform::MPEiX'=> '0.37_05',
              'Module::Build::Platform::MacOS'=> '0.37_05',
              'Module::Build::Platform::RiscOS'=> '0.37_05',
              'Module::Build::Platform::Unix'=> '0.37_05',
              'Module::Build::Platform::VMS'=> '0.37_05',
              'Module::Build::Platform::VOS'=> '0.37_05',
              'Module::Build::Platform::Windows'=> '0.37_05',
              'Module::Build::Platform::aix'=> '0.37_05',
              'Module::Build::Platform::cygwin'=> '0.37_05',
              'Module::Build::Platform::darwin'=> '0.37_05',
              'Module::Build::Platform::os2'=> '0.37_05',
              'Module::Build::PodParser'=> '0.37_05',
              'Module::Build::Version'=> '0.87',
              'Module::Build::YAML'   => '1.41',
              'Module::CoreList'      => '2.45',
              'Module::Load::Conditional'=> '0.44',
              'Module::Metadata'      => '1.000004',
              'OS2::Process'          => '1.06',
              'Parse::CPAN::Meta'     => '1.4401',
              'Pod::Html'             => '1.1',
              'Socket'                => '1.94',
              'Term::UI'              => '0.26',
              'Unicode::Collate'      => '0.72',
              'Unicode::Collate::Locale'=> '0.71',
              'Unicode::UCD'          => '0.31',
              'VMS::DCLsym'           => '1.05',
              'Version::Requirements' => '0.101020',
              'bigrat'                => '0.27',
              'deprecate'             => '0.02',
              'diagnostics'           => '1.22',
              'inc::latest'           => '0.37_05',
              'overload'              => '1.13',
              're'                    => '0.17',
              'utf8'                  => '1.09',
              'warnings'              => '1.12',
          },
          removed => {
          }
      },
      5.013011 => {
          delta_from => 5.01301,
          changed => {
              'App::Prove'            => '3.23',
              'App::Prove::State'     => '3.23',
              'App::Prove::State::Result'=> '3.23',
              'App::Prove::State::Result::Test'=> '3.23',
              'B'                     => '1.29',
              'CPAN'                  => '1.9600',
              'CPAN::Author'          => '5.5001',
              'CPAN::CacheMgr'        => '5.5001',
              'CPAN::Distribution'    => '1.9602',
              'CPAN::Exception::blocked_urllist'=> '1.001',
              'CPAN::HTTP::Client'    => '1.9600',
              'CPAN::HTTP::Credentials'=> '1.9600',
              'CPAN::Index'           => '1.9600',
              'CPAN::LWP::UserAgent'  => '1.9600',
              'CPAN::Mirrors'         => '1.9600',
              'CPAN::Module'          => '5.5001',
              'CPANPLUS'              => '0.9103',
              'CPANPLUS::Dist::Build' => '0.54',
              'CPANPLUS::Dist::Build::Constants'=> '0.54',
              'CPANPLUS::Internals'   => '0.9103',
              'CPANPLUS::Shell::Default'=> '0.9103',
              'Cwd'                   => '3.36',
              'Devel::DProf'          => '20110228.00',
              'Digest::SHA'           => '5.61',
              'ExtUtils::Command'     => '1.17',
              'File::Basename'        => '2.81',
              'File::Copy'            => '2.21',
              'File::Glob'            => '1.12',
              'GDBM_File'             => '1.14',
              'HTTP::Tiny'            => '0.011',
              'Hash::Util'            => '0.11',
              'Hash::Util::FieldHash' => '1.09',
              'I18N::Langinfo'        => '0.08',
              'IO'                    => '1.25_04',
              'IO::Dir'               => '1.08',
              'IO::File'              => '1.15',
              'IO::Handle'            => '1.30',
              'IO::Pipe'              => '1.14',
              'IO::Poll'              => '0.08',
              'IO::Select'            => '1.20',
              'JSON::PP'              => '2.27105',
              'Locale::Codes'         => '3.16',
              'Locale::Codes::Country'=> '3.16',
              'Locale::Codes::Currency'=> '3.16',
              'Locale::Codes::Language'=> '3.16',
              'Locale::Codes::Script' => '3.16',
              'Locale::Constants'     => '3.16',
              'Locale::Country'       => '3.16',
              'Locale::Currency'      => '3.16',
              'Locale::Language'      => '3.16',
              'Locale::Script'        => '3.16',
              'Math::BigFloat'        => '1.993',
              'Math::BigInt'          => '1.994',
              'Math::BigInt::Calc'    => '1.993',
              'Math::BigInt::CalcEmu' => '1.993',
              'Math::BigInt::FastCalc'=> '0.28',
              'Module::Build'         => '0.3800',
              'Module::Build::Base'   => '0.3800',
              'Module::Build::Compat' => '0.3800',
              'Module::Build::Config' => '0.3800',
              'Module::Build::Cookbook'=> '0.3800',
              'Module::Build::Dumper' => '0.3800',
              'Module::Build::ModuleInfo'=> '0.3800',
              'Module::Build::Notes'  => '0.3800',
              'Module::Build::PPMMaker'=> '0.3800',
              'Module::Build::Platform::Amiga'=> '0.3800',
              'Module::Build::Platform::Default'=> '0.3800',
              'Module::Build::Platform::EBCDIC'=> '0.3800',
              'Module::Build::Platform::MPEiX'=> '0.3800',
              'Module::Build::Platform::MacOS'=> '0.3800',
              'Module::Build::Platform::RiscOS'=> '0.3800',
              'Module::Build::Platform::Unix'=> '0.3800',
              'Module::Build::Platform::VMS'=> '0.3800',
              'Module::Build::Platform::VOS'=> '0.3800',
              'Module::Build::Platform::Windows'=> '0.3800',
              'Module::Build::Platform::aix'=> '0.3800',
              'Module::Build::Platform::cygwin'=> '0.3800',
              'Module::Build::Platform::darwin'=> '0.3800',
              'Module::Build::Platform::os2'=> '0.3800',
              'Module::Build::PodParser'=> '0.3800',
              'Module::CoreList'      => '2.46',
              'NDBM_File'             => '1.12',
              'Pod::Simple'           => '3.16',
              'Pod::Simple::BlackBox' => '3.16',
              'Pod::Simple::Checker'  => '3.16',
              'Pod::Simple::Debug'    => '3.16',
              'Pod::Simple::DumpAsText'=> '3.16',
              'Pod::Simple::DumpAsXML'=> '3.16',
              'Pod::Simple::HTML'     => '3.16',
              'Pod::Simple::HTMLBatch'=> '3.16',
              'Pod::Simple::LinkSection'=> '3.16',
              'Pod::Simple::Methody'  => '3.16',
              'Pod::Simple::Progress' => '3.16',
              'Pod::Simple::PullParser'=> '3.16',
              'Pod::Simple::PullParserEndToken'=> '3.16',
              'Pod::Simple::PullParserStartToken'=> '3.16',
              'Pod::Simple::PullParserTextToken'=> '3.16',
              'Pod::Simple::PullParserToken'=> '3.16',
              'Pod::Simple::RTF'      => '3.16',
              'Pod::Simple::Search'   => '3.16',
              'Pod::Simple::SimpleTree'=> '3.16',
              'Pod::Simple::Text'     => '3.16',
              'Pod::Simple::TextContent'=> '3.16',
              'Pod::Simple::TiedOutFH'=> '3.16',
              'Pod::Simple::Transcode'=> '3.16',
              'Pod::Simple::TranscodeDumb'=> '3.16',
              'Pod::Simple::TranscodeSmart'=> '3.16',
              'Pod::Simple::XHTML'    => '3.16',
              'Pod::Simple::XMLOutStream'=> '3.16',
              'Storable'              => '2.27',
              'Sys::Hostname'         => '1.16',
              'TAP::Base'             => '3.23',
              'TAP::Formatter::Base'  => '3.23',
              'TAP::Formatter::Color' => '3.23',
              'TAP::Formatter::Console'=> '3.23',
              'TAP::Formatter::Console::ParallelSession'=> '3.23',
              'TAP::Formatter::Console::Session'=> '3.23',
              'TAP::Formatter::File'  => '3.23',
              'TAP::Formatter::File::Session'=> '3.23',
              'TAP::Formatter::Session'=> '3.23',
              'TAP::Harness'          => '3.23',
              'TAP::Object'           => '3.23',
              'TAP::Parser'           => '3.23',
              'TAP::Parser::Aggregator'=> '3.23',
              'TAP::Parser::Grammar'  => '3.23',
              'TAP::Parser::Iterator' => '3.23',
              'TAP::Parser::Iterator::Array'=> '3.23',
              'TAP::Parser::Iterator::Process'=> '3.23',
              'TAP::Parser::Iterator::Stream'=> '3.23',
              'TAP::Parser::IteratorFactory'=> '3.23',
              'TAP::Parser::Multiplexer'=> '3.23',
              'TAP::Parser::Result'   => '3.23',
              'TAP::Parser::Result::Bailout'=> '3.23',
              'TAP::Parser::Result::Comment'=> '3.23',
              'TAP::Parser::Result::Plan'=> '3.23',
              'TAP::Parser::Result::Pragma'=> '3.23',
              'TAP::Parser::Result::Test'=> '3.23',
              'TAP::Parser::Result::Unknown'=> '3.23',
              'TAP::Parser::Result::Version'=> '3.23',
              'TAP::Parser::Result::YAML'=> '3.23',
              'TAP::Parser::ResultFactory'=> '3.23',
              'TAP::Parser::Scheduler'=> '3.23',
              'TAP::Parser::Scheduler::Job'=> '3.23',
              'TAP::Parser::Scheduler::Spinner'=> '3.23',
              'TAP::Parser::Source'   => '3.23',
              'TAP::Parser::SourceHandler'=> '3.23',
              'TAP::Parser::SourceHandler::Executable'=> '3.23',
              'TAP::Parser::SourceHandler::File'=> '3.23',
              'TAP::Parser::SourceHandler::Handle'=> '3.23',
              'TAP::Parser::SourceHandler::Perl'=> '3.23',
              'TAP::Parser::SourceHandler::RawTAP'=> '3.23',
              'TAP::Parser::Utils'    => '3.23',
              'TAP::Parser::YAMLish::Reader'=> '3.23',
              'TAP::Parser::YAMLish::Writer'=> '3.23',
              'Test::Builder'         => '0.98',
              'Test::Builder::Module' => '0.98',
              'Test::Builder::Tester' => '1.22',
              'Test::Builder::Tester::Color'=> '1.22',
              'Test::Harness'         => '3.23',
              'Test::More'            => '0.98',
              'Test::Simple'          => '0.98',
              'Tie::Hash::NamedCapture'=> '0.08',
              'Tie::RefHash'          => '1.39',
              'Unicode::Collate'      => '0.73',
              'Unicode::Collate::Locale'=> '0.73',
              'Unicode::UCD'          => '0.32',
              'XS::Typemap'           => '0.05',
              'attributes'            => '0.14',
              'base'                  => '2.16',
              'inc::latest'           => '0.3800',
              'mro'                   => '1.07',
              'parent'                => '0.225',
          },
          removed => {
          }
      },
      5.014 => {
          delta_from => 5.013011,
          changed => {
              'ExtUtils::CBuilder'    => '0.280203',
              'ExtUtils::CBuilder::Base'=> '0.280203',
              'ExtUtils::CBuilder::Platform::Unix'=> '0.280203',
              'ExtUtils::CBuilder::Platform::VMS'=> '0.280203',
              'ExtUtils::CBuilder::Platform::Windows'=> '0.280203',
              'ExtUtils::CBuilder::Platform::Windows::BCC'=> '0.280203',
              'ExtUtils::CBuilder::Platform::Windows::GCC'=> '0.280203',
              'ExtUtils::CBuilder::Platform::Windows::MSVC'=> '0.280203',
              'ExtUtils::CBuilder::Platform::aix'=> '0.280203',
              'ExtUtils::CBuilder::Platform::cygwin'=> '0.280203',
              'ExtUtils::CBuilder::Platform::darwin'=> '0.280203',
              'ExtUtils::CBuilder::Platform::dec_osf'=> '0.280203',
              'ExtUtils::CBuilder::Platform::os2'=> '0.280203',
              'ExtUtils::ParseXS'     => '2.2210',
              'File::Basename'        => '2.82',
              'HTTP::Tiny'            => '0.012',
              'IO::Handle'            => '1.31',
              'Module::CoreList'      => '2.49',
              'PerlIO'                => '1.07',
              'Pod::Html'             => '1.11',
              'XS::APItest'           => '0.28',
              'bigint'                => '0.27',
              'bignum'                => '0.27',
              'bigrat'                => '0.28',
              'constant'              => '1.21',
              'feature'               => '1.20',
              're'                    => '0.18',
              'threads::shared'       => '1.37',
          },
          removed => {
          }
      },
      5.014001 => {
          delta_from => 5.014,
          changed => {
              'B::Deparse'            => '1.04',
              'Module::CoreList'      => '2.49_01',
              'Pod::Perldoc'          => '3.15_04',
          },
          removed => {
          }
      },
      5.014002 => {
          delta_from => 5.014001,
          changed => {
              'CPAN'                  => '1.9600_01',
              'CPAN::Distribution'    => '1.9602_01',
              'Devel::DProf::dprof::V'=> undef,
              'Encode'                => '2.42_01',
              'File::Glob'            => '1.13',
              'Module::CoreList'      => '2.49_02',
              'PerlIO::scalar'        => '0.11_01',
              'Time::Piece::Seconds'  => undef,
          },
          removed => {
          }
      },
      5.014003 => {
          delta_from => 5.014002,
          changed => {
              'Digest'                => '1.16_01',
              'IPC::Open3'            => '1.09_01',
              'Module::CoreList'      => '2.49_04',
          },
          removed => {
          }
      },
      5.014004 => {
          delta_from => 5.014003,
          changed => {
              'Encode'                => '2.42_02',
              'IPC::Open3'            => '1.0901',
              'Module::CoreList'      => '2.49_06',
          },
          removed => {
          }
      },
      5.015 => {
          delta_from => 5.014001,
          changed => {
              'Archive::Extract'      => '0.52',
              'Attribute::Handlers'   => '0.91',
              'B'                     => '1.30',
              'B::Concise'            => '0.84',
              'B::Deparse'            => '1.05',
              'Benchmark'             => '1.13',
              'CGI'                   => '3.54',
              'CGI::Util'             => '3.53',
              'CPAN::Meta'            => '2.110930',
              'CPAN::Meta::Converter' => '2.110930',
              'CPAN::Meta::Feature'   => '2.110930',
              'CPAN::Meta::History'   => '2.110930',
              'CPAN::Meta::Prereqs'   => '2.110930',
              'CPAN::Meta::Spec'      => '2.110930',
              'CPAN::Meta::Validator' => '2.110930',
              'CPANPLUS'              => '0.9105',
              'CPANPLUS::Dist::Build' => '0.56',
              'CPANPLUS::Dist::Build::Constants'=> '0.56',
              'CPANPLUS::Internals'   => '0.9105',
              'CPANPLUS::Shell::Default'=> '0.9105',
              'Compress::Raw::Bzip2'  => '2.035',
              'Compress::Raw::Zlib'   => '2.035',
              'Compress::Zlib'        => '2.035',
              'DB_File'               => '1.822',
              'Data::Dumper'          => '2.131',
              'Devel::Peek'           => '1.08',
              'Digest::SHA'           => '5.62',
              'Encode'                => '2.43',
              'Encode::Alias'         => '2.14',
              'ExtUtils::CBuilder'    => '0.280204',
              'ExtUtils::CBuilder::Base'=> '0.280204',
              'Fatal'                 => '2.10',
              'File::Spec::Win32'     => '3.34',
              'Filter::Simple'        => '0.87',
              'Filter::Util::Call'    => '1.39',
              'FindBin'               => '1.51',
              'Hash::Util::FieldHash' => '1.10',
              'I18N::LangTags'        => '0.36',
              'IO::Compress::Adapter::Bzip2'=> '2.035',
              'IO::Compress::Adapter::Deflate'=> '2.035',
              'IO::Compress::Adapter::Identity'=> '2.035',
              'IO::Compress::Base'    => '2.035',
              'IO::Compress::Base::Common'=> '2.035',
              'IO::Compress::Bzip2'   => '2.035',
              'IO::Compress::Deflate' => '2.035',
              'IO::Compress::Gzip'    => '2.035',
              'IO::Compress::Gzip::Constants'=> '2.035',
              'IO::Compress::RawDeflate'=> '2.035',
              'IO::Compress::Zip'     => '2.035',
              'IO::Compress::Zip::Constants'=> '2.035',
              'IO::Compress::Zlib::Constants'=> '2.035',
              'IO::Compress::Zlib::Extra'=> '2.035',
              'IO::Uncompress::Adapter::Bunzip2'=> '2.035',
              'IO::Uncompress::Adapter::Identity'=> '2.035',
              'IO::Uncompress::Adapter::Inflate'=> '2.035',
              'IO::Uncompress::AnyInflate'=> '2.035',
              'IO::Uncompress::AnyUncompress'=> '2.035',
              'IO::Uncompress::Base'  => '2.035',
              'IO::Uncompress::Bunzip2'=> '2.035',
              'IO::Uncompress::Gunzip'=> '2.035',
              'IO::Uncompress::Inflate'=> '2.035',
              'IO::Uncompress::RawInflate'=> '2.035',
              'IO::Uncompress::Unzip' => '2.035',
              'IPC::Open2'            => '1.04',
              'IPC::Open3'            => '1.11',
              'JSON::PP'              => '2.27200',
              'Math::BigFloat'        => '1.994',
              'Math::BigInt'          => '1.995',
              'Math::Complex'         => '1.57',
              'Math::Trig'            => '1.21',
              'Module::CoreList'      => '2.51',
              'ODBM_File'             => '1.11',
              'Object::Accessor'      => '0.42',
              'Opcode'                => '1.19',
              'PerlIO::encoding'      => '0.15',
              'PerlIO::scalar'        => '0.12',
              'Pod::Perldoc'          => '3.15_05',
              'Storable'              => '2.28',
              'Sys::Syslog'           => '0.29',
              'Time::HiRes'           => '1.9722',
              'Unicode::Collate'      => '0.76',
              'Unicode::Collate::CJK::Pinyin'=> '0.76',
              'Unicode::Collate::CJK::Stroke'=> '0.76',
              'Unicode::Collate::Locale'=> '0.76',
              'Unicode::Normalize'    => '1.12',
              'XS::APItest'           => '0.29',
              'XSLoader'              => '0.15',
              'autodie'               => '2.10',
              'autodie::exception'    => '2.10',
              'autodie::exception::system'=> '2.10',
              'autodie::hints'        => '2.10',
              'base'                  => '2.17',
              'charnames'             => '1.22',
              'constant'              => '1.22',
              'feature'               => '1.21',
              'mro'                   => '1.08',
              'overload'              => '1.14',
              'threads::shared'       => '1.38',
              'vmsish'                => '1.03',
          },
          removed => {
              'Devel::DProf'          => 1,
              'Shell'                 => 1,
          }
      },
      5.015001 => {
          delta_from => 5.015,
          changed => {
              'B::Deparse'            => '1.06',
              'CGI'                   => '3.55',
              'CPAN::Meta'            => '2.110930001',
              'CPAN::Meta::Converter' => '2.110930001',
              'CPANPLUS'              => '0.9108',
              'CPANPLUS::Internals'   => '0.9108',
              'CPANPLUS::Shell::Default'=> '0.9108',
              'Carp'                  => '1.21',
              'Carp::Heavy'           => '1.21',
              'Compress::Raw::Bzip2'  => '2.037',
              'Compress::Raw::Zlib'   => '2.037',
              'Compress::Zlib'        => '2.037',
              'Cwd'                   => '3.37',
              'Env'                   => '1.03',
              'ExtUtils::Command::MM' => '6.58',
              'ExtUtils::Liblist'     => '6.58',
              'ExtUtils::Liblist::Kid'=> '6.58',
              'ExtUtils::MM'          => '6.58',
              'ExtUtils::MM_AIX'      => '6.58',
              'ExtUtils::MM_Any'      => '6.58',
              'ExtUtils::MM_BeOS'     => '6.58',
              'ExtUtils::MM_Cygwin'   => '6.58',
              'ExtUtils::MM_DOS'      => '6.58',
              'ExtUtils::MM_Darwin'   => '6.58',
              'ExtUtils::MM_MacOS'    => '6.58',
              'ExtUtils::MM_NW5'      => '6.58',
              'ExtUtils::MM_OS2'      => '6.58',
              'ExtUtils::MM_QNX'      => '6.58',
              'ExtUtils::MM_UWIN'     => '6.58',
              'ExtUtils::MM_Unix'     => '6.58',
              'ExtUtils::MM_VMS'      => '6.58',
              'ExtUtils::MM_VOS'      => '6.58',
              'ExtUtils::MM_Win32'    => '6.58',
              'ExtUtils::MM_Win95'    => '6.58',
              'ExtUtils::MY'          => '6.58',
              'ExtUtils::MakeMaker'   => '6.58',
              'ExtUtils::MakeMaker::Config'=> '6.58',
              'ExtUtils::Mkbootstrap' => '6.58',
              'ExtUtils::Mksymlists'  => '6.58',
              'ExtUtils::ParseXS'     => '3.00_01',
              'ExtUtils::ParseXS::Constants'=> undef,
              'ExtUtils::ParseXS::CountLines'=> undef,
              'ExtUtils::ParseXS::Utilities'=> undef,
              'ExtUtils::Typemaps'    => '1.00',
              'ExtUtils::Typemaps::InputMap'=> undef,
              'ExtUtils::Typemaps::OutputMap'=> undef,
              'ExtUtils::Typemaps::Type'=> '0.05',
              'ExtUtils::testlib'     => '6.58',
              'File::Basename'        => '2.83',
              'File::Find'            => '1.20',
              'HTTP::Tiny'            => '0.013',
              'I18N::Langinfo'        => '0.08_02',
              'IO::Compress::Adapter::Bzip2'=> '2.037',
              'IO::Compress::Adapter::Deflate'=> '2.037',
              'IO::Compress::Adapter::Identity'=> '2.037',
              'IO::Compress::Base'    => '2.037',
              'IO::Compress::Base::Common'=> '2.037',
              'IO::Compress::Bzip2'   => '2.037',
              'IO::Compress::Deflate' => '2.037',
              'IO::Compress::Gzip'    => '2.037',
              'IO::Compress::Gzip::Constants'=> '2.037',
              'IO::Compress::RawDeflate'=> '2.037',
              'IO::Compress::Zip'     => '2.037',
              'IO::Compress::Zip::Constants'=> '2.037',
              'IO::Compress::Zlib::Constants'=> '2.037',
              'IO::Compress::Zlib::Extra'=> '2.037',
              'IO::Uncompress::Adapter::Bunzip2'=> '2.037',
              'IO::Uncompress::Adapter::Identity'=> '2.037',
              'IO::Uncompress::Adapter::Inflate'=> '2.037',
              'IO::Uncompress::AnyInflate'=> '2.037',
              'IO::Uncompress::AnyUncompress'=> '2.037',
              'IO::Uncompress::Base'  => '2.037',
              'IO::Uncompress::Bunzip2'=> '2.037',
              'IO::Uncompress::Gunzip'=> '2.037',
              'IO::Uncompress::Inflate'=> '2.037',
              'IO::Uncompress::RawInflate'=> '2.037',
              'IO::Uncompress::Unzip' => '2.037',
              'IPC::Cmd'              => '0.72',
              'Locale::Codes'         => '3.17',
              'Locale::Codes::Constants'=> '3.17',
              'Locale::Codes::Country'=> '3.17',
              'Locale::Codes::Country_Codes'=> '3.17',
              'Locale::Codes::Currency'=> '3.17',
              'Locale::Codes::Currency_Codes'=> '3.17',
              'Locale::Codes::LangExt'=> '3.17',
              'Locale::Codes::LangExt_Codes'=> '3.17',
              'Locale::Codes::LangVar'=> '3.17',
              'Locale::Codes::LangVar_Codes'=> '3.17',
              'Locale::Codes::Language'=> '3.17',
              'Locale::Codes::Language_Codes'=> '3.17',
              'Locale::Codes::Script' => '3.17',
              'Locale::Codes::Script_Codes'=> '3.17',
              'Locale::Country'       => '3.17',
              'Locale::Currency'      => '3.17',
              'Locale::Language'      => '3.17',
              'Locale::Script'        => '3.17',
              'Math::BigFloat::Trace' => '0.28',
              'Math::BigInt::FastCalc'=> '0.29',
              'Math::BigInt::Trace'   => '0.28',
              'Math::BigRat'          => '0.2602',
              'Math::Complex'         => '1.58',
              'Math::Trig'            => '1.22',
              'Module::CoreList'      => '2.54',
              'OS2::Process'          => '1.07',
              'Pod::Perldoc'          => '3.15_06',
              'Pod::Simple'           => '3.18',
              'Pod::Simple::BlackBox' => '3.18',
              'Pod::Simple::Checker'  => '3.18',
              'Pod::Simple::Debug'    => '3.18',
              'Pod::Simple::DumpAsText'=> '3.18',
              'Pod::Simple::DumpAsXML'=> '3.18',
              'Pod::Simple::HTML'     => '3.18',
              'Pod::Simple::HTMLBatch'=> '3.18',
              'Pod::Simple::LinkSection'=> '3.18',
              'Pod::Simple::Methody'  => '3.18',
              'Pod::Simple::Progress' => '3.18',
              'Pod::Simple::PullParser'=> '3.18',
              'Pod::Simple::PullParserEndToken'=> '3.18',
              'Pod::Simple::PullParserStartToken'=> '3.18',
              'Pod::Simple::PullParserTextToken'=> '3.18',
              'Pod::Simple::PullParserToken'=> '3.18',
              'Pod::Simple::RTF'      => '3.18',
              'Pod::Simple::Search'   => '3.18',
              'Pod::Simple::SimpleTree'=> '3.18',
              'Pod::Simple::Text'     => '3.18',
              'Pod::Simple::TextContent'=> '3.18',
              'Pod::Simple::TiedOutFH'=> '3.18',
              'Pod::Simple::Transcode'=> '3.18',
              'Pod::Simple::TranscodeDumb'=> '3.18',
              'Pod::Simple::TranscodeSmart'=> '3.18',
              'Pod::Simple::XHTML'    => '3.18',
              'Pod::Simple::XMLOutStream'=> '3.18',
              'Storable'              => '2.31',
              'Sys::Syslog::Win32'    => undef,
              'Time::HiRes'           => '1.9724',
              'Unicode::Collate'      => '0.77',
              'Unicode::UCD'          => '0.33',
              'Win32API::File'        => '0.1200',
              'XS::APItest'           => '0.30',
              'attributes'            => '0.15',
              'bigint'                => '0.28',
              'bignum'                => '0.28',
              'charnames'             => '1.23',
              'diagnostics'           => '1.23',
              'feature'               => '1.22',
              'overload'              => '1.15',
              'perlfaq'               => '5.015000',
              'threads'               => '1.84',
              'version'               => '0.93',
          },
          removed => {
              'ExtUtils::MakeMaker::YAML'=> 1,
              'Locale::Constants'     => 1,
              'Sys::Syslog::win32::Win32'=> 1,
          }
      },
      5.015002 => {
          delta_from => 5.015001,
          changed => {
              'Attribute::Handlers'   => '0.92',
              'B'                     => '1.31',
              'B::Concise'            => '0.85',
              'B::Deparse'            => '1.07',
              'B::Terse'              => '1.06',
              'B::Xref'               => '1.03',
              'CPAN'                  => '1.9800',
              'CPAN::Exception::yaml_process_error'=> '5.5',
              'CPAN::Meta'            => '2.112150',
              'CPAN::Meta::Converter' => '2.112150',
              'CPAN::Meta::Feature'   => '2.112150',
              'CPAN::Meta::History'   => '2.112150',
              'CPAN::Meta::Prereqs'   => '2.112150',
              'CPAN::Meta::Spec'      => '2.112150',
              'CPAN::Meta::Validator' => '2.112150',
              'CPANPLUS'              => '0.9109',
              'CPANPLUS::Internals'   => '0.9109',
              'CPANPLUS::Shell::Default'=> '0.9109',
              'DB_File'               => '1.824',
              'Data::Dumper'          => '2.132',
              'Encode'                => '2.44',
              'Encode::Alias'         => '2.15',
              'Encode::Encoder'       => '2.02',
              'Encode::Guess'         => '2.05',
              'ExtUtils::Command::MM' => '6.59',
              'ExtUtils::Install'     => '1.57',
              'ExtUtils::Installed'   => '1.999002',
              'ExtUtils::Liblist'     => '6.59',
              'ExtUtils::Liblist::Kid'=> '6.59',
              'ExtUtils::MM'          => '6.59',
              'ExtUtils::MM_AIX'      => '6.59',
              'ExtUtils::MM_Any'      => '6.59',
              'ExtUtils::MM_BeOS'     => '6.59',
              'ExtUtils::MM_Cygwin'   => '6.59',
              'ExtUtils::MM_DOS'      => '6.59',
              'ExtUtils::MM_Darwin'   => '6.59',
              'ExtUtils::MM_MacOS'    => '6.59',
              'ExtUtils::MM_NW5'      => '6.59',
              'ExtUtils::MM_OS2'      => '6.59',
              'ExtUtils::MM_QNX'      => '6.59',
              'ExtUtils::MM_UWIN'     => '6.59',
              'ExtUtils::MM_Unix'     => '6.59',
              'ExtUtils::MM_VMS'      => '6.59',
              'ExtUtils::MM_VOS'      => '6.59',
              'ExtUtils::MM_Win32'    => '6.59',
              'ExtUtils::MM_Win95'    => '6.59',
              'ExtUtils::MY'          => '6.59',
              'ExtUtils::MakeMaker'   => '6.59',
              'ExtUtils::MakeMaker::Config'=> '6.59',
              'ExtUtils::Manifest'    => '1.60',
              'ExtUtils::Mkbootstrap' => '6.59',
              'ExtUtils::Mksymlists'  => '6.59',
              'ExtUtils::ParseXS'     => '3.03_01',
              'ExtUtils::Typemaps'    => '1.01',
              'ExtUtils::testlib'     => '6.59',
              'File::Spec'            => '3.34',
              'File::Spec::Mac'       => '3.35',
              'File::Spec::Unix'      => '3.34',
              'File::Spec::VMS'       => '3.35',
              'File::Spec::Win32'     => '3.35',
              'I18N::LangTags'        => '0.37',
              'IO'                    => '1.25_05',
              'IO::Handle'            => '1.32',
              'IO::Socket'            => '1.33',
              'IO::Socket::INET'      => '1.32',
              'IPC::Open3'            => '1.12',
              'Math::BigFloat'        => '1.995',
              'Math::BigFloat::Trace' => '0.29',
              'Math::BigInt'          => '1.996',
              'Math::BigInt::Trace'   => '0.29',
              'Module::Build'         => '0.39_01',
              'Module::Build::Base'   => '0.39_01',
              'Module::Build::Compat' => '0.39_01',
              'Module::Build::Config' => '0.39_01',
              'Module::Build::Cookbook'=> '0.39_01',
              'Module::Build::Dumper' => '0.39_01',
              'Module::Build::ModuleInfo'=> '0.39_01',
              'Module::Build::Notes'  => '0.39_01',
              'Module::Build::PPMMaker'=> '0.39_01',
              'Module::Build::Platform::Amiga'=> '0.39_01',
              'Module::Build::Platform::Default'=> '0.39_01',
              'Module::Build::Platform::EBCDIC'=> '0.39_01',
              'Module::Build::Platform::MPEiX'=> '0.39_01',
              'Module::Build::Platform::MacOS'=> '0.39_01',
              'Module::Build::Platform::RiscOS'=> '0.39_01',
              'Module::Build::Platform::Unix'=> '0.39_01',
              'Module::Build::Platform::VMS'=> '0.39_01',
              'Module::Build::Platform::VOS'=> '0.39_01',
              'Module::Build::Platform::Windows'=> '0.39_01',
              'Module::Build::Platform::aix'=> '0.39_01',
              'Module::Build::Platform::cygwin'=> '0.39_01',
              'Module::Build::Platform::darwin'=> '0.39_01',
              'Module::Build::Platform::os2'=> '0.39_01',
              'Module::Build::PodParser'=> '0.39_01',
              'Module::CoreList'      => '2.55',
              'Module::Load'          => '0.20',
              'Module::Metadata'      => '1.000005_01',
              'Opcode'                => '1.20',
              'Params::Check'         => '0.32',
              'PerlIO::via'           => '0.12',
              'Term::ANSIColor'       => '3.01',
              'Unicode::Collate'      => '0.78',
              'Unicode::Normalize'    => '1.13',
              'Unicode::UCD'          => '0.34',
              'bigint'                => '0.29',
              'bignum'                => '0.29',
              'bigrat'                => '0.29',
              'diagnostics'           => '1.24',
              'fields'                => '2.16',
              'inc::latest'           => '0.39_01',
          },
          removed => {
          }
      },
      5.015003 => {
          delta_from => 5.015002,
          changed => {
              'AnyDBM_File'           => '1.01',
              'Archive::Extract'      => '0.56',
              'Archive::Tar'          => '1.78',
              'Archive::Tar::Constant'=> '1.78',
              'Archive::Tar::File'    => '1.78',
              'Attribute::Handlers'   => '0.93',
              'B'                     => '1.32',
              'B::Concise'            => '0.86',
              'B::Deparse'            => '1.08',
              'CPAN::Meta'            => '2.112621',
              'CPAN::Meta::Converter' => '2.112621',
              'CPAN::Meta::Feature'   => '2.112621',
              'CPAN::Meta::History'   => '2.112621',
              'CPAN::Meta::Prereqs'   => '2.112621',
              'CPAN::Meta::Spec'      => '2.112621',
              'CPAN::Meta::Validator' => '2.112621',
              'CPAN::Meta::YAML'      => '0.004',
              'CPANPLUS'              => '0.9111',
              'CPANPLUS::Dist::Build' => '0.58',
              'CPANPLUS::Dist::Build::Constants'=> '0.58',
              'CPANPLUS::Internals'   => '0.9111',
              'CPANPLUS::Shell::Default'=> '0.9111',
              'Carp'                  => '1.23',
              'Carp::Heavy'           => '1.23',
              'Data::Dumper'          => '2.134',
              'Devel::PPPort'         => '3.20',
              'Errno'                 => '1.14',
              'Exporter'              => '5.65',
              'Exporter::Heavy'       => '5.65',
              'ExtUtils::ParseXS'     => '3.04_04',
              'ExtUtils::ParseXS::Constants'=> '3.04_04',
              'ExtUtils::ParseXS::CountLines'=> '3.04_04',
              'ExtUtils::ParseXS::Utilities'=> '3.04_04',
              'ExtUtils::Typemaps'    => '1.02',
              'File::Glob'            => '1.13',
              'Filter::Simple'        => '0.88',
              'IO'                    => '1.25_06',
              'IO::Handle'            => '1.33',
              'Locale::Codes'         => '3.18',
              'Locale::Codes::Constants'=> '3.18',
              'Locale::Codes::Country'=> '3.18',
              'Locale::Codes::Country_Codes'=> '3.18',
              'Locale::Codes::Currency'=> '3.18',
              'Locale::Codes::Currency_Codes'=> '3.18',
              'Locale::Codes::LangExt'=> '3.18',
              'Locale::Codes::LangExt_Codes'=> '3.18',
              'Locale::Codes::LangVar'=> '3.18',
              'Locale::Codes::LangVar_Codes'=> '3.18',
              'Locale::Codes::Language'=> '3.18',
              'Locale::Codes::Language_Codes'=> '3.18',
              'Locale::Codes::Script' => '3.18',
              'Locale::Codes::Script_Codes'=> '3.18',
              'Locale::Country'       => '3.18',
              'Locale::Currency'      => '3.18',
              'Locale::Language'      => '3.18',
              'Locale::Script'        => '3.18',
              'Math::BigFloat'        => '1.997',
              'Math::BigInt'          => '1.997',
              'Math::BigInt::Calc'    => '1.997',
              'Math::BigInt::CalcEmu' => '1.997',
              'Math::BigInt::FastCalc'=> '0.30',
              'Math::BigRat'          => '0.2603',
              'Module::CoreList'      => '2.56',
              'Module::Load::Conditional'=> '0.46',
              'Module::Metadata'      => '1.000007',
              'ODBM_File'             => '1.12',
              'POSIX'                 => '1.26',
              'Pod::Perldoc'          => '3.15_07',
              'Pod::Simple'           => '3.19',
              'Pod::Simple::BlackBox' => '3.19',
              'Pod::Simple::Checker'  => '3.19',
              'Pod::Simple::Debug'    => '3.19',
              'Pod::Simple::DumpAsText'=> '3.19',
              'Pod::Simple::DumpAsXML'=> '3.19',
              'Pod::Simple::HTML'     => '3.19',
              'Pod::Simple::HTMLBatch'=> '3.19',
              'Pod::Simple::LinkSection'=> '3.19',
              'Pod::Simple::Methody'  => '3.19',
              'Pod::Simple::Progress' => '3.19',
              'Pod::Simple::PullParser'=> '3.19',
              'Pod::Simple::PullParserEndToken'=> '3.19',
              'Pod::Simple::PullParserStartToken'=> '3.19',
              'Pod::Simple::PullParserTextToken'=> '3.19',
              'Pod::Simple::PullParserToken'=> '3.19',
              'Pod::Simple::RTF'      => '3.19',
              'Pod::Simple::Search'   => '3.19',
              'Pod::Simple::SimpleTree'=> '3.19',
              'Pod::Simple::Text'     => '3.19',
              'Pod::Simple::TextContent'=> '3.19',
              'Pod::Simple::TiedOutFH'=> '3.19',
              'Pod::Simple::Transcode'=> '3.19',
              'Pod::Simple::TranscodeDumb'=> '3.19',
              'Pod::Simple::TranscodeSmart'=> '3.19',
              'Pod::Simple::XHTML'    => '3.19',
              'Pod::Simple::XMLOutStream'=> '3.19',
              'Search::Dict'          => '1.04',
              'Socket'                => '1.94_01',
              'Storable'              => '2.32',
              'Text::Abbrev'          => '1.02',
              'Tie::Array'            => '1.05',
              'UNIVERSAL'             => '1.09',
              'Unicode::UCD'          => '0.35',
              'XS::APItest'           => '0.31',
              'XSLoader'              => '0.16',
              'attributes'            => '0.16',
              'diagnostics'           => '1.25',
              'open'                  => '1.09',
              'perlfaq'               => '5.0150034',
              'threads'               => '1.85',
              'threads::shared'       => '1.40',
          },
          removed => {
          }
      },
      5.015004 => {
          delta_from => 5.015003,
          changed => {
              'Archive::Tar'          => '1.80',
              'Archive::Tar::Constant'=> '1.80',
              'Archive::Tar::File'    => '1.80',
              'Digest'                => '1.17',
              'DynaLoader'            => '1.14',
              'ExtUtils::Command::MM' => '6.61_01',
              'ExtUtils::Liblist'     => '6.61_01',
              'ExtUtils::Liblist::Kid'=> '6.61_01',
              'ExtUtils::MM'          => '6.61_01',
              'ExtUtils::MM_AIX'      => '6.61_01',
              'ExtUtils::MM_Any'      => '6.61_01',
              'ExtUtils::MM_BeOS'     => '6.61_01',
              'ExtUtils::MM_Cygwin'   => '6.61_01',
              'ExtUtils::MM_DOS'      => '6.61_01',
              'ExtUtils::MM_Darwin'   => '6.61_01',
              'ExtUtils::MM_MacOS'    => '6.61_01',
              'ExtUtils::MM_NW5'      => '6.61_01',
              'ExtUtils::MM_OS2'      => '6.61_01',
              'ExtUtils::MM_QNX'      => '6.61_01',
              'ExtUtils::MM_UWIN'     => '6.61_01',
              'ExtUtils::MM_Unix'     => '6.61_01',
              'ExtUtils::MM_VMS'      => '6.61_01',
              'ExtUtils::MM_VOS'      => '6.61_01',
              'ExtUtils::MM_Win32'    => '6.61_01',
              'ExtUtils::MM_Win95'    => '6.61_01',
              'ExtUtils::MY'          => '6.61_01',
              'ExtUtils::MakeMaker'   => '6.61_01',
              'ExtUtils::MakeMaker::Config'=> '6.61_01',
              'ExtUtils::Mkbootstrap' => '6.61_01',
              'ExtUtils::Mksymlists'  => '6.61_01',
              'ExtUtils::ParseXS'     => '3.05',
              'ExtUtils::ParseXS::Constants'=> '3.05',
              'ExtUtils::ParseXS::CountLines'=> '3.05',
              'ExtUtils::ParseXS::Utilities'=> '3.05',
              'ExtUtils::testlib'     => '6.61_01',
              'File::DosGlob'         => '1.05',
              'Module::CoreList'      => '2.57',
              'Module::Load'          => '0.22',
              'Unicode::Collate'      => '0.80',
              'Unicode::Collate::Locale'=> '0.80',
              'Unicode::UCD'          => '0.36',
              'XS::APItest'           => '0.32',
              'XS::Typemap'           => '0.07',
              'attributes'            => '0.17',
              'base'                  => '2.18',
              'constant'              => '1.23',
              'mro'                   => '1.09',
              'open'                  => '1.10',
              'perlfaq'               => '5.0150035',
          },
          removed => {
          }
      },
      5.015005 => {
          delta_from => 5.015004,
          changed => {
              'Archive::Extract'      => '0.58',
              'B::Concise'            => '0.87',
              'B::Deparse'            => '1.09',
              'CGI'                   => '3.58',
              'CGI::Fast'             => '1.09',
              'CPANPLUS'              => '0.9112',
              'CPANPLUS::Dist::Build' => '0.60',
              'CPANPLUS::Dist::Build::Constants'=> '0.60',
              'CPANPLUS::Internals'   => '0.9112',
              'CPANPLUS::Shell::Default'=> '0.9112',
              'Compress::Raw::Bzip2'  => '2.042',
              'Compress::Raw::Zlib'   => '2.042',
              'Compress::Zlib'        => '2.042',
              'Digest::SHA'           => '5.63',
              'Errno'                 => '1.15',
              'ExtUtils::Command::MM' => '6.63_02',
              'ExtUtils::Liblist'     => '6.63_02',
              'ExtUtils::Liblist::Kid'=> '6.63_02',
              'ExtUtils::MM'          => '6.63_02',
              'ExtUtils::MM_AIX'      => '6.63_02',
              'ExtUtils::MM_Any'      => '6.63_02',
              'ExtUtils::MM_BeOS'     => '6.63_02',
              'ExtUtils::MM_Cygwin'   => '6.63_02',
              'ExtUtils::MM_DOS'      => '6.63_02',
              'ExtUtils::MM_Darwin'   => '6.63_02',
              'ExtUtils::MM_MacOS'    => '6.63_02',
              'ExtUtils::MM_NW5'      => '6.63_02',
              'ExtUtils::MM_OS2'      => '6.63_02',
              'ExtUtils::MM_QNX'      => '6.63_02',
              'ExtUtils::MM_UWIN'     => '6.63_02',
              'ExtUtils::MM_Unix'     => '6.63_02',
              'ExtUtils::MM_VMS'      => '6.63_02',
              'ExtUtils::MM_VOS'      => '6.63_02',
              'ExtUtils::MM_Win32'    => '6.63_02',
              'ExtUtils::MM_Win95'    => '6.63_02',
              'ExtUtils::MY'          => '6.63_02',
              'ExtUtils::MakeMaker'   => '6.63_02',
              'ExtUtils::MakeMaker::Config'=> '6.63_02',
              'ExtUtils::Mkbootstrap' => '6.63_02',
              'ExtUtils::Mksymlists'  => '6.63_02',
              'ExtUtils::testlib'     => '6.63_02',
              'File::DosGlob'         => '1.06',
              'File::Glob'            => '1.14',
              'HTTP::Tiny'            => '0.016',
              'IO::Compress::Adapter::Bzip2'=> '2.042',
              'IO::Compress::Adapter::Deflate'=> '2.042',
              'IO::Compress::Adapter::Identity'=> '2.042',
              'IO::Compress::Base'    => '2.042',
              'IO::Compress::Base::Common'=> '2.042',
              'IO::Compress::Bzip2'   => '2.042',
              'IO::Compress::Deflate' => '2.042',
              'IO::Compress::Gzip'    => '2.042',
              'IO::Compress::Gzip::Constants'=> '2.042',
              'IO::Compress::RawDeflate'=> '2.042',
              'IO::Compress::Zip'     => '2.042',
              'IO::Compress::Zip::Constants'=> '2.042',
              'IO::Compress::Zlib::Constants'=> '2.042',
              'IO::Compress::Zlib::Extra'=> '2.042',
              'IO::Uncompress::Adapter::Bunzip2'=> '2.042',
              'IO::Uncompress::Adapter::Identity'=> '2.042',
              'IO::Uncompress::Adapter::Inflate'=> '2.042',
              'IO::Uncompress::AnyInflate'=> '2.042',
              'IO::Uncompress::AnyUncompress'=> '2.042',
              'IO::Uncompress::Base'  => '2.042',
              'IO::Uncompress::Bunzip2'=> '2.042',
              'IO::Uncompress::Gunzip'=> '2.042',
              'IO::Uncompress::Inflate'=> '2.042',
              'IO::Uncompress::RawInflate'=> '2.042',
              'IO::Uncompress::Unzip' => '2.042',
              'Locale::Maketext'      => '1.20',
              'Locale::Maketext::Guts'=> '1.20',
              'Locale::Maketext::GutsLoader'=> '1.20',
              'Module::CoreList'      => '2.58',
              'Opcode'                => '1.21',
              'Socket'                => '1.94_02',
              'Storable'              => '2.33',
              'UNIVERSAL'             => '1.10',
              'Unicode::Collate'      => '0.85',
              'Unicode::Collate::CJK::Pinyin'=> '0.85',
              'Unicode::Collate::CJK::Stroke'=> '0.85',
              'Unicode::Collate::Locale'=> '0.85',
              'Unicode::UCD'          => '0.37',
              'XS::APItest'           => '0.33',
              'arybase'               => '0.01',
              'charnames'             => '1.24',
              'feature'               => '1.23',
              'perlfaq'               => '5.0150036',
              'strict'                => '1.05',
              'unicore::Name'         => undef,
          },
          removed => {
          }
      },
      5.015006 => {
          delta_from => 5.015005,
          changed => {
              'Archive::Tar'          => '1.82',
              'Archive::Tar::Constant'=> '1.82',
              'Archive::Tar::File'    => '1.82',
              'AutoLoader'            => '5.72',
              'B::Concise'            => '0.88',
              'B::Debug'              => '1.17',
              'B::Deparse'            => '1.10',
              'CPAN::Meta::YAML'      => '0.005',
              'CPANPLUS'              => '0.9113',
              'CPANPLUS::Internals'   => '0.9113',
              'CPANPLUS::Shell::Default'=> '0.9113',
              'Carp'                  => '1.24',
              'Compress::Raw::Bzip2'  => '2.045',
              'Compress::Raw::Zlib'   => '2.045',
              'Compress::Zlib'        => '2.045',
              'Cwd'                   => '3.38',
              'DB'                    => '1.04',
              'Data::Dumper'          => '2.135_01',
              'Digest::SHA'           => '5.70',
              'Dumpvalue'             => '1.17',
              'Exporter'              => '5.66',
              'Exporter::Heavy'       => '5.66',
              'ExtUtils::CBuilder'    => '0.280205',
              'ExtUtils::CBuilder::Platform::os2'=> '0.280204',
              'ExtUtils::Packlist'    => '1.45',
              'ExtUtils::ParseXS'     => '3.08',
              'ExtUtils::ParseXS::Constants'=> '3.08',
              'ExtUtils::ParseXS::CountLines'=> '3.08',
              'ExtUtils::ParseXS::Utilities'=> '3.08',
              'File::Basename'        => '2.84',
              'File::Glob'            => '1.15',
              'File::Spec::Unix'      => '3.35',
              'Getopt::Std'           => '1.07',
              'I18N::LangTags'        => '0.38',
              'IO::Compress::Adapter::Bzip2'=> '2.045',
              'IO::Compress::Adapter::Deflate'=> '2.045',
              'IO::Compress::Adapter::Identity'=> '2.045',
              'IO::Compress::Base'    => '2.046',
              'IO::Compress::Base::Common'=> '2.045',
              'IO::Compress::Bzip2'   => '2.045',
              'IO::Compress::Deflate' => '2.045',
              'IO::Compress::Gzip'    => '2.045',
              'IO::Compress::Gzip::Constants'=> '2.045',
              'IO::Compress::RawDeflate'=> '2.045',
              'IO::Compress::Zip'     => '2.046',
              'IO::Compress::Zip::Constants'=> '2.045',
              'IO::Compress::Zlib::Constants'=> '2.045',
              'IO::Compress::Zlib::Extra'=> '2.045',
              'IO::Dir'               => '1.09',
              'IO::File'              => '1.16',
              'IO::Uncompress::Adapter::Bunzip2'=> '2.045',
              'IO::Uncompress::Adapter::Identity'=> '2.045',
              'IO::Uncompress::Adapter::Inflate'=> '2.045',
              'IO::Uncompress::AnyInflate'=> '2.045',
              'IO::Uncompress::AnyUncompress'=> '2.045',
              'IO::Uncompress::Base'  => '2.046',
              'IO::Uncompress::Bunzip2'=> '2.045',
              'IO::Uncompress::Gunzip'=> '2.045',
              'IO::Uncompress::Inflate'=> '2.045',
              'IO::Uncompress::RawInflate'=> '2.045',
              'IO::Uncompress::Unzip' => '2.046',
              'Locale::Codes'         => '3.20',
              'Locale::Codes::Constants'=> '3.20',
              'Locale::Codes::Country'=> '3.20',
              'Locale::Codes::Country_Codes'=> '3.20',
              'Locale::Codes::Country_Retired'=> '3.20',
              'Locale::Codes::Currency'=> '3.20',
              'Locale::Codes::Currency_Codes'=> '3.20',
              'Locale::Codes::Currency_Retired'=> '3.20',
              'Locale::Codes::LangExt'=> '3.20',
              'Locale::Codes::LangExt_Codes'=> '3.20',
              'Locale::Codes::LangExt_Retired'=> '3.20',
              'Locale::Codes::LangFam'=> '3.20',
              'Locale::Codes::LangFam_Codes'=> '3.20',
              'Locale::Codes::LangFam_Retired'=> '3.20',
              'Locale::Codes::LangVar'=> '3.20',
              'Locale::Codes::LangVar_Codes'=> '3.20',
              'Locale::Codes::LangVar_Retired'=> '3.20',
              'Locale::Codes::Language'=> '3.20',
              'Locale::Codes::Language_Codes'=> '3.20',
              'Locale::Codes::Language_Retired'=> '3.20',
              'Locale::Codes::Script' => '3.20',
              'Locale::Codes::Script_Codes'=> '3.20',
              'Locale::Codes::Script_Retired'=> '3.20',
              'Locale::Country'       => '3.20',
              'Locale::Currency'      => '3.20',
              'Locale::Language'      => '3.20',
              'Locale::Maketext'      => '1.21',
              'Locale::Script'        => '3.20',
              'Module::CoreList'      => '2.59',
              'Module::Loaded'        => '0.08',
              'Opcode'                => '1.22',
              'POSIX'                 => '1.27',
              'Pod::Html'             => '1.12',
              'Pod::LaTeX'            => '0.60',
              'Pod::Perldoc'          => '3.15_08',
              'Safe'                  => '2.30',
              'SelfLoader'            => '1.20',
              'Socket'                => '1.97',
              'Storable'              => '2.34',
              'UNIVERSAL'             => '1.11',
              'Unicode::Collate'      => '0.87',
              'Unicode::Collate::Locale'=> '0.87',
              'XS::APItest'           => '0.34',
              'arybase'               => '0.02',
              'charnames'             => '1.27',
              'diagnostics'           => '1.26',
              'feature'               => '1.24',
              'if'                    => '0.0602',
              'overload'              => '1.16',
              'sigtrap'               => '1.06',
              'strict'                => '1.06',
              'threads'               => '1.86',
              'version'               => '0.96',
          },
          removed => {
          }
      },
      5.015007 => {
          delta_from => 5.015006,
          changed => {
              'B'                     => '1.33',
              'B::Deparse'            => '1.11',
              'CGI'                   => '3.59',
              'CPAN::Meta'            => '2.113640',
              'CPAN::Meta::Converter' => '2.113640',
              'CPAN::Meta::Feature'   => '2.113640',
              'CPAN::Meta::History'   => '2.113640',
              'CPAN::Meta::Prereqs'   => '2.113640',
              'CPAN::Meta::Requirements'=> '2.113640',
              'CPAN::Meta::Spec'      => '2.113640',
              'CPAN::Meta::Validator' => '2.113640',
              'CPANPLUS'              => '0.9116',
              'CPANPLUS::Internals'   => '0.9116',
              'CPANPLUS::Shell::Default'=> '0.9116',
              'Cwd'                   => '3.39_01',
              'Data::Dumper'          => '2.135_03',
              'Devel::InnerPackage'   => '0.4',
              'ExtUtils::CBuilder::Base'=> '0.280205',
              'ExtUtils::CBuilder::Platform::Unix'=> '0.280205',
              'ExtUtils::CBuilder::Platform::VMS'=> '0.280205',
              'ExtUtils::CBuilder::Platform::Windows'=> '0.280205',
              'ExtUtils::CBuilder::Platform::Windows::BCC'=> '0.280205',
              'ExtUtils::CBuilder::Platform::Windows::GCC'=> '0.280205',
              'ExtUtils::CBuilder::Platform::Windows::MSVC'=> '0.280205',
              'ExtUtils::CBuilder::Platform::aix'=> '0.280205',
              'ExtUtils::CBuilder::Platform::cygwin'=> '0.280205',
              'ExtUtils::CBuilder::Platform::darwin'=> '0.280205',
              'ExtUtils::CBuilder::Platform::dec_osf'=> '0.280205',
              'ExtUtils::CBuilder::Platform::os2'=> '0.280205',
              'ExtUtils::Manifest'    => '1.61',
              'ExtUtils::Packlist'    => '1.46',
              'ExtUtils::ParseXS'     => '3.12',
              'ExtUtils::ParseXS::Constants'=> '3.12',
              'ExtUtils::ParseXS::CountLines'=> '3.12',
              'ExtUtils::ParseXS::Utilities'=> '3.12',
              'ExtUtils::Typemaps'    => '1.03',
              'ExtUtils::Typemaps::Cmd'=> undef,
              'ExtUtils::Typemaps::Type'=> '0.06',
              'File::Glob'            => '1.16',
              'File::Spec'            => '3.39_01',
              'File::Spec::Cygwin'    => '3.39_01',
              'File::Spec::Epoc'      => '3.39_01',
              'File::Spec::Functions' => '3.39_01',
              'File::Spec::Mac'       => '3.39_01',
              'File::Spec::OS2'       => '3.39_01',
              'File::Spec::Unix'      => '3.39_01',
              'File::Spec::VMS'       => '3.39_01',
              'File::Spec::Win32'     => '3.39_01',
              'IO::Dir'               => '1.10',
              'IO::Pipe'              => '1.15',
              'IO::Poll'              => '0.09',
              'IO::Select'            => '1.21',
              'IO::Socket'            => '1.34',
              'IO::Socket::INET'      => '1.33',
              'IO::Socket::UNIX'      => '1.24',
              'Locale::Maketext'      => '1.22',
              'Math::BigInt'          => '1.998',
              'Module::CoreList'      => '2.60',
              'Module::Pluggable'     => '4.0',
              'POSIX'                 => '1.28',
              'PerlIO::scalar'        => '0.13',
              'Pod::Html'             => '1.13',
              'Pod::Perldoc'          => '3.15_15',
              'Pod::Perldoc::BaseTo'  => '3.15_15',
              'Pod::Perldoc::GetOptsOO'=> '3.15_15',
              'Pod::Perldoc::ToANSI'  => '3.15_15',
              'Pod::Perldoc::ToChecker'=> '3.15_15',
              'Pod::Perldoc::ToMan'   => '3.15_15',
              'Pod::Perldoc::ToNroff' => '3.15_15',
              'Pod::Perldoc::ToPod'   => '3.15_15',
              'Pod::Perldoc::ToRtf'   => '3.15_15',
              'Pod::Perldoc::ToTerm'  => '3.15_15',
              'Pod::Perldoc::ToText'  => '3.15_15',
              'Pod::Perldoc::ToTk'    => '3.15_15',
              'Pod::Perldoc::ToXml'   => '3.15_15',
              'Term::UI'              => '0.30',
              'Tie::File'             => '0.98',
              'Unicode::UCD'          => '0.39',
              'Version::Requirements' => '0.101021',
              'XS::APItest'           => '0.35',
              '_charnames'            => '1.28',
              'arybase'               => '0.03',
              'autouse'               => '1.07',
              'charnames'             => '1.28',
              'diagnostics'           => '1.27',
              'feature'               => '1.25',
              'overload'              => '1.17',
              'overloading'           => '0.02',
              'perlfaq'               => '5.0150038',
          },
          removed => {
          }
      },
      5.015008 => {
          delta_from => 5.015007,
          changed => {
              'B'                     => '1.34',
              'B::Deparse'            => '1.12',
              'CPAN::Meta'            => '2.120351',
              'CPAN::Meta::Converter' => '2.120351',
              'CPAN::Meta::Feature'   => '2.120351',
              'CPAN::Meta::History'   => '2.120351',
              'CPAN::Meta::Prereqs'   => '2.120351',
              'CPAN::Meta::Requirements'=> '2.120351',
              'CPAN::Meta::Spec'      => '2.120351',
              'CPAN::Meta::Validator' => '2.120351',
              'CPAN::Meta::YAML'      => '0.007',
              'CPANPLUS'              => '0.9118',
              'CPANPLUS::Dist::Build' => '0.62',
              'CPANPLUS::Dist::Build::Constants'=> '0.62',
              'CPANPLUS::Internals'   => '0.9118',
              'CPANPLUS::Shell::Default'=> '0.9118',
              'Carp'                  => '1.25',
              'Carp::Heavy'           => '1.25',
              'Compress::Raw::Bzip2'  => '2.048',
              'Compress::Raw::Zlib'   => '2.048',
              'Compress::Zlib'        => '2.048',
              'Cwd'                   => '3.39_02',
              'DB_File'               => '1.826',
              'Data::Dumper'          => '2.135_05',
              'English'               => '1.05',
              'ExtUtils::Install'     => '1.58',
              'ExtUtils::ParseXS'     => '3.16',
              'ExtUtils::ParseXS::Constants'=> '3.16',
              'ExtUtils::ParseXS::CountLines'=> '3.16',
              'ExtUtils::ParseXS::Utilities'=> '3.16',
              'ExtUtils::Typemaps'    => '3.16',
              'ExtUtils::Typemaps::Cmd'=> '3.16',
              'ExtUtils::Typemaps::InputMap'=> '3.16',
              'ExtUtils::Typemaps::OutputMap'=> '3.16',
              'ExtUtils::Typemaps::Type'=> '3.16',
              'File::Copy'            => '2.23',
              'File::Glob'            => '1.17',
              'File::Spec'            => '3.39_02',
              'File::Spec::Cygwin'    => '3.39_02',
              'File::Spec::Epoc'      => '3.39_02',
              'File::Spec::Functions' => '3.39_02',
              'File::Spec::Mac'       => '3.39_02',
              'File::Spec::OS2'       => '3.39_02',
              'File::Spec::Unix'      => '3.39_02',
              'File::Spec::VMS'       => '3.39_02',
              'File::Spec::Win32'     => '3.39_02',
              'Filter::Util::Call'    => '1.40',
              'IO::Compress::Adapter::Bzip2'=> '2.048',
              'IO::Compress::Adapter::Deflate'=> '2.048',
              'IO::Compress::Adapter::Identity'=> '2.048',
              'IO::Compress::Base'    => '2.048',
              'IO::Compress::Base::Common'=> '2.048',
              'IO::Compress::Bzip2'   => '2.048',
              'IO::Compress::Deflate' => '2.048',
              'IO::Compress::Gzip'    => '2.048',
              'IO::Compress::Gzip::Constants'=> '2.048',
              'IO::Compress::RawDeflate'=> '2.048',
              'IO::Compress::Zip'     => '2.048',
              'IO::Compress::Zip::Constants'=> '2.048',
              'IO::Compress::Zlib::Constants'=> '2.048',
              'IO::Compress::Zlib::Extra'=> '2.048',
              'IO::Uncompress::Adapter::Bunzip2'=> '2.048',
              'IO::Uncompress::Adapter::Identity'=> '2.048',
              'IO::Uncompress::Adapter::Inflate'=> '2.048',
              'IO::Uncompress::AnyInflate'=> '2.048',
              'IO::Uncompress::AnyUncompress'=> '2.048',
              'IO::Uncompress::Base'  => '2.048',
              'IO::Uncompress::Bunzip2'=> '2.048',
              'IO::Uncompress::Gunzip'=> '2.048',
              'IO::Uncompress::Inflate'=> '2.048',
              'IO::Uncompress::RawInflate'=> '2.048',
              'IO::Uncompress::Unzip' => '2.048',
              'IPC::Cmd'              => '0.76',
              'Math::Complex'         => '1.59',
              'Math::Trig'            => '1.23',
              'Module::Metadata'      => '1.000009',
              'Opcode'                => '1.23',
              'POSIX'                 => '1.30',
              'Parse::CPAN::Meta'     => '1.4402',
              'PerlIO::mmap'          => '0.010',
              'Pod::Checker'          => '1.51',
              'Pod::Find'             => '1.51',
              'Pod::Functions'        => '1.05',
              'Pod::Html'             => '1.14',
              'Pod::InputObjects'     => '1.51',
              'Pod::ParseUtils'       => '1.51',
              'Pod::Parser'           => '1.51',
              'Pod::PlainText'        => '2.05',
              'Pod::Select'           => '1.51',
              'Pod::Usage'            => '1.51',
              'Safe'                  => '2.31',
              'Socket'                => '1.98',
              'Term::Cap'             => '1.13',
              'Term::ReadLine'        => '1.08',
              'Time::HiRes'           => '1.9725',
              'Unicode'               => '6.1.0',
              'Unicode::UCD'          => '0.41',
              'Version::Requirements' => '0.101022',
              'XS::APItest'           => '0.36',
              'XS::Typemap'           => '0.08',
              '_charnames'            => '1.29',
              'arybase'               => '0.04',
              'charnames'             => '1.29',
              'diagnostics'           => '1.28',
              'feature'               => '1.26',
              'locale'                => '1.01',
              'overload'              => '1.18',
              'perlfaq'               => '5.0150039',
              're'                    => '0.19',
              'subs'                  => '1.01',
              'warnings'              => '1.13',
          },
          removed => {
          }
      },
      5.015009 => {
          delta_from => 5.015008,
          changed => {
              'B::Deparse'            => '1.13',
              'B::Lint'               => '1.14',
              'B::Lint::Debug'        => '1.14',
              'CPAN::Meta'            => '2.120630',
              'CPAN::Meta::Converter' => '2.120630',
              'CPAN::Meta::Feature'   => '2.120630',
              'CPAN::Meta::History'   => '2.120630',
              'CPAN::Meta::Prereqs'   => '2.120630',
              'CPAN::Meta::Requirements'=> '2.120630',
              'CPAN::Meta::Spec'      => '2.120630',
              'CPAN::Meta::Validator' => '2.120630',
              'CPANPLUS'              => '0.9121',
              'CPANPLUS::Internals'   => '0.9121',
              'CPANPLUS::Shell::Default'=> '0.9121',
              'Data::Dumper'          => '2.135_06',
              'Digest::SHA'           => '5.71',
              'ExtUtils::CBuilder'    => '0.280206',
              'ExtUtils::CBuilder::Base'=> '0.280206',
              'ExtUtils::CBuilder::Platform::Unix'=> '0.280206',
              'ExtUtils::CBuilder::Platform::VMS'=> '0.280206',
              'ExtUtils::CBuilder::Platform::Windows'=> '0.280206',
              'ExtUtils::CBuilder::Platform::Windows::BCC'=> '0.280206',
              'ExtUtils::CBuilder::Platform::Windows::GCC'=> '0.280206',
              'ExtUtils::CBuilder::Platform::Windows::MSVC'=> '0.280206',
              'ExtUtils::CBuilder::Platform::aix'=> '0.280206',
              'ExtUtils::CBuilder::Platform::cygwin'=> '0.280206',
              'ExtUtils::CBuilder::Platform::darwin'=> '0.280206',
              'ExtUtils::CBuilder::Platform::dec_osf'=> '0.280206',
              'ExtUtils::CBuilder::Platform::os2'=> '0.280206',
              'HTTP::Tiny'            => '0.017',
              'Locale::Codes'         => '3.21',
              'Locale::Codes::Constants'=> '3.21',
              'Locale::Codes::Country'=> '3.21',
              'Locale::Codes::Country_Codes'=> '3.21',
              'Locale::Codes::Country_Retired'=> '3.21',
              'Locale::Codes::Currency'=> '3.21',
              'Locale::Codes::Currency_Codes'=> '3.21',
              'Locale::Codes::Currency_Retired'=> '3.21',
              'Locale::Codes::LangExt'=> '3.21',
              'Locale::Codes::LangExt_Codes'=> '3.21',
              'Locale::Codes::LangExt_Retired'=> '3.21',
              'Locale::Codes::LangFam'=> '3.21',
              'Locale::Codes::LangFam_Codes'=> '3.21',
              'Locale::Codes::LangFam_Retired'=> '3.21',
              'Locale::Codes::LangVar'=> '3.21',
              'Locale::Codes::LangVar_Codes'=> '3.21',
              'Locale::Codes::LangVar_Retired'=> '3.21',
              'Locale::Codes::Language'=> '3.21',
              'Locale::Codes::Language_Codes'=> '3.21',
              'Locale::Codes::Language_Retired'=> '3.21',
              'Locale::Codes::Script' => '3.21',
              'Locale::Codes::Script_Codes'=> '3.21',
              'Locale::Codes::Script_Retired'=> '3.21',
              'Locale::Country'       => '3.21',
              'Locale::Currency'      => '3.21',
              'Locale::Language'      => '3.21',
              'Locale::Script'        => '3.21',
              'Module::CoreList'      => '2.65',
              'Pod::Html'             => '1.1501',
              'Pod::Perldoc'          => '3.17',
              'Pod::Perldoc::BaseTo'  => '3.17',
              'Pod::Perldoc::GetOptsOO'=> '3.17',
              'Pod::Perldoc::ToANSI'  => '3.17',
              'Pod::Perldoc::ToChecker'=> '3.17',
              'Pod::Perldoc::ToMan'   => '3.17',
              'Pod::Perldoc::ToNroff' => '3.17',
              'Pod::Perldoc::ToPod'   => '3.17',
              'Pod::Perldoc::ToRtf'   => '3.17',
              'Pod::Perldoc::ToTerm'  => '3.17',
              'Pod::Perldoc::ToText'  => '3.17',
              'Pod::Perldoc::ToTk'    => '3.17',
              'Pod::Perldoc::ToXml'   => '3.17',
              'Pod::Simple'           => '3.20',
              'Pod::Simple::BlackBox' => '3.20',
              'Pod::Simple::Checker'  => '3.20',
              'Pod::Simple::Debug'    => '3.20',
              'Pod::Simple::DumpAsText'=> '3.20',
              'Pod::Simple::DumpAsXML'=> '3.20',
              'Pod::Simple::HTML'     => '3.20',
              'Pod::Simple::HTMLBatch'=> '3.20',
              'Pod::Simple::LinkSection'=> '3.20',
              'Pod::Simple::Methody'  => '3.20',
              'Pod::Simple::Progress' => '3.20',
              'Pod::Simple::PullParser'=> '3.20',
              'Pod::Simple::PullParserEndToken'=> '3.20',
              'Pod::Simple::PullParserStartToken'=> '3.20',
              'Pod::Simple::PullParserTextToken'=> '3.20',
              'Pod::Simple::PullParserToken'=> '3.20',
              'Pod::Simple::RTF'      => '3.20',
              'Pod::Simple::Search'   => '3.20',
              'Pod::Simple::SimpleTree'=> '3.20',
              'Pod::Simple::Text'     => '3.20',
              'Pod::Simple::TextContent'=> '3.20',
              'Pod::Simple::TiedOutFH'=> '3.20',
              'Pod::Simple::Transcode'=> '3.20',
              'Pod::Simple::TranscodeDumb'=> '3.20',
              'Pod::Simple::TranscodeSmart'=> '3.20',
              'Pod::Simple::XHTML'    => '3.20',
              'Pod::Simple::XMLOutStream'=> '3.20',
              'Socket'                => '2.000',
              'Term::ReadLine'        => '1.09',
              'Unicode::Collate'      => '0.89',
              'Unicode::Collate::CJK::Korean'=> '0.88',
              'Unicode::Collate::Locale'=> '0.89',
              'Unicode::Normalize'    => '1.14',
              'Unicode::UCD'          => '0.42',
              'XS::APItest'           => '0.37',
              'arybase'               => '0.05',
              'attributes'            => '0.18',
              'charnames'             => '1.30',
              'feature'               => '1.27',
          },
          removed => {
          }
      },
      5.016 => {
          delta_from => 5.015009,
          changed => {
              'B::Concise'            => '0.89',
              'B::Deparse'            => '1.14',
              'Carp'                  => '1.26',
              'Carp::Heavy'           => '1.26',
              'IO::Socket'            => '1.35',
              'Module::CoreList'      => '2.66',
              'PerlIO::scalar'        => '0.14',
              'Pod::Html'             => '1.1502',
              'Safe'                  => '2.31_01',
              'Socket'                => '2.001',
              'Unicode::UCD'          => '0.43',
              'XS::APItest'           => '0.38',
              '_charnames'            => '1.31',
              'attributes'            => '0.19',
              'strict'                => '1.07',
              'version'               => '0.99',
          },
          removed => {
          }
      },
      5.016001 => {
          delta_from => 5.016,
          changed => {
              'B'                     => '1.35',
              'B::Deparse'            => '1.14_01',
              'List::Util'            => '1.25',
              'List::Util::PP'        => '1.25',
              'List::Util::XS'        => '1.25',
              'Module::CoreList'      => '2.70',
              'PerlIO::scalar'        => '0.14_01',
              'Scalar::Util'          => '1.25',
              'Scalar::Util::PP'      => '1.25',
              're'                    => '0.19_01',
          },
          removed => {
          }
      },
      5.016002 => {
          delta_from => 5.016001,
          changed => {
              'Module::CoreList'      => '2.76',
          },
          removed => {
          }
      },
      5.016003 => {
          delta_from => 5.016002,
          changed => {
              'Encode'                => '2.44_01',
              'Module::CoreList'      => '2.76_02',
              'XS::APItest'           => '0.39',
          },
          removed => {
          }
      },
      5.017 => {
          delta_from => 5.016,
          changed => {
              'B'                     => '1.35',
              'B::Concise'            => '0.90',
              'ExtUtils::ParseXS'     => '3.17',
              'ExtUtils::ParseXS::Utilities'=> '3.17',
              'File::DosGlob'         => '1.07',
              'File::Find'            => '1.21',
              'File::stat'            => '1.06',
              'Hash::Util'            => '0.12',
              'IO::Socket'            => '1.34',
              'Module::CoreList'      => '2.67',
              'Pod::Functions'        => '1.06',
              'Storable'              => '2.35',
              'XS::APItest'           => '0.39',
              'diagnostics'           => '1.29',
              'feature'               => '1.28',
              'overload'              => '1.19',
              'utf8'                  => '1.10',
          },
          removed => {
              'Version::Requirements' => 1,
          }
      },
      5.017001 => {
          delta_from => 5.017,
          changed => {
              'App::Prove'            => '3.25',
              'App::Prove::State'     => '3.25',
              'App::Prove::State::Result'=> '3.25',
              'App::Prove::State::Result::Test'=> '3.25',
              'Archive::Extract'      => '0.60',
              'Archive::Tar'          => '1.88',
              'Archive::Tar::Constant'=> '1.88',
              'Archive::Tar::File'    => '1.88',
              'B'                     => '1.36',
              'B::Deparse'            => '1.15',
              'CPAN::Meta'            => '2.120921',
              'CPAN::Meta::Converter' => '2.120921',
              'CPAN::Meta::Feature'   => '2.120921',
              'CPAN::Meta::History'   => '2.120921',
              'CPAN::Meta::Prereqs'   => '2.120921',
              'CPAN::Meta::Requirements'=> '2.122',
              'CPAN::Meta::Spec'      => '2.120921',
              'CPAN::Meta::Validator' => '2.120921',
              'CPAN::Meta::YAML'      => '0.008',
              'CPANPLUS'              => '0.9130',
              'CPANPLUS::Config::HomeEnv'=> '0.04',
              'CPANPLUS::Internals'   => '0.9130',
              'CPANPLUS::Shell::Default'=> '0.9130',
              'Class::Struct'         => '0.64',
              'Compress::Raw::Bzip2'  => '2.052',
              'Compress::Raw::Zlib'   => '2.054',
              'Compress::Zlib'        => '2.052',
              'Digest::MD5'           => '2.52',
              'DynaLoader'            => '1.15',
              'ExtUtils::CBuilder'    => '0.280208',
              'ExtUtils::CBuilder::Base'=> '0.280208',
              'ExtUtils::CBuilder::Platform::Unix'=> '0.280208',
              'ExtUtils::CBuilder::Platform::VMS'=> '0.280208',
              'ExtUtils::CBuilder::Platform::Windows'=> '0.280208',
              'ExtUtils::CBuilder::Platform::Windows::BCC'=> '0.280208',
              'ExtUtils::CBuilder::Platform::Windows::GCC'=> '0.280208',
              'ExtUtils::CBuilder::Platform::Windows::MSVC'=> '0.280208',
              'ExtUtils::CBuilder::Platform::aix'=> '0.280208',
              'ExtUtils::CBuilder::Platform::cygwin'=> '0.280208',
              'ExtUtils::CBuilder::Platform::darwin'=> '0.280208',
              'ExtUtils::CBuilder::Platform::dec_osf'=> '0.280208',
              'ExtUtils::CBuilder::Platform::os2'=> '0.280208',
              'Fatal'                 => '2.11',
              'File::DosGlob'         => '1.08',
              'File::Fetch'           => '0.34',
              'File::Spec::Unix'      => '3.39_03',
              'Filter::Util::Call'    => '1.45',
              'HTTP::Tiny'            => '0.022',
              'IO'                    => '1.25_07',
              'IO::Compress::Adapter::Bzip2'=> '2.052',
              'IO::Compress::Adapter::Deflate'=> '2.052',
              'IO::Compress::Adapter::Identity'=> '2.052',
              'IO::Compress::Base'    => '2.052',
              'IO::Compress::Base::Common'=> '2.052',
              'IO::Compress::Bzip2'   => '2.052',
              'IO::Compress::Deflate' => '2.052',
              'IO::Compress::Gzip'    => '2.052',
              'IO::Compress::Gzip::Constants'=> '2.052',
              'IO::Compress::RawDeflate'=> '2.052',
              'IO::Compress::Zip'     => '2.052',
              'IO::Compress::Zip::Constants'=> '2.052',
              'IO::Compress::Zlib::Constants'=> '2.052',
              'IO::Compress::Zlib::Extra'=> '2.052',
              'IO::Uncompress::Adapter::Bunzip2'=> '2.052',
              'IO::Uncompress::Adapter::Identity'=> '2.052',
              'IO::Uncompress::Adapter::Inflate'=> '2.052',
              'IO::Uncompress::AnyInflate'=> '2.052',
              'IO::Uncompress::AnyUncompress'=> '2.052',
              'IO::Uncompress::Base'  => '2.052',
              'IO::Uncompress::Bunzip2'=> '2.052',
              'IO::Uncompress::Gunzip'=> '2.052',
              'IO::Uncompress::Inflate'=> '2.052',
              'IO::Uncompress::RawInflate'=> '2.052',
              'IO::Uncompress::Unzip' => '2.052',
              'IPC::Cmd'              => '0.78',
              'List::Util'            => '1.25',
              'List::Util::XS'        => '1.25',
              'Locale::Codes'         => '3.22',
              'Locale::Codes::Constants'=> '3.22',
              'Locale::Codes::Country'=> '3.22',
              'Locale::Codes::Country_Codes'=> '3.22',
              'Locale::Codes::Country_Retired'=> '3.22',
              'Locale::Codes::Currency'=> '3.22',
              'Locale::Codes::Currency_Codes'=> '3.22',
              'Locale::Codes::Currency_Retired'=> '3.22',
              'Locale::Codes::LangExt'=> '3.22',
              'Locale::Codes::LangExt_Codes'=> '3.22',
              'Locale::Codes::LangExt_Retired'=> '3.22',
              'Locale::Codes::LangFam'=> '3.22',
              'Locale::Codes::LangFam_Codes'=> '3.22',
              'Locale::Codes::LangFam_Retired'=> '3.22',
              'Locale::Codes::LangVar'=> '3.22',
              'Locale::Codes::LangVar_Codes'=> '3.22',
              'Locale::Codes::LangVar_Retired'=> '3.22',
              'Locale::Codes::Language'=> '3.22',
              'Locale::Codes::Language_Codes'=> '3.22',
              'Locale::Codes::Language_Retired'=> '3.22',
              'Locale::Codes::Script' => '3.22',
              'Locale::Codes::Script_Codes'=> '3.22',
              'Locale::Codes::Script_Retired'=> '3.22',
              'Locale::Country'       => '3.22',
              'Locale::Currency'      => '3.22',
              'Locale::Language'      => '3.22',
              'Locale::Script'        => '3.22',
              'Memoize'               => '1.03',
              'Memoize::AnyDBM_File'  => '1.03',
              'Memoize::Expire'       => '1.03',
              'Memoize::ExpireFile'   => '1.03',
              'Memoize::ExpireTest'   => '1.03',
              'Memoize::NDBM_File'    => '1.03',
              'Memoize::SDBM_File'    => '1.03',
              'Memoize::Storable'     => '1.03',
              'Module::Build'         => '0.40',
              'Module::Build::Base'   => '0.40',
              'Module::Build::Compat' => '0.40',
              'Module::Build::Config' => '0.40',
              'Module::Build::Cookbook'=> '0.40',
              'Module::Build::Dumper' => '0.40',
              'Module::Build::ModuleInfo'=> '0.40',
              'Module::Build::Notes'  => '0.40',
              'Module::Build::PPMMaker'=> '0.40',
              'Module::Build::Platform::Amiga'=> '0.40',
              'Module::Build::Platform::Default'=> '0.40',
              'Module::Build::Platform::EBCDIC'=> '0.40',
              'Module::Build::Platform::MPEiX'=> '0.40',
              'Module::Build::Platform::MacOS'=> '0.40',
              'Module::Build::Platform::RiscOS'=> '0.40',
              'Module::Build::Platform::Unix'=> '0.40',
              'Module::Build::Platform::VMS'=> '0.40',
              'Module::Build::Platform::VOS'=> '0.40',
              'Module::Build::Platform::Windows'=> '0.40',
              'Module::Build::Platform::aix'=> '0.40',
              'Module::Build::Platform::cygwin'=> '0.40',
              'Module::Build::Platform::darwin'=> '0.40',
              'Module::Build::Platform::os2'=> '0.40',
              'Module::Build::PodParser'=> '0.40',
              'Module::CoreList'      => '2.68',
              'Module::Load::Conditional'=> '0.50',
              'Object::Accessor'      => '0.44',
              'POSIX'                 => '1.31',
              'Params::Check'         => '0.36',
              'Parse::CPAN::Meta'     => '1.4404',
              'PerlIO::mmap'          => '0.011',
              'PerlIO::via::QuotedPrint'=> '0.07',
              'Pod::Html'             => '1.16',
              'Pod::Man'              => '2.26',
              'Pod::Text'             => '3.16',
              'Safe'                  => '2.33_01',
              'Scalar::Util'          => '1.25',
              'Search::Dict'          => '1.07',
              'Storable'              => '2.36',
              'TAP::Base'             => '3.25',
              'TAP::Formatter::Base'  => '3.25',
              'TAP::Formatter::Color' => '3.25',
              'TAP::Formatter::Console'=> '3.25',
              'TAP::Formatter::Console::ParallelSession'=> '3.25',
              'TAP::Formatter::Console::Session'=> '3.25',
              'TAP::Formatter::File'  => '3.25',
              'TAP::Formatter::File::Session'=> '3.25',
              'TAP::Formatter::Session'=> '3.25',
              'TAP::Harness'          => '3.25',
              'TAP::Object'           => '3.25',
              'TAP::Parser'           => '3.25',
              'TAP::Parser::Aggregator'=> '3.25',
              'TAP::Parser::Grammar'  => '3.25',
              'TAP::Parser::Iterator' => '3.25',
              'TAP::Parser::Iterator::Array'=> '3.25',
              'TAP::Parser::Iterator::Process'=> '3.25',
              'TAP::Parser::Iterator::Stream'=> '3.25',
              'TAP::Parser::IteratorFactory'=> '3.25',
              'TAP::Parser::Multiplexer'=> '3.25',
              'TAP::Parser::Result'   => '3.25',
              'TAP::Parser::Result::Bailout'=> '3.25',
              'TAP::Parser::Result::Comment'=> '3.25',
              'TAP::Parser::Result::Plan'=> '3.25',
              'TAP::Parser::Result::Pragma'=> '3.25',
              'TAP::Parser::Result::Test'=> '3.25',
              'TAP::Parser::Result::Unknown'=> '3.25',
              'TAP::Parser::Result::Version'=> '3.25',
              'TAP::Parser::Result::YAML'=> '3.25',
              'TAP::Parser::ResultFactory'=> '3.25',
              'TAP::Parser::Scheduler'=> '3.25',
              'TAP::Parser::Scheduler::Job'=> '3.25',
              'TAP::Parser::Scheduler::Spinner'=> '3.25',
              'TAP::Parser::Source'   => '3.25',
              'TAP::Parser::SourceHandler'=> '3.25',
              'TAP::Parser::SourceHandler::Executable'=> '3.25',
              'TAP::Parser::SourceHandler::File'=> '3.25',
              'TAP::Parser::SourceHandler::Handle'=> '3.25',
              'TAP::Parser::SourceHandler::Perl'=> '3.25',
              'TAP::Parser::SourceHandler::RawTAP'=> '3.25',
              'TAP::Parser::Utils'    => '3.25',
              'TAP::Parser::YAMLish::Reader'=> '3.25',
              'TAP::Parser::YAMLish::Writer'=> '3.25',
              'Term::ANSIColor'       => '3.02',
              'Test::Harness'         => '3.25',
              'Unicode'               => '6.2.0',
              'Unicode::UCD'          => '0.44',
              'XS::APItest'           => '0.40',
              '_charnames'            => '1.32',
              'attributes'            => '0.2',
              'autodie'               => '2.11',
              'autodie::exception'    => '2.11',
              'autodie::exception::system'=> '2.11',
              'autodie::hints'        => '2.11',
              'bigint'                => '0.30',
              'charnames'             => '1.32',
              'feature'               => '1.29',
              'inc::latest'           => '0.40',
              'perlfaq'               => '5.0150040',
              're'                    => '0.20',
          },
          removed => {
              'List::Util::PP'        => 1,
              'Scalar::Util::PP'      => 1,
          }
      },
      5.017002 => {
          delta_from => 5.017001,
          changed => {
              'App::Prove'            => '3.25_01',
              'App::Prove::State'     => '3.25_01',
              'App::Prove::State::Result'=> '3.25_01',
              'App::Prove::State::Result::Test'=> '3.25_01',
              'B::Concise'            => '0.91',
              'Compress::Raw::Bzip2'  => '2.05201',
              'Compress::Raw::Zlib'   => '2.05401',
              'Exporter'              => '5.67',
              'Exporter::Heavy'       => '5.67',
              'Fatal'                 => '2.12',
              'File::Fetch'           => '0.36',
              'File::stat'            => '1.07',
              'IO'                    => '1.25_08',
              'IO::Socket'            => '1.35',
              'Module::CoreList'      => '2.69',
              'PerlIO::scalar'        => '0.15',
              'Socket'                => '2.002',
              'Storable'              => '2.37',
              'TAP::Base'             => '3.25_01',
              'TAP::Formatter::Base'  => '3.25_01',
              'TAP::Formatter::Color' => '3.25_01',
              'TAP::Formatter::Console'=> '3.25_01',
              'TAP::Formatter::Console::ParallelSession'=> '3.25_01',
              'TAP::Formatter::Console::Session'=> '3.25_01',
              'TAP::Formatter::File'  => '3.25_01',
              'TAP::Formatter::File::Session'=> '3.25_01',
              'TAP::Formatter::Session'=> '3.25_01',
              'TAP::Harness'          => '3.25_01',
              'TAP::Object'           => '3.25_01',
              'TAP::Parser'           => '3.25_01',
              'TAP::Parser::Aggregator'=> '3.25_01',
              'TAP::Parser::Grammar'  => '3.25_01',
              'TAP::Parser::Iterator' => '3.25_01',
              'TAP::Parser::Iterator::Array'=> '3.25_01',
              'TAP::Parser::Iterator::Process'=> '3.25_01',
              'TAP::Parser::Iterator::Stream'=> '3.25_01',
              'TAP::Parser::IteratorFactory'=> '3.25_01',
              'TAP::Parser::Multiplexer'=> '3.25_01',
              'TAP::Parser::Result'   => '3.25_01',
              'TAP::Parser::Result::Bailout'=> '3.25_01',
              'TAP::Parser::Result::Comment'=> '3.25_01',
              'TAP::Parser::Result::Plan'=> '3.25_01',
              'TAP::Parser::Result::Pragma'=> '3.25_01',
              'TAP::Parser::Result::Test'=> '3.25_01',
              'TAP::Parser::Result::Unknown'=> '3.25_01',
              'TAP::Parser::Result::Version'=> '3.25_01',
              'TAP::Parser::Result::YAML'=> '3.25_01',
              'TAP::Parser::ResultFactory'=> '3.25_01',
              'TAP::Parser::Scheduler'=> '3.25_01',
              'TAP::Parser::Scheduler::Job'=> '3.25_01',
              'TAP::Parser::Scheduler::Spinner'=> '3.25_01',
              'TAP::Parser::Source'   => '3.25_01',
              'TAP::Parser::SourceHandler'=> '3.25_01',
              'TAP::Parser::SourceHandler::Executable'=> '3.25_01',
              'TAP::Parser::SourceHandler::File'=> '3.25_01',
              'TAP::Parser::SourceHandler::Handle'=> '3.25_01',
              'TAP::Parser::SourceHandler::Perl'=> '3.25_01',
              'TAP::Parser::SourceHandler::RawTAP'=> '3.25_01',
              'TAP::Parser::Utils'    => '3.25_01',
              'TAP::Parser::YAMLish::Reader'=> '3.25_01',
              'TAP::Parser::YAMLish::Writer'=> '3.25_01',
              'Test::Harness'         => '3.25_01',
              'Tie::StdHandle'        => '4.3',
              'XS::APItest'           => '0.41',
              'autodie'               => '2.12',
              'autodie::exception'    => '2.12',
              'autodie::exception::system'=> '2.12',
              'autodie::hints'        => '2.12',
              'diagnostics'           => '1.30',
              'overload'              => '1.20',
              're'                    => '0.21',
              'vars'                  => '1.03',
          },
          removed => {
          }
      },
      5.017003 => {
          delta_from => 5.017002,
          changed => {
              'B'                     => '1.37',
              'B::Concise'            => '0.92',
              'B::Debug'              => '1.18',
              'B::Deparse'            => '1.16',
              'CGI'                   => '3.60',
              'Compress::Raw::Bzip2'  => '2.055',
              'Compress::Raw::Zlib'   => '2.056',
              'Compress::Zlib'        => '2.055',
              'Data::Dumper'          => '2.135_07',
              'Devel::Peek'           => '1.09',
              'Encode'                => '2.47',
              'Encode::Alias'         => '2.16',
              'Encode::GSM0338'       => '2.02',
              'Encode::Unicode::UTF7' => '2.06',
              'IO::Compress::Adapter::Bzip2'=> '2.055',
              'IO::Compress::Adapter::Deflate'=> '2.055',
              'IO::Compress::Adapter::Identity'=> '2.055',
              'IO::Compress::Base'    => '2.055',
              'IO::Compress::Base::Common'=> '2.055',
              'IO::Compress::Bzip2'   => '2.055',
              'IO::Compress::Deflate' => '2.055',
              'IO::Compress::Gzip'    => '2.055',
              'IO::Compress::Gzip::Constants'=> '2.055',
              'IO::Compress::RawDeflate'=> '2.055',
              'IO::Compress::Zip'     => '2.055',
              'IO::Compress::Zip::Constants'=> '2.055',
              'IO::Compress::Zlib::Constants'=> '2.055',
              'IO::Compress::Zlib::Extra'=> '2.055',
              'IO::Uncompress::Adapter::Bunzip2'=> '2.055',
              'IO::Uncompress::Adapter::Identity'=> '2.055',
              'IO::Uncompress::Adapter::Inflate'=> '2.055',
              'IO::Uncompress::AnyInflate'=> '2.055',
              'IO::Uncompress::AnyUncompress'=> '2.055',
              'IO::Uncompress::Base'  => '2.055',
              'IO::Uncompress::Bunzip2'=> '2.055',
              'IO::Uncompress::Gunzip'=> '2.055',
              'IO::Uncompress::Inflate'=> '2.055',
              'IO::Uncompress::RawInflate'=> '2.055',
              'IO::Uncompress::Unzip' => '2.055',
              'Module::Build'         => '0.4003',
              'Module::Build::Base'   => '0.4003',
              'Module::Build::Compat' => '0.4003',
              'Module::Build::Config' => '0.4003',
              'Module::Build::Cookbook'=> '0.4003',
              'Module::Build::Dumper' => '0.4003',
              'Module::Build::ModuleInfo'=> '0.4003',
              'Module::Build::Notes'  => '0.4003',
              'Module::Build::PPMMaker'=> '0.4003',
              'Module::Build::Platform::Amiga'=> '0.4003',
              'Module::Build::Platform::Default'=> '0.4003',
              'Module::Build::Platform::EBCDIC'=> '0.4003',
              'Module::Build::Platform::MPEiX'=> '0.4003',
              'Module::Build::Platform::MacOS'=> '0.4003',
              'Module::Build::Platform::RiscOS'=> '0.4003',
              'Module::Build::Platform::Unix'=> '0.4003',
              'Module::Build::Platform::VMS'=> '0.4003',
              'Module::Build::Platform::VOS'=> '0.4003',
              'Module::Build::Platform::Windows'=> '0.4003',
              'Module::Build::Platform::aix'=> '0.4003',
              'Module::Build::Platform::cygwin'=> '0.4003',
              'Module::Build::Platform::darwin'=> '0.4003',
              'Module::Build::Platform::os2'=> '0.4003',
              'Module::Build::PodParser'=> '0.4003',
              'Module::CoreList'      => '2.71',
              'Module::CoreList::TieHashDelta'=> '2.71',
              'Module::Load::Conditional'=> '0.54',
              'Module::Metadata'      => '1.000011',
              'Module::Pluggable'     => '4.3',
              'Module::Pluggable::Object'=> '4.3',
              'Pod::Simple'           => '3.23',
              'Pod::Simple::BlackBox' => '3.23',
              'Pod::Simple::Checker'  => '3.23',
              'Pod::Simple::Debug'    => '3.23',
              'Pod::Simple::DumpAsText'=> '3.23',
              'Pod::Simple::DumpAsXML'=> '3.23',
              'Pod::Simple::HTML'     => '3.23',
              'Pod::Simple::HTMLBatch'=> '3.23',
              'Pod::Simple::LinkSection'=> '3.23',
              'Pod::Simple::Methody'  => '3.23',
              'Pod::Simple::Progress' => '3.23',
              'Pod::Simple::PullParser'=> '3.23',
              'Pod::Simple::PullParserEndToken'=> '3.23',
              'Pod::Simple::PullParserStartToken'=> '3.23',
              'Pod::Simple::PullParserTextToken'=> '3.23',
              'Pod::Simple::PullParserToken'=> '3.23',
              'Pod::Simple::RTF'      => '3.23',
              'Pod::Simple::Search'   => '3.23',
              'Pod::Simple::SimpleTree'=> '3.23',
              'Pod::Simple::Text'     => '3.23',
              'Pod::Simple::TextContent'=> '3.23',
              'Pod::Simple::TiedOutFH'=> '3.23',
              'Pod::Simple::Transcode'=> '3.23',
              'Pod::Simple::TranscodeDumb'=> '3.23',
              'Pod::Simple::TranscodeSmart'=> '3.23',
              'Pod::Simple::XHTML'    => '3.23',
              'Pod::Simple::XMLOutStream'=> '3.23',
              'Socket'                => '2.004',
              'Storable'              => '2.38',
              'Sys::Syslog'           => '0.31',
              'Term::ReadLine'        => '1.10',
              'Text::Tabs'            => '2012.0818',
              'Text::Wrap'            => '2012.0818',
              'Time::Local'           => '1.2300',
              'Unicode::UCD'          => '0.45',
              'Win32'                 => '0.45',
              'Win32CORE'             => '0.03',
              'XS::APItest'           => '0.42',
              'inc::latest'           => '0.4003',
              'perlfaq'               => '5.0150041',
              're'                    => '0.22',
          },
          removed => {
          }
      },
      5.017004 => {
          delta_from => 5.017003,
          changed => {
              'Archive::Tar'          => '1.90',
              'Archive::Tar::Constant'=> '1.90',
              'Archive::Tar::File'    => '1.90',
              'B'                     => '1.38',
              'B::Concise'            => '0.93',
              'B::Deparse'            => '1.17',
              'B::Xref'               => '1.04',
              'CPANPLUS'              => '0.9131',
              'CPANPLUS::Internals'   => '0.9131',
              'CPANPLUS::Shell::Default'=> '0.9131',
              'DB_File'               => '1.827',
              'Devel::Peek'           => '1.10',
              'DynaLoader'            => '1.16',
              'Errno'                 => '1.16',
              'ExtUtils::ParseXS'     => '3.18',
              'ExtUtils::ParseXS::Constants'=> '3.18',
              'ExtUtils::ParseXS::CountLines'=> '3.18',
              'ExtUtils::ParseXS::Utilities'=> '3.18',
              'File::Copy'            => '2.24',
              'File::Find'            => '1.22',
              'IPC::Open3'            => '1.13',
              'Locale::Codes'         => '3.23',
              'Locale::Codes::Constants'=> '3.23',
              'Locale::Codes::Country'=> '3.23',
              'Locale::Codes::Country_Codes'=> '3.23',
              'Locale::Codes::Country_Retired'=> '3.23',
              'Locale::Codes::Currency'=> '3.23',
              'Locale::Codes::Currency_Codes'=> '3.23',
              'Locale::Codes::Currency_Retired'=> '3.23',
              'Locale::Codes::LangExt'=> '3.23',
              'Locale::Codes::LangExt_Codes'=> '3.23',
              'Locale::Codes::LangExt_Retired'=> '3.23',
              'Locale::Codes::LangFam'=> '3.23',
              'Locale::Codes::LangFam_Codes'=> '3.23',
              'Locale::Codes::LangFam_Retired'=> '3.23',
              'Locale::Codes::LangVar'=> '3.23',
              'Locale::Codes::LangVar_Codes'=> '3.23',
              'Locale::Codes::LangVar_Retired'=> '3.23',
              'Locale::Codes::Language'=> '3.23',
              'Locale::Codes::Language_Codes'=> '3.23',
              'Locale::Codes::Language_Retired'=> '3.23',
              'Locale::Codes::Script' => '3.23',
              'Locale::Codes::Script_Codes'=> '3.23',
              'Locale::Codes::Script_Retired'=> '3.23',
              'Locale::Country'       => '3.23',
              'Locale::Currency'      => '3.23',
              'Locale::Language'      => '3.23',
              'Locale::Script'        => '3.23',
              'Math::BigFloat::Trace' => '0.30',
              'Math::BigInt::Trace'   => '0.30',
              'Module::CoreList'      => '2.73',
              'Module::CoreList::TieHashDelta'=> '2.73',
              'Opcode'                => '1.24',
              'Socket'                => '2.006',
              'Storable'              => '2.39',
              'Sys::Syslog'           => '0.32',
              'Unicode::UCD'          => '0.46',
              'XS::APItest'           => '0.43',
              'bignum'                => '0.30',
              'bigrat'                => '0.30',
              'constant'              => '1.24',
              'feature'               => '1.30',
              'threads::shared'       => '1.41',
              'version'               => '0.9901',
              'warnings'              => '1.14',
          },
          removed => {
          }
      },
      5.017005 => {
          delta_from => 5.017004,
          changed => {
              'AutoLoader'            => '5.73',
              'B'                     => '1.39',
              'B::Deparse'            => '1.18',
              'CPANPLUS'              => '0.9133',
              'CPANPLUS::Internals'   => '0.9133',
              'CPANPLUS::Shell::Default'=> '0.9133',
              'Carp'                  => '1.27',
              'Carp::Heavy'           => '1.27',
              'Data::Dumper'          => '2.136',
              'Digest::SHA'           => '5.72',
              'ExtUtils::CBuilder'    => '0.280209',
              'ExtUtils::CBuilder::Base'=> '0.280209',
              'ExtUtils::CBuilder::Platform::Unix'=> '0.280209',
              'ExtUtils::CBuilder::Platform::VMS'=> '0.280209',
              'ExtUtils::CBuilder::Platform::Windows'=> '0.280209',
              'ExtUtils::CBuilder::Platform::Windows::BCC'=> '0.280209',
              'ExtUtils::CBuilder::Platform::Windows::GCC'=> '0.280209',
              'ExtUtils::CBuilder::Platform::Windows::MSVC'=> '0.280209',
              'ExtUtils::CBuilder::Platform::aix'=> '0.280209',
              'ExtUtils::CBuilder::Platform::cygwin'=> '0.280209',
              'ExtUtils::CBuilder::Platform::darwin'=> '0.280209',
              'ExtUtils::CBuilder::Platform::dec_osf'=> '0.280209',
              'ExtUtils::CBuilder::Platform::os2'=> '0.280209',
              'File::Copy'            => '2.25',
              'File::Glob'            => '1.18',
              'HTTP::Tiny'            => '0.024',
              'Module::CoreList'      => '2.75',
              'Module::CoreList::TieHashDelta'=> '2.75',
              'PerlIO::encoding'      => '0.16',
              'Unicode::Collate'      => '0.90',
              'Unicode::Collate::Locale'=> '0.90',
              'Unicode::Normalize'    => '1.15',
              'Win32CORE'             => '0.04',
              'XS::APItest'           => '0.44',
              'attributes'            => '0.21',
              'bigint'                => '0.31',
              'bignum'                => '0.31',
              'bigrat'                => '0.31',
              'feature'               => '1.31',
              'threads::shared'       => '1.42',
              'warnings'              => '1.15',
          },
          removed => {
          }
      },
      5.017006 => {
          delta_from => 5.017005,
          changed => {
              'B'                     => '1.40',
              'B::Concise'            => '0.94',
              'B::Deparse'            => '1.19',
              'B::Xref'               => '1.05',
              'CGI'                   => '3.63',
              'CGI::Util'             => '3.62',
              'CPAN'                  => '1.99_51',
              'CPANPLUS::Dist::Build' => '0.64',
              'CPANPLUS::Dist::Build::Constants'=> '0.64',
              'Carp'                  => '1.28',
              'Carp::Heavy'           => '1.28',
              'Compress::Raw::Bzip2'  => '2.058',
              'Compress::Raw::Zlib'   => '2.058',
              'Compress::Zlib'        => '2.058',
              'Data::Dumper'          => '2.137',
              'Digest::SHA'           => '5.73',
              'DynaLoader'            => '1.17',
              'Env'                   => '1.04',
              'Errno'                 => '1.17',
              'ExtUtils::Manifest'    => '1.62',
              'ExtUtils::Typemaps'    => '3.18',
              'ExtUtils::Typemaps::Cmd'=> '3.18',
              'ExtUtils::Typemaps::InputMap'=> '3.18',
              'ExtUtils::Typemaps::OutputMap'=> '3.18',
              'ExtUtils::Typemaps::Type'=> '3.18',
              'Fatal'                 => '2.13',
              'File::Find'            => '1.23',
              'Hash::Util'            => '0.13',
              'IO::Compress::Adapter::Bzip2'=> '2.058',
              'IO::Compress::Adapter::Deflate'=> '2.058',
              'IO::Compress::Adapter::Identity'=> '2.058',
              'IO::Compress::Base'    => '2.058',
              'IO::Compress::Base::Common'=> '2.058',
              'IO::Compress::Bzip2'   => '2.058',
              'IO::Compress::Deflate' => '2.058',
              'IO::Compress::Gzip'    => '2.058',
              'IO::Compress::Gzip::Constants'=> '2.058',
              'IO::Compress::RawDeflate'=> '2.058',
              'IO::Compress::Zip'     => '2.058',
              'IO::Compress::Zip::Constants'=> '2.058',
              'IO::Compress::Zlib::Constants'=> '2.058',
              'IO::Compress::Zlib::Extra'=> '2.058',
              'IO::Uncompress::Adapter::Bunzip2'=> '2.058',
              'IO::Uncompress::Adapter::Identity'=> '2.058',
              'IO::Uncompress::Adapter::Inflate'=> '2.058',
              'IO::Uncompress::AnyInflate'=> '2.058',
              'IO::Uncompress::AnyUncompress'=> '2.058',
              'IO::Uncompress::Base'  => '2.058',
              'IO::Uncompress::Bunzip2'=> '2.058',
              'IO::Uncompress::Gunzip'=> '2.058',
              'IO::Uncompress::Inflate'=> '2.058',
              'IO::Uncompress::RawInflate'=> '2.058',
              'IO::Uncompress::Unzip' => '2.058',
              'Module::CoreList'      => '2.78',
              'Module::CoreList::TieHashDelta'=> '2.77',
              'Module::Pluggable'     => '4.5',
              'Module::Pluggable::Object'=> '4.5',
              'Opcode'                => '1.25',
              'Sys::Hostname'         => '1.17',
              'Term::UI'              => '0.32',
              'Thread::Queue'         => '3.01',
              'Tie::Hash::NamedCapture'=> '0.09',
              'Unicode::Collate'      => '0.93',
              'Unicode::Collate::CJK::Korean'=> '0.93',
              'Unicode::Collate::Locale'=> '0.93',
              'Unicode::Normalize'    => '1.16',
              'Unicode::UCD'          => '0.47',
              'XS::APItest'           => '0.46',
              '_charnames'            => '1.33',
              'autodie'               => '2.13',
              'autodie::exception'    => '2.13',
              'autodie::exception::system'=> '2.13',
              'autodie::hints'        => '2.13',
              'charnames'             => '1.33',
              're'                    => '0.23',
          },
          removed => {
          }
      },
      5.017007 => {
          delta_from => 5.017006,
          changed => {
              'B'                     => '1.41',
              'CPANPLUS::Dist::Build' => '0.68',
              'CPANPLUS::Dist::Build::Constants'=> '0.68',
              'Compress::Raw::Bzip2'  => '2.059',
              'Compress::Raw::Zlib'   => '2.059',
              'Compress::Zlib'        => '2.059',
              'Cwd'                   => '3.39_03',
              'Data::Dumper'          => '2.139',
              'Devel::Peek'           => '1.11',
              'Digest::SHA'           => '5.80',
              'DynaLoader'            => '1.18',
              'English'               => '1.06',
              'Errno'                 => '1.18',
              'ExtUtils::Command::MM' => '6.64',
              'ExtUtils::Liblist'     => '6.64',
              'ExtUtils::Liblist::Kid'=> '6.64',
              'ExtUtils::MM'          => '6.64',
              'ExtUtils::MM_AIX'      => '6.64',
              'ExtUtils::MM_Any'      => '6.64',
              'ExtUtils::MM_BeOS'     => '6.64',
              'ExtUtils::MM_Cygwin'   => '6.64',
              'ExtUtils::MM_DOS'      => '6.64',
              'ExtUtils::MM_Darwin'   => '6.64',
              'ExtUtils::MM_MacOS'    => '6.64',
              'ExtUtils::MM_NW5'      => '6.64',
              'ExtUtils::MM_OS2'      => '6.64',
              'ExtUtils::MM_QNX'      => '6.64',
              'ExtUtils::MM_UWIN'     => '6.64',
              'ExtUtils::MM_Unix'     => '6.64',
              'ExtUtils::MM_VMS'      => '6.64',
              'ExtUtils::MM_VOS'      => '6.64',
              'ExtUtils::MM_Win32'    => '6.64',
              'ExtUtils::MM_Win95'    => '6.64',
              'ExtUtils::MY'          => '6.64',
              'ExtUtils::MakeMaker'   => '6.64',
              'ExtUtils::MakeMaker::Config'=> '6.64',
              'ExtUtils::Mkbootstrap' => '6.64',
              'ExtUtils::Mksymlists'  => '6.64',
              'ExtUtils::testlib'     => '6.64',
              'File::DosGlob'         => '1.09',
              'File::Glob'            => '1.19',
              'GDBM_File'             => '1.15',
              'IO::Compress::Adapter::Bzip2'=> '2.059',
              'IO::Compress::Adapter::Deflate'=> '2.059',
              'IO::Compress::Adapter::Identity'=> '2.059',
              'IO::Compress::Base'    => '2.059',
              'IO::Compress::Base::Common'=> '2.059',
              'IO::Compress::Bzip2'   => '2.059',
              'IO::Compress::Deflate' => '2.059',
              'IO::Compress::Gzip'    => '2.059',
              'IO::Compress::Gzip::Constants'=> '2.059',
              'IO::Compress::RawDeflate'=> '2.059',
              'IO::Compress::Zip'     => '2.059',
              'IO::Compress::Zip::Constants'=> '2.059',
              'IO::Compress::Zlib::Constants'=> '2.059',
              'IO::Compress::Zlib::Extra'=> '2.059',
              'IO::Uncompress::Adapter::Bunzip2'=> '2.059',
              'IO::Uncompress::Adapter::Identity'=> '2.059',
              'IO::Uncompress::Adapter::Inflate'=> '2.059',
              'IO::Uncompress::AnyInflate'=> '2.059',
              'IO::Uncompress::AnyUncompress'=> '2.059',
              'IO::Uncompress::Base'  => '2.059',
              'IO::Uncompress::Bunzip2'=> '2.059',
              'IO::Uncompress::Gunzip'=> '2.059',
              'IO::Uncompress::Inflate'=> '2.059',
              'IO::Uncompress::RawInflate'=> '2.059',
              'IO::Uncompress::Unzip' => '2.059',
              'List::Util'            => '1.26',
              'List::Util::XS'        => '1.26',
              'Locale::Codes'         => '3.24',
              'Locale::Codes::Constants'=> '3.24',
              'Locale::Codes::Country'=> '3.24',
              'Locale::Codes::Country_Codes'=> '3.24',
              'Locale::Codes::Country_Retired'=> '3.24',
              'Locale::Codes::Currency'=> '3.24',
              'Locale::Codes::Currency_Codes'=> '3.24',
              'Locale::Codes::Currency_Retired'=> '3.24',
              'Locale::Codes::LangExt'=> '3.24',
              'Locale::Codes::LangExt_Codes'=> '3.24',
              'Locale::Codes::LangExt_Retired'=> '3.24',
              'Locale::Codes::LangFam'=> '3.24',
              'Locale::Codes::LangFam_Codes'=> '3.24',
              'Locale::Codes::LangFam_Retired'=> '3.24',
              'Locale::Codes::LangVar'=> '3.24',
              'Locale::Codes::LangVar_Codes'=> '3.24',
              'Locale::Codes::LangVar_Retired'=> '3.24',
              'Locale::Codes::Language'=> '3.24',
              'Locale::Codes::Language_Codes'=> '3.24',
              'Locale::Codes::Language_Retired'=> '3.24',
              'Locale::Codes::Script' => '3.24',
              'Locale::Codes::Script_Codes'=> '3.24',
              'Locale::Codes::Script_Retired'=> '3.24',
              'Locale::Country'       => '3.24',
              'Locale::Currency'      => '3.24',
              'Locale::Language'      => '3.24',
              'Locale::Maketext'      => '1.23',
              'Locale::Script'        => '3.24',
              'Module::CoreList'      => '2.79',
              'Module::CoreList::TieHashDelta'=> '2.79',
              'POSIX'                 => '1.32',
              'Scalar::Util'          => '1.26',
              'Socket'                => '2.006_001',
              'Storable'              => '2.40',
              'Term::ReadLine'        => '1.11',
              'Unicode::Collate'      => '0.96',
              'Unicode::Collate::CJK::Stroke'=> '0.94',
              'Unicode::Collate::CJK::Zhuyin'=> '0.94',
              'Unicode::Collate::Locale'=> '0.96',
              'XS::APItest'           => '0.48',
              'XS::Typemap'           => '0.09',
              '_charnames'            => '1.34',
              'charnames'             => '1.34',
              'feature'               => '1.32',
              'mro'                   => '1.10',
              'sigtrap'               => '1.07',
              'sort'                  => '2.02',
          },
          removed => {
          }
      },
      5.017008 => {
          delta_from => 5.017007,
          changed => {
              'Archive::Extract'      => '0.62',
              'B'                     => '1.42',
              'B::Concise'            => '0.95',
              'Compress::Raw::Bzip2'  => '2.060',
              'Compress::Raw::Zlib'   => '2.060',
              'Compress::Zlib'        => '2.060',
              'Cwd'                   => '3.40',
              'Data::Dumper'          => '2.141',
              'Digest::SHA'           => '5.81',
              'ExtUtils::Install'     => '1.59',
              'File::Fetch'           => '0.38',
              'File::Path'            => '2.09',
              'File::Spec'            => '3.40',
              'File::Spec::Cygwin'    => '3.40',
              'File::Spec::Epoc'      => '3.40',
              'File::Spec::Functions' => '3.40',
              'File::Spec::Mac'       => '3.40',
              'File::Spec::OS2'       => '3.40',
              'File::Spec::Unix'      => '3.40',
              'File::Spec::VMS'       => '3.40',
              'File::Spec::Win32'     => '3.40',
              'HTTP::Tiny'            => '0.025',
              'Hash::Util'            => '0.14',
              'I18N::LangTags'        => '0.39',
              'I18N::LangTags::List'  => '0.39',
              'I18N::Langinfo'        => '0.09',
              'IO'                    => '1.26',
              'IO::Compress::Adapter::Bzip2'=> '2.060',
              'IO::Compress::Adapter::Deflate'=> '2.060',
              'IO::Compress::Adapter::Identity'=> '2.060',
              'IO::Compress::Base'    => '2.060',
              'IO::Compress::Base::Common'=> '2.060',
              'IO::Compress::Bzip2'   => '2.060',
              'IO::Compress::Deflate' => '2.060',
              'IO::Compress::Gzip'    => '2.060',
              'IO::Compress::Gzip::Constants'=> '2.060',
              'IO::Compress::RawDeflate'=> '2.060',
              'IO::Compress::Zip'     => '2.060',
              'IO::Compress::Zip::Constants'=> '2.060',
              'IO::Compress::Zlib::Constants'=> '2.060',
              'IO::Compress::Zlib::Extra'=> '2.060',
              'IO::Uncompress::Adapter::Bunzip2'=> '2.060',
              'IO::Uncompress::Adapter::Identity'=> '2.060',
              'IO::Uncompress::Adapter::Inflate'=> '2.060',
              'IO::Uncompress::AnyInflate'=> '2.060',
              'IO::Uncompress::AnyUncompress'=> '2.060',
              'IO::Uncompress::Base'  => '2.060',
              'IO::Uncompress::Bunzip2'=> '2.060',
              'IO::Uncompress::Gunzip'=> '2.060',
              'IO::Uncompress::Inflate'=> '2.060',
              'IO::Uncompress::RawInflate'=> '2.060',
              'IO::Uncompress::Unzip' => '2.060',
              'List::Util'            => '1.27',
              'List::Util::XS'        => '1.27',
              'Module::CoreList'      => '2.80',
              'Module::CoreList::TieHashDelta'=> '2.80',
              'Pod::Html'             => '1.17',
              'Pod::LaTeX'            => '0.61',
              'Pod::Man'              => '2.27',
              'Pod::Text'             => '3.17',
              'Pod::Text::Color'      => '2.07',
              'Pod::Text::Overstrike' => '2.05',
              'Pod::Text::Termcap'    => '2.07',
              'Safe'                  => '2.34',
              'Scalar::Util'          => '1.27',
              'Socket'                => '2.009',
              'Term::ANSIColor'       => '4.02',
              'Test'                  => '1.26',
              'Unicode::Collate'      => '0.97',
              'XS::APItest'           => '0.51',
              'XS::Typemap'           => '0.10',
              '_charnames'            => '1.35',
              'charnames'             => '1.35',
              'constant'              => '1.25',
              'diagnostics'           => '1.31',
              'threads::shared'       => '1.43',
              'warnings'              => '1.16',
          },
          removed => {
          }
      },
      5.017009 => {
          delta_from => 5.017008,
          changed => {
              'App::Cpan'             => '1.60_02',
              'App::Prove'            => '3.26',
              'App::Prove::State'     => '3.26',
              'App::Prove::State::Result'=> '3.26',
              'App::Prove::State::Result::Test'=> '3.26',
              'Archive::Extract'      => '0.68',
              'Attribute::Handlers'   => '0.94',
              'B::Lint'               => '1.17',
              'B::Lint::Debug'        => '1.17',
              'Benchmark'             => '1.14',
              'CPAN'                  => '2.00',
              'CPAN::Distribution'    => '2.00',
              'CPAN::FirstTime'       => '5.5304',
              'CPAN::Nox'             => '5.5001',
              'CPANPLUS'              => '0.9135',
              'CPANPLUS::Backend'     => '0.9135',
              'CPANPLUS::Backend::RV' => '0.9135',
              'CPANPLUS::Config'      => '0.9135',
              'CPANPLUS::Config::HomeEnv'=> '0.9135',
              'CPANPLUS::Configure'   => '0.9135',
              'CPANPLUS::Configure::Setup'=> '0.9135',
              'CPANPLUS::Dist'        => '0.9135',
              'CPANPLUS::Dist::Autobundle'=> '0.9135',
              'CPANPLUS::Dist::Base'  => '0.9135',
              'CPANPLUS::Dist::Build' => '0.70',
              'CPANPLUS::Dist::Build::Constants'=> '0.70',
              'CPANPLUS::Dist::MM'    => '0.9135',
              'CPANPLUS::Dist::Sample'=> '0.9135',
              'CPANPLUS::Error'       => '0.9135',
              'CPANPLUS::Internals'   => '0.9135',
              'CPANPLUS::Internals::Constants'=> '0.9135',
              'CPANPLUS::Internals::Constants::Report'=> '0.9135',
              'CPANPLUS::Internals::Extract'=> '0.9135',
              'CPANPLUS::Internals::Fetch'=> '0.9135',
              'CPANPLUS::Internals::Report'=> '0.9135',
              'CPANPLUS::Internals::Search'=> '0.9135',
              'CPANPLUS::Internals::Source'=> '0.9135',
              'CPANPLUS::Internals::Source::Memory'=> '0.9135',
              'CPANPLUS::Internals::Source::SQLite'=> '0.9135',
              'CPANPLUS::Internals::Source::SQLite::Tie'=> '0.9135',
              'CPANPLUS::Internals::Utils'=> '0.9135',
              'CPANPLUS::Internals::Utils::Autoflush'=> '0.9135',
              'CPANPLUS::Module'      => '0.9135',
              'CPANPLUS::Module::Author'=> '0.9135',
              'CPANPLUS::Module::Author::Fake'=> '0.9135',
              'CPANPLUS::Module::Checksums'=> '0.9135',
              'CPANPLUS::Module::Fake'=> '0.9135',
              'CPANPLUS::Module::Signature'=> '0.9135',
              'CPANPLUS::Selfupdate'  => '0.9135',
              'CPANPLUS::Shell'       => '0.9135',
              'CPANPLUS::Shell::Classic'=> '0.9135',
              'CPANPLUS::Shell::Default'=> '0.9135',
              'CPANPLUS::Shell::Default::Plugins::CustomSource'=> '0.9135',
              'CPANPLUS::Shell::Default::Plugins::Remote'=> '0.9135',
              'CPANPLUS::Shell::Default::Plugins::Source'=> '0.9135',
              'Config'                => '5.017009',
              'Config::Perl::V'       => '0.17',
              'DBM_Filter'            => '0.05',
              'Data::Dumper'          => '2.142',
              'Digest::SHA'           => '5.82',
              'Encode'                => '2.48',
              'ExtUtils::Installed'   => '1.999003',
              'ExtUtils::Manifest'    => '1.63',
              'ExtUtils::ParseXS::Utilities'=> '3.19',
              'ExtUtils::Typemaps'    => '3.19',
              'File::CheckTree'       => '4.42',
              'File::DosGlob'         => '1.10',
              'File::Temp'            => '0.22_90',
              'Filter::Simple'        => '0.89',
              'IO'                    => '1.27',
              'Log::Message'          => '0.06',
              'Log::Message::Config'  => '0.06',
              'Log::Message::Handlers'=> '0.06',
              'Log::Message::Item'    => '0.06',
              'Log::Message::Simple'  => '0.10',
              'Math::BigInt'          => '1.999',
              'Module::CoreList'      => '2.82',
              'Module::CoreList::TieHashDelta'=> '2.82',
              'Module::Load'          => '0.24',
              'Module::Pluggable'     => '4.6',
              'Module::Pluggable::Object'=> '4.6',
              'OS2::DLL'              => '1.05',
              'OS2::ExtAttr'          => '0.03',
              'OS2::Process'          => '1.08',
              'Object::Accessor'      => '0.46',
              'PerlIO::scalar'        => '0.16',
              'Pod::Checker'          => '1.60',
              'Pod::Find'             => '1.60',
              'Pod::Html'             => '1.18',
              'Pod::InputObjects'     => '1.60',
              'Pod::ParseUtils'       => '1.60',
              'Pod::Parser'           => '1.60',
              'Pod::Perldoc'          => '3.19',
              'Pod::Perldoc::BaseTo'  => '3.19',
              'Pod::Perldoc::GetOptsOO'=> '3.19',
              'Pod::Perldoc::ToANSI'  => '3.19',
              'Pod::Perldoc::ToChecker'=> '3.19',
              'Pod::Perldoc::ToMan'   => '3.19',
              'Pod::Perldoc::ToNroff' => '3.19',
              'Pod::Perldoc::ToPod'   => '3.19',
              'Pod::Perldoc::ToRtf'   => '3.19',
              'Pod::Perldoc::ToTerm'  => '3.19',
              'Pod::Perldoc::ToText'  => '3.19',
              'Pod::Perldoc::ToTk'    => '3.19',
              'Pod::Perldoc::ToXml'   => '3.19',
              'Pod::PlainText'        => '2.06',
              'Pod::Select'           => '1.60',
              'Pod::Usage'            => '1.61',
              'SelfLoader'            => '1.21',
              'TAP::Base'             => '3.26',
              'TAP::Formatter::Base'  => '3.26',
              'TAP::Formatter::Color' => '3.26',
              'TAP::Formatter::Console'=> '3.26',
              'TAP::Formatter::Console::ParallelSession'=> '3.26',
              'TAP::Formatter::Console::Session'=> '3.26',
              'TAP::Formatter::File'  => '3.26',
              'TAP::Formatter::File::Session'=> '3.26',
              'TAP::Formatter::Session'=> '3.26',
              'TAP::Harness'          => '3.26',
              'TAP::Object'           => '3.26',
              'TAP::Parser'           => '3.26',
              'TAP::Parser::Aggregator'=> '3.26',
              'TAP::Parser::Grammar'  => '3.26',
              'TAP::Parser::Iterator' => '3.26',
              'TAP::Parser::Iterator::Array'=> '3.26',
              'TAP::Parser::Iterator::Process'=> '3.26',
              'TAP::Parser::Iterator::Stream'=> '3.26',
              'TAP::Parser::IteratorFactory'=> '3.26',
              'TAP::Parser::Multiplexer'=> '3.26',
              'TAP::Parser::Result'   => '3.26',
              'TAP::Parser::Result::Bailout'=> '3.26',
              'TAP::Parser::Result::Comment'=> '3.26',
              'TAP::Parser::Result::Plan'=> '3.26',
              'TAP::Parser::Result::Pragma'=> '3.26',
              'TAP::Parser::Result::Test'=> '3.26',
              'TAP::Parser::Result::Unknown'=> '3.26',
              'TAP::Parser::Result::Version'=> '3.26',
              'TAP::Parser::Result::YAML'=> '3.26',
              'TAP::Parser::ResultFactory'=> '3.26',
              'TAP::Parser::Scheduler'=> '3.26',
              'TAP::Parser::Scheduler::Job'=> '3.26',
              'TAP::Parser::Scheduler::Spinner'=> '3.26',
              'TAP::Parser::Source'   => '3.26',
              'TAP::Parser::SourceHandler'=> '3.26',
              'TAP::Parser::SourceHandler::Executable'=> '3.26',
              'TAP::Parser::SourceHandler::File'=> '3.26',
              'TAP::Parser::SourceHandler::Handle'=> '3.26',
              'TAP::Parser::SourceHandler::Perl'=> '3.26',
              'TAP::Parser::SourceHandler::RawTAP'=> '3.26',
              'TAP::Parser::Utils'    => '3.26',
              'TAP::Parser::YAMLish::Reader'=> '3.26',
              'TAP::Parser::YAMLish::Writer'=> '3.26',
              'Term::UI'              => '0.34',
              'Test::Harness'         => '3.26',
              'Text::Soundex'         => '3.04',
              'Thread::Queue'         => '3.02',
              'Unicode::UCD'          => '0.50',
              'Win32'                 => '0.46',
              'Win32API::File'        => '0.1201',
              '_charnames'            => '1.36',
              'arybase'               => '0.06',
              'bigint'                => '0.32',
              'bignum'                => '0.32',
              'charnames'             => '1.36',
              'filetest'              => '1.03',
              'locale'                => '1.02',
              'overload'              => '1.21',
              'warnings'              => '1.17',
          },
          removed => {
          }
      },
      5.017010 => {
          delta_from => 5.017009,
          changed => {
              'Benchmark'             => '1.15',
              'Config'                => '5.017009',
              'Data::Dumper'          => '2.145',
              'Digest::SHA'           => '5.84',
              'Encode'                => '2.49',
              'ExtUtils::Command::MM' => '6.65_01',
              'ExtUtils::Liblist'     => '6.65_01',
              'ExtUtils::Liblist::Kid'=> '6.65_01',
              'ExtUtils::MM'          => '6.65_01',
              'ExtUtils::MM_AIX'      => '6.65_01',
              'ExtUtils::MM_Any'      => '6.65_01',
              'ExtUtils::MM_BeOS'     => '6.65_01',
              'ExtUtils::MM_Cygwin'   => '6.65_01',
              'ExtUtils::MM_DOS'      => '6.65_01',
              'ExtUtils::MM_Darwin'   => '6.65_01',
              'ExtUtils::MM_MacOS'    => '6.65_01',
              'ExtUtils::MM_NW5'      => '6.65_01',
              'ExtUtils::MM_OS2'      => '6.65_01',
              'ExtUtils::MM_QNX'      => '6.65_01',
              'ExtUtils::MM_UWIN'     => '6.65_01',
              'ExtUtils::MM_Unix'     => '6.65_01',
              'ExtUtils::MM_VMS'      => '6.65_01',
              'ExtUtils::MM_VOS'      => '6.65_01',
              'ExtUtils::MM_Win32'    => '6.65_01',
              'ExtUtils::MM_Win95'    => '6.65_01',
              'ExtUtils::MY'          => '6.65_01',
              'ExtUtils::MakeMaker'   => '6.65_01',
              'ExtUtils::MakeMaker::Config'=> '6.65_01',
              'ExtUtils::Mkbootstrap' => '6.65_01',
              'ExtUtils::Mksymlists'  => '6.65_01',
              'ExtUtils::testlib'     => '6.65_01',
              'File::Copy'            => '2.26',
              'File::Temp'            => '0.23',
              'Getopt::Long'          => '2.39',
              'Hash::Util'            => '0.15',
              'I18N::Langinfo'        => '0.10',
              'IPC::Cmd'              => '0.80',
              'JSON::PP'              => '2.27202',
              'Locale::Codes'         => '3.25',
              'Locale::Codes::Constants'=> '3.25',
              'Locale::Codes::Country'=> '3.25',
              'Locale::Codes::Country_Codes'=> '3.25',
              'Locale::Codes::Country_Retired'=> '3.25',
              'Locale::Codes::Currency'=> '3.25',
              'Locale::Codes::Currency_Codes'=> '3.25',
              'Locale::Codes::Currency_Retired'=> '3.25',
              'Locale::Codes::LangExt'=> '3.25',
              'Locale::Codes::LangExt_Codes'=> '3.25',
              'Locale::Codes::LangExt_Retired'=> '3.25',
              'Locale::Codes::LangFam'=> '3.25',
              'Locale::Codes::LangFam_Codes'=> '3.25',
              'Locale::Codes::LangFam_Retired'=> '3.25',
              'Locale::Codes::LangVar'=> '3.25',
              'Locale::Codes::LangVar_Codes'=> '3.25',
              'Locale::Codes::LangVar_Retired'=> '3.25',
              'Locale::Codes::Language'=> '3.25',
              'Locale::Codes::Language_Codes'=> '3.25',
              'Locale::Codes::Language_Retired'=> '3.25',
              'Locale::Codes::Script' => '3.25',
              'Locale::Codes::Script_Codes'=> '3.25',
              'Locale::Codes::Script_Retired'=> '3.25',
              'Locale::Country'       => '3.25',
              'Locale::Currency'      => '3.25',
              'Locale::Language'      => '3.25',
              'Locale::Script'        => '3.25',
              'Math::BigFloat'        => '1.998',
              'Math::BigFloat::Trace' => '0.32',
              'Math::BigInt'          => '1.9991',
              'Math::BigInt::CalcEmu' => '1.998',
              'Math::BigInt::Trace'   => '0.32',
              'Math::BigRat'          => '0.2604',
              'Module::CoreList'      => '2.84',
              'Module::CoreList::TieHashDelta'=> '2.84',
              'Module::Pluggable'     => '4.7',
              'Net::Ping'             => '2.41',
              'Perl::OSType'          => '1.003',
              'Pod::Simple'           => '3.26',
              'Pod::Simple::BlackBox' => '3.26',
              'Pod::Simple::Checker'  => '3.26',
              'Pod::Simple::Debug'    => '3.26',
              'Pod::Simple::DumpAsText'=> '3.26',
              'Pod::Simple::DumpAsXML'=> '3.26',
              'Pod::Simple::HTML'     => '3.26',
              'Pod::Simple::HTMLBatch'=> '3.26',
              'Pod::Simple::LinkSection'=> '3.26',
              'Pod::Simple::Methody'  => '3.26',
              'Pod::Simple::Progress' => '3.26',
              'Pod::Simple::PullParser'=> '3.26',
              'Pod::Simple::PullParserEndToken'=> '3.26',
              'Pod::Simple::PullParserStartToken'=> '3.26',
              'Pod::Simple::PullParserTextToken'=> '3.26',
              'Pod::Simple::PullParserToken'=> '3.26',
              'Pod::Simple::RTF'      => '3.26',
              'Pod::Simple::Search'   => '3.26',
              'Pod::Simple::SimpleTree'=> '3.26',
              'Pod::Simple::Text'     => '3.26',
              'Pod::Simple::TextContent'=> '3.26',
              'Pod::Simple::TiedOutFH'=> '3.26',
              'Pod::Simple::Transcode'=> '3.26',
              'Pod::Simple::TranscodeDumb'=> '3.26',
              'Pod::Simple::TranscodeSmart'=> '3.26',
              'Pod::Simple::XHTML'    => '3.26',
              'Pod::Simple::XMLOutStream'=> '3.26',
              'Safe'                  => '2.35',
              'Term::ReadLine'        => '1.12',
              'Text::ParseWords'      => '3.28',
              'Tie::File'             => '0.99',
              'Unicode::UCD'          => '0.51',
              'Win32'                 => '0.47',
              'bigint'                => '0.33',
              'bignum'                => '0.33',
              'bigrat'                => '0.33',
              'constant'              => '1.27',
              'perlfaq'               => '5.0150042',
              'version'               => '0.9902',
          },
          removed => {
          }
      },
      5.017011 => {
          delta_from => 5.017010,
          changed => {
              'App::Cpan'             => '1.61',
              'B::Deparse'            => '1.20',
              'Config'                => '5.017009',
              'Exporter'              => '5.68',
              'Exporter::Heavy'       => '5.68',
              'ExtUtils::CBuilder'    => '0.280210',
              'ExtUtils::Command::MM' => '6.66',
              'ExtUtils::Liblist'     => '6.66',
              'ExtUtils::Liblist::Kid'=> '6.66',
              'ExtUtils::MM'          => '6.66',
              'ExtUtils::MM_AIX'      => '6.66',
              'ExtUtils::MM_Any'      => '6.66',
              'ExtUtils::MM_BeOS'     => '6.66',
              'ExtUtils::MM_Cygwin'   => '6.66',
              'ExtUtils::MM_DOS'      => '6.66',
              'ExtUtils::MM_Darwin'   => '6.66',
              'ExtUtils::MM_MacOS'    => '6.66',
              'ExtUtils::MM_NW5'      => '6.66',
              'ExtUtils::MM_OS2'      => '6.66',
              'ExtUtils::MM_QNX'      => '6.66',
              'ExtUtils::MM_UWIN'     => '6.66',
              'ExtUtils::MM_Unix'     => '6.66',
              'ExtUtils::MM_VMS'      => '6.66',
              'ExtUtils::MM_VOS'      => '6.66',
              'ExtUtils::MM_Win32'    => '6.66',
              'ExtUtils::MM_Win95'    => '6.66',
              'ExtUtils::MY'          => '6.66',
              'ExtUtils::MakeMaker'   => '6.66',
              'ExtUtils::MakeMaker::Config'=> '6.66',
              'ExtUtils::Mkbootstrap' => '6.66',
              'ExtUtils::Mksymlists'  => '6.66',
              'ExtUtils::testlib'     => '6.66',
              'File::Glob'            => '1.20',
              'IO'                    => '1.28',
              'Module::CoreList'      => '2.87',
              'Module::CoreList::TieHashDelta'=> '2.87',
              'Storable'              => '2.41',
              'bigint'                => '0.34',
              'mro'                   => '1.11',
              'overload'              => '1.22',
              'warnings'              => '1.18',
          },
          removed => {
          }
      },
      5.018000 => {
          delta_from => 5.017011,
          changed => {
              'Carp'                  => '1.29',
              'Carp::Heavy'           => '1.29',
              'Config'                => '5.018000',
              'Hash::Util'            => '0.16',
              'IO::Handle'            => '1.34',
              'IO::Socket'            => '1.36',
              'Module::CoreList'      => '2.89',
              'Module::CoreList::TieHashDelta'=> '2.89',
              'Pod::Simple'           => '3.28',
              'Pod::Simple::BlackBox' => '3.28',
              'Pod::Simple::Checker'  => '3.28',
              'Pod::Simple::Debug'    => '3.28',
              'Pod::Simple::DumpAsText'=> '3.28',
              'Pod::Simple::DumpAsXML'=> '3.28',
              'Pod::Simple::HTML'     => '3.28',
              'Pod::Simple::HTMLBatch'=> '3.28',
              'Pod::Simple::LinkSection'=> '3.28',
              'Pod::Simple::Methody'  => '3.28',
              'Pod::Simple::Progress' => '3.28',
              'Pod::Simple::PullParser'=> '3.28',
              'Pod::Simple::PullParserEndToken'=> '3.28',
              'Pod::Simple::PullParserStartToken'=> '3.28',
              'Pod::Simple::PullParserTextToken'=> '3.28',
              'Pod::Simple::PullParserToken'=> '3.28',
              'Pod::Simple::RTF'      => '3.28',
              'Pod::Simple::Search'   => '3.28',
              'Pod::Simple::SimpleTree'=> '3.28',
              'Pod::Simple::Text'     => '3.28',
              'Pod::Simple::TextContent'=> '3.28',
              'Pod::Simple::TiedOutFH'=> '3.28',
              'Pod::Simple::Transcode'=> '3.28',
              'Pod::Simple::TranscodeDumb'=> '3.28',
              'Pod::Simple::TranscodeSmart'=> '3.28',
              'Pod::Simple::XHTML'    => '3.28',
              'Pod::Simple::XMLOutStream'=> '3.28',
          },
          removed => {
          }
      },
      5.018001 => {
          delta_from => 5.018000,
          changed => {
              'B'                     => '1.42_01',
              'Config'                => '5.018001',
              'Digest::SHA'           => '5.84_01',
              'Module::CoreList'      => '2.96',
              'Module::CoreList::TieHashDelta'=> '2.96',
              'Module::CoreList::Utils'=> '2.96',
          },
          removed => {
             'VMS::Filespec'         => 1,
          }
      },
      5.018002 => {
          delta_from => 5.018001,
          changed => {
              'B'                     => '1.42_02',
              'B::Concise'            => '0.95_01',
              'Config'                => '5.018002',
              'File::Glob'            => '1.20_01',
              'Module::CoreList'      => '3.03',
              'Module::CoreList::TieHashDelta'=> '3.03',
              'Module::CoreList::Utils'=> '3.03',
          },
      },
      5.018003 => {
          delta_from => 5.018002,
          changed => {
              'Module::CoreList'      => '3.12',
              'Module::CoreList::TieHashDelta'=> '3.12',
              'Module::CoreList::Utils'=> '3.12',
          },
      },
      5.018004 => {
          delta_from => 5.018003,
          changed => {
              'Module::CoreList'      => '3.13',
              'Module::CoreList::TieHashDelta'=> '3.13',
              'Module::CoreList::Utils'=> '3.13',
          },
      },
      5.019000 => {
          delta_from => 5.018000,
          changed => {
              'Config'                => '5.019000',
              'Getopt::Std'           => '1.08',
              'Module::CoreList'      => '2.91',
              'Module::CoreList::TieHashDelta'=> '2.91',
              'Storable'              => '2.42',
              'feature'               => '1.33',
              'utf8'                  => '1.11',
          },
          removed => {
             'Archive::Extract'      => 1,
             'B::Lint'               => 1,
             'B::Lint::Debug'        => 1,
             'CPANPLUS'              => 1,
             'CPANPLUS::Backend'     => 1,
             'CPANPLUS::Backend::RV' => 1,
             'CPANPLUS::Config'      => 1,
             'CPANPLUS::Config::HomeEnv'=> 1,
             'CPANPLUS::Configure'   => 1,
             'CPANPLUS::Configure::Setup'=> 1,
             'CPANPLUS::Dist'        => 1,
             'CPANPLUS::Dist::Autobundle'=> 1,
             'CPANPLUS::Dist::Base'  => 1,
             'CPANPLUS::Dist::Build' => 1,
             'CPANPLUS::Dist::Build::Constants'=> 1,
             'CPANPLUS::Dist::MM'    => 1,
             'CPANPLUS::Dist::Sample'=> 1,
             'CPANPLUS::Error'       => 1,
             'CPANPLUS::Internals'   => 1,
             'CPANPLUS::Internals::Constants'=> 1,
             'CPANPLUS::Internals::Constants::Report'=> 1,
             'CPANPLUS::Internals::Extract'=> 1,
             'CPANPLUS::Internals::Fetch'=> 1,
             'CPANPLUS::Internals::Report'=> 1,
             'CPANPLUS::Internals::Search'=> 1,
             'CPANPLUS::Internals::Source'=> 1,
             'CPANPLUS::Internals::Source::Memory'=> 1,
             'CPANPLUS::Internals::Source::SQLite'=> 1,
             'CPANPLUS::Internals::Source::SQLite::Tie'=> 1,
             'CPANPLUS::Internals::Utils'=> 1,
             'CPANPLUS::Internals::Utils::Autoflush'=> 1,
             'CPANPLUS::Module'      => 1,
             'CPANPLUS::Module::Author'=> 1,
             'CPANPLUS::Module::Author::Fake'=> 1,
             'CPANPLUS::Module::Checksums'=> 1,
             'CPANPLUS::Module::Fake'=> 1,
             'CPANPLUS::Module::Signature'=> 1,
             'CPANPLUS::Selfupdate'  => 1,
             'CPANPLUS::Shell'       => 1,
             'CPANPLUS::Shell::Classic'=> 1,
             'CPANPLUS::Shell::Default'=> 1,
             'CPANPLUS::Shell::Default::Plugins::CustomSource'=> 1,
             'CPANPLUS::Shell::Default::Plugins::Remote'=> 1,
             'CPANPLUS::Shell::Default::Plugins::Source'=> 1,
             'Devel::InnerPackage'   => 1,
             'File::CheckTree'       => 1,
             'Log::Message'          => 1,
             'Log::Message::Config'  => 1,
             'Log::Message::Handlers'=> 1,
             'Log::Message::Item'    => 1,
             'Log::Message::Simple'  => 1,
             'Module::Pluggable'     => 1,
             'Module::Pluggable::Object'=> 1,
             'Object::Accessor'      => 1,
             'Pod::LaTeX'            => 1,
             'Term::UI'              => 1,
             'Term::UI::History'     => 1,
             'Text::Soundex'         => 1,
          }
      },
      5.019001 => {
          delta_from => 5.019000,
          changed => {
              'App::Prove'            => '3.28',
              'App::Prove::State'     => '3.28',
              'App::Prove::State::Result'=> '3.28',
              'App::Prove::State::Result::Test'=> '3.28',
              'Archive::Tar'          => '1.92',
              'Archive::Tar::Constant'=> '1.92',
              'Archive::Tar::File'    => '1.92',
              'Attribute::Handlers'   => '0.95',
              'B'                     => '1.43',
              'B::Concise'            => '0.96',
              'B::Deparse'            => '1.21',
              'B::Showlex'            => '1.04',
              'Benchmark'             => '1.16',
              'CPAN::Meta'            => '2.131560',
              'CPAN::Meta::Converter' => '2.131560',
              'CPAN::Meta::Feature'   => '2.131560',
              'CPAN::Meta::History'   => '2.131560',
              'CPAN::Meta::Prereqs'   => '2.131560',
              'CPAN::Meta::Spec'      => '2.131560',
              'CPAN::Meta::Validator' => '2.131560',
              'Carp'                  => '1.30',
              'Carp::Heavy'           => '1.30',
              'Compress::Raw::Bzip2'  => '2.061',
              'Compress::Raw::Zlib'   => '2.061',
              'Compress::Zlib'        => '2.061',
              'Config'                => '5.019001',
              'Config::Perl::V'       => '0.18',
              'Cwd'                   => '3.41',
              'DB'                    => '1.06',
              'DB_File'               => '1.828',
              'Data::Dumper'          => '2.146',
              'Encode'                => '2.51',
              'Encode::CN::HZ'        => '2.06',
              'Encode::GSM0338'       => '2.03',
              'Encode::Unicode::UTF7' => '2.07',
              'ExtUtils::CBuilder::Base'=> '0.280210',
              'ExtUtils::CBuilder::Platform::Windows::BCC'=> '0.280210',
              'ExtUtils::Command::MM' => '6.68',
              'ExtUtils::Install'     => '1.60',
              'ExtUtils::Liblist'     => '6.68',
              'ExtUtils::Liblist::Kid'=> '6.68',
              'ExtUtils::MM'          => '6.68',
              'ExtUtils::MM_AIX'      => '6.68',
              'ExtUtils::MM_Any'      => '6.68',
              'ExtUtils::MM_BeOS'     => '6.68',
              'ExtUtils::MM_Cygwin'   => '6.68',
              'ExtUtils::MM_DOS'      => '6.68',
              'ExtUtils::MM_Darwin'   => '6.68',
              'ExtUtils::MM_MacOS'    => '6.68',
              'ExtUtils::MM_NW5'      => '6.68',
              'ExtUtils::MM_OS2'      => '6.68',
              'ExtUtils::MM_QNX'      => '6.68',
              'ExtUtils::MM_UWIN'     => '6.68',
              'ExtUtils::MM_Unix'     => '6.68',
              'ExtUtils::MM_VMS'      => '6.68',
              'ExtUtils::MM_VOS'      => '6.68',
              'ExtUtils::MM_Win32'    => '6.68',
              'ExtUtils::MM_Win95'    => '6.68',
              'ExtUtils::MY'          => '6.68',
              'ExtUtils::MakeMaker'   => '6.68',
              'ExtUtils::MakeMaker::Config'=> '6.68',
              'ExtUtils::Mkbootstrap' => '6.68',
              'ExtUtils::Mksymlists'  => '6.68',
              'ExtUtils::ParseXS'     => '3.19',
              'ExtUtils::testlib'     => '6.68',
              'Fatal'                 => '2.19',
              'File::Copy'            => '2.27',
              'File::DosGlob'         => '1.11',
              'File::Fetch'           => '0.42',
              'File::Find'            => '1.24',
              'File::Spec'            => '3.41',
              'File::Spec::Cygwin'    => '3.41',
              'File::Spec::Epoc'      => '3.41',
              'File::Spec::Mac'       => '3.41',
              'File::Spec::OS2'       => '3.41',
              'File::Spec::Unix'      => '3.41',
              'File::Spec::VMS'       => '3.41',
              'File::Spec::Win32'     => '3.41',
              'File::Temp'            => '0.2301',
              'Filter::Simple'        => '0.90',
              'Filter::Util::Call'    => '1.49',
              'Getopt::Long'          => '2.4',
              'HTTP::Tiny'            => '0.031',
              'Hash::Util::FieldHash' => '1.11',
              'IO::Compress::Adapter::Bzip2'=> '2.061',
              'IO::Compress::Adapter::Deflate'=> '2.061',
              'IO::Compress::Adapter::Identity'=> '2.061',
              'IO::Compress::Base'    => '2.061',
              'IO::Compress::Base::Common'=> '2.061',
              'IO::Compress::Bzip2'   => '2.061',
              'IO::Compress::Deflate' => '2.061',
              'IO::Compress::Gzip'    => '2.061',
              'IO::Compress::Gzip::Constants'=> '2.061',
              'IO::Compress::RawDeflate'=> '2.061',
              'IO::Compress::Zip'     => '2.061',
              'IO::Compress::Zip::Constants'=> '2.061',
              'IO::Compress::Zlib::Constants'=> '2.061',
              'IO::Compress::Zlib::Extra'=> '2.061',
              'IO::Handle'            => '1.35',
              'IO::Uncompress::Adapter::Bunzip2'=> '2.061',
              'IO::Uncompress::Adapter::Identity'=> '2.061',
              'IO::Uncompress::Adapter::Inflate'=> '2.061',
              'IO::Uncompress::AnyInflate'=> '2.061',
              'IO::Uncompress::AnyUncompress'=> '2.061',
              'IO::Uncompress::Base'  => '2.061',
              'IO::Uncompress::Bunzip2'=> '2.061',
              'IO::Uncompress::Gunzip'=> '2.061',
              'IO::Uncompress::Inflate'=> '2.061',
              'IO::Uncompress::RawInflate'=> '2.061',
              'IO::Uncompress::Unzip' => '2.061',
              'IPC::Open3'            => '1.14',
              'Locale::Codes'         => '3.26',
              'Locale::Codes::Constants'=> '3.26',
              'Locale::Codes::Country'=> '3.26',
              'Locale::Codes::Country_Codes'=> '3.26',
              'Locale::Codes::Country_Retired'=> '3.26',
              'Locale::Codes::Currency'=> '3.26',
              'Locale::Codes::Currency_Codes'=> '3.26',
              'Locale::Codes::Currency_Retired'=> '3.26',
              'Locale::Codes::LangExt'=> '3.26',
              'Locale::Codes::LangExt_Codes'=> '3.26',
              'Locale::Codes::LangExt_Retired'=> '3.26',
              'Locale::Codes::LangFam'=> '3.26',
              'Locale::Codes::LangFam_Codes'=> '3.26',
              'Locale::Codes::LangFam_Retired'=> '3.26',
              'Locale::Codes::LangVar'=> '3.26',
              'Locale::Codes::LangVar_Codes'=> '3.26',
              'Locale::Codes::LangVar_Retired'=> '3.26',
              'Locale::Codes::Language'=> '3.26',
              'Locale::Codes::Language_Codes'=> '3.26',
              'Locale::Codes::Language_Retired'=> '3.26',
              'Locale::Codes::Script' => '3.26',
              'Locale::Codes::Script_Codes'=> '3.26',
              'Locale::Codes::Script_Retired'=> '3.26',
              'Locale::Country'       => '3.26',
              'Locale::Currency'      => '3.26',
              'Locale::Language'      => '3.26',
              'Locale::Maketext'      => '1.24',
              'Locale::Script'        => '3.26',
              'Math::BigFloat'        => '1.999',
              'Math::BigInt'          => '1.9992',
              'Math::BigInt::Calc'    => '1.998',
              'Math::BigInt::CalcEmu' => '1.9991',
              'Math::BigRat'          => '0.2606',
              'Module::Build'         => '0.4005',
              'Module::Build::Base'   => '0.4005',
              'Module::Build::Compat' => '0.4005',
              'Module::Build::Config' => '0.4005',
              'Module::Build::Cookbook'=> '0.4005',
              'Module::Build::Dumper' => '0.4005',
              'Module::Build::ModuleInfo'=> '0.4005',
              'Module::Build::Notes'  => '0.4005',
              'Module::Build::PPMMaker'=> '0.4005',
              'Module::Build::Platform::Amiga'=> '0.4005',
              'Module::Build::Platform::Default'=> '0.4005',
              'Module::Build::Platform::EBCDIC'=> '0.4005',
              'Module::Build::Platform::MPEiX'=> '0.4005',
              'Module::Build::Platform::MacOS'=> '0.4005',
              'Module::Build::Platform::RiscOS'=> '0.4005',
              'Module::Build::Platform::Unix'=> '0.4005',
              'Module::Build::Platform::VMS'=> '0.4005',
              'Module::Build::Platform::VOS'=> '0.4005',
              'Module::Build::Platform::Windows'=> '0.4005',
              'Module::Build::Platform::aix'=> '0.4005',
              'Module::Build::Platform::cygwin'=> '0.4005',
              'Module::Build::Platform::darwin'=> '0.4005',
              'Module::Build::Platform::os2'=> '0.4005',
              'Module::Build::PodParser'=> '0.4005',
              'Module::CoreList'      => '2.92',
              'Module::CoreList::TieHashDelta'=> '2.92',
              'Module::CoreList::Utils'=> '2.92',
              'Module::Metadata'      => '1.000014',
              'Net::Ping'             => '2.42',
              'OS2::Process'          => '1.09',
              'POSIX'                 => '1.33',
              'Pod::Find'             => '1.61',
              'Pod::Html'             => '1.19',
              'Pod::InputObjects'     => '1.61',
              'Pod::ParseUtils'       => '1.61',
              'Pod::Parser'           => '1.61',
              'Pod::Perldoc'          => '3.20',
              'Pod::Perldoc::BaseTo'  => '3.20',
              'Pod::Perldoc::GetOptsOO'=> '3.20',
              'Pod::Perldoc::ToANSI'  => '3.20',
              'Pod::Perldoc::ToChecker'=> '3.20',
              'Pod::Perldoc::ToMan'   => '3.20',
              'Pod::Perldoc::ToNroff' => '3.20',
              'Pod::Perldoc::ToPod'   => '3.20',
              'Pod::Perldoc::ToRtf'   => '3.20',
              'Pod::Perldoc::ToTerm'  => '3.20',
              'Pod::Perldoc::ToText'  => '3.20',
              'Pod::Perldoc::ToTk'    => '3.20',
              'Pod::Perldoc::ToXml'   => '3.20',
              'Pod::Select'           => '1.61',
              'Pod::Usage'            => '1.63',
              'Safe'                  => '2.36',
              'Storable'              => '2.43',
              'Sys::Hostname'         => '1.18',
              'Sys::Syslog'           => '0.33',
              'TAP::Base'             => '3.28',
              'TAP::Formatter::Base'  => '3.28',
              'TAP::Formatter::Color' => '3.28',
              'TAP::Formatter::Console'=> '3.28',
              'TAP::Formatter::Console::ParallelSession'=> '3.28',
              'TAP::Formatter::Console::Session'=> '3.28',
              'TAP::Formatter::File'  => '3.28',
              'TAP::Formatter::File::Session'=> '3.28',
              'TAP::Formatter::Session'=> '3.28',
              'TAP::Harness'          => '3.28',
              'TAP::Object'           => '3.28',
              'TAP::Parser'           => '3.28',
              'TAP::Parser::Aggregator'=> '3.28',
              'TAP::Parser::Grammar'  => '3.28',
              'TAP::Parser::Iterator' => '3.28',
              'TAP::Parser::Iterator::Array'=> '3.28',
              'TAP::Parser::Iterator::Process'=> '3.28',
              'TAP::Parser::Iterator::Stream'=> '3.28',
              'TAP::Parser::IteratorFactory'=> '3.28',
              'TAP::Parser::Multiplexer'=> '3.28',
              'TAP::Parser::Result'   => '3.28',
              'TAP::Parser::Result::Bailout'=> '3.28',
              'TAP::Parser::Result::Comment'=> '3.28',
              'TAP::Parser::Result::Plan'=> '3.28',
              'TAP::Parser::Result::Pragma'=> '3.28',
              'TAP::Parser::Result::Test'=> '3.28',
              'TAP::Parser::Result::Unknown'=> '3.28',
              'TAP::Parser::Result::Version'=> '3.28',
              'TAP::Parser::Result::YAML'=> '3.28',
              'TAP::Parser::ResultFactory'=> '3.28',
              'TAP::Parser::Scheduler'=> '3.28',
              'TAP::Parser::Scheduler::Job'=> '3.28',
              'TAP::Parser::Scheduler::Spinner'=> '3.28',
              'TAP::Parser::Source'   => '3.28',
              'TAP::Parser::SourceHandler'=> '3.28',
              'TAP::Parser::SourceHandler::Executable'=> '3.28',
              'TAP::Parser::SourceHandler::File'=> '3.28',
              'TAP::Parser::SourceHandler::Handle'=> '3.28',
              'TAP::Parser::SourceHandler::Perl'=> '3.28',
              'TAP::Parser::SourceHandler::RawTAP'=> '3.28',
              'TAP::Parser::Utils'    => '3.28',
              'TAP::Parser::YAMLish::Reader'=> '3.28',
              'TAP::Parser::YAMLish::Writer'=> '3.28',
              'Term::ReadLine'        => '1.13',
              'Test::Harness'         => '3.28',
              'Text::Tabs'            => '2013.0523',
              'Text::Wrap'            => '2013.0523',
              'Thread'                => '3.04',
              'Tie::File'             => '1.00',
              'Time::Piece'           => '1.2002',
              'Unicode::Collate'      => '0.98',
              'Unicode::UCD'          => '0.53',
              'XS::APItest'           => '0.53',
              '_charnames'            => '1.37',
              'autodie'               => '2.19',
              'autodie::exception'    => '2.19',
              'autodie::exception::system'=> '2.19',
              'autodie::hints'        => '2.19',
              'autodie::skip'         => '2.19',
              'bigint'                => '0.35',
              'charnames'             => '1.38',
              'encoding'              => '2.12',
              'inc::latest'           => '0.4005',
              'mro'                   => '1.12',
              'perlfaq'               => '5.0150043',
              're'                    => '0.25',
              'threads'               => '1.87',
              'threads::shared'       => '1.44',
              'utf8'                  => '1.12',
          },
          removed => {
          }
      },
      5.019002 => {
          delta_from => 5.019001,
          changed => {
              'B'                     => '1.44',
              'B::Concise'            => '0.98',
              'B::Deparse'            => '1.22',
              'Benchmark'             => '1.17',
              'Class::Struct'         => '0.65',
              'Config'                => '5.019002',
              'DB'                    => '1.07',
              'DBM_Filter'            => '0.06',
              'DBM_Filter::compress'  => '0.03',
              'DBM_Filter::encode'    => '0.03',
              'DBM_Filter::int32'     => '0.03',
              'DBM_Filter::null'      => '0.03',
              'DBM_Filter::utf8'      => '0.03',
              'DB_File'               => '1.829',
              'Data::Dumper'          => '2.147',
              'Devel::Peek'           => '1.12',
              'Digest::MD5'           => '2.53',
              'Digest::SHA'           => '5.85',
              'English'               => '1.07',
              'Errno'                 => '1.19',
              'ExtUtils::Embed'       => '1.31',
              'ExtUtils::Miniperl'    => '1',
              'ExtUtils::ParseXS'     => '3.21',
              'ExtUtils::ParseXS::Constants'=> '3.21',
              'ExtUtils::ParseXS::CountLines'=> '3.21',
              'ExtUtils::ParseXS::Eval'=> '3.19',
              'ExtUtils::ParseXS::Utilities'=> '3.21',
              'ExtUtils::Typemaps'    => '3.21',
              'ExtUtils::Typemaps::Cmd'=> '3.21',
              'ExtUtils::Typemaps::InputMap'=> '3.21',
              'ExtUtils::Typemaps::OutputMap'=> '3.21',
              'ExtUtils::Typemaps::Type'=> '3.21',
              'ExtUtils::XSSymSet'    => '1.3',
              'Fatal'                 => '2.20',
              'File::Basename'        => '2.85',
              'File::Spec::VMS'       => '3.43',
              'File::Spec::Win32'     => '3.42',
              'Getopt::Long'          => '2.41',
              'Getopt::Std'           => '1.09',
              'HTTP::Tiny'            => '0.034',
              'Hash::Util::FieldHash' => '1.12',
              'I18N::Langinfo'        => '0.11',
              'IO::Socket::INET'      => '1.34',
              'IO::Socket::UNIX'      => '1.25',
              'IPC::Cmd'              => '0.82',
              'MIME::Base64'          => '3.14',
              'Module::CoreList'      => '2.94',
              'Module::CoreList::TieHashDelta'=> '2.94',
              'Module::CoreList::Utils'=> '2.94',
              'POSIX'                 => '1.34',
              'Params::Check'         => '0.38',
              'Parse::CPAN::Meta'     => '1.4405',
              'Pod::Functions'        => '1.07',
              'Pod::Html'             => '1.2',
              'Safe'                  => '2.37',
              'Socket'                => '2.010',
              'Storable'              => '2.45',
              'Text::ParseWords'      => '3.29',
              'Tie::Array'            => '1.06',
              'Tie::Hash'             => '1.05',
              'Tie::Scalar'           => '1.03',
              'Time::Piece'           => '1.21',
              'Time::Seconds'         => '1.21',
              'XS::APItest'           => '0.54',
              'autodie'               => '2.20',
              'autodie::exception'    => '2.20',
              'autodie::exception::system'=> '2.20',
              'autodie::hints'        => '2.20',
              'autodie::skip'         => '2.20',
              'base'                  => '2.19',
              'deprecate'             => '0.03',
              'if'                    => '0.0603',
              'integer'               => '1.01',
              'strict'                => '1.08',
              'subs'                  => '1.02',
              'vmsish'                => '1.04',
          },
          removed => {
          }
      },
      5.019003 => {
          delta_from => 5.019002,
          changed => {
              'B'                     => '1.45',
              'CPAN::Meta'            => '2.132140',
              'CPAN::Meta::Converter' => '2.132140',
              'CPAN::Meta::Feature'   => '2.132140',
              'CPAN::Meta::History'   => '2.132140',
              'CPAN::Meta::Prereqs'   => '2.132140',
              'CPAN::Meta::Spec'      => '2.132140',
              'CPAN::Meta::Validator' => '2.132140',
              'Carp'                  => '1.31',
              'Carp::Heavy'           => '1.31',
              'Compress::Raw::Bzip2'  => '2.062',
              'Compress::Raw::Zlib'   => '2.062',
              'Compress::Zlib'        => '2.062',
              'Config'                => '5.019003',
              'Config::Perl::V'       => '0.19',
              'Cwd'                   => '3.44',
              'Data::Dumper'          => '2.148',
              'Devel::PPPort'         => '3.21',
              'Devel::Peek'           => '1.13',
              'DynaLoader'            => '1.19',
              'Encode'                => '2.52',
              'Encode::Alias'         => '2.17',
              'Encode::Encoding'      => '2.06',
              'Encode::GSM0338'       => '2.04',
              'Encode::MIME::Header'  => '2.14',
              'Encode::Unicode'       => '2.08',
              'English'               => '1.08',
              'Exporter'              => '5.69',
              'Exporter::Heavy'       => '5.69',
              'ExtUtils::Command::MM' => '6.72',
              'ExtUtils::Liblist'     => '6.72',
              'ExtUtils::Liblist::Kid'=> '6.72',
              'ExtUtils::MM'          => '6.72',
              'ExtUtils::MM_AIX'      => '6.72',
              'ExtUtils::MM_Any'      => '6.72',
              'ExtUtils::MM_BeOS'     => '6.72',
              'ExtUtils::MM_Cygwin'   => '6.72',
              'ExtUtils::MM_DOS'      => '6.72',
              'ExtUtils::MM_Darwin'   => '6.72',
              'ExtUtils::MM_MacOS'    => '6.72',
              'ExtUtils::MM_NW5'      => '6.72',
              'ExtUtils::MM_OS2'      => '6.72',
              'ExtUtils::MM_QNX'      => '6.72',
              'ExtUtils::MM_UWIN'     => '6.72',
              'ExtUtils::MM_Unix'     => '6.72',
              'ExtUtils::MM_VMS'      => '6.72',
              'ExtUtils::MM_VOS'      => '6.72',
              'ExtUtils::MM_Win32'    => '6.72',
              'ExtUtils::MM_Win95'    => '6.72',
              'ExtUtils::MY'          => '6.72',
              'ExtUtils::MakeMaker'   => '6.72',
              'ExtUtils::MakeMaker::Config'=> '6.72',
              'ExtUtils::Mkbootstrap' => '6.72',
              'ExtUtils::Mksymlists'  => '6.72',
              'ExtUtils::ParseXS::Eval'=> '3.21',
              'ExtUtils::testlib'     => '6.72',
              'File::Spec'            => '3.44',
              'File::Spec::Cygwin'    => '3.44',
              'File::Spec::Epoc'      => '3.44',
              'File::Spec::Functions' => '3.44',
              'File::Spec::Mac'       => '3.44',
              'File::Spec::OS2'       => '3.44',
              'File::Spec::Unix'      => '3.44',
              'File::Spec::VMS'       => '3.44',
              'File::Spec::Win32'     => '3.44',
              'Getopt::Std'           => '1.10',
              'IO::Compress::Adapter::Bzip2'=> '2.062',
              'IO::Compress::Adapter::Deflate'=> '2.062',
              'IO::Compress::Adapter::Identity'=> '2.062',
              'IO::Compress::Base'    => '2.062',
              'IO::Compress::Base::Common'=> '2.062',
              'IO::Compress::Bzip2'   => '2.062',
              'IO::Compress::Deflate' => '2.062',
              'IO::Compress::Gzip'    => '2.062',
              'IO::Compress::Gzip::Constants'=> '2.062',
              'IO::Compress::RawDeflate'=> '2.062',
              'IO::Compress::Zip'     => '2.062',
              'IO::Compress::Zip::Constants'=> '2.062',
              'IO::Compress::Zlib::Constants'=> '2.062',
              'IO::Compress::Zlib::Extra'=> '2.062',
              'IO::Uncompress::Adapter::Bunzip2'=> '2.062',
              'IO::Uncompress::Adapter::Identity'=> '2.062',
              'IO::Uncompress::Adapter::Inflate'=> '2.062',
              'IO::Uncompress::AnyInflate'=> '2.062',
              'IO::Uncompress::AnyUncompress'=> '2.062',
              'IO::Uncompress::Base'  => '2.062',
              'IO::Uncompress::Bunzip2'=> '2.062',
              'IO::Uncompress::Gunzip'=> '2.062',
              'IO::Uncompress::Inflate'=> '2.062',
              'IO::Uncompress::RawInflate'=> '2.062',
              'IO::Uncompress::Unzip' => '2.062',
              'IPC::Cmd'              => '0.84',
              'IPC::Msg'              => '2.04',
              'IPC::Open3'            => '1.15',
              'IPC::Semaphore'        => '2.04',
              'IPC::SharedMem'        => '2.04',
              'IPC::SysV'             => '2.04',
              'List::Util'            => '1.31',
              'List::Util::XS'        => '1.31',
              'Math::BigFloat::Trace' => '0.36',
              'Math::BigInt::Trace'   => '0.36',
              'Module::Build'         => '0.4007',
              'Module::Build::Base'   => '0.4007',
              'Module::Build::Compat' => '0.4007',
              'Module::Build::Config' => '0.4007',
              'Module::Build::Cookbook'=> '0.4007',
              'Module::Build::Dumper' => '0.4007',
              'Module::Build::ModuleInfo'=> '0.4007',
              'Module::Build::Notes'  => '0.4007',
              'Module::Build::PPMMaker'=> '0.4007',
              'Module::Build::Platform::Default'=> '0.4007',
              'Module::Build::Platform::MacOS'=> '0.4007',
              'Module::Build::Platform::Unix'=> '0.4007',
              'Module::Build::Platform::VMS'=> '0.4007',
              'Module::Build::Platform::VOS'=> '0.4007',
              'Module::Build::Platform::Windows'=> '0.4007',
              'Module::Build::Platform::aix'=> '0.4007',
              'Module::Build::Platform::cygwin'=> '0.4007',
              'Module::Build::Platform::darwin'=> '0.4007',
              'Module::Build::Platform::os2'=> '0.4007',
              'Module::Build::PodParser'=> '0.4007',
              'Module::CoreList'      => '2.97',
              'Module::CoreList::TieHashDelta'=> '2.97',
              'Module::CoreList::Utils'=> '2.97',
              'Net::Cmd'              => '2.30',
              'Net::Config'           => '1.12',
              'Net::Domain'           => '2.22',
              'Net::FTP'              => '2.78',
              'Net::FTP::dataconn'    => '0.12',
              'Net::NNTP'             => '2.25',
              'Net::Netrc'            => '2.14',
              'Net::POP3'             => '2.30',
              'Net::SMTP'             => '2.32',
              'PerlIO'                => '1.08',
              'Pod::Functions'        => '1.08',
              'Scalar::Util'          => '1.31',
              'Socket'                => '2.011',
              'Storable'              => '2.46',
              'Time::HiRes'           => '1.9726',
              'Time::Piece'           => '1.22',
              'Time::Seconds'         => '1.22',
              'XS::APItest'           => '0.55',
              'bigint'                => '0.36',
              'bignum'                => '0.36',
              'bigrat'                => '0.36',
              'constant'              => '1.28',
              'diagnostics'           => '1.32',
              'inc::latest'           => '0.4007',
              'mro'                   => '1.13',
              'parent'                => '0.226',
              'utf8'                  => '1.13',
              'version'               => '0.9903',
          },
          removed => {
             'Module::Build::Platform::Amiga'=> 1,
             'Module::Build::Platform::EBCDIC'=> 1,
             'Module::Build::Platform::MPEiX'=> 1,
             'Module::Build::Platform::RiscOS'=> 1,
          }
      },
      5.019004 => {
          delta_from => 5.019003,
          changed => {
              'B'                     => '1.46',
              'B::Concise'            => '0.99',
              'B::Deparse'            => '1.23',
              'CPAN'                  => '2.03',
              'CPAN::Meta'            => '2.132620',
              'CPAN::Meta::Converter' => '2.132620',
              'CPAN::Meta::Feature'   => '2.132620',
              'CPAN::Meta::History'   => '2.132620',
              'CPAN::Meta::Prereqs'   => '2.132620',
              'CPAN::Meta::Requirements'=> '2.123',
              'CPAN::Meta::Spec'      => '2.132620',
              'CPAN::Meta::Validator' => '2.132620',
              'Carp'                  => '1.32',
              'Carp::Heavy'           => '1.32',
              'Config'                => '5.019004',
              'Data::Dumper'          => '2.149',
              'Devel::Peek'           => '1.14',
              'DynaLoader'            => '1.20',
              'Encode'                => '2.55',
              'Encode::Alias'         => '2.18',
              'Encode::CN::HZ'        => '2.07',
              'Encode::Encoder'       => '2.03',
              'Encode::Encoding'      => '2.07',
              'Encode::GSM0338'       => '2.05',
              'Encode::Guess'         => '2.06',
              'Encode::JP::JIS7'      => '2.05',
              'Encode::KR::2022_KR'   => '2.03',
              'Encode::MIME::Header'  => '2.15',
              'Encode::MIME::Header::ISO_2022_JP'=> '1.04',
              'Encode::Unicode'       => '2.09',
              'Encode::Unicode::UTF7' => '2.08',
              'Errno'                 => '1.20',
              'Exporter'              => '5.70',
              'Exporter::Heavy'       => '5.70',
              'ExtUtils::CBuilder'    => '0.280212',
              'ExtUtils::CBuilder::Base'=> '0.280212',
              'ExtUtils::CBuilder::Platform::Unix'=> '0.280212',
              'ExtUtils::CBuilder::Platform::VMS'=> '0.280212',
              'ExtUtils::CBuilder::Platform::Windows'=> '0.280212',
              'ExtUtils::CBuilder::Platform::Windows::BCC'=> '0.280212',
              'ExtUtils::CBuilder::Platform::Windows::GCC'=> '0.280212',
              'ExtUtils::CBuilder::Platform::Windows::MSVC'=> '0.280212',
              'ExtUtils::CBuilder::Platform::aix'=> '0.280212',
              'ExtUtils::CBuilder::Platform::cygwin'=> '0.280212',
              'ExtUtils::CBuilder::Platform::darwin'=> '0.280212',
              'ExtUtils::CBuilder::Platform::dec_osf'=> '0.280212',
              'ExtUtils::CBuilder::Platform::os2'=> '0.280212',
              'ExtUtils::Command'     => '1.18',
              'ExtUtils::Command::MM' => '6.76',
              'ExtUtils::Liblist'     => '6.76',
              'ExtUtils::Liblist::Kid'=> '6.76',
              'ExtUtils::MM'          => '6.76',
              'ExtUtils::MM_AIX'      => '6.76',
              'ExtUtils::MM_Any'      => '6.76',
              'ExtUtils::MM_BeOS'     => '6.76',
              'ExtUtils::MM_Cygwin'   => '6.76',
              'ExtUtils::MM_DOS'      => '6.76',
              'ExtUtils::MM_Darwin'   => '6.76',
              'ExtUtils::MM_MacOS'    => '6.76',
              'ExtUtils::MM_NW5'      => '6.76',
              'ExtUtils::MM_OS2'      => '6.76',
              'ExtUtils::MM_QNX'      => '6.76',
              'ExtUtils::MM_UWIN'     => '6.76',
              'ExtUtils::MM_Unix'     => '6.76',
              'ExtUtils::MM_VMS'      => '6.76',
              'ExtUtils::MM_VOS'      => '6.76',
              'ExtUtils::MM_Win32'    => '6.76',
              'ExtUtils::MM_Win95'    => '6.76',
              'ExtUtils::MY'          => '6.76',
              'ExtUtils::MakeMaker'   => '6.76',
              'ExtUtils::MakeMaker::Config'=> '6.76',
              'ExtUtils::Mkbootstrap' => '6.76',
              'ExtUtils::Mksymlists'  => '6.76',
              'ExtUtils::ParseXS'     => '3.23',
              'ExtUtils::ParseXS::Constants'=> '3.23',
              'ExtUtils::ParseXS::CountLines'=> '3.23',
              'ExtUtils::ParseXS::Eval'=> '3.23',
              'ExtUtils::ParseXS::Utilities'=> '3.23',
              'ExtUtils::Typemaps'    => '3.23',
              'ExtUtils::Typemaps::Cmd'=> '3.23',
              'ExtUtils::Typemaps::InputMap'=> '3.23',
              'ExtUtils::Typemaps::OutputMap'=> '3.23',
              'ExtUtils::Typemaps::Type'=> '3.23',
              'ExtUtils::testlib'     => '6.76',
              'Fatal'                 => '2.21',
              'File::Copy'            => '2.28',
              'File::Find'            => '1.25',
              'File::Glob'            => '1.21',
              'FileCache'             => '1.09',
              'HTTP::Tiny'            => '0.035',
              'Hash::Util::FieldHash' => '1.13',
              'I18N::LangTags'        => '0.40',
              'IO'                    => '1.29',
              'IO::Socket'            => '1.37',
              'IPC::Open3'            => '1.16',
              'JSON::PP'              => '2.27202_01',
              'List::Util'            => '1.32',
              'List::Util::XS'        => '1.32',
              'Locale::Codes'         => '3.27',
              'Locale::Codes::Constants'=> '3.27',
              'Locale::Codes::Country'=> '3.27',
              'Locale::Codes::Country_Codes'=> '3.27',
              'Locale::Codes::Country_Retired'=> '3.27',
              'Locale::Codes::Currency'=> '3.27',
              'Locale::Codes::Currency_Codes'=> '3.27',
              'Locale::Codes::Currency_Retired'=> '3.27',
              'Locale::Codes::LangExt'=> '3.27',
              'Locale::Codes::LangExt_Codes'=> '3.27',
              'Locale::Codes::LangExt_Retired'=> '3.27',
              'Locale::Codes::LangFam'=> '3.27',
              'Locale::Codes::LangFam_Codes'=> '3.27',
              'Locale::Codes::LangFam_Retired'=> '3.27',
              'Locale::Codes::LangVar'=> '3.27',
              'Locale::Codes::LangVar_Codes'=> '3.27',
              'Locale::Codes::LangVar_Retired'=> '3.27',
              'Locale::Codes::Language'=> '3.27',
              'Locale::Codes::Language_Codes'=> '3.27',
              'Locale::Codes::Language_Retired'=> '3.27',
              'Locale::Codes::Script' => '3.27',
              'Locale::Codes::Script_Codes'=> '3.27',
              'Locale::Codes::Script_Retired'=> '3.27',
              'Locale::Country'       => '3.27',
              'Locale::Currency'      => '3.27',
              'Locale::Language'      => '3.27',
              'Locale::Script'        => '3.27',
              'Math::BigFloat'        => '1.9991',
              'Math::BigInt'          => '1.9993',
              'Math::BigInt::FastCalc'=> '0.31',
              'Module::CoreList'      => '2.99',
              'Module::CoreList::TieHashDelta'=> '2.99',
              'Module::CoreList::Utils'=> '2.99',
              'Module::Load::Conditional'=> '0.58',
              'Module::Metadata'      => '1.000018',
              'Opcode'                => '1.26',
              'POSIX'                 => '1.35',
              'Parse::CPAN::Meta'     => '1.4407',
              'Perl::OSType'          => '1.005',
              'Pod::Html'             => '1.21',
              'Scalar::Util'          => '1.32',
              'Socket'                => '2.012',
              'Storable'              => '2.47',
              'Term::ReadLine'        => '1.14',
              'Test::Builder'         => '0.98_06',
              'Test::Builder::Module' => '0.98_06',
              'Test::More'            => '0.98_06',
              'Test::Simple'          => '0.98_06',
              'Time::Piece'           => '1.23',
              'Time::Seconds'         => '1.23',
              'Unicode::Collate'      => '0.99',
              'Unicode::UCD'          => '0.54',
              'XS::APItest'           => '0.56',
              'XS::Typemap'           => '0.11',
              '_charnames'            => '1.39',
              'autodie'               => '2.21',
              'autodie::exception'    => '2.21',
              'autodie::exception::system'=> '2.21',
              'autodie::hints'        => '2.21',
              'autodie::skip'         => '2.21',
              'charnames'             => '1.39',
              'diagnostics'           => '1.33',
              'mro'                   => '1.14',
              'parent'                => '0.228',
              'perlfaq'               => '5.0150044',
              're'                    => '0.26',
              'version'               => '0.9904',
              'warnings'              => '1.19',
          },
          removed => {
          }
      },
      5.019005 => {
          delta_from => 5.019004,
          changed => {
              'App::Prove'            => '3.29',
              'App::Prove::State'     => '3.29',
              'App::Prove::State::Result'=> '3.29',
              'App::Prove::State::Result::Test'=> '3.29',
              'CPAN::Meta'            => '2.132830',
              'CPAN::Meta::Converter' => '2.132830',
              'CPAN::Meta::Feature'   => '2.132830',
              'CPAN::Meta::History'   => '2.132830',
              'CPAN::Meta::Prereqs'   => '2.132830',
              'CPAN::Meta::Requirements'=> '2.125',
              'CPAN::Meta::Spec'      => '2.132830',
              'CPAN::Meta::Validator' => '2.132830',
              'CPAN::Meta::YAML'      => '0.010',
              'Config'                => '5.019005',
              'Cwd'                   => '3.45',
              'ExtUtils::Command::MM' => '6.80',
              'ExtUtils::Install'     => '1.61',
              'ExtUtils::Liblist'     => '6.80',
              'ExtUtils::Liblist::Kid'=> '6.80',
              'ExtUtils::MM'          => '6.80',
              'ExtUtils::MM_AIX'      => '6.80',
              'ExtUtils::MM_Any'      => '6.80',
              'ExtUtils::MM_BeOS'     => '6.80',
              'ExtUtils::MM_Cygwin'   => '6.80',
              'ExtUtils::MM_DOS'      => '6.80',
              'ExtUtils::MM_Darwin'   => '6.80',
              'ExtUtils::MM_MacOS'    => '6.80',
              'ExtUtils::MM_NW5'      => '6.80',
              'ExtUtils::MM_OS2'      => '6.80',
              'ExtUtils::MM_QNX'      => '6.80',
              'ExtUtils::MM_UWIN'     => '6.80',
              'ExtUtils::MM_Unix'     => '6.80',
              'ExtUtils::MM_VMS'      => '6.80',
              'ExtUtils::MM_VOS'      => '6.80',
              'ExtUtils::MM_Win32'    => '6.80',
              'ExtUtils::MM_Win95'    => '6.80',
              'ExtUtils::MY'          => '6.80',
              'ExtUtils::MakeMaker'   => '6.80',
              'ExtUtils::MakeMaker::Config'=> '6.80',
              'ExtUtils::Mkbootstrap' => '6.80',
              'ExtUtils::Mksymlists'  => '6.80',
              'ExtUtils::testlib'     => '6.80',
              'Fatal'                 => '2.22',
              'File::Fetch'           => '0.44',
              'File::Glob'            => '1.22',
              'File::Spec'            => '3.45',
              'File::Spec::Cygwin'    => '3.45',
              'File::Spec::Epoc'      => '3.45',
              'File::Spec::Functions' => '3.45',
              'File::Spec::Mac'       => '3.45',
              'File::Spec::OS2'       => '3.45',
              'File::Spec::Unix'      => '3.45',
              'File::Spec::VMS'       => '3.45',
              'File::Spec::Win32'     => '3.45',
              'File::Temp'            => '0.2304',
              'Getopt::Long'          => '2.42',
              'HTTP::Tiny'            => '0.036',
              'IPC::Cmd'              => '0.84_01',
              'JSON::PP'              => '2.27203',
              'List::Util'            => '1.35',
              'List::Util::XS'        => '1.35',
              'Module::CoreList'      => '3.00',
              'Module::CoreList::TieHashDelta'=> '3.00',
              'Module::CoreList::Utils'=> '3.00',
              'Module::Metadata'      => '1.000019',
              'Parse::CPAN::Meta'     => '1.4409',
              'Perl::OSType'          => '1.006',
              'PerlIO::scalar'        => '0.17',
              'Pod::Man'              => '2.28',
              'Pod::Text'             => '3.18',
              'Pod::Text::Termcap'    => '2.08',
              'Scalar::Util'          => '1.35',
              'TAP::Base'             => '3.29',
              'TAP::Formatter::Base'  => '3.29',
              'TAP::Formatter::Color' => '3.29',
              'TAP::Formatter::Console'=> '3.29',
              'TAP::Formatter::Console::ParallelSession'=> '3.29',
              'TAP::Formatter::Console::Session'=> '3.29',
              'TAP::Formatter::File'  => '3.29',
              'TAP::Formatter::File::Session'=> '3.29',
              'TAP::Formatter::Session'=> '3.29',
              'TAP::Harness'          => '3.29',
              'TAP::Harness::Env'     => '3.29',
              'TAP::Object'           => '3.29',
              'TAP::Parser'           => '3.29',
              'TAP::Parser::Aggregator'=> '3.29',
              'TAP::Parser::Grammar'  => '3.29',
              'TAP::Parser::Iterator' => '3.29',
              'TAP::Parser::Iterator::Array'=> '3.29',
              'TAP::Parser::Iterator::Process'=> '3.29',
              'TAP::Parser::Iterator::Stream'=> '3.29',
              'TAP::Parser::IteratorFactory'=> '3.29',
              'TAP::Parser::Multiplexer'=> '3.29',
              'TAP::Parser::Result'   => '3.29',
              'TAP::Parser::Result::Bailout'=> '3.29',
              'TAP::Parser::Result::Comment'=> '3.29',
              'TAP::Parser::Result::Plan'=> '3.29',
              'TAP::Parser::Result::Pragma'=> '3.29',
              'TAP::Parser::Result::Test'=> '3.29',
              'TAP::Parser::Result::Unknown'=> '3.29',
              'TAP::Parser::Result::Version'=> '3.29',
              'TAP::Parser::Result::YAML'=> '3.29',
              'TAP::Parser::ResultFactory'=> '3.29',
              'TAP::Parser::Scheduler'=> '3.29',
              'TAP::Parser::Scheduler::Job'=> '3.29',
              'TAP::Parser::Scheduler::Spinner'=> '3.29',
              'TAP::Parser::Source'   => '3.29',
              'TAP::Parser::SourceHandler'=> '3.29',
              'TAP::Parser::SourceHandler::Executable'=> '3.29',
              'TAP::Parser::SourceHandler::File'=> '3.29',
              'TAP::Parser::SourceHandler::Handle'=> '3.29',
              'TAP::Parser::SourceHandler::Perl'=> '3.29',
              'TAP::Parser::SourceHandler::RawTAP'=> '3.29',
              'TAP::Parser::YAMLish::Reader'=> '3.29',
              'TAP::Parser::YAMLish::Writer'=> '3.29',
              'Test::Builder'         => '0.99',
              'Test::Builder::Module' => '0.99',
              'Test::Builder::Tester' => '1.23_002',
              'Test::Builder::Tester::Color'=> '1.23_002',
              'Test::Harness'         => '3.29',
              'Test::More'            => '0.99',
              'Test::Simple'          => '0.99',
              'Unicode'               => '6.3.0',
              'Unicode::Normalize'    => '1.17',
              'Unicode::UCD'          => '0.55',
              'attributes'            => '0.22',
              'autodie'               => '2.22',
              'autodie::exception'    => '2.22',
              'autodie::exception::system'=> '2.22',
              'autodie::hints'        => '2.22',
              'autodie::skip'         => '2.22',
              'feature'               => '1.34',
              'threads'               => '1.89',
              'warnings'              => '1.20',
          },
          removed => {
              'TAP::Parser::Utils'    => 1,
          }
      },
      5.019006 => {
          delta_from => 5.019005,
          changed => {
              'App::Prove'            => '3.30',
              'App::Prove::State'     => '3.30',
              'App::Prove::State::Result'=> '3.30',
              'App::Prove::State::Result::Test'=> '3.30',
              'Archive::Tar'          => '1.96',
              'Archive::Tar::Constant'=> '1.96',
              'Archive::Tar::File'    => '1.96',
              'AutoLoader'            => '5.74',
              'B'                     => '1.47',
              'B::Concise'            => '0.991',
              'B::Debug'              => '1.19',
              'B::Deparse'            => '1.24',
              'Benchmark'             => '1.18',
              'Compress::Raw::Bzip2'  => '2.063',
              'Compress::Raw::Zlib'   => '2.063',
              'Compress::Zlib'        => '2.063',
              'Config'                => '5.019006',
              'DB_File'               => '1.831',
              'Devel::Peek'           => '1.15',
              'DynaLoader'            => '1.21',
              'Errno'                 => '1.20_01',
              'ExtUtils::Command::MM' => '6.82',
              'ExtUtils::Liblist'     => '6.82',
              'ExtUtils::Liblist::Kid'=> '6.82',
              'ExtUtils::MM'          => '6.82',
              'ExtUtils::MM_AIX'      => '6.82',
              'ExtUtils::MM_Any'      => '6.82',
              'ExtUtils::MM_BeOS'     => '6.82',
              'ExtUtils::MM_Cygwin'   => '6.82',
              'ExtUtils::MM_DOS'      => '6.82',
              'ExtUtils::MM_Darwin'   => '6.82',
              'ExtUtils::MM_MacOS'    => '6.82',
              'ExtUtils::MM_NW5'      => '6.82',
              'ExtUtils::MM_OS2'      => '6.82',
              'ExtUtils::MM_QNX'      => '6.82',
              'ExtUtils::MM_UWIN'     => '6.82',
              'ExtUtils::MM_Unix'     => '6.82',
              'ExtUtils::MM_VMS'      => '6.82',
              'ExtUtils::MM_VOS'      => '6.82',
              'ExtUtils::MM_Win32'    => '6.82',
              'ExtUtils::MM_Win95'    => '6.82',
              'ExtUtils::MY'          => '6.82',
              'ExtUtils::MakeMaker'   => '6.82',
              'ExtUtils::MakeMaker::Config'=> '6.82',
              'ExtUtils::Mkbootstrap' => '6.82',
              'ExtUtils::Mksymlists'  => '6.82',
              'ExtUtils::testlib'     => '6.82',
              'File::DosGlob'         => '1.12',
              'File::Find'            => '1.26',
              'File::Glob'            => '1.23',
              'HTTP::Tiny'            => '0.038',
              'IO'                    => '1.30',
              'IO::Compress::Adapter::Bzip2'=> '2.063',
              'IO::Compress::Adapter::Deflate'=> '2.063',
              'IO::Compress::Adapter::Identity'=> '2.063',
              'IO::Compress::Base'    => '2.063',
              'IO::Compress::Base::Common'=> '2.063',
              'IO::Compress::Bzip2'   => '2.063',
              'IO::Compress::Deflate' => '2.063',
              'IO::Compress::Gzip'    => '2.063',
              'IO::Compress::Gzip::Constants'=> '2.063',
              'IO::Compress::RawDeflate'=> '2.063',
              'IO::Compress::Zip'     => '2.063',
              'IO::Compress::Zip::Constants'=> '2.063',
              'IO::Compress::Zlib::Constants'=> '2.063',
              'IO::Compress::Zlib::Extra'=> '2.063',
              'IO::Select'            => '1.22',
              'IO::Uncompress::Adapter::Bunzip2'=> '2.063',
              'IO::Uncompress::Adapter::Identity'=> '2.063',
              'IO::Uncompress::Adapter::Inflate'=> '2.063',
              'IO::Uncompress::AnyInflate'=> '2.063',
              'IO::Uncompress::AnyUncompress'=> '2.063',
              'IO::Uncompress::Base'  => '2.063',
              'IO::Uncompress::Bunzip2'=> '2.063',
              'IO::Uncompress::Gunzip'=> '2.063',
              'IO::Uncompress::Inflate'=> '2.063',
              'IO::Uncompress::RawInflate'=> '2.063',
              'IO::Uncompress::Unzip' => '2.063',
              'IPC::Cmd'              => '0.90',
              'Locale::Maketext'      => '1.25',
              'Module::Build'         => '0.4202',
              'Module::Build::Base'   => '0.4202',
              'Module::Build::Compat' => '0.4202',
              'Module::Build::Config' => '0.4202',
              'Module::Build::Cookbook'=> '0.4202',
              'Module::Build::Dumper' => '0.4202',
              'Module::Build::ModuleInfo'=> '0.4202',
              'Module::Build::Notes'  => '0.4202',
              'Module::Build::PPMMaker'=> '0.4202',
              'Module::Build::Platform::Default'=> '0.4202',
              'Module::Build::Platform::MacOS'=> '0.4202',
              'Module::Build::Platform::Unix'=> '0.4202',
              'Module::Build::Platform::VMS'=> '0.4202',
              'Module::Build::Platform::VOS'=> '0.4202',
              'Module::Build::Platform::Windows'=> '0.4202',
              'Module::Build::Platform::aix'=> '0.4202',
              'Module::Build::Platform::cygwin'=> '0.4202',
              'Module::Build::Platform::darwin'=> '0.4202',
              'Module::Build::Platform::os2'=> '0.4202',
              'Module::Build::PodParser'=> '0.4202',
              'Module::CoreList'      => '3.01',
              'Module::CoreList::TieHashDelta'=> '3.01',
              'Module::CoreList::Utils'=> '3.01',
              'Opcode'                => '1.27',
              'POSIX'                 => '1.36',
              'Package::Constants'    => '0.04',
              'PerlIO::scalar'        => '0.18',
              'PerlIO::via'           => '0.13',
              'SDBM_File'             => '1.10',
              'Socket'                => '2.013',
              'TAP::Base'             => '3.30',
              'TAP::Formatter::Base'  => '3.30',
              'TAP::Formatter::Color' => '3.30',
              'TAP::Formatter::Console'=> '3.30',
              'TAP::Formatter::Console::ParallelSession'=> '3.30',
              'TAP::Formatter::Console::Session'=> '3.30',
              'TAP::Formatter::File'  => '3.30',
              'TAP::Formatter::File::Session'=> '3.30',
              'TAP::Formatter::Session'=> '3.30',
              'TAP::Harness'          => '3.30',
              'TAP::Harness::Env'     => '3.30',
              'TAP::Object'           => '3.30',
              'TAP::Parser'           => '3.30',
              'TAP::Parser::Aggregator'=> '3.30',
              'TAP::Parser::Grammar'  => '3.30',
              'TAP::Parser::Iterator' => '3.30',
              'TAP::Parser::Iterator::Array'=> '3.30',
              'TAP::Parser::Iterator::Process'=> '3.30',
              'TAP::Parser::Iterator::Stream'=> '3.30',
              'TAP::Parser::IteratorFactory'=> '3.30',
              'TAP::Parser::Multiplexer'=> '3.30',
              'TAP::Parser::Result'   => '3.30',
              'TAP::Parser::Result::Bailout'=> '3.30',
              'TAP::Parser::Result::Comment'=> '3.30',
              'TAP::Parser::Result::Plan'=> '3.30',
              'TAP::Parser::Result::Pragma'=> '3.30',
              'TAP::Parser::Result::Test'=> '3.30',
              'TAP::Parser::Result::Unknown'=> '3.30',
              'TAP::Parser::Result::Version'=> '3.30',
              'TAP::Parser::Result::YAML'=> '3.30',
              'TAP::Parser::ResultFactory'=> '3.30',
              'TAP::Parser::Scheduler'=> '3.30',
              'TAP::Parser::Scheduler::Job'=> '3.30',
              'TAP::Parser::Scheduler::Spinner'=> '3.30',
              'TAP::Parser::Source'   => '3.30',
              'TAP::Parser::SourceHandler'=> '3.30',
              'TAP::Parser::SourceHandler::Executable'=> '3.30',
              'TAP::Parser::SourceHandler::File'=> '3.30',
              'TAP::Parser::SourceHandler::Handle'=> '3.30',
              'TAP::Parser::SourceHandler::Perl'=> '3.30',
              'TAP::Parser::SourceHandler::RawTAP'=> '3.30',
              'TAP::Parser::YAMLish::Reader'=> '3.30',
              'TAP::Parser::YAMLish::Writer'=> '3.30',
              'Term::Cap'             => '1.15',
              'Test::Builder'         => '1.001002',
              'Test::Builder::Module' => '1.001002',
              'Test::Harness'         => '3.30',
              'Test::More'            => '1.001002',
              'Test::Simple'          => '1.001002',
              'Tie::StdHandle'        => '4.4',
              'Unicode::Collate'      => '1.02',
              'Unicode::Collate::CJK::Korean'=> '1.02',
              'Unicode::Collate::Locale'=> '1.02',
              'XS::APItest'           => '0.57',
              'XS::Typemap'           => '0.12',
              'arybase'               => '0.07',
              'bignum'                => '0.37',
              'constant'              => '1.29',
              'fields'                => '2.17',
              'inc::latest'           => '0.4202',
              'threads'               => '1.90',
              'threads::shared'       => '1.45',
          },
          removed => {
          }
      },
      5.019007 => {
          delta_from => 5.019006,
          changed => {
              'CGI'                   => '3.64',
              'CGI::Apache'           => '1.02',
              'CGI::Carp'             => '3.64',
              'CGI::Cookie'           => '1.31',
              'CGI::Fast'             => '1.10',
              'CGI::Pretty'           => '3.64',
              'CGI::Push'             => '1.06',
              'CGI::Switch'           => '1.02',
              'CGI::Util'             => '3.64',
              'CPAN::Meta'            => '2.133380',
              'CPAN::Meta::Converter' => '2.133380',
              'CPAN::Meta::Feature'   => '2.133380',
              'CPAN::Meta::History'   => '2.133380',
              'CPAN::Meta::Prereqs'   => '2.133380',
              'CPAN::Meta::Spec'      => '2.133380',
              'CPAN::Meta::Validator' => '2.133380',
              'Config'                => '5.019007',
              'Data::Dumper'          => '2.150',
              'DynaLoader'            => '1.22',
              'ExtUtils::Command::MM' => '6.84',
              'ExtUtils::Liblist'     => '6.84',
              'ExtUtils::Liblist::Kid'=> '6.84',
              'ExtUtils::MM'          => '6.84',
              'ExtUtils::MM_AIX'      => '6.84',
              'ExtUtils::MM_Any'      => '6.84',
              'ExtUtils::MM_BeOS'     => '6.84',
              'ExtUtils::MM_Cygwin'   => '6.84',
              'ExtUtils::MM_DOS'      => '6.84',
              'ExtUtils::MM_Darwin'   => '6.84',
              'ExtUtils::MM_MacOS'    => '6.84',
              'ExtUtils::MM_NW5'      => '6.84',
              'ExtUtils::MM_OS2'      => '6.84',
              'ExtUtils::MM_QNX'      => '6.84',
              'ExtUtils::MM_UWIN'     => '6.84',
              'ExtUtils::MM_Unix'     => '6.84',
              'ExtUtils::MM_VMS'      => '6.84',
              'ExtUtils::MM_VOS'      => '6.84',
              'ExtUtils::MM_Win32'    => '6.84',
              'ExtUtils::MM_Win95'    => '6.84',
              'ExtUtils::MY'          => '6.84',
              'ExtUtils::MakeMaker'   => '6.84',
              'ExtUtils::MakeMaker::Config'=> '6.84',
              'ExtUtils::Mkbootstrap' => '6.84',
              'ExtUtils::Mksymlists'  => '6.84',
              'ExtUtils::testlib'     => '6.84',
              'File::Fetch'           => '0.46',
              'HTTP::Tiny'            => '0.039',
              'Locale::Codes'         => '3.28',
              'Locale::Codes::Constants'=> '3.28',
              'Locale::Codes::Country'=> '3.28',
              'Locale::Codes::Country_Codes'=> '3.28',
              'Locale::Codes::Country_Retired'=> '3.28',
              'Locale::Codes::Currency'=> '3.28',
              'Locale::Codes::Currency_Codes'=> '3.28',
              'Locale::Codes::Currency_Retired'=> '3.28',
              'Locale::Codes::LangExt'=> '3.28',
              'Locale::Codes::LangExt_Codes'=> '3.28',
              'Locale::Codes::LangExt_Retired'=> '3.28',
              'Locale::Codes::LangFam'=> '3.28',
              'Locale::Codes::LangFam_Codes'=> '3.28',
              'Locale::Codes::LangFam_Retired'=> '3.28',
              'Locale::Codes::LangVar'=> '3.28',
              'Locale::Codes::LangVar_Codes'=> '3.28',
              'Locale::Codes::LangVar_Retired'=> '3.28',
              'Locale::Codes::Language'=> '3.28',
              'Locale::Codes::Language_Codes'=> '3.28',
              'Locale::Codes::Language_Retired'=> '3.28',
              'Locale::Codes::Script' => '3.28',
              'Locale::Codes::Script_Codes'=> '3.28',
              'Locale::Codes::Script_Retired'=> '3.28',
              'Locale::Country'       => '3.28',
              'Locale::Currency'      => '3.28',
              'Locale::Language'      => '3.28',
              'Locale::Script'        => '3.28',
              'Module::Build'         => '0.4203',
              'Module::Build::Base'   => '0.4203',
              'Module::Build::Compat' => '0.4203',
              'Module::Build::Config' => '0.4203',
              'Module::Build::Cookbook'=> '0.4203',
              'Module::Build::Dumper' => '0.4203',
              'Module::Build::ModuleInfo'=> '0.4203',
              'Module::Build::Notes'  => '0.4203',
              'Module::Build::PPMMaker'=> '0.4203',
              'Module::Build::Platform::Default'=> '0.4203',
              'Module::Build::Platform::MacOS'=> '0.4203',
              'Module::Build::Platform::Unix'=> '0.4203',
              'Module::Build::Platform::VMS'=> '0.4203',
              'Module::Build::Platform::VOS'=> '0.4203',
              'Module::Build::Platform::Windows'=> '0.4203',
              'Module::Build::Platform::aix'=> '0.4203',
              'Module::Build::Platform::cygwin'=> '0.4203',
              'Module::Build::Platform::darwin'=> '0.4203',
              'Module::Build::Platform::os2'=> '0.4203',
              'Module::Build::PodParser'=> '0.4203',
              'Module::CoreList'      => '3.02',
              'Module::CoreList::TieHashDelta'=> '3.02',
              'Module::CoreList::Utils'=> '3.02',
              'POSIX'                 => '1.37',
              'PerlIO::encoding'      => '0.17',
              'PerlIO::via'           => '0.14',
              'SDBM_File'             => '1.11',
              'Storable'              => '2.48',
              'Time::Piece'           => '1.24',
              'Time::Seconds'         => '1.24',
              'Unicode::Collate'      => '1.04',
              'Win32'                 => '0.48',
              'XS::APItest'           => '0.58',
              'base'                  => '2.20',
              'constant'              => '1.30',
              'inc::latest'           => '0.4203',
              'threads'               => '1.91',
          },
          removed => {
          }
      },
      5.019008 => {
          delta_from => 5.019007,
          changed => {
              'Config'                => '5.019008',
              'DynaLoader'            => '1.24',
              'Encode'                => '2.57',
              'Errno'                 => '1.20_02',
              'ExtUtils::CBuilder'    => '0.280213',
              'ExtUtils::CBuilder::Base'=> '0.280213',
              'ExtUtils::CBuilder::Platform::Unix'=> '0.280213',
              'ExtUtils::CBuilder::Platform::VMS'=> '0.280213',
              'ExtUtils::CBuilder::Platform::Windows'=> '0.280213',
              'ExtUtils::CBuilder::Platform::Windows::BCC'=> '0.280213',
              'ExtUtils::CBuilder::Platform::Windows::GCC'=> '0.280213',
              'ExtUtils::CBuilder::Platform::Windows::MSVC'=> '0.280213',
              'ExtUtils::CBuilder::Platform::aix'=> '0.280213',
              'ExtUtils::CBuilder::Platform::cygwin'=> '0.280213',
              'ExtUtils::CBuilder::Platform::darwin'=> '0.280213',
              'ExtUtils::CBuilder::Platform::dec_osf'=> '0.280213',
              'ExtUtils::CBuilder::Platform::os2'=> '0.280213',
              'ExtUtils::Command::MM' => '6.86',
              'ExtUtils::Liblist'     => '6.86',
              'ExtUtils::Liblist::Kid'=> '6.86',
              'ExtUtils::MM'          => '6.86',
              'ExtUtils::MM_AIX'      => '6.86',
              'ExtUtils::MM_Any'      => '6.86',
              'ExtUtils::MM_BeOS'     => '6.86',
              'ExtUtils::MM_Cygwin'   => '6.86',
              'ExtUtils::MM_DOS'      => '6.86',
              'ExtUtils::MM_Darwin'   => '6.86',
              'ExtUtils::MM_MacOS'    => '6.86',
              'ExtUtils::MM_NW5'      => '6.86',
              'ExtUtils::MM_OS2'      => '6.86',
              'ExtUtils::MM_QNX'      => '6.86',
              'ExtUtils::MM_UWIN'     => '6.86',
              'ExtUtils::MM_Unix'     => '6.86',
              'ExtUtils::MM_VMS'      => '6.86',
              'ExtUtils::MM_VOS'      => '6.86',
              'ExtUtils::MM_Win32'    => '6.86',
              'ExtUtils::MM_Win95'    => '6.86',
              'ExtUtils::MY'          => '6.86',
              'ExtUtils::MakeMaker'   => '6.86',
              'ExtUtils::MakeMaker::Config'=> '6.86',
              'ExtUtils::Mkbootstrap' => '6.86',
              'ExtUtils::Mksymlists'  => '6.86',
              'ExtUtils::testlib'     => '6.86',
              'File::Copy'            => '2.29',
              'Hash::Util::FieldHash' => '1.14',
              'IO::Socket::IP'        => '0.26',
              'IO::Socket::UNIX'      => '1.26',
              'List::Util'            => '1.36',
              'List::Util::XS'        => '1.36',
              'Module::Build'         => '0.4204',
              'Module::Build::Base'   => '0.4204',
              'Module::Build::Compat' => '0.4204',
              'Module::Build::Config' => '0.4204',
              'Module::Build::Cookbook'=> '0.4204',
              'Module::Build::Dumper' => '0.4204',
              'Module::Build::ModuleInfo'=> '0.4204',
              'Module::Build::Notes'  => '0.4204',
              'Module::Build::PPMMaker'=> '0.4204',
              'Module::Build::Platform::Default'=> '0.4204',
              'Module::Build::Platform::MacOS'=> '0.4204',
              'Module::Build::Platform::Unix'=> '0.4204',
              'Module::Build::Platform::VMS'=> '0.4204',
              'Module::Build::Platform::VOS'=> '0.4204',
              'Module::Build::Platform::Windows'=> '0.4204',
              'Module::Build::Platform::aix'=> '0.4204',
              'Module::Build::Platform::cygwin'=> '0.4204',
              'Module::Build::Platform::darwin'=> '0.4204',
              'Module::Build::Platform::os2'=> '0.4204',
              'Module::Build::PodParser'=> '0.4204',
              'Module::CoreList'      => '3.04',
              'Module::CoreList::TieHashDelta'=> '3.04',
              'Module::CoreList::Utils'=> '3.04',
              'Module::Load'          => '0.28',
              'Module::Load::Conditional'=> '0.60',
              'Net::Config'           => '1.13',
              'Net::FTP::A'           => '1.19',
              'POSIX'                 => '1.38_01',
              'Perl::OSType'          => '1.007',
              'PerlIO::encoding'      => '0.18',
              'Pod::Perldoc'          => '3.21',
              'Pod::Perldoc::BaseTo'  => '3.21',
              'Pod::Perldoc::GetOptsOO'=> '3.21',
              'Pod::Perldoc::ToANSI'  => '3.21',
              'Pod::Perldoc::ToChecker'=> '3.21',
              'Pod::Perldoc::ToMan'   => '3.21',
              'Pod::Perldoc::ToNroff' => '3.21',
              'Pod::Perldoc::ToPod'   => '3.21',
              'Pod::Perldoc::ToRtf'   => '3.21',
              'Pod::Perldoc::ToTerm'  => '3.21',
              'Pod::Perldoc::ToText'  => '3.21',
              'Pod::Perldoc::ToTk'    => '3.21',
              'Pod::Perldoc::ToXml'   => '3.21',
              'Scalar::Util'          => '1.36',
              'Time::Piece'           => '1.27',
              'Time::Seconds'         => '1.27',
              'Unicode::UCD'          => '0.57',
              'XS::APItest'           => '0.59',
              'XSLoader'              => '0.17',
              'base'                  => '2.21',
              'constant'              => '1.31',
              'inc::latest'           => '0.4204',
              'threads::shared'       => '1.46',
              'version'               => '0.9907',
              'version::regex'        => '0.9907',
              'version::vpp'          => '0.9907',
              'warnings'              => '1.21',
          },
          removed => {
          }
      },
      5.019009 => {
          delta_from => 5.019008,
          changed => {
              'B'                     => '1.48',
              'B::Concise'            => '0.992',
              'B::Deparse'            => '1.25',
              'CGI'                   => '3.65',
              'CPAN::Meta::YAML'      => '0.011',
              'Compress::Raw::Bzip2'  => '2.064',
              'Compress::Raw::Zlib'   => '2.065',
              'Compress::Zlib'        => '2.064',
              'Config'                => '5.019009',
              'Config::Perl::V'       => '0.20',
              'Cwd'                   => '3.47',
              'Devel::Peek'           => '1.16',
              'Digest::SHA'           => '5.87',
              'DynaLoader'            => '1.25',
              'English'               => '1.09',
              'ExtUtils::CBuilder'    => '0.280216',
              'ExtUtils::CBuilder::Base'=> '0.280216',
              'ExtUtils::CBuilder::Platform::Unix'=> '0.280216',
              'ExtUtils::CBuilder::Platform::VMS'=> '0.280216',
              'ExtUtils::CBuilder::Platform::Windows'=> '0.280216',
              'ExtUtils::CBuilder::Platform::Windows::BCC'=> '0.280216',
              'ExtUtils::CBuilder::Platform::Windows::GCC'=> '0.280216',
              'ExtUtils::CBuilder::Platform::Windows::MSVC'=> '0.280216',
              'ExtUtils::CBuilder::Platform::aix'=> '0.280216',
              'ExtUtils::CBuilder::Platform::android'=> '0.280216',
              'ExtUtils::CBuilder::Platform::cygwin'=> '0.280216',
              'ExtUtils::CBuilder::Platform::darwin'=> '0.280216',
              'ExtUtils::CBuilder::Platform::dec_osf'=> '0.280216',
              'ExtUtils::CBuilder::Platform::os2'=> '0.280216',
              'ExtUtils::Command::MM' => '6.88',
              'ExtUtils::Embed'       => '1.32',
              'ExtUtils::Install'     => '1.62',
              'ExtUtils::Installed'   => '1.999004',
              'ExtUtils::Liblist'     => '6.88',
              'ExtUtils::Liblist::Kid'=> '6.88',
              'ExtUtils::MM'          => '6.88',
              'ExtUtils::MM_AIX'      => '6.88',
              'ExtUtils::MM_Any'      => '6.88',
              'ExtUtils::MM_BeOS'     => '6.88',
              'ExtUtils::MM_Cygwin'   => '6.88',
              'ExtUtils::MM_DOS'      => '6.88',
              'ExtUtils::MM_Darwin'   => '6.88',
              'ExtUtils::MM_MacOS'    => '6.88',
              'ExtUtils::MM_NW5'      => '6.88',
              'ExtUtils::MM_OS2'      => '6.88',
              'ExtUtils::MM_QNX'      => '6.88',
              'ExtUtils::MM_UWIN'     => '6.88',
              'ExtUtils::MM_Unix'     => '6.88',
              'ExtUtils::MM_VMS'      => '6.88',
              'ExtUtils::MM_VOS'      => '6.88',
              'ExtUtils::MM_Win32'    => '6.88',
              'ExtUtils::MM_Win95'    => '6.88',
              'ExtUtils::MY'          => '6.88',
              'ExtUtils::MakeMaker'   => '6.88',
              'ExtUtils::MakeMaker::Config'=> '6.88',
              'ExtUtils::Mkbootstrap' => '6.88',
              'ExtUtils::Mksymlists'  => '6.88',
              'ExtUtils::Packlist'    => '1.47',
              'ExtUtils::testlib'     => '6.88',
              'Fatal'                 => '2.23',
              'File::Fetch'           => '0.48',
              'File::Spec'            => '3.47',
              'File::Spec::Cygwin'    => '3.47',
              'File::Spec::Epoc'      => '3.47',
              'File::Spec::Functions' => '3.47',
              'File::Spec::Mac'       => '3.47',
              'File::Spec::OS2'       => '3.47',
              'File::Spec::Unix'      => '3.47',
              'File::Spec::VMS'       => '3.47',
              'File::Spec::Win32'     => '3.47',
              'HTTP::Tiny'            => '0.042',
              'IO::Compress::Adapter::Bzip2'=> '2.064',
              'IO::Compress::Adapter::Deflate'=> '2.064',
              'IO::Compress::Adapter::Identity'=> '2.064',
              'IO::Compress::Base'    => '2.064',
              'IO::Compress::Base::Common'=> '2.064',
              'IO::Compress::Bzip2'   => '2.064',
              'IO::Compress::Deflate' => '2.064',
              'IO::Compress::Gzip'    => '2.064',
              'IO::Compress::Gzip::Constants'=> '2.064',
              'IO::Compress::RawDeflate'=> '2.064',
              'IO::Compress::Zip'     => '2.064',
              'IO::Compress::Zip::Constants'=> '2.064',
              'IO::Compress::Zlib::Constants'=> '2.064',
              'IO::Compress::Zlib::Extra'=> '2.064',
              'IO::Socket::INET'      => '1.35',
              'IO::Socket::IP'        => '0.28',
              'IO::Uncompress::Adapter::Bunzip2'=> '2.064',
              'IO::Uncompress::Adapter::Identity'=> '2.064',
              'IO::Uncompress::Adapter::Inflate'=> '2.064',
              'IO::Uncompress::AnyInflate'=> '2.064',
              'IO::Uncompress::AnyUncompress'=> '2.064',
              'IO::Uncompress::Base'  => '2.064',
              'IO::Uncompress::Bunzip2'=> '2.064',
              'IO::Uncompress::Gunzip'=> '2.064',
              'IO::Uncompress::Inflate'=> '2.064',
              'IO::Uncompress::RawInflate'=> '2.064',
              'IO::Uncompress::Unzip' => '2.064',
              'IPC::Cmd'              => '0.92',
              'List::Util'            => '1.38',
              'List::Util::XS'        => '1.38',
              'Locale::Codes'         => '3.29',
              'Locale::Codes::Constants'=> '3.29',
              'Locale::Codes::Country'=> '3.29',
              'Locale::Codes::Country_Codes'=> '3.29',
              'Locale::Codes::Country_Retired'=> '3.29',
              'Locale::Codes::Currency'=> '3.29',
              'Locale::Codes::Currency_Codes'=> '3.29',
              'Locale::Codes::Currency_Retired'=> '3.29',
              'Locale::Codes::LangExt'=> '3.29',
              'Locale::Codes::LangExt_Codes'=> '3.29',
              'Locale::Codes::LangExt_Retired'=> '3.29',
              'Locale::Codes::LangFam'=> '3.29',
              'Locale::Codes::LangFam_Codes'=> '3.29',
              'Locale::Codes::LangFam_Retired'=> '3.29',
              'Locale::Codes::LangVar'=> '3.29',
              'Locale::Codes::LangVar_Codes'=> '3.29',
              'Locale::Codes::LangVar_Retired'=> '3.29',
              'Locale::Codes::Language'=> '3.29',
              'Locale::Codes::Language_Codes'=> '3.29',
              'Locale::Codes::Language_Retired'=> '3.29',
              'Locale::Codes::Script' => '3.29',
              'Locale::Codes::Script_Codes'=> '3.29',
              'Locale::Codes::Script_Retired'=> '3.29',
              'Locale::Country'       => '3.29',
              'Locale::Currency'      => '3.29',
              'Locale::Language'      => '3.29',
              'Locale::Script'        => '3.29',
              'Module::Build'         => '0.4205',
              'Module::Build::Base'   => '0.4205',
              'Module::Build::Compat' => '0.4205',
              'Module::Build::Config' => '0.4205',
              'Module::Build::Cookbook'=> '0.4205',
              'Module::Build::Dumper' => '0.4205',
              'Module::Build::ModuleInfo'=> '0.4205',
              'Module::Build::Notes'  => '0.4205',
              'Module::Build::PPMMaker'=> '0.4205',
              'Module::Build::Platform::Default'=> '0.4205',
              'Module::Build::Platform::MacOS'=> '0.4205',
              'Module::Build::Platform::Unix'=> '0.4205',
              'Module::Build::Platform::VMS'=> '0.4205',
              'Module::Build::Platform::VOS'=> '0.4205',
              'Module::Build::Platform::Windows'=> '0.4205',
              'Module::Build::Platform::aix'=> '0.4205',
              'Module::Build::Platform::cygwin'=> '0.4205',
              'Module::Build::Platform::darwin'=> '0.4205',
              'Module::Build::Platform::os2'=> '0.4205',
              'Module::Build::PodParser'=> '0.4205',
              'Module::CoreList'      => '3.06',
              'Module::CoreList::TieHashDelta'=> '3.06',
              'Module::CoreList::Utils'=> '3.06',
              'Module::Load'          => '0.30',
              'Module::Load::Conditional'=> '0.62',
              'Net::Domain'           => '2.23',
              'Net::FTP'              => '2.79',
              'Net::NNTP'             => '2.26',
              'Net::POP3'             => '2.31',
              'Net::Ping'             => '2.43',
              'Net::SMTP'             => '2.33',
              'POSIX'                 => '1.38_02',
              'Parse::CPAN::Meta'     => '1.4413',
              'Pod::Escapes'          => '1.06',
              'Pod::Find'             => '1.62',
              'Pod::InputObjects'     => '1.62',
              'Pod::ParseUtils'       => '1.62',
              'Pod::Parser'           => '1.62',
              'Pod::Select'           => '1.62',
              'Scalar::Util'          => '1.38',
              'autodie'               => '2.23',
              'autodie::exception'    => '2.23',
              'autodie::exception::system'=> '2.23',
              'autodie::hints'        => '2.23',
              'autodie::skip'         => '2.23',
              'diagnostics'           => '1.34',
              'feature'               => '1.35',
              'inc::latest'           => '0.4205',
              'locale'                => '1.03',
              'mro'                   => '1.15',
              'threads'               => '1.92',
              'version'               => '0.9908',
              'version::regex'        => '0.9908',
              'version::vpp'          => '0.9908',
              'warnings'              => '1.22',
          },
          removed => {
          }
      },
      5.01901 => {
          delta_from => 5.019009,
          changed => {
              'App::Cpan'             => '1.62',
              'Attribute::Handlers'   => '0.96',
              'B::Deparse'            => '1.26',
              'CPAN'                  => '2.04',
              'CPAN::Bundle'          => '5.5001',
              'CPAN::Complete'        => '5.5001',
              'CPAN::Distribution'    => '2.01',
              'CPAN::Distroprefs'     => '6.0001',
              'CPAN::FirstTime'       => '5.5305',
              'CPAN::Meta'            => '2.140640',
              'CPAN::Meta::Converter' => '2.140640',
              'CPAN::Meta::Feature'   => '2.140640',
              'CPAN::Meta::History'   => '2.140640',
              'CPAN::Meta::Prereqs'   => '2.140640',
              'CPAN::Meta::Spec'      => '2.140640',
              'CPAN::Meta::Validator' => '2.140640',
              'CPAN::Meta::YAML'      => '0.012',
              'CPAN::Queue'           => '5.5002',
              'CPAN::Shell'           => '5.5003',
              'CPAN::Tarzip'          => '5.5012',
              'CPAN::Version'         => '5.5003',
              'Carp'                  => '1.33',
              'Carp::Heavy'           => '1.33',
              'Config'                => '5.019010',
              'Data::Dumper'          => '2.151',
              'Devel::PPPort'         => '3.22',
              'Digest::SHA'           => '5.88',
              'ExtUtils::Command::MM' => '6.92',
              'ExtUtils::Install'     => '1.63',
              'ExtUtils::Installed'   => '1.999005',
              'ExtUtils::Liblist'     => '6.92',
              'ExtUtils::Liblist::Kid'=> '6.92',
              'ExtUtils::MM'          => '6.92',
              'ExtUtils::MM_AIX'      => '6.92',
              'ExtUtils::MM_Any'      => '6.92',
              'ExtUtils::MM_BeOS'     => '6.92',
              'ExtUtils::MM_Cygwin'   => '6.92',
              'ExtUtils::MM_DOS'      => '6.92',
              'ExtUtils::MM_Darwin'   => '6.92',
              'ExtUtils::MM_MacOS'    => '6.92',
              'ExtUtils::MM_NW5'      => '6.92',
              'ExtUtils::MM_OS2'      => '6.92',
              'ExtUtils::MM_QNX'      => '6.92',
              'ExtUtils::MM_UWIN'     => '6.92',
              'ExtUtils::MM_Unix'     => '6.92',
              'ExtUtils::MM_VMS'      => '6.92',
              'ExtUtils::MM_VOS'      => '6.92',
              'ExtUtils::MM_Win32'    => '6.92',
              'ExtUtils::MM_Win95'    => '6.92',
              'ExtUtils::MY'          => '6.92',
              'ExtUtils::MakeMaker'   => '6.92',
              'ExtUtils::MakeMaker::Config'=> '6.92',
              'ExtUtils::Mkbootstrap' => '6.92',
              'ExtUtils::Mksymlists'  => '6.92',
              'ExtUtils::Packlist'    => '1.48',
              'ExtUtils::ParseXS'     => '3.24',
              'ExtUtils::ParseXS::Constants'=> '3.24',
              'ExtUtils::ParseXS::CountLines'=> '3.24',
              'ExtUtils::ParseXS::Eval'=> '3.24',
              'ExtUtils::ParseXS::Utilities'=> '3.24',
              'ExtUtils::Typemaps'    => '3.24',
              'ExtUtils::Typemaps::Cmd'=> '3.24',
              'ExtUtils::Typemaps::InputMap'=> '3.24',
              'ExtUtils::Typemaps::OutputMap'=> '3.24',
              'ExtUtils::Typemaps::Type'=> '3.24',
              'ExtUtils::testlib'     => '6.92',
              'File::Find'            => '1.27',
              'Filter::Simple'        => '0.91',
              'HTTP::Tiny'            => '0.043',
              'Hash::Util::FieldHash' => '1.15',
              'IO'                    => '1.31',
              'IO::Socket::IP'        => '0.29',
              'Locale::Codes'         => '3.30',
              'Locale::Codes::Constants'=> '3.30',
              'Locale::Codes::Country'=> '3.30',
              'Locale::Codes::Country_Codes'=> '3.30',
              'Locale::Codes::Country_Retired'=> '3.30',
              'Locale::Codes::Currency'=> '3.30',
              'Locale::Codes::Currency_Codes'=> '3.30',
              'Locale::Codes::Currency_Retired'=> '3.30',
              'Locale::Codes::LangExt'=> '3.30',
              'Locale::Codes::LangExt_Codes'=> '3.30',
              'Locale::Codes::LangExt_Retired'=> '3.30',
              'Locale::Codes::LangFam'=> '3.30',
              'Locale::Codes::LangFam_Codes'=> '3.30',
              'Locale::Codes::LangFam_Retired'=> '3.30',
              'Locale::Codes::LangVar'=> '3.30',
              'Locale::Codes::LangVar_Codes'=> '3.30',
              'Locale::Codes::LangVar_Retired'=> '3.30',
              'Locale::Codes::Language'=> '3.30',
              'Locale::Codes::Language_Codes'=> '3.30',
              'Locale::Codes::Language_Retired'=> '3.30',
              'Locale::Codes::Script' => '3.30',
              'Locale::Codes::Script_Codes'=> '3.30',
              'Locale::Codes::Script_Retired'=> '3.30',
              'Locale::Country'       => '3.30',
              'Locale::Currency'      => '3.30',
              'Locale::Language'      => '3.30',
              'Locale::Script'        => '3.30',
              'Module::CoreList'      => '3.09',
              'Module::CoreList::TieHashDelta'=> '3.09',
              'Module::CoreList::Utils'=> '3.09',
              'Module::Load'          => '0.32',
              'POSIX'                 => '1.38_03',
              'Parse::CPAN::Meta'     => '1.4414',
              'Pod::Perldoc'          => '3.23',
              'Pod::Perldoc::BaseTo'  => '3.23',
              'Pod::Perldoc::GetOptsOO'=> '3.23',
              'Pod::Perldoc::ToANSI'  => '3.23',
              'Pod::Perldoc::ToChecker'=> '3.23',
              'Pod::Perldoc::ToMan'   => '3.23',
              'Pod::Perldoc::ToNroff' => '3.23',
              'Pod::Perldoc::ToPod'   => '3.23',
              'Pod::Perldoc::ToRtf'   => '3.23',
              'Pod::Perldoc::ToTerm'  => '3.23',
              'Pod::Perldoc::ToText'  => '3.23',
              'Pod::Perldoc::ToTk'    => '3.23',
              'Pod::Perldoc::ToXml'   => '3.23',
              'Thread::Queue'         => '3.05',
              'XS::APItest'           => '0.60',
              'XS::Typemap'           => '0.13',
              'autouse'               => '1.08',
              'base'                  => '2.22',
              'charnames'             => '1.40',
              'feature'               => '1.36',
              'mro'                   => '1.16',
              'threads'               => '1.93',
              'warnings'              => '1.23',
              'warnings::register'    => '1.03',
          },
          removed => {
          }
      },
      5.019011 => {
          delta_from => 5.01901,
          changed => {
              'CPAN'                  => '2.05',
              'CPAN::Distribution'    => '2.02',
              'CPAN::FirstTime'       => '5.5306',
              'CPAN::Shell'           => '5.5004',
              'Carp'                  => '1.3301',
              'Carp::Heavy'           => '1.3301',
              'Config'                => '5.019011',
              'ExtUtils::Command::MM' => '6.94',
              'ExtUtils::Install'     => '1.67',
              'ExtUtils::Liblist'     => '6.94',
              'ExtUtils::Liblist::Kid'=> '6.94',
              'ExtUtils::MM'          => '6.94',
              'ExtUtils::MM_AIX'      => '6.94',
              'ExtUtils::MM_Any'      => '6.94',
              'ExtUtils::MM_BeOS'     => '6.94',
              'ExtUtils::MM_Cygwin'   => '6.94',
              'ExtUtils::MM_DOS'      => '6.94',
              'ExtUtils::MM_Darwin'   => '6.94',
              'ExtUtils::MM_MacOS'    => '6.94',
              'ExtUtils::MM_NW5'      => '6.94',
              'ExtUtils::MM_OS2'      => '6.94',
              'ExtUtils::MM_QNX'      => '6.94',
              'ExtUtils::MM_UWIN'     => '6.94',
              'ExtUtils::MM_Unix'     => '6.94',
              'ExtUtils::MM_VMS'      => '6.94',
              'ExtUtils::MM_VOS'      => '6.94',
              'ExtUtils::MM_Win32'    => '6.94',
              'ExtUtils::MM_Win95'    => '6.94',
              'ExtUtils::MY'          => '6.94',
              'ExtUtils::MakeMaker'   => '6.94',
              'ExtUtils::MakeMaker::Config'=> '6.94',
              'ExtUtils::Mkbootstrap' => '6.94',
              'ExtUtils::Mksymlists'  => '6.94',
              'ExtUtils::testlib'     => '6.94',
              'Module::CoreList'      => '3.10',
              'Module::CoreList::TieHashDelta'=> '3.10',
              'Module::CoreList::Utils'=> '3.10',
              'PerlIO'                => '1.09',
              'Storable'              => '2.49',
              'Win32'                 => '0.49',
              'experimental'          => '0.007',
          },
          removed => {
          }
      },
      5.020000 => {
          delta_from => 5.019011,
          changed => {
              'Config'                => '5.02',
              'Devel::PPPort'         => '3.21',
              'Encode'                => '2.60',
              'Errno'                 => '1.20_03',
              'ExtUtils::Command::MM' => '6.98',
              'ExtUtils::Liblist'     => '6.98',
              'ExtUtils::Liblist::Kid'=> '6.98',
              'ExtUtils::MM'          => '6.98',
              'ExtUtils::MM_AIX'      => '6.98',
              'ExtUtils::MM_Any'      => '6.98',
              'ExtUtils::MM_BeOS'     => '6.98',
              'ExtUtils::MM_Cygwin'   => '6.98',
              'ExtUtils::MM_DOS'      => '6.98',
              'ExtUtils::MM_Darwin'   => '6.98',
              'ExtUtils::MM_MacOS'    => '6.98',
              'ExtUtils::MM_NW5'      => '6.98',
              'ExtUtils::MM_OS2'      => '6.98',
              'ExtUtils::MM_QNX'      => '6.98',
              'ExtUtils::MM_UWIN'     => '6.98',
              'ExtUtils::MM_Unix'     => '6.98',
              'ExtUtils::MM_VMS'      => '6.98',
              'ExtUtils::MM_VOS'      => '6.98',
              'ExtUtils::MM_Win32'    => '6.98',
              'ExtUtils::MM_Win95'    => '6.98',
              'ExtUtils::MY'          => '6.98',
              'ExtUtils::MakeMaker'   => '6.98',
              'ExtUtils::MakeMaker::Config'=> '6.98',
              'ExtUtils::Miniperl'    => '1.01',
              'ExtUtils::Mkbootstrap' => '6.98',
              'ExtUtils::Mksymlists'  => '6.98',
              'ExtUtils::testlib'     => '6.98',
              'Pod::Functions::Functions'=> '1.08',
          },
          removed => {
          }
      },
      5.021000 => {
          delta_from => 5.020000,
          changed => {
              'Module::CoreList'      => '5.021001',
              'Module::CoreList::TieHashDelta'=> '5.021001',
              'Module::CoreList::Utils'=> '5.021001',
              'feature'               => '1.37',
          },
          removed => {
              'CGI'                   => 1,
              'CGI::Apache'           => 1,
              'CGI::Carp'             => 1,
              'CGI::Cookie'           => 1,
              'CGI::Fast'             => 1,
              'CGI::Pretty'           => 1,
              'CGI::Push'             => 1,
              'CGI::Switch'           => 1,
              'CGI::Util'             => 1,
              'Module::Build'         => 1,
              'Module::Build::Base'   => 1,
              'Module::Build::Compat' => 1,
              'Module::Build::Config' => 1,
              'Module::Build::ConfigData'=> 1,
              'Module::Build::Cookbook'=> 1,
              'Module::Build::Dumper' => 1,
              'Module::Build::ModuleInfo'=> 1,
              'Module::Build::Notes'  => 1,
              'Module::Build::PPMMaker'=> 1,
              'Module::Build::Platform::Default'=> 1,
              'Module::Build::Platform::MacOS'=> 1,
              'Module::Build::Platform::Unix'=> 1,
              'Module::Build::Platform::VMS'=> 1,
              'Module::Build::Platform::VOS'=> 1,
              'Module::Build::Platform::Windows'=> 1,
              'Module::Build::Platform::aix'=> 1,
              'Module::Build::Platform::cygwin'=> 1,
              'Module::Build::Platform::darwin'=> 1,
              'Module::Build::Platform::os2'=> 1,
              'Module::Build::PodParser'=> 1,
              'Module::Build::Version'=> 1,
              'Module::Build::YAML'   => 1,
              'Package::Constants'    => 1,
              'Simple'                => 1,
              'inc::latest'           => 1,
          }
      },
      5.021001 => {
          delta_from => 5.021000,
          changed => {
              'App::Prove'            => '3.32',
              'App::Prove::State'     => '3.32',
              'App::Prove::State::Result'=> '3.32',
              'App::Prove::State::Result::Test'=> '3.32',
              'Archive::Tar'          => '2.00',
              'Archive::Tar::Constant'=> '2.00',
              'Archive::Tar::File'    => '2.00',
              'B'                     => '1.49',
              'B::Deparse'            => '1.27',
              'Benchmark'             => '1.19',
              'CPAN::Meta'            => '2.141520',
              'CPAN::Meta::Converter' => '2.141520',
              'CPAN::Meta::Feature'   => '2.141520',
              'CPAN::Meta::History'   => '2.141520',
              'CPAN::Meta::Prereqs'   => '2.141520',
              'CPAN::Meta::Spec'      => '2.141520',
              'CPAN::Meta::Validator' => '2.141520',
              'Carp'                  => '1.34',
              'Carp::Heavy'           => '1.34',
              'Config'                => '5.021001',
              'Cwd'                   => '3.48',
              'Data::Dumper'          => '2.152',
              'Devel::PPPort'         => '3.24',
              'Devel::Peek'           => '1.17',
              'Digest::SHA'           => '5.92',
              'DynaLoader'            => '1.26',
              'Encode'                => '2.62',
              'Errno'                 => '1.20_04',
              'Exporter'              => '5.71',
              'Exporter::Heavy'       => '5.71',
              'ExtUtils::Install'     => '1.68',
              'ExtUtils::Miniperl'    => '1.02',
              'ExtUtils::ParseXS'     => '3.25',
              'ExtUtils::ParseXS::Constants'=> '3.25',
              'ExtUtils::ParseXS::CountLines'=> '3.25',
              'ExtUtils::ParseXS::Eval'=> '3.25',
              'ExtUtils::ParseXS::Utilities'=> '3.25',
              'ExtUtils::Typemaps'    => '3.25',
              'ExtUtils::Typemaps::Cmd'=> '3.25',
              'ExtUtils::Typemaps::InputMap'=> '3.25',
              'ExtUtils::Typemaps::OutputMap'=> '3.25',
              'ExtUtils::Typemaps::Type'=> '3.25',
              'Fatal'                 => '2.25',
              'File::Spec'            => '3.48',
              'File::Spec::Cygwin'    => '3.48',
              'File::Spec::Epoc'      => '3.48',
              'File::Spec::Functions' => '3.48',
              'File::Spec::Mac'       => '3.48',
              'File::Spec::OS2'       => '3.48',
              'File::Spec::Unix'      => '3.48',
              'File::Spec::VMS'       => '3.48',
              'File::Spec::Win32'     => '3.48',
              'Hash::Util'            => '0.17',
              'IO'                    => '1.32',
              'List::Util'            => '1.39',
              'List::Util::XS'        => '1.39',
              'Locale::Codes'         => '3.31',
              'Locale::Codes::Constants'=> '3.31',
              'Locale::Codes::Country'=> '3.31',
              'Locale::Codes::Country_Codes'=> '3.31',
              'Locale::Codes::Country_Retired'=> '3.31',
              'Locale::Codes::Currency'=> '3.31',
              'Locale::Codes::Currency_Codes'=> '3.31',
              'Locale::Codes::Currency_Retired'=> '3.31',
              'Locale::Codes::LangExt'=> '3.31',
              'Locale::Codes::LangExt_Codes'=> '3.31',
              'Locale::Codes::LangExt_Retired'=> '3.31',
              'Locale::Codes::LangFam'=> '3.31',
              'Locale::Codes::LangFam_Codes'=> '3.31',
              'Locale::Codes::LangFam_Retired'=> '3.31',
              'Locale::Codes::LangVar'=> '3.31',
              'Locale::Codes::LangVar_Codes'=> '3.31',
              'Locale::Codes::LangVar_Retired'=> '3.31',
              'Locale::Codes::Language'=> '3.31',
              'Locale::Codes::Language_Codes'=> '3.31',
              'Locale::Codes::Language_Retired'=> '3.31',
              'Locale::Codes::Script' => '3.31',
              'Locale::Codes::Script_Codes'=> '3.31',
              'Locale::Codes::Script_Retired'=> '3.31',
              'Locale::Country'       => '3.31',
              'Locale::Currency'      => '3.31',
              'Locale::Language'      => '3.31',
              'Locale::Script'        => '3.31',
              'Math::BigFloat'        => '1.9994',
              'Math::BigInt'          => '1.9995',
              'Math::BigInt::Calc'    => '1.9994',
              'Math::BigInt::CalcEmu' => '1.9994',
              'Math::BigRat'          => '0.2608',
              'Module::CoreList'      => '5.021001_01',
              'Module::CoreList::TieHashDelta'=> '5.021001_01',
              'Module::CoreList::Utils'=> '5.021001_01',
              'Module::Metadata'      => '1.000024',
              'Module::Metadata::corpus::BOMTest::UTF16BE'=> undef,
              'Module::Metadata::corpus::BOMTest::UTF16LE'=> undef,
              'Module::Metadata::corpus::BOMTest::UTF8'=> '1',
              'NDBM_File'             => '1.13',
              'Net::Config'           => '1.14',
              'Net::SMTP'             => '2.34',
              'Net::Time'             => '2.11',
              'OS2::Process'          => '1.10',
              'POSIX'                 => '1.40',
              'PerlIO::encoding'      => '0.19',
              'PerlIO::mmap'          => '0.013',
              'PerlIO::scalar'        => '0.19',
              'PerlIO::via'           => '0.15',
              'Pod::Html'             => '1.22',
              'Scalar::Util'          => '1.39',
              'SelfLoader'            => '1.22',
              'Socket'                => '2.014',
              'Storable'              => '2.51',
              'TAP::Base'             => '3.32',
              'TAP::Formatter::Base'  => '3.32',
              'TAP::Formatter::Color' => '3.32',
              'TAP::Formatter::Console'=> '3.32',
              'TAP::Formatter::Console::ParallelSession'=> '3.32',
              'TAP::Formatter::Console::Session'=> '3.32',
              'TAP::Formatter::File'  => '3.32',
              'TAP::Formatter::File::Session'=> '3.32',
              'TAP::Formatter::Session'=> '3.32',
              'TAP::Harness'          => '3.32',
              'TAP::Harness::Env'     => '3.32',
              'TAP::Object'           => '3.32',
              'TAP::Parser'           => '3.32',
              'TAP::Parser::Aggregator'=> '3.32',
              'TAP::Parser::Grammar'  => '3.32',
              'TAP::Parser::Iterator' => '3.32',
              'TAP::Parser::Iterator::Array'=> '3.32',
              'TAP::Parser::Iterator::Process'=> '3.32',
              'TAP::Parser::Iterator::Stream'=> '3.32',
              'TAP::Parser::IteratorFactory'=> '3.32',
              'TAP::Parser::Multiplexer'=> '3.32',
              'TAP::Parser::Result'   => '3.32',
              'TAP::Parser::Result::Bailout'=> '3.32',
              'TAP::Parser::Result::Comment'=> '3.32',
              'TAP::Parser::Result::Plan'=> '3.32',
              'TAP::Parser::Result::Pragma'=> '3.32',
              'TAP::Parser::Result::Test'=> '3.32',
              'TAP::Parser::Result::Unknown'=> '3.32',
              'TAP::Parser::Result::Version'=> '3.32',
              'TAP::Parser::Result::YAML'=> '3.32',
              'TAP::Parser::ResultFactory'=> '3.32',
              'TAP::Parser::Scheduler'=> '3.32',
              'TAP::Parser::Scheduler::Job'=> '3.32',
              'TAP::Parser::Scheduler::Spinner'=> '3.32',
              'TAP::Parser::Source'   => '3.32',
              'TAP::Parser::SourceHandler'=> '3.32',
              'TAP::Parser::SourceHandler::Executable'=> '3.32',
              'TAP::Parser::SourceHandler::File'=> '3.32',
              'TAP::Parser::SourceHandler::Handle'=> '3.32',
              'TAP::Parser::SourceHandler::Perl'=> '3.32',
              'TAP::Parser::SourceHandler::RawTAP'=> '3.32',
              'TAP::Parser::YAMLish::Reader'=> '3.32',
              'TAP::Parser::YAMLish::Writer'=> '3.32',
              'Term::ANSIColor'       => '4.03',
              'Test::Builder'         => '1.001003',
              'Test::Builder::Module' => '1.001003',
              'Test::Builder::Tester' => '1.23_003',
              'Test::Harness'         => '3.32',
              'Test::More'            => '1.001003',
              'Test::Simple'          => '1.001003',
              'Tie::File'             => '1.01',
              'Unicode'               => '7.0.0',
              'Unicode::Collate'      => '1.07',
              'Unicode::Normalize'    => '1.18',
              'Unicode::UCD'          => '0.58',
              'XS::APItest'           => '0.61',
              '_charnames'            => '1.41',
              'autodie'               => '2.25',
              'autodie::Scope::Guard' => '2.25',
              'autodie::Scope::GuardStack'=> '2.25',
              'autodie::ScopeUtil'    => '2.25',
              'autodie::exception'    => '2.25',
              'autodie::exception::system'=> '2.25',
              'autodie::hints'        => '2.25',
              'autodie::skip'         => '2.25',
              'charnames'             => '1.41',
              'locale'                => '1.04',
              'threads'               => '1.94',
              'utf8'                  => '1.14',
              'warnings'              => '1.24',
          },
          removed => {
          }
      },
      5.021002 => {
          delta_from => 5.021001,
          changed => {
              'B'                     => '1.50',
              'Config'                => '5.021002',
              'Cwd'                   => '3.49',
              'Devel::Peek'           => '1.18',
              'ExtUtils::Manifest'    => '1.64',
              'File::Copy'            => '2.30',
              'File::Spec'            => '3.49',
              'File::Spec::Cygwin'    => '3.49',
              'File::Spec::Epoc'      => '3.49',
              'File::Spec::Functions' => '3.49',
              'File::Spec::Mac'       => '3.49',
              'File::Spec::OS2'       => '3.49',
              'File::Spec::Unix'      => '3.49',
              'File::Spec::VMS'       => '3.49',
              'File::Spec::Win32'     => '3.49',
              'Filter::Simple'        => '0.92',
              'Hash::Util'            => '0.18',
              'IO'                    => '1.33',
              'IO::Socket::IP'        => '0.31',
              'IPC::Open3'            => '1.17',
              'Math::BigFloat'        => '1.9996',
              'Math::BigInt'          => '1.9996',
              'Math::BigInt::Calc'    => '1.9996',
              'Math::BigInt::CalcEmu' => '1.9996',
              'Module::CoreList'      => '5.021002',
              'Module::CoreList::TieHashDelta'=> '5.021002',
              'Module::CoreList::Utils'=> '5.021002',
              'POSIX'                 => '1.41',
              'Pod::Usage'            => '1.64',
              'XS::APItest'           => '0.62',
              'arybase'               => '0.08',
              'experimental'          => '0.008',
              'threads'               => '1.95',
              'warnings'              => '1.26',
          },
          removed => {
          }
      },
      5.021003 => {
          delta_from => 5.021002,
          changed => {
              'B::Debug'              => '1.21',
              'CPAN::Meta'            => '2.142060',
              'CPAN::Meta::Converter' => '2.142060',
              'CPAN::Meta::Feature'   => '2.142060',
              'CPAN::Meta::History'   => '2.142060',
              'CPAN::Meta::Merge'     => '2.142060',
              'CPAN::Meta::Prereqs'   => '2.142060',
              'CPAN::Meta::Requirements'=> '2.126',
              'CPAN::Meta::Spec'      => '2.142060',
              'CPAN::Meta::Validator' => '2.142060',
              'Config'                => '5.021003',
              'Config::Perl::V'       => '0.22',
              'ExtUtils::CBuilder'    => '0.280217',
              'ExtUtils::CBuilder::Base'=> '0.280217',
              'ExtUtils::CBuilder::Platform::Unix'=> '0.280217',
              'ExtUtils::CBuilder::Platform::VMS'=> '0.280217',
              'ExtUtils::CBuilder::Platform::Windows'=> '0.280217',
              'ExtUtils::CBuilder::Platform::Windows::BCC'=> '0.280217',
              'ExtUtils::CBuilder::Platform::Windows::GCC'=> '0.280217',
              'ExtUtils::CBuilder::Platform::Windows::MSVC'=> '0.280217',
              'ExtUtils::CBuilder::Platform::aix'=> '0.280217',
              'ExtUtils::CBuilder::Platform::android'=> '0.280217',
              'ExtUtils::CBuilder::Platform::cygwin'=> '0.280217',
              'ExtUtils::CBuilder::Platform::darwin'=> '0.280217',
              'ExtUtils::CBuilder::Platform::dec_osf'=> '0.280217',
              'ExtUtils::CBuilder::Platform::os2'=> '0.280217',
              'ExtUtils::Manifest'    => '1.65',
              'HTTP::Tiny'            => '0.047',
              'IPC::Open3'            => '1.18',
              'Module::CoreList'      => '5.021003',
              'Module::CoreList::TieHashDelta'=> '5.021003',
              'Module::CoreList::Utils'=> '5.021003',
              'Opcode'                => '1.28',
              'POSIX'                 => '1.42',
              'Safe'                  => '2.38',
              'Socket'                => '2.015',
              'Sys::Hostname'         => '1.19',
              'UNIVERSAL'             => '1.12',
              'XS::APItest'           => '0.63',
              'perlfaq'               => '5.0150045',
          },
          removed => {
          }
      },
      5.020001 => {
          delta_from => 5.020000,
          changed => {
              'Config'                => '5.020001',
              'Config::Perl::V'       => '0.22',
              'Cwd'                   => '3.48',
              'Exporter'              => '5.71',
              'Exporter::Heavy'       => '5.71',
              'ExtUtils::CBuilder'    => '0.280217',
              'ExtUtils::CBuilder::Base'=> '0.280217',
              'ExtUtils::CBuilder::Platform::Unix'=> '0.280217',
              'ExtUtils::CBuilder::Platform::VMS'=> '0.280217',
              'ExtUtils::CBuilder::Platform::Windows'=> '0.280217',
              'ExtUtils::CBuilder::Platform::Windows::BCC'=> '0.280217',
              'ExtUtils::CBuilder::Platform::Windows::GCC'=> '0.280217',
              'ExtUtils::CBuilder::Platform::Windows::MSVC'=> '0.280217',
              'ExtUtils::CBuilder::Platform::aix'=> '0.280217',
              'ExtUtils::CBuilder::Platform::android'=> '0.280217',
              'ExtUtils::CBuilder::Platform::cygwin'=> '0.280217',
              'ExtUtils::CBuilder::Platform::darwin'=> '0.280217',
              'ExtUtils::CBuilder::Platform::dec_osf'=> '0.280217',
              'ExtUtils::CBuilder::Platform::os2'=> '0.280217',
              'File::Copy'            => '2.30',
              'File::Spec'            => '3.48',
              'File::Spec::Cygwin'    => '3.48',
              'File::Spec::Epoc'      => '3.48',
              'File::Spec::Functions' => '3.48',
              'File::Spec::Mac'       => '3.48',
              'File::Spec::OS2'       => '3.48',
              'File::Spec::Unix'      => '3.48',
              'File::Spec::VMS'       => '3.48',
              'File::Spec::Win32'     => '3.48',
              'Module::CoreList'      => '5.020001',
              'Module::CoreList::TieHashDelta'=> '5.020001',
              'Module::CoreList::Utils'=> '5.020001',
              'PerlIO::via'           => '0.15',
              'Unicode::UCD'          => '0.58',
              'XS::APItest'           => '0.60_01',
              'utf8'                  => '1.13_01',
              'version'               => '0.9909',
              'version::regex'        => '0.9909',
              'version::vpp'          => '0.9909',
          },
          removed => {
          }
      },
      5.021004 => {
          delta_from => 5.021003,
          changed => {
              'App::Prove'            => '3.33',
              'App::Prove::State'     => '3.33',
              'App::Prove::State::Result'=> '3.33',
              'App::Prove::State::Result::Test'=> '3.33',
              'Archive::Tar'          => '2.02',
              'Archive::Tar::Constant'=> '2.02',
              'Archive::Tar::File'    => '2.02',
              'Attribute::Handlers'   => '0.97',
              'B'                     => '1.51',
              'B::Concise'            => '0.993',
              'B::Deparse'            => '1.28',
              'B::Op_private'         => '5.021004',
              'CPAN::Meta::Requirements'=> '2.128',
              'Config'                => '5.021004',
              'Cwd'                   => '3.50',
              'Data::Dumper'          => '2.154',
              'ExtUtils::CBuilder'    => '0.280219',
              'ExtUtils::CBuilder::Base'=> '0.280219',
              'ExtUtils::CBuilder::Platform::Unix'=> '0.280219',
              'ExtUtils::CBuilder::Platform::VMS'=> '0.280219',
              'ExtUtils::CBuilder::Platform::Windows'=> '0.280219',
              'ExtUtils::CBuilder::Platform::Windows::BCC'=> '0.280219',
              'ExtUtils::CBuilder::Platform::Windows::GCC'=> '0.280219',
              'ExtUtils::CBuilder::Platform::Windows::MSVC'=> '0.280219',
              'ExtUtils::CBuilder::Platform::aix'=> '0.280219',
              'ExtUtils::CBuilder::Platform::android'=> '0.280219',
              'ExtUtils::CBuilder::Platform::cygwin'=> '0.280219',
              'ExtUtils::CBuilder::Platform::darwin'=> '0.280219',
              'ExtUtils::CBuilder::Platform::dec_osf'=> '0.280219',
              'ExtUtils::CBuilder::Platform::os2'=> '0.280219',
              'ExtUtils::Install'     => '2.04',
              'ExtUtils::Installed'   => '2.04',
              'ExtUtils::Liblist::Kid'=> '6.98_01',
              'ExtUtils::Manifest'    => '1.68',
              'ExtUtils::Packlist'    => '2.04',
              'File::Find'            => '1.28',
              'File::Spec'            => '3.50',
              'File::Spec::Cygwin'    => '3.50',
              'File::Spec::Epoc'      => '3.50',
              'File::Spec::Functions' => '3.50',
              'File::Spec::Mac'       => '3.50',
              'File::Spec::OS2'       => '3.50',
              'File::Spec::Unix'      => '3.50',
              'File::Spec::VMS'       => '3.50',
              'File::Spec::Win32'     => '3.50',
              'Getopt::Std'           => '1.11',
              'HTTP::Tiny'            => '0.049',
              'IO'                    => '1.34',
              'IO::Socket::IP'        => '0.32',
              'List::Util'            => '1.41',
              'List::Util::XS'        => '1.41',
              'Locale::Codes'         => '3.32',
              'Locale::Codes::Constants'=> '3.32',
              'Locale::Codes::Country'=> '3.32',
              'Locale::Codes::Country_Codes'=> '3.32',
              'Locale::Codes::Country_Retired'=> '3.32',
              'Locale::Codes::Currency'=> '3.32',
              'Locale::Codes::Currency_Codes'=> '3.32',
              'Locale::Codes::Currency_Retired'=> '3.32',
              'Locale::Codes::LangExt'=> '3.32',
              'Locale::Codes::LangExt_Codes'=> '3.32',
              'Locale::Codes::LangExt_Retired'=> '3.32',
              'Locale::Codes::LangFam'=> '3.32',
              'Locale::Codes::LangFam_Codes'=> '3.32',
              'Locale::Codes::LangFam_Retired'=> '3.32',
              'Locale::Codes::LangVar'=> '3.32',
              'Locale::Codes::LangVar_Codes'=> '3.32',
              'Locale::Codes::LangVar_Retired'=> '3.32',
              'Locale::Codes::Language'=> '3.32',
              'Locale::Codes::Language_Codes'=> '3.32',
              'Locale::Codes::Language_Retired'=> '3.32',
              'Locale::Codes::Script' => '3.32',
              'Locale::Codes::Script_Codes'=> '3.32',
              'Locale::Codes::Script_Retired'=> '3.32',
              'Locale::Country'       => '3.32',
              'Locale::Currency'      => '3.32',
              'Locale::Language'      => '3.32',
              'Locale::Script'        => '3.32',
              'Math::BigFloat'        => '1.9997',
              'Math::BigInt'          => '1.9997',
              'Math::BigInt::Calc'    => '1.9997',
              'Math::BigInt::CalcEmu' => '1.9997',
              'Module::CoreList'      => '5.20140920',
              'Module::CoreList::TieHashDelta'=> '5.20140920',
              'Module::CoreList::Utils'=> '5.20140920',
              'POSIX'                 => '1.43',
              'Pod::Perldoc'          => '3.24',
              'Pod::Perldoc::BaseTo'  => '3.24',
              'Pod::Perldoc::GetOptsOO'=> '3.24',
              'Pod::Perldoc::ToANSI'  => '3.24',
              'Pod::Perldoc::ToChecker'=> '3.24',
              'Pod::Perldoc::ToMan'   => '3.24',
              'Pod::Perldoc::ToNroff' => '3.24',
              'Pod::Perldoc::ToPod'   => '3.24',
              'Pod::Perldoc::ToRtf'   => '3.24',
              'Pod::Perldoc::ToTerm'  => '3.24',
              'Pod::Perldoc::ToText'  => '3.24',
              'Pod::Perldoc::ToTk'    => '3.24',
              'Pod::Perldoc::ToXml'   => '3.24',
              'Scalar::Util'          => '1.41',
              'Sub::Util'             => '1.41',
              'TAP::Base'             => '3.33',
              'TAP::Formatter::Base'  => '3.33',
              'TAP::Formatter::Color' => '3.33',
              'TAP::Formatter::Console'=> '3.33',
              'TAP::Formatter::Console::ParallelSession'=> '3.33',
              'TAP::Formatter::Console::Session'=> '3.33',
              'TAP::Formatter::File'  => '3.33',
              'TAP::Formatter::File::Session'=> '3.33',
              'TAP::Formatter::Session'=> '3.33',
              'TAP::Harness'          => '3.33',
              'TAP::Harness::Env'     => '3.33',
              'TAP::Object'           => '3.33',
              'TAP::Parser'           => '3.33',
              'TAP::Parser::Aggregator'=> '3.33',
              'TAP::Parser::Grammar'  => '3.33',
              'TAP::Parser::Iterator' => '3.33',
              'TAP::Parser::Iterator::Array'=> '3.33',
              'TAP::Parser::Iterator::Process'=> '3.33',
              'TAP::Parser::Iterator::Stream'=> '3.33',
              'TAP::Parser::IteratorFactory'=> '3.33',
              'TAP::Parser::Multiplexer'=> '3.33',
              'TAP::Parser::Result'   => '3.33',
              'TAP::Parser::Result::Bailout'=> '3.33',
              'TAP::Parser::Result::Comment'=> '3.33',
              'TAP::Parser::Result::Plan'=> '3.33',
              'TAP::Parser::Result::Pragma'=> '3.33',
              'TAP::Parser::Result::Test'=> '3.33',
              'TAP::Parser::Result::Unknown'=> '3.33',
              'TAP::Parser::Result::Version'=> '3.33',
              'TAP::Parser::Result::YAML'=> '3.33',
              'TAP::Parser::ResultFactory'=> '3.33',
              'TAP::Parser::Scheduler'=> '3.33',
              'TAP::Parser::Scheduler::Job'=> '3.33',
              'TAP::Parser::Scheduler::Spinner'=> '3.33',
              'TAP::Parser::Source'   => '3.33',
              'TAP::Parser::SourceHandler'=> '3.33',
              'TAP::Parser::SourceHandler::Executable'=> '3.33',
              'TAP::Parser::SourceHandler::File'=> '3.33',
              'TAP::Parser::SourceHandler::Handle'=> '3.33',
              'TAP::Parser::SourceHandler::Perl'=> '3.33',
              'TAP::Parser::SourceHandler::RawTAP'=> '3.33',
              'TAP::Parser::YAMLish::Reader'=> '3.33',
              'TAP::Parser::YAMLish::Writer'=> '3.33',
              'Term::ReadLine'        => '1.15',
              'Test::Builder'         => '1.001006',
              'Test::Builder::Module' => '1.001006',
              'Test::Builder::Tester' => '1.24',
              'Test::Builder::Tester::Color'=> '1.24',
              'Test::Harness'         => '3.33',
              'Test::More'            => '1.001006',
              'Test::Simple'          => '1.001006',
              'Time::Piece'           => '1.29',
              'Time::Seconds'         => '1.29',
              'XS::APItest'           => '0.64',
              '_charnames'            => '1.42',
              'attributes'            => '0.23',
              'bigint'                => '0.37',
              'bignum'                => '0.38',
              'bigrat'                => '0.37',
              'constant'              => '1.32',
              'experimental'          => '0.010',
              'overload'              => '1.23',
              'threads'               => '1.96',
              'version'               => '0.9909',
              'version::regex'        => '0.9909',
              'version::vpp'          => '0.9909',
          },
          removed => {
          }
      },
      5.021005 => {
          delta_from => 5.021004,
          changed => {
              'B'                     => '1.52',
              'B::Concise'            => '0.994',
              'B::Debug'              => '1.22',
              'B::Deparse'            => '1.29',
              'B::Op_private'         => '5.021005',
              'CPAN::Meta'            => '2.142690',
              'CPAN::Meta::Converter' => '2.142690',
              'CPAN::Meta::Feature'   => '2.142690',
              'CPAN::Meta::History'   => '2.142690',
              'CPAN::Meta::Merge'     => '2.142690',
              'CPAN::Meta::Prereqs'   => '2.142690',
              'CPAN::Meta::Spec'      => '2.142690',
              'CPAN::Meta::Validator' => '2.142690',
              'Compress::Raw::Bzip2'  => '2.066',
              'Compress::Raw::Zlib'   => '2.066',
              'Compress::Zlib'        => '2.066',
              'Config'                => '5.021005',
              'Cwd'                   => '3.51',
              'DynaLoader'            => '1.27',
              'Errno'                 => '1.21',
              'ExtUtils::CBuilder'    => '0.280220',
              'ExtUtils::CBuilder::Base'=> '0.280220',
              'ExtUtils::CBuilder::Platform::Unix'=> '0.280220',
              'ExtUtils::CBuilder::Platform::VMS'=> '0.280220',
              'ExtUtils::CBuilder::Platform::Windows'=> '0.280220',
              'ExtUtils::CBuilder::Platform::Windows::BCC'=> '0.280220',
              'ExtUtils::CBuilder::Platform::Windows::GCC'=> '0.280220',
              'ExtUtils::CBuilder::Platform::Windows::MSVC'=> '0.280220',
              'ExtUtils::CBuilder::Platform::aix'=> '0.280220',
              'ExtUtils::CBuilder::Platform::android'=> '0.280220',
              'ExtUtils::CBuilder::Platform::cygwin'=> '0.280220',
              'ExtUtils::CBuilder::Platform::darwin'=> '0.280220',
              'ExtUtils::CBuilder::Platform::dec_osf'=> '0.280220',
              'ExtUtils::CBuilder::Platform::os2'=> '0.280220',
              'ExtUtils::Miniperl'    => '1.03',
              'Fcntl'                 => '1.13',
              'File::Find'            => '1.29',
              'File::Spec'            => '3.51',
              'File::Spec::Cygwin'    => '3.51',
              'File::Spec::Epoc'      => '3.51',
              'File::Spec::Functions' => '3.51',
              'File::Spec::Mac'       => '3.51',
              'File::Spec::OS2'       => '3.51',
              'File::Spec::Unix'      => '3.51',
              'File::Spec::VMS'       => '3.51',
              'File::Spec::Win32'     => '3.51',
              'HTTP::Tiny'            => '0.050',
              'IO::Compress::Adapter::Bzip2'=> '2.066',
              'IO::Compress::Adapter::Deflate'=> '2.066',
              'IO::Compress::Adapter::Identity'=> '2.066',
              'IO::Compress::Base'    => '2.066',
              'IO::Compress::Base::Common'=> '2.066',
              'IO::Compress::Bzip2'   => '2.066',
              'IO::Compress::Deflate' => '2.066',
              'IO::Compress::Gzip'    => '2.066',
              'IO::Compress::Gzip::Constants'=> '2.066',
              'IO::Compress::RawDeflate'=> '2.066',
              'IO::Compress::Zip'     => '2.066',
              'IO::Compress::Zip::Constants'=> '2.066',
              'IO::Compress::Zlib::Constants'=> '2.066',
              'IO::Compress::Zlib::Extra'=> '2.066',
              'IO::Uncompress::Adapter::Bunzip2'=> '2.066',
              'IO::Uncompress::Adapter::Identity'=> '2.066',
              'IO::Uncompress::Adapter::Inflate'=> '2.066',
              'IO::Uncompress::AnyInflate'=> '2.066',
              'IO::Uncompress::AnyUncompress'=> '2.066',
              'IO::Uncompress::Base'  => '2.066',
              'IO::Uncompress::Bunzip2'=> '2.066',
              'IO::Uncompress::Gunzip'=> '2.066',
              'IO::Uncompress::Inflate'=> '2.066',
              'IO::Uncompress::RawInflate'=> '2.066',
              'IO::Uncompress::Unzip' => '2.066',
              'JSON::PP'              => '2.27300',
              'Module::CoreList'      => '5.20141020',
              'Module::CoreList::TieHashDelta'=> '5.20141020',
              'Module::CoreList::Utils'=> '5.20141020',
              'Net::Cmd'              => '3.02',
              'Net::Config'           => '3.02',
              'Net::Domain'           => '3.02',
              'Net::FTP'              => '3.02',
              'Net::FTP::A'           => '3.02',
              'Net::FTP::E'           => '3.02',
              'Net::FTP::I'           => '3.02',
              'Net::FTP::L'           => '3.02',
              'Net::FTP::dataconn'    => '3.02',
              'Net::NNTP'             => '3.02',
              'Net::Netrc'            => '3.02',
              'Net::POP3'             => '3.02',
              'Net::SMTP'             => '3.02',
              'Net::Time'             => '3.02',
              'Opcode'                => '1.29',
              'POSIX'                 => '1.45',
              'Socket'                => '2.016',
              'Test::Builder'         => '1.001008',
              'Test::Builder::Module' => '1.001008',
              'Test::More'            => '1.001008',
              'Test::Simple'          => '1.001008',
              'XS::APItest'           => '0.65',
              'XSLoader'              => '0.18',
              'attributes'            => '0.24',
              'experimental'          => '0.012',
              'feature'               => '1.38',
              'perlfaq'               => '5.0150046',
              're'                    => '0.27',
              'threads::shared'       => '1.47',
              'warnings'              => '1.28',
              'warnings::register'    => '1.04',
          },
          removed => {
          }
      },
      5.021006 => {
          delta_from => 5.021005,
          changed => {
              'App::Prove'            => '3.34',
              'App::Prove::State'     => '3.34',
              'App::Prove::State::Result'=> '3.34',
              'App::Prove::State::Result::Test'=> '3.34',
              'B'                     => '1.53',
              'B::Concise'            => '0.995',
              'B::Deparse'            => '1.30',
              'B::Op_private'         => '5.021006',
              'CPAN::Meta'            => '2.143240',
              'CPAN::Meta::Converter' => '2.143240',
              'CPAN::Meta::Feature'   => '2.143240',
              'CPAN::Meta::History'   => '2.143240',
              'CPAN::Meta::Merge'     => '2.143240',
              'CPAN::Meta::Prereqs'   => '2.143240',
              'CPAN::Meta::Requirements'=> '2.130',
              'CPAN::Meta::Spec'      => '2.143240',
              'CPAN::Meta::Validator' => '2.143240',
              'Config'                => '5.021006',
              'Devel::Peek'           => '1.19',
              'Digest::SHA'           => '5.93',
              'DynaLoader'            => '1.28',
              'Encode'                => '2.64',
              'Exporter'              => '5.72',
              'Exporter::Heavy'       => '5.72',
              'ExtUtils::Command::MM' => '7.02',
              'ExtUtils::Liblist'     => '7.02',
              'ExtUtils::Liblist::Kid'=> '7.02',
              'ExtUtils::MM'          => '7.02',
              'ExtUtils::MM_AIX'      => '7.02',
              'ExtUtils::MM_Any'      => '7.02',
              'ExtUtils::MM_BeOS'     => '7.02',
              'ExtUtils::MM_Cygwin'   => '7.02',
              'ExtUtils::MM_DOS'      => '7.02',
              'ExtUtils::MM_Darwin'   => '7.02',
              'ExtUtils::MM_MacOS'    => '7.02',
              'ExtUtils::MM_NW5'      => '7.02',
              'ExtUtils::MM_OS2'      => '7.02',
              'ExtUtils::MM_QNX'      => '7.02',
              'ExtUtils::MM_UWIN'     => '7.02',
              'ExtUtils::MM_Unix'     => '7.02',
              'ExtUtils::MM_VMS'      => '7.02',
              'ExtUtils::MM_VOS'      => '7.02',
              'ExtUtils::MM_Win32'    => '7.02',
              'ExtUtils::MM_Win95'    => '7.02',
              'ExtUtils::MY'          => '7.02',
              'ExtUtils::MakeMaker'   => '7.02',
              'ExtUtils::MakeMaker::Config'=> '7.02',
              'ExtUtils::MakeMaker::Locale'=> '7.02',
              'ExtUtils::MakeMaker::version'=> '7.02',
              'ExtUtils::MakeMaker::version::regex'=> '7.02',
              'ExtUtils::MakeMaker::version::vpp'=> '7.02',
              'ExtUtils::Manifest'    => '1.69',
              'ExtUtils::Mkbootstrap' => '7.02',
              'ExtUtils::Mksymlists'  => '7.02',
              'ExtUtils::ParseXS'     => '3.26',
              'ExtUtils::ParseXS::Constants'=> '3.26',
              'ExtUtils::ParseXS::CountLines'=> '3.26',
              'ExtUtils::ParseXS::Eval'=> '3.26',
              'ExtUtils::ParseXS::Utilities'=> '3.26',
              'ExtUtils::testlib'     => '7.02',
              'File::Spec::VMS'       => '3.52',
              'HTTP::Tiny'            => '0.051',
              'I18N::Langinfo'        => '0.12',
              'IO::Socket'            => '1.38',
              'Module::CoreList'      => '5.20141120',
              'Module::CoreList::TieHashDelta'=> '5.20141120',
              'Module::CoreList::Utils'=> '5.20141120',
              'POSIX'                 => '1.46',
              'PerlIO::encoding'      => '0.20',
              'PerlIO::scalar'        => '0.20',
              'TAP::Base'             => '3.34',
              'TAP::Formatter::Base'  => '3.34',
              'TAP::Formatter::Color' => '3.34',
              'TAP::Formatter::Console'=> '3.34',
              'TAP::Formatter::Console::ParallelSession'=> '3.34',
              'TAP::Formatter::Console::Session'=> '3.34',
              'TAP::Formatter::File'  => '3.34',
              'TAP::Formatter::File::Session'=> '3.34',
              'TAP::Formatter::Session'=> '3.34',
              'TAP::Harness'          => '3.34',
              'TAP::Harness::Env'     => '3.34',
              'TAP::Object'           => '3.34',
              'TAP::Parser'           => '3.34',
              'TAP::Parser::Aggregator'=> '3.34',
              'TAP::Parser::Grammar'  => '3.34',
              'TAP::Parser::Iterator' => '3.34',
              'TAP::Parser::Iterator::Array'=> '3.34',
              'TAP::Parser::Iterator::Process'=> '3.34',
              'TAP::Parser::Iterator::Stream'=> '3.34',
              'TAP::Parser::IteratorFactory'=> '3.34',
              'TAP::Parser::Multiplexer'=> '3.34',
              'TAP::Parser::Result'   => '3.34',
              'TAP::Parser::Result::Bailout'=> '3.34',
              'TAP::Parser::Result::Comment'=> '3.34',
              'TAP::Parser::Result::Plan'=> '3.34',
              'TAP::Parser::Result::Pragma'=> '3.34',
              'TAP::Parser::Result::Test'=> '3.34',
              'TAP::Parser::Result::Unknown'=> '3.34',
              'TAP::Parser::Result::Version'=> '3.34',
              'TAP::Parser::Result::YAML'=> '3.34',
              'TAP::Parser::ResultFactory'=> '3.34',
              'TAP::Parser::Scheduler'=> '3.34',
              'TAP::Parser::Scheduler::Job'=> '3.34',
              'TAP::Parser::Scheduler::Spinner'=> '3.34',
              'TAP::Parser::Source'   => '3.34',
              'TAP::Parser::SourceHandler'=> '3.34',
              'TAP::Parser::SourceHandler::Executable'=> '3.34',
              'TAP::Parser::SourceHandler::File'=> '3.34',
              'TAP::Parser::SourceHandler::Handle'=> '3.34',
              'TAP::Parser::SourceHandler::Perl'=> '3.34',
              'TAP::Parser::SourceHandler::RawTAP'=> '3.34',
              'TAP::Parser::YAMLish::Reader'=> '3.34',
              'TAP::Parser::YAMLish::Writer'=> '3.34',
              'Test::Builder'         => '1.301001_075',
              'Test::Builder::Module' => '1.301001_075',
              'Test::Builder::Tester' => '1.301001_075',
              'Test::Builder::Tester::Color'=> '1.301001_075',
              'Test::Harness'         => '3.34',
              'Test::More'            => '1.301001_075',
              'Test::More::DeepCheck' => undef,
              'Test::More::DeepCheck::Strict'=> undef,
              'Test::More::DeepCheck::Tolerant'=> undef,
              'Test::More::Tools'     => undef,
              'Test::MostlyLike'      => undef,
              'Test::Simple'          => '1.301001_075',
              'Test::Stream'          => '1.301001_075',
              'Test::Stream::ArrayBase'=> undef,
              'Test::Stream::ArrayBase::Meta'=> undef,
              'Test::Stream::Carp'    => undef,
              'Test::Stream::Context' => undef,
              'Test::Stream::Event'   => undef,
              'Test::Stream::Event::Bail'=> undef,
              'Test::Stream::Event::Child'=> undef,
              'Test::Stream::Event::Diag'=> undef,
              'Test::Stream::Event::Finish'=> undef,
              'Test::Stream::Event::Note'=> undef,
              'Test::Stream::Event::Ok'=> undef,
              'Test::Stream::Event::Plan'=> undef,
              'Test::Stream::Event::Subtest'=> undef,
              'Test::Stream::ExitMagic'=> undef,
              'Test::Stream::ExitMagic::Context'=> undef,
              'Test::Stream::Exporter'=> undef,
              'Test::Stream::Exporter::Meta'=> undef,
              'Test::Stream::IOSets'  => undef,
              'Test::Stream::Meta'    => undef,
              'Test::Stream::PackageUtil'=> undef,
              'Test::Stream::Tester'  => undef,
              'Test::Stream::Tester::Checks'=> undef,
              'Test::Stream::Tester::Checks::Event'=> undef,
              'Test::Stream::Tester::Events'=> undef,
              'Test::Stream::Tester::Events::Event'=> undef,
              'Test::Stream::Tester::Grab'=> undef,
              'Test::Stream::Threads' => undef,
              'Test::Stream::Toolset' => undef,
              'Test::Stream::Util'    => undef,
              'Test::Tester'          => '1.301001_075',
              'Test::Tester::Capture' => undef,
              'Test::use::ok'         => '1.301001_075',
              'Unicode::UCD'          => '0.59',
              'XS::APItest'           => '0.68',
              'XSLoader'              => '0.19',
              'experimental'          => '0.013',
              'locale'                => '1.05',
              'ok'                    => '1.301001_075',
              'overload'              => '1.24',
              're'                    => '0.28',
              'warnings'              => '1.29',
          },
          removed => {
          }
      },
      5.021007 => {
          delta_from => 5.021006,
          changed => {
              'Archive::Tar'          => '2.04',
              'Archive::Tar::Constant'=> '2.04',
              'Archive::Tar::File'    => '2.04',
              'B'                     => '1.54',
              'B::Concise'            => '0.996',
              'B::Deparse'            => '1.31',
              'B::Op_private'         => '5.021007',
              'B::Showlex'            => '1.05',
              'Compress::Raw::Bzip2'  => '2.067',
              'Compress::Raw::Zlib'   => '2.067',
              'Compress::Zlib'        => '2.067',
              'Config'                => '5.021007',
              'Cwd'                   => '3.54',
              'DB_File'               => '1.834',
              'Data::Dumper'          => '2.155',
              'Devel::PPPort'         => '3.25',
              'Devel::Peek'           => '1.20',
              'DynaLoader'            => '1.29',
              'Encode'                => '2.67',
              'Errno'                 => '1.22',
              'ExtUtils::CBuilder'    => '0.280221',
              'ExtUtils::CBuilder::Base'=> '0.280221',
              'ExtUtils::CBuilder::Platform::Unix'=> '0.280221',
              'ExtUtils::CBuilder::Platform::VMS'=> '0.280221',
              'ExtUtils::CBuilder::Platform::Windows'=> '0.280221',
              'ExtUtils::CBuilder::Platform::aix'=> '0.280221',
              'ExtUtils::CBuilder::Platform::android'=> '0.280221',
              'ExtUtils::CBuilder::Platform::cygwin'=> '0.280221',
              'ExtUtils::CBuilder::Platform::darwin'=> '0.280221',
              'ExtUtils::CBuilder::Platform::dec_osf'=> '0.280221',
              'ExtUtils::CBuilder::Platform::os2'=> '0.280221',
              'ExtUtils::Command::MM' => '7.04',
              'ExtUtils::Liblist'     => '7.04',
              'ExtUtils::Liblist::Kid'=> '7.04',
              'ExtUtils::MM'          => '7.04',
              'ExtUtils::MM_AIX'      => '7.04',
              'ExtUtils::MM_Any'      => '7.04',
              'ExtUtils::MM_BeOS'     => '7.04',
              'ExtUtils::MM_Cygwin'   => '7.04',
              'ExtUtils::MM_DOS'      => '7.04',
              'ExtUtils::MM_Darwin'   => '7.04',
              'ExtUtils::MM_MacOS'    => '7.04',
              'ExtUtils::MM_NW5'      => '7.04',
              'ExtUtils::MM_OS2'      => '7.04',
              'ExtUtils::MM_QNX'      => '7.04',
              'ExtUtils::MM_UWIN'     => '7.04',
              'ExtUtils::MM_Unix'     => '7.04',
              'ExtUtils::MM_VMS'      => '7.04',
              'ExtUtils::MM_VOS'      => '7.04',
              'ExtUtils::MM_Win32'    => '7.04',
              'ExtUtils::MM_Win95'    => '7.04',
              'ExtUtils::MY'          => '7.04',
              'ExtUtils::MakeMaker'   => '7.04',
              'ExtUtils::MakeMaker::Config'=> '7.04',
              'ExtUtils::MakeMaker::Locale'=> '7.04',
              'ExtUtils::MakeMaker::version'=> '7.04',
              'ExtUtils::MakeMaker::version::regex'=> '7.04',
              'ExtUtils::MakeMaker::version::vpp'=> '7.04',
              'ExtUtils::Mkbootstrap' => '7.04',
              'ExtUtils::Mksymlists'  => '7.04',
              'ExtUtils::ParseXS'     => '3.27',
              'ExtUtils::ParseXS::Constants'=> '3.27',
              'ExtUtils::ParseXS::CountLines'=> '3.27',
              'ExtUtils::ParseXS::Eval'=> '3.27',
              'ExtUtils::ParseXS::Utilities'=> '3.27',
              'ExtUtils::testlib'     => '7.04',
              'File::Spec'            => '3.53',
              'File::Spec::Cygwin'    => '3.54',
              'File::Spec::Epoc'      => '3.54',
              'File::Spec::Functions' => '3.54',
              'File::Spec::Mac'       => '3.54',
              'File::Spec::OS2'       => '3.54',
              'File::Spec::Unix'      => '3.54',
              'File::Spec::VMS'       => '3.54',
              'File::Spec::Win32'     => '3.54',
              'Filter::Util::Call'    => '1.51',
              'HTTP::Tiny'            => '0.053',
              'IO'                    => '1.35',
              'IO::Compress::Adapter::Bzip2'=> '2.067',
              'IO::Compress::Adapter::Deflate'=> '2.067',
              'IO::Compress::Adapter::Identity'=> '2.067',
              'IO::Compress::Base'    => '2.067',
              'IO::Compress::Base::Common'=> '2.067',
              'IO::Compress::Bzip2'   => '2.067',
              'IO::Compress::Deflate' => '2.067',
              'IO::Compress::Gzip'    => '2.067',
              'IO::Compress::Gzip::Constants'=> '2.067',
              'IO::Compress::RawDeflate'=> '2.067',
              'IO::Compress::Zip'     => '2.067',
              'IO::Compress::Zip::Constants'=> '2.067',
              'IO::Compress::Zlib::Constants'=> '2.067',
              'IO::Compress::Zlib::Extra'=> '2.067',
              'IO::Socket::IP'        => '0.34',
              'IO::Uncompress::Adapter::Bunzip2'=> '2.067',
              'IO::Uncompress::Adapter::Identity'=> '2.067',
              'IO::Uncompress::Adapter::Inflate'=> '2.067',
              'IO::Uncompress::AnyInflate'=> '2.067',
              'IO::Uncompress::AnyUncompress'=> '2.067',
              'IO::Uncompress::Base'  => '2.067',
              'IO::Uncompress::Bunzip2'=> '2.067',
              'IO::Uncompress::Gunzip'=> '2.067',
              'IO::Uncompress::Inflate'=> '2.067',
              'IO::Uncompress::RawInflate'=> '2.067',
              'IO::Uncompress::Unzip' => '2.067',
              'Locale::Codes'         => '3.33',
              'Locale::Codes::Constants'=> '3.33',
              'Locale::Codes::Country'=> '3.33',
              'Locale::Codes::Country_Codes'=> '3.33',
              'Locale::Codes::Country_Retired'=> '3.33',
              'Locale::Codes::Currency'=> '3.33',
              'Locale::Codes::Currency_Codes'=> '3.33',
              'Locale::Codes::Currency_Retired'=> '3.33',
              'Locale::Codes::LangExt'=> '3.33',
              'Locale::Codes::LangExt_Codes'=> '3.33',
              'Locale::Codes::LangExt_Retired'=> '3.33',
              'Locale::Codes::LangFam'=> '3.33',
              'Locale::Codes::LangFam_Codes'=> '3.33',
              'Locale::Codes::LangFam_Retired'=> '3.33',
              'Locale::Codes::LangVar'=> '3.33',
              'Locale::Codes::LangVar_Codes'=> '3.33',
              'Locale::Codes::LangVar_Retired'=> '3.33',
              'Locale::Codes::Language'=> '3.33',
              'Locale::Codes::Language_Codes'=> '3.33',
              'Locale::Codes::Language_Retired'=> '3.33',
              'Locale::Codes::Script' => '3.33',
              'Locale::Codes::Script_Codes'=> '3.33',
              'Locale::Codes::Script_Retired'=> '3.33',
              'Locale::Country'       => '3.33',
              'Locale::Currency'      => '3.33',
              'Locale::Language'      => '3.33',
              'Locale::Maketext'      => '1.26',
              'Locale::Script'        => '3.33',
              'Module::CoreList'      => '5.20141220',
              'Module::CoreList::TieHashDelta'=> '5.20141220',
              'Module::CoreList::Utils'=> '5.20141220',
              'NDBM_File'             => '1.14',
              'Net::Cmd'              => '3.04',
              'Net::Config'           => '3.04',
              'Net::Domain'           => '3.04',
              'Net::FTP'              => '3.04',
              'Net::FTP::A'           => '3.04',
              'Net::FTP::E'           => '3.04',
              'Net::FTP::I'           => '3.04',
              'Net::FTP::L'           => '3.04',
              'Net::FTP::dataconn'    => '3.04',
              'Net::NNTP'             => '3.04',
              'Net::Netrc'            => '3.04',
              'Net::POP3'             => '3.04',
              'Net::SMTP'             => '3.04',
              'Net::Time'             => '3.04',
              'Opcode'                => '1.30',
              'POSIX'                 => '1.48',
              'PerlIO::scalar'        => '0.21',
              'Pod::Escapes'          => '1.07',
              'SDBM_File'             => '1.12',
              'Storable'              => '2.52',
              'Sys::Hostname'         => '1.20',
              'Test::Builder'         => '1.301001_090',
              'Test::Builder::Module' => '1.301001_090',
              'Test::Builder::Tester' => '1.301001_090',
              'Test::Builder::Tester::Color'=> '1.301001_090',
              'Test::CanFork'         => undef,
              'Test::CanThread'       => undef,
              'Test::More'            => '1.301001_090',
              'Test::Simple'          => '1.301001_090',
              'Test::Stream'          => '1.301001_090',
              'Test::Stream::API'     => undef,
              'Test::Stream::ForceExit'=> undef,
              'Test::Stream::Subtest' => undef,
              'Test::Tester'          => '1.301001_090',
              'Test::use::ok'         => '1.301001_090',
              'Unicode::Collate'      => '1.09',
              'Unicode::Collate::CJK::Big5'=> '1.09',
              'Unicode::Collate::CJK::GB2312'=> '1.09',
              'Unicode::Collate::CJK::JISX0208'=> '1.09',
              'Unicode::Collate::CJK::Korean'=> '1.09',
              'Unicode::Collate::CJK::Pinyin'=> '1.09',
              'Unicode::Collate::CJK::Stroke'=> '1.09',
              'Unicode::Collate::CJK::Zhuyin'=> '1.09',
              'Unicode::Collate::Locale'=> '1.09',
              'XS::APItest'           => '0.69',
              'XSLoader'              => '0.20',
              '_charnames'            => '1.43',
              'arybase'               => '0.09',
              'charnames'             => '1.43',
              'feature'               => '1.39',
              'mro'                   => '1.17',
              'ok'                    => '1.301001_090',
              'strict'                => '1.09',
              'threads'               => '1.96_001',
          },
          removed => {
          }
      },
      5.021008 => {
          delta_from => 5.021007,
          changed => {
              'App::Prove'            => '3.35',
              'App::Prove::State'     => '3.35',
              'App::Prove::State::Result'=> '3.35',
              'App::Prove::State::Result::Test'=> '3.35',
              'B'                     => '1.55',
              'B::Deparse'            => '1.32',
              'B::Op_private'         => '5.021008',
              'CPAN::Meta::Requirements'=> '2.131',
              'Compress::Raw::Bzip2'  => '2.068',
              'Compress::Raw::Zlib'   => '2.068',
              'Compress::Zlib'        => '2.068',
              'Config'                => '5.021008',
              'DB_File'               => '1.835',
              'Data::Dumper'          => '2.156',
              'Devel::PPPort'         => '3.28',
              'Devel::Peek'           => '1.21',
              'Digest::MD5'           => '2.54',
              'Digest::SHA'           => '5.95',
              'DynaLoader'            => '1.30',
              'ExtUtils::Command'     => '1.20',
              'ExtUtils::Manifest'    => '1.70',
              'Fatal'                 => '2.26',
              'File::Glob'            => '1.24',
              'Filter::Util::Call'    => '1.54',
              'Getopt::Long'          => '2.43',
              'IO::Compress::Adapter::Bzip2'=> '2.068',
              'IO::Compress::Adapter::Deflate'=> '2.068',
              'IO::Compress::Adapter::Identity'=> '2.068',
              'IO::Compress::Base'    => '2.068',
              'IO::Compress::Base::Common'=> '2.068',
              'IO::Compress::Bzip2'   => '2.068',
              'IO::Compress::Deflate' => '2.068',
              'IO::Compress::Gzip'    => '2.068',
              'IO::Compress::Gzip::Constants'=> '2.068',
              'IO::Compress::RawDeflate'=> '2.068',
              'IO::Compress::Zip'     => '2.068',
              'IO::Compress::Zip::Constants'=> '2.068',
              'IO::Compress::Zlib::Constants'=> '2.068',
              'IO::Compress::Zlib::Extra'=> '2.068',
              'IO::Socket::IP'        => '0.36',
              'IO::Uncompress::Adapter::Bunzip2'=> '2.068',
              'IO::Uncompress::Adapter::Identity'=> '2.068',
              'IO::Uncompress::Adapter::Inflate'=> '2.068',
              'IO::Uncompress::AnyInflate'=> '2.068',
              'IO::Uncompress::AnyUncompress'=> '2.068',
              'IO::Uncompress::Base'  => '2.068',
              'IO::Uncompress::Bunzip2'=> '2.068',
              'IO::Uncompress::Gunzip'=> '2.068',
              'IO::Uncompress::Inflate'=> '2.068',
              'IO::Uncompress::RawInflate'=> '2.068',
              'IO::Uncompress::Unzip' => '2.068',
              'MIME::Base64'          => '3.15',
              'Module::CoreList'      => '5.20150220',
              'Module::CoreList::TieHashDelta'=> '5.20150220',
              'Module::CoreList::Utils'=> '5.20150220',
              'Module::Load::Conditional'=> '0.64',
              'Module::Metadata'      => '1.000026',
              'Net::Cmd'              => '3.05',
              'Net::Config'           => '3.05',
              'Net::Domain'           => '3.05',
              'Net::FTP'              => '3.05',
              'Net::FTP::A'           => '3.05',
              'Net::FTP::E'           => '3.05',
              'Net::FTP::I'           => '3.05',
              'Net::FTP::L'           => '3.05',
              'Net::FTP::dataconn'    => '3.05',
              'Net::NNTP'             => '3.05',
              'Net::Netrc'            => '3.05',
              'Net::POP3'             => '3.05',
              'Net::SMTP'             => '3.05',
              'Net::Time'             => '3.05',
              'Opcode'                => '1.31',
              'POSIX'                 => '1.49',
              'PerlIO::encoding'      => '0.21',
              'Pod::Simple'           => '3.29',
              'Pod::Simple::BlackBox' => '3.29',
              'Pod::Simple::Checker'  => '3.29',
              'Pod::Simple::Debug'    => '3.29',
              'Pod::Simple::DumpAsText'=> '3.29',
              'Pod::Simple::DumpAsXML'=> '3.29',
              'Pod::Simple::HTML'     => '3.29',
              'Pod::Simple::HTMLBatch'=> '3.29',
              'Pod::Simple::LinkSection'=> '3.29',
              'Pod::Simple::Methody'  => '3.29',
              'Pod::Simple::Progress' => '3.29',
              'Pod::Simple::PullParser'=> '3.29',
              'Pod::Simple::PullParserEndToken'=> '3.29',
              'Pod::Simple::PullParserStartToken'=> '3.29',
              'Pod::Simple::PullParserTextToken'=> '3.29',
              'Pod::Simple::PullParserToken'=> '3.29',
              'Pod::Simple::RTF'      => '3.29',
              'Pod::Simple::Search'   => '3.29',
              'Pod::Simple::SimpleTree'=> '3.29',
              'Pod::Simple::Text'     => '3.29',
              'Pod::Simple::TextContent'=> '3.29',
              'Pod::Simple::TiedOutFH'=> '3.29',
              'Pod::Simple::Transcode'=> '3.29',
              'Pod::Simple::TranscodeDumb'=> '3.29',
              'Pod::Simple::TranscodeSmart'=> '3.29',
              'Pod::Simple::XHTML'    => '3.29',
              'Pod::Simple::XMLOutStream'=> '3.29',
              'SDBM_File'             => '1.13',
              'Safe'                  => '2.39',
              'TAP::Base'             => '3.35',
              'TAP::Formatter::Base'  => '3.35',
              'TAP::Formatter::Color' => '3.35',
              'TAP::Formatter::Console'=> '3.35',
              'TAP::Formatter::Console::ParallelSession'=> '3.35',
              'TAP::Formatter::Console::Session'=> '3.35',
              'TAP::Formatter::File'  => '3.35',
              'TAP::Formatter::File::Session'=> '3.35',
              'TAP::Formatter::Session'=> '3.35',
              'TAP::Harness'          => '3.35',
              'TAP::Harness::Env'     => '3.35',
              'TAP::Object'           => '3.35',
              'TAP::Parser'           => '3.35',
              'TAP::Parser::Aggregator'=> '3.35',
              'TAP::Parser::Grammar'  => '3.35',
              'TAP::Parser::Iterator' => '3.35',
              'TAP::Parser::Iterator::Array'=> '3.35',
              'TAP::Parser::Iterator::Process'=> '3.35',
              'TAP::Parser::Iterator::Stream'=> '3.35',
              'TAP::Parser::IteratorFactory'=> '3.35',
              'TAP::Parser::Multiplexer'=> '3.35',
              'TAP::Parser::Result'   => '3.35',
              'TAP::Parser::Result::Bailout'=> '3.35',
              'TAP::Parser::Result::Comment'=> '3.35',
              'TAP::Parser::Result::Plan'=> '3.35',
              'TAP::Parser::Result::Pragma'=> '3.35',
              'TAP::Parser::Result::Test'=> '3.35',
              'TAP::Parser::Result::Unknown'=> '3.35',
              'TAP::Parser::Result::Version'=> '3.35',
              'TAP::Parser::Result::YAML'=> '3.35',
              'TAP::Parser::ResultFactory'=> '3.35',
              'TAP::Parser::Scheduler'=> '3.35',
              'TAP::Parser::Scheduler::Job'=> '3.35',
              'TAP::Parser::Scheduler::Spinner'=> '3.35',
              'TAP::Parser::Source'   => '3.35',
              'TAP::Parser::SourceHandler'=> '3.35',
              'TAP::Parser::SourceHandler::Executable'=> '3.35',
              'TAP::Parser::SourceHandler::File'=> '3.35',
              'TAP::Parser::SourceHandler::Handle'=> '3.35',
              'TAP::Parser::SourceHandler::Perl'=> '3.35',
              'TAP::Parser::SourceHandler::RawTAP'=> '3.35',
              'TAP::Parser::YAMLish::Reader'=> '3.35',
              'TAP::Parser::YAMLish::Writer'=> '3.35',
              'Test::Builder'         => '1.301001_097',
              'Test::Builder::Module' => '1.301001_097',
              'Test::Builder::Tester' => '1.301001_097',
              'Test::Builder::Tester::Color'=> '1.301001_097',
              'Test::Harness'         => '3.35',
              'Test::More'            => '1.301001_097',
              'Test::Simple'          => '1.301001_097',
              'Test::Stream'          => '1.301001_097',
              'Test::Stream::Block'   => undef,
              'Test::Tester'          => '1.301001_097',
              'Test::Tester::CaptureRunner'=> undef,
              'Test::Tester::Delegate'=> undef,
              'Test::use::ok'         => '1.301001_097',
              'Unicode::Collate'      => '1.10',
              'Unicode::Collate::CJK::Big5'=> '1.10',
              'Unicode::Collate::CJK::GB2312'=> '1.10',
              'Unicode::Collate::CJK::JISX0208'=> '1.10',
              'Unicode::Collate::CJK::Korean'=> '1.10',
              'Unicode::Collate::CJK::Pinyin'=> '1.10',
              'Unicode::Collate::CJK::Stroke'=> '1.10',
              'Unicode::Collate::CJK::Zhuyin'=> '1.10',
              'Unicode::Collate::Locale'=> '1.10',
              'VMS::DCLsym'           => '1.06',
              'XS::APItest'           => '0.70',
              'arybase'               => '0.10',
              'attributes'            => '0.25',
              'autodie'               => '2.26',
              'autodie::Scope::Guard' => '2.26',
              'autodie::Scope::GuardStack'=> '2.26',
              'autodie::ScopeUtil'    => '2.26',
              'autodie::exception'    => '2.26',
              'autodie::exception::system'=> '2.26',
              'autodie::hints'        => '2.26',
              'autodie::skip'         => '2.26',
              'ok'                    => '1.301001_097',
              're'                    => '0.30',
              'warnings'              => '1.30',
          },
          removed => {
          }
      },
      5.020002 => {
          delta_from => 5.020001,
          changed => {
              'CPAN::Author'          => '5.5002',
              'CPAN::CacheMgr'        => '5.5002',
              'CPAN::FTP'             => '5.5006',
              'CPAN::HTTP::Client'    => '1.9601',
              'CPAN::HandleConfig'    => '5.5005',
              'CPAN::Index'           => '1.9601',
              'CPAN::LWP::UserAgent'  => '1.9601',
              'CPAN::Mirrors'         => '1.9601',
              'Config'                => '5.020002',
              'Cwd'                   => '3.48_01',
              'Data::Dumper'          => '2.151_01',
              'Errno'                 => '1.20_05',
              'File::Spec'            => '3.48_01',
              'File::Spec::Cygwin'    => '3.48_01',
              'File::Spec::Epoc'      => '3.48_01',
              'File::Spec::Functions' => '3.48_01',
              'File::Spec::Mac'       => '3.48_01',
              'File::Spec::OS2'       => '3.48_01',
              'File::Spec::Unix'      => '3.48_01',
              'File::Spec::VMS'       => '3.48_01',
              'File::Spec::Win32'     => '3.48_01',
              'IO::Socket'            => '1.38',
              'Module::CoreList'      => '5.20150214',
              'Module::CoreList::TieHashDelta'=> '5.20150214',
              'Module::CoreList::Utils'=> '5.20150214',
              'PerlIO::scalar'        => '0.18_01',
              'Pod::PlainText'        => '2.07',
              'Storable'              => '2.49_01',
              'VMS::DCLsym'           => '1.05_01',
              'VMS::Stdio'            => '2.41',
              'attributes'            => '0.23',
              'feature'               => '1.36_01',
          },
          removed => {
          }
      },
      5.021009 => {
          delta_from => 5.021008,
          changed => {
              'B'                     => '1.56',
              'B::Debug'              => '1.23',
              'B::Deparse'            => '1.33',
              'B::Op_private'         => '5.021009',
              'Benchmark'             => '1.20',
              'CPAN::Author'          => '5.5002',
              'CPAN::CacheMgr'        => '5.5002',
              'CPAN::FTP'             => '5.5006',
              'CPAN::HTTP::Client'    => '1.9601',
              'CPAN::HandleConfig'    => '5.5005',
              'CPAN::Index'           => '1.9601',
              'CPAN::LWP::UserAgent'  => '1.9601',
              'CPAN::Meta::Requirements'=> '2.132',
              'CPAN::Mirrors'         => '1.9601',
              'Carp'                  => '1.35',
              'Carp::Heavy'           => '1.35',
              'Config'                => '5.021009',
              'Config::Perl::V'       => '0.23',
              'Data::Dumper'          => '2.157',
              'Devel::Peek'           => '1.22',
              'DynaLoader'            => '1.31',
              'Encode'                => '2.70',
              'Encode::MIME::Header'  => '2.16',
              'Errno'                 => '1.23',
              'ExtUtils::Miniperl'    => '1.04',
              'HTTP::Tiny'            => '0.054',
              'Module::CoreList'      => '5.20150220',
              'Module::CoreList::TieHashDelta'=> '5.20150220',
              'Module::CoreList::Utils'=> '5.20150220',
              'Opcode'                => '1.32',
              'POSIX'                 => '1.51',
              'Perl::OSType'          => '1.008',
              'PerlIO::scalar'        => '0.22',
              'Pod::Find'             => '1.63',
              'Pod::InputObjects'     => '1.63',
              'Pod::ParseUtils'       => '1.63',
              'Pod::Parser'           => '1.63',
              'Pod::Perldoc'          => '3.25',
              'Pod::Perldoc::BaseTo'  => '3.25',
              'Pod::Perldoc::GetOptsOO'=> '3.25',
              'Pod::Perldoc::ToANSI'  => '3.25',
              'Pod::Perldoc::ToChecker'=> '3.25',
              'Pod::Perldoc::ToMan'   => '3.25',
              'Pod::Perldoc::ToNroff' => '3.25',
              'Pod::Perldoc::ToPod'   => '3.25',
              'Pod::Perldoc::ToRtf'   => '3.25',
              'Pod::Perldoc::ToTerm'  => '3.25',
              'Pod::Perldoc::ToText'  => '3.25',
              'Pod::Perldoc::ToTk'    => '3.25',
              'Pod::Perldoc::ToXml'   => '3.25',
              'Pod::PlainText'        => '2.07',
              'Pod::Select'           => '1.63',
              'Socket'                => '2.018',
              'Storable'              => '2.53',
              'Test::Builder'         => '1.301001_098',
              'Test::Builder::Module' => '1.301001_098',
              'Test::Builder::Tester' => '1.301001_098',
              'Test::Builder::Tester::Color'=> '1.301001_098',
              'Test::More'            => '1.301001_098',
              'Test::Simple'          => '1.301001_098',
              'Test::Stream'          => '1.301001_098',
              'Test::Tester'          => '1.301001_098',
              'Test::use::ok'         => '1.301001_098',
              'Unicode::Collate'      => '1.11',
              'Unicode::Collate::CJK::Big5'=> '1.11',
              'Unicode::Collate::CJK::GB2312'=> '1.11',
              'Unicode::Collate::CJK::JISX0208'=> '1.11',
              'Unicode::Collate::CJK::Korean'=> '1.11',
              'Unicode::Collate::CJK::Pinyin'=> '1.11',
              'Unicode::Collate::CJK::Stroke'=> '1.11',
              'Unicode::Collate::CJK::Zhuyin'=> '1.11',
              'Unicode::Collate::Locale'=> '1.11',
              'Unicode::UCD'          => '0.61',
              'VMS::Stdio'            => '2.41',
              'Win32'                 => '0.51',
              'Win32API::File'        => '0.1202',
              'attributes'            => '0.26',
              'bigint'                => '0.39',
              'bignum'                => '0.39',
              'bigrat'                => '0.39',
              'constant'              => '1.33',
              'encoding'              => '2.13',
              'feature'               => '1.40',
              'ok'                    => '1.301001_098',
              'overload'              => '1.25',
              'perlfaq'               => '5.021009',
              're'                    => '0.31',
              'threads::shared'       => '1.48',
              'warnings'              => '1.31',
          },
          removed => {
          }
      },
      5.021010 => {
          delta_from => 5.021009,
          changed => {
              'App::Cpan'             => '1.63',
              'B'                     => '1.57',
              'B::Deparse'            => '1.34',
              'B::Op_private'         => '5.021010',
              'Benchmark'             => '1.2',
              'CPAN'                  => '2.10',
              'CPAN::Distribution'    => '2.04',
              'CPAN::FirstTime'       => '5.5307',
              'CPAN::HTTP::Credentials'=> '1.9601',
              'CPAN::HandleConfig'    => '5.5006',
              'CPAN::Meta'            => '2.150001',
              'CPAN::Meta::Converter' => '2.150001',
              'CPAN::Meta::Feature'   => '2.150001',
              'CPAN::Meta::History'   => '2.150001',
              'CPAN::Meta::Merge'     => '2.150001',
              'CPAN::Meta::Prereqs'   => '2.150001',
              'CPAN::Meta::Spec'      => '2.150001',
              'CPAN::Meta::Validator' => '2.150001',
              'CPAN::Module'          => '5.5002',
              'CPAN::Plugin'          => '0.95',
              'CPAN::Plugin::Specfile'=> '0.01',
              'CPAN::Shell'           => '5.5005',
              'Carp'                  => '1.36',
              'Carp::Heavy'           => '1.36',
              'Config'                => '5.02101',
              'Cwd'                   => '3.55',
              'DB'                    => '1.08',
              'Data::Dumper'          => '2.158',
              'Devel::PPPort'         => '3.31',
              'DynaLoader'            => '1.32',
              'Encode'                => '2.72',
              'Encode::Alias'         => '2.19',
              'File::Spec'            => '3.55',
              'File::Spec::Cygwin'    => '3.55',
              'File::Spec::Epoc'      => '3.55',
              'File::Spec::Functions' => '3.55',
              'File::Spec::Mac'       => '3.55',
              'File::Spec::OS2'       => '3.55',
              'File::Spec::Unix'      => '3.55',
              'File::Spec::VMS'       => '3.55',
              'File::Spec::Win32'     => '3.55',
              'Getopt::Long'          => '2.45',
              'Locale::Codes'         => '3.34',
              'Locale::Codes::Constants'=> '3.34',
              'Locale::Codes::Country'=> '3.34',
              'Locale::Codes::Country_Codes'=> '3.34',
              'Locale::Codes::Country_Retired'=> '3.34',
              'Locale::Codes::Currency'=> '3.34',
              'Locale::Codes::Currency_Codes'=> '3.34',
              'Locale::Codes::Currency_Retired'=> '3.34',
              'Locale::Codes::LangExt'=> '3.34',
              'Locale::Codes::LangExt_Codes'=> '3.34',
              'Locale::Codes::LangExt_Retired'=> '3.34',
              'Locale::Codes::LangFam'=> '3.34',
              'Locale::Codes::LangFam_Codes'=> '3.34',
              'Locale::Codes::LangFam_Retired'=> '3.34',
              'Locale::Codes::LangVar'=> '3.34',
              'Locale::Codes::LangVar_Codes'=> '3.34',
              'Locale::Codes::LangVar_Retired'=> '3.34',
              'Locale::Codes::Language'=> '3.34',
              'Locale::Codes::Language_Codes'=> '3.34',
              'Locale::Codes::Language_Retired'=> '3.34',
              'Locale::Codes::Script' => '3.34',
              'Locale::Codes::Script_Codes'=> '3.34',
              'Locale::Codes::Script_Retired'=> '3.34',
              'Locale::Country'       => '3.34',
              'Locale::Currency'      => '3.34',
              'Locale::Language'      => '3.34',
              'Locale::Script'        => '3.34',
              'Module::CoreList'      => '5.20150320',
              'Module::CoreList::TieHashDelta'=> '5.20150320',
              'Module::CoreList::Utils'=> '5.20150320',
              'POSIX'                 => '1.52',
              'Pod::Functions'        => '1.09',
              'Pod::Functions::Functions'=> '1.09',
              'Term::Complete'        => '1.403',
              'Test::Builder'         => '1.001014',
              'Test::Builder::IO::Scalar'=> '2.113',
              'Test::Builder::Module' => '1.001014',
              'Test::Builder::Tester' => '1.28',
              'Test::Builder::Tester::Color'=> '1.290001',
              'Test::More'            => '1.001014',
              'Test::Simple'          => '1.001014',
              'Test::Tester'          => '0.114',
              'Test::use::ok'         => '0.16',
              'Text::Balanced'        => '2.03',
              'Text::ParseWords'      => '3.30',
              'Unicode::Collate'      => '1.12',
              'Unicode::Collate::CJK::Big5'=> '1.12',
              'Unicode::Collate::CJK::GB2312'=> '1.12',
              'Unicode::Collate::CJK::JISX0208'=> '1.12',
              'Unicode::Collate::CJK::Korean'=> '1.12',
              'Unicode::Collate::CJK::Pinyin'=> '1.12',
              'Unicode::Collate::CJK::Stroke'=> '1.12',
              'Unicode::Collate::CJK::Zhuyin'=> '1.12',
              'Unicode::Collate::Locale'=> '1.12',
              'XS::APItest'           => '0.71',
              'encoding'              => '2.14',
              'locale'                => '1.06',
              'meta_notation'         => undef,
              'ok'                    => '0.16',
              'parent'                => '0.232',
              're'                    => '0.32',
              'sigtrap'               => '1.08',
              'threads'               => '2.01',
              'utf8'                  => '1.15',
          },
          removed => {
              'Test::CanFork'         => 1,
              'Test::CanThread'       => 1,
              'Test::More::DeepCheck' => 1,
              'Test::More::DeepCheck::Strict'=> 1,
              'Test::More::DeepCheck::Tolerant'=> 1,
              'Test::More::Tools'     => 1,
              'Test::MostlyLike'      => 1,
              'Test::Stream'          => 1,
              'Test::Stream::API'     => 1,
              'Test::Stream::ArrayBase'=> 1,
              'Test::Stream::ArrayBase::Meta'=> 1,
              'Test::Stream::Block'   => 1,
              'Test::Stream::Carp'    => 1,
              'Test::Stream::Context' => 1,
              'Test::Stream::Event'   => 1,
              'Test::Stream::Event::Bail'=> 1,
              'Test::Stream::Event::Child'=> 1,
              'Test::Stream::Event::Diag'=> 1,
              'Test::Stream::Event::Finish'=> 1,
              'Test::Stream::Event::Note'=> 1,
              'Test::Stream::Event::Ok'=> 1,
              'Test::Stream::Event::Plan'=> 1,
              'Test::Stream::Event::Subtest'=> 1,
              'Test::Stream::ExitMagic'=> 1,
              'Test::Stream::ExitMagic::Context'=> 1,
              'Test::Stream::Exporter'=> 1,
              'Test::Stream::Exporter::Meta'=> 1,
              'Test::Stream::ForceExit'=> 1,
              'Test::Stream::IOSets'  => 1,
              'Test::Stream::Meta'    => 1,
              'Test::Stream::PackageUtil'=> 1,
              'Test::Stream::Subtest' => 1,
              'Test::Stream::Tester'  => 1,
              'Test::Stream::Tester::Checks'=> 1,
              'Test::Stream::Tester::Checks::Event'=> 1,
              'Test::Stream::Tester::Events'=> 1,
              'Test::Stream::Tester::Events::Event'=> 1,
              'Test::Stream::Tester::Grab'=> 1,
              'Test::Stream::Threads' => 1,
              'Test::Stream::Toolset' => 1,
              'Test::Stream::Util'    => 1,
          }
      },
      5.021011 => {
          delta_from => 5.021010,
          changed => {
              'B'                     => '1.58',
              'B::Deparse'            => '1.35',
              'B::Op_private'         => '5.021011',
              'CPAN'                  => '2.11',
              'Config'                => '5.021011',
              'Config::Perl::V'       => '0.24',
              'Cwd'                   => '3.56',
              'ExtUtils::Miniperl'    => '1.05',
              'ExtUtils::ParseXS'     => '3.28',
              'ExtUtils::ParseXS::Constants'=> '3.28',
              'ExtUtils::ParseXS::CountLines'=> '3.28',
              'ExtUtils::ParseXS::Eval'=> '3.28',
              'ExtUtils::ParseXS::Utilities'=> '3.28',
              'ExtUtils::Typemaps'    => '3.28',
              'ExtUtils::Typemaps::Cmd'=> '3.28',
              'ExtUtils::Typemaps::InputMap'=> '3.28',
              'ExtUtils::Typemaps::OutputMap'=> '3.28',
              'ExtUtils::Typemaps::Type'=> '3.28',
              'File::Spec'            => '3.56',
              'File::Spec::Cygwin'    => '3.56',
              'File::Spec::Epoc'      => '3.56',
              'File::Spec::Functions' => '3.56',
              'File::Spec::Mac'       => '3.56',
              'File::Spec::OS2'       => '3.56',
              'File::Spec::Unix'      => '3.56',
              'File::Spec::VMS'       => '3.56',
              'File::Spec::Win32'     => '3.56',
              'IO::Socket::IP'        => '0.37',
              'Module::CoreList'      => '5.20150420',
              'Module::CoreList::TieHashDelta'=> '5.20150420',
              'Module::CoreList::Utils'=> '5.20150420',
              'PerlIO::mmap'          => '0.014',
              'XS::APItest'           => '0.72',
              'attributes'            => '0.27',
              'if'                    => '0.0604',
              'utf8'                  => '1.16',
              'warnings'              => '1.32',
          },
          removed => {
          }
      },
      5.022000 => {
          delta_from => 5.021011,
          changed => {
              'B::Op_private'         => '5.022000',
              'Config'                => '5.022',
              'ExtUtils::Command::MM' => '7.04_01',
              'ExtUtils::Liblist'     => '7.04_01',
              'ExtUtils::Liblist::Kid'=> '7.04_01',
              'ExtUtils::MM'          => '7.04_01',
              'ExtUtils::MM_AIX'      => '7.04_01',
              'ExtUtils::MM_Any'      => '7.04_01',
              'ExtUtils::MM_BeOS'     => '7.04_01',
              'ExtUtils::MM_Cygwin'   => '7.04_01',
              'ExtUtils::MM_DOS'      => '7.04_01',
              'ExtUtils::MM_Darwin'   => '7.04_01',
              'ExtUtils::MM_MacOS'    => '7.04_01',
              'ExtUtils::MM_NW5'      => '7.04_01',
              'ExtUtils::MM_OS2'      => '7.04_01',
              'ExtUtils::MM_QNX'      => '7.04_01',
              'ExtUtils::MM_UWIN'     => '7.04_01',
              'ExtUtils::MM_Unix'     => '7.04_01',
              'ExtUtils::MM_VMS'      => '7.04_01',
              'ExtUtils::MM_VOS'      => '7.04_01',
              'ExtUtils::MM_Win32'    => '7.04_01',
              'ExtUtils::MM_Win95'    => '7.04_01',
              'ExtUtils::MY'          => '7.04_01',
              'ExtUtils::MakeMaker'   => '7.04_01',
              'ExtUtils::MakeMaker::Config'=> '7.04_01',
              'ExtUtils::MakeMaker::Locale'=> '7.04_01',
              'ExtUtils::MakeMaker::version'=> '7.04_01',
              'ExtUtils::MakeMaker::version::regex'=> '7.04_01',
              'ExtUtils::MakeMaker::version::vpp'=> '7.04_01',
              'ExtUtils::Mkbootstrap' => '7.04_01',
              'ExtUtils::Mksymlists'  => '7.04_01',
              'ExtUtils::testlib'     => '7.04_01',
              'Module::CoreList'      => '5.20150520',
              'Module::CoreList::TieHashDelta'=> '5.20150520',
              'Module::CoreList::Utils'=> '5.20150520',
              'POSIX'                 => '1.53',
              'PerlIO::via::QuotedPrint'=> '0.08',
              'overload'              => '1.26',
              'utf8'                  => '1.17',
          },
          removed => {
          }
      },
      5.023000 => {
          delta_from => 5.022000,
          changed => {
              'B::Op_private'         => '5.023000',
              'CPAN::Meta'            => '2.150005',
              'CPAN::Meta::Converter' => '2.150005',
              'CPAN::Meta::Feature'   => '2.150005',
              'CPAN::Meta::History'   => '2.150005',
              'CPAN::Meta::Merge'     => '2.150005',
              'CPAN::Meta::Prereqs'   => '2.150005',
              'CPAN::Meta::Requirements'=> '2.133',
              'CPAN::Meta::Spec'      => '2.150005',
              'CPAN::Meta::Validator' => '2.150005',
              'CPAN::Meta::YAML'      => '0.016',
              'Config'                => '5.023',
              'Encode'                => '2.73',
              'ExtUtils::CBuilder'    => '0.280223',
              'ExtUtils::CBuilder::Base'=> '0.280223',
              'ExtUtils::CBuilder::Platform::Unix'=> '0.280223',
              'ExtUtils::CBuilder::Platform::VMS'=> '0.280223',
              'ExtUtils::CBuilder::Platform::Windows'=> '0.280223',
              'ExtUtils::CBuilder::Platform::Windows::BCC'=> '0.280223',
              'ExtUtils::CBuilder::Platform::Windows::GCC'=> '0.280223',
              'ExtUtils::CBuilder::Platform::Windows::MSVC'=> '0.280223',
              'ExtUtils::CBuilder::Platform::aix'=> '0.280223',
              'ExtUtils::CBuilder::Platform::android'=> '0.280223',
              'ExtUtils::CBuilder::Platform::cygwin'=> '0.280223',
              'ExtUtils::CBuilder::Platform::darwin'=> '0.280223',
              'ExtUtils::CBuilder::Platform::dec_osf'=> '0.280223',
              'ExtUtils::CBuilder::Platform::os2'=> '0.280223',
              'Fatal'                 => '2.27',
              'Getopt::Long'          => '2.46',
              'HTTP::Tiny'            => '0.056',
              'List::Util'            => '1.42_01',
              'List::Util::XS'        => '1.42_01',
              'Locale::Codes'         => '3.35',
              'Locale::Codes::Constants'=> '3.35',
              'Locale::Codes::Country'=> '3.35',
              'Locale::Codes::Country_Codes'=> '3.35',
              'Locale::Codes::Country_Retired'=> '3.35',
              'Locale::Codes::Currency'=> '3.35',
              'Locale::Codes::Currency_Codes'=> '3.35',
              'Locale::Codes::Currency_Retired'=> '3.35',
              'Locale::Codes::LangExt'=> '3.35',
              'Locale::Codes::LangExt_Codes'=> '3.35',
              'Locale::Codes::LangExt_Retired'=> '3.35',
              'Locale::Codes::LangFam'=> '3.35',
              'Locale::Codes::LangFam_Codes'=> '3.35',
              'Locale::Codes::LangFam_Retired'=> '3.35',
              'Locale::Codes::LangVar'=> '3.35',
              'Locale::Codes::LangVar_Codes'=> '3.35',
              'Locale::Codes::LangVar_Retired'=> '3.35',
              'Locale::Codes::Language'=> '3.35',
              'Locale::Codes::Language_Codes'=> '3.35',
              'Locale::Codes::Language_Retired'=> '3.35',
              'Locale::Codes::Script' => '3.35',
              'Locale::Codes::Script_Codes'=> '3.35',
              'Locale::Codes::Script_Retired'=> '3.35',
              'Locale::Country'       => '3.35',
              'Locale::Currency'      => '3.35',
              'Locale::Language'      => '3.35',
              'Locale::Script'        => '3.35',
              'Math::BigFloat'        => '1.999701',
              'Math::BigInt'          => '1.999701',
              'Math::BigInt::Calc'    => '1.999701',
              'Math::BigInt::CalcEmu' => '1.999701',
              'Math::BigRat'          => '0.260801',
              'Module::CoreList'      => '5.20150620',
              'Module::CoreList::TieHashDelta'=> '5.20150620',
              'Module::CoreList::Utils'=> '5.20150620',
              'Module::Metadata'      => '1.000027',
              'Net::Cmd'              => '3.06',
              'Net::Config'           => '3.06',
              'Net::Domain'           => '3.06',
              'Net::FTP'              => '3.06',
              'Net::FTP::A'           => '3.06',
              'Net::FTP::E'           => '3.06',
              'Net::FTP::I'           => '3.06',
              'Net::FTP::L'           => '3.06',
              'Net::FTP::dataconn'    => '3.06',
              'Net::NNTP'             => '3.06',
              'Net::Netrc'            => '3.06',
              'Net::POP3'             => '3.06',
              'Net::SMTP'             => '3.06',
              'Net::Time'             => '3.06',
              'POSIX'                 => '1.54',
              'Parse::CPAN::Meta'     => '1.4417',
              'Pod::Simple'           => '3.30',
              'Pod::Simple::BlackBox' => '3.30',
              'Pod::Simple::Checker'  => '3.30',
              'Pod::Simple::Debug'    => '3.30',
              'Pod::Simple::DumpAsText'=> '3.30',
              'Pod::Simple::DumpAsXML'=> '3.30',
              'Pod::Simple::HTML'     => '3.30',
              'Pod::Simple::HTMLBatch'=> '3.30',
              'Pod::Simple::LinkSection'=> '3.30',
              'Pod::Simple::Methody'  => '3.30',
              'Pod::Simple::Progress' => '3.30',
              'Pod::Simple::PullParser'=> '3.30',
              'Pod::Simple::PullParserEndToken'=> '3.30',
              'Pod::Simple::PullParserStartToken'=> '3.30',
              'Pod::Simple::PullParserTextToken'=> '3.30',
              'Pod::Simple::PullParserToken'=> '3.30',
              'Pod::Simple::RTF'      => '3.30',
              'Pod::Simple::Search'   => '3.30',
              'Pod::Simple::SimpleTree'=> '3.30',
              'Pod::Simple::Text'     => '3.30',
              'Pod::Simple::TextContent'=> '3.30',
              'Pod::Simple::TiedOutFH'=> '3.30',
              'Pod::Simple::Transcode'=> '3.30',
              'Pod::Simple::TranscodeDumb'=> '3.30',
              'Pod::Simple::TranscodeSmart'=> '3.30',
              'Pod::Simple::XHTML'    => '3.30',
              'Pod::Simple::XMLOutStream'=> '3.30',
              'Pod::Usage'            => '1.67',
              'Scalar::Util'          => '1.42_01',
              'Socket'                => '2.019',
              'Sub::Util'             => '1.42_01',
              'Time::Piece'           => '1.30',
              'Time::Seconds'         => '1.30',
              'UNIVERSAL'             => '1.13',
              'Unicode'               => '8.0.0',
              'XS::APItest'           => '0.73',
              'autodie'               => '2.27',
              'autodie::Scope::Guard' => '2.27',
              'autodie::Scope::GuardStack'=> '2.27',
              'autodie::Util'         => '2.27',
              'autodie::exception'    => '2.27',
              'autodie::exception::system'=> '2.27',
              'autodie::hints'        => '2.27',
              'autodie::skip'         => '2.27',
              'encoding'              => '2.15',
              'feature'               => '1.41',
              'parent'                => '0.234',
              'threads'               => '2.02',
          },
          removed => {
          }
      },
  );
  
  sub is_core
  {
      my $module = shift;
      $module = shift if eval { $module->isa(__PACKAGE__) } && @_ > 0 && defined($_[0]) && $_[0] =~ /^\w/;
      my ($module_version, $perl_version);
  
      $module_version = shift if @_ > 0;
      $perl_version   = @_ > 0 ? shift : $];
  
      my $first_release = first_release($module);
  
      return 0 if !defined($first_release) || $first_release > $perl_version;
  
      my $final_release = removed_from($module);
  
      return 0 if defined($final_release) && $perl_version >= $final_release;
  
      # If a minimum version of the module was specified:
      # Step through all perl releases ($prn)
      # so we can find what version of the module
      # was included in the specified version of perl.
      # On the way if we pass the required module version, we can
      # short-circuit and return true
      if (defined($module_version)) {
          # The Perl releases aren't a linear sequence, but a tree. We need to build the path
          # of releases from 5 to the specified release, and follow the module's version(s)
          # along that path.
          my @releases = ($perl_version);
          my $rel = $perl_version;
          while (defined($rel)) {
              # XXX: This line is a sign of failure. -- rjbs, 2015-04-15
              my $this_delta = $delta{$rel} || $delta{ sprintf '%0.6f', $rel };
              $rel = $this_delta->{delta_from};
              unshift(@releases, $rel) if defined($rel);
          }
          RELEASE:
          foreach my $prn (@releases) {
              next RELEASE if $prn <= $first_release;
              last RELEASE if $prn > $perl_version;
              next unless defined(my $next_module_version
                                     = $delta{$prn}->{changed}->{$module});
              return 1 if version->parse($next_module_version) >= version->parse($module_version);
          }
          return 0;
      }
  
      return 1 if !defined($final_release);
  
      return $perl_version <= $final_release;
  }
  
  for my $version (sort { $a <=> $b } keys %delta) {
      my $data = $delta{$version};
  
      tie %{$version{$version}}, 'Module::CoreList::TieHashDelta',
          $data->{changed}, $data->{removed},
          $data->{delta_from} ? $version{$data->{delta_from}} : undef;
  }
  
  %deprecated = (
      5.011    => {
          changed => { map { $_ => 1 } qw/
              Class::ISA
              Pod::Plainer
              Shell
              Switch
          /},
      },
      5.011001 => { delta_from => 5.011 },
      5.011002 => { delta_from => 5.011001 },
      5.011003 => { delta_from => 5.011002 },
      5.011004 => { delta_from => 5.011003 },
      5.011005 => { delta_from => 5.011004 },
  
      5.012    => { delta_from => 5.011005 },
      5.012001 => { delta_from => 5.012 },
      5.012002 => { delta_from => 5.012001 },
      5.012003 => { delta_from => 5.012002 },
      5.012004 => { delta_from => 5.012003 },
      5.012005 => { delta_from => 5.012004 },
  
      5.013    => { delta_from => 5.012005 },
      5.013001 => {
          delta_from => 5.013,
          removed => { map { $_ => 1 } qw/
              Class::ISA
              Pod::Plainer
              Switch
          /},
      },
      5.013002 => { delta_from => 5.013001 },
      5.013003 => { delta_from => 5.013002 },
      5.013004 => { delta_from => 5.013003 },
      5.013005 => { delta_from => 5.013004 },
      5.013006 => { delta_from => 5.013005 },
      5.013007 => { delta_from => 5.013006 },
      5.013008 => { delta_from => 5.013007 },
      5.013009 => { delta_from => 5.013008 },
      5.01301  => { delta_from => 5.013009 },
      5.013011 => { delta_from => 5.01301  },
  
      5.014    => { delta_from => 5.013011 },
      5.014001 => { delta_from => 5.014    },
      5.014002 => { delta_from => 5.014001 },
      5.014003 => { delta_from => 5.014002 },
      5.014004 => { delta_from => 5.014003 },
  
      5.015    => {
          delta_from => 5.014004,
          removed => { Shell => 1 },
      },
      5.015001 => { delta_from => 5.015    },
      5.015002 => { delta_from => 5.015001 },
      5.015003 => { delta_from => 5.015002 },
      5.015004 => { delta_from => 5.015003 },
      5.015005 => { delta_from => 5.015004 },
      5.015006 => { delta_from => 5.015005 },
      5.015007 => { delta_from => 5.015006 },
      5.015008 => { delta_from => 5.015007 },
      5.015009 => { delta_from => 5.015008 },
  
      5.016    => { delta_from => 5.015009 },
      5.016001 => { delta_from => 5.016    },
      5.016002 => { delta_from => 5.016001 },
      5.016003 => { delta_from => 5.016002 },
  
      5.017    => { delta_from => 5.016003 },
      5.017001 => { delta_from => 5.017    },
      5.017002 => { delta_from => 5.017001 },
      5.017003 => { delta_from => 5.017002 },
      5.017004 => { delta_from => 5.017003 },
      5.017005 => { delta_from => 5.017004 },
      5.017006 => { delta_from => 5.017005 },
      5.017007 => { delta_from => 5.017006 },
      5.017008 => {
          delta_from => 5.017007,
          changed => { 'Pod::LaTeX' => 1 },
      },
      5.017009 => {
          delta_from => 5.017008,
          changed => { map { $_ => 1 } qw/
              Archive::Extract
              B::Lint
              B::Lint::Debug
              CPANPLUS
              CPANPLUS::Backend
              CPANPLUS::Backend::RV
              CPANPLUS::Config
              CPANPLUS::Config::HomeEnv
              CPANPLUS::Configure
              CPANPLUS::Configure::Setup
              CPANPLUS::Dist
              CPANPLUS::Dist::Autobundle
              CPANPLUS::Dist::Base
              CPANPLUS::Dist::Build
              CPANPLUS::Dist::Build::Constants
              CPANPLUS::Dist::MM
              CPANPLUS::Dist::Sample
              CPANPLUS::Error
              CPANPLUS::Internals
              CPANPLUS::Internals::Constants
              CPANPLUS::Internals::Constants::Report
              CPANPLUS::Internals::Extract
              CPANPLUS::Internals::Fetch
              CPANPLUS::Internals::Report
              CPANPLUS::Internals::Search
              CPANPLUS::Internals::Source
              CPANPLUS::Internals::Source::Memory
              CPANPLUS::Internals::Source::SQLite
              CPANPLUS::Internals::Source::SQLite::Tie
              CPANPLUS::Internals::Utils
              CPANPLUS::Internals::Utils::Autoflush
              CPANPLUS::Module
              CPANPLUS::Module::Author
              CPANPLUS::Module::Author::Fake
              CPANPLUS::Module::Checksums
              CPANPLUS::Module::Fake
              CPANPLUS::Module::Signature
              CPANPLUS::Selfupdate
              CPANPLUS::Shell
              CPANPLUS::Shell::Classic
              CPANPLUS::Shell::Default
              CPANPLUS::Shell::Default::Plugins::CustomSource
              CPANPLUS::Shell::Default::Plugins::Remote
              CPANPLUS::Shell::Default::Plugins::Source
              Devel::InnerPackage
              File::CheckTree
              Log::Message
              Log::Message::Config
              Log::Message::Handlers
              Log::Message::Item
              Log::Message::Simple
              Module::Pluggable
              Module::Pluggable::Object
              Object::Accessor
              Term::UI
              Term::UI::History
              Text::Soundex
          /},
      },
      5.01701  => { delta_from => 5.017009 },
      5.017011 => { delta_from => 5.01701  },
  
      5.018    => { delta_from => 5.017011 },
      5.018001 => {
          delta_from => 5.018,
          changed => {
          },
          removed => {
          }
      },
      5.018002 => {
          delta_from => 5.018001,
          changed => {
          },
          removed => {
          }
      },
      5.018003 => {
          delta_from => 5.018,
          changed => {
          },
          removed => {
          }
      },
      5.018004 => {
          delta_from => 5.018,
          changed => {
          },
          removed => {
          }
      },
  
      5.019    => {
          delta_from => 5.018,
          changed => { 'Module::Build' => 1 },
          removed => { map { $_ => 1 } qw/
              Archive::Extract
              B::Lint
              B::Lint::Debug
              CPANPLUS
              CPANPLUS::Backend
              CPANPLUS::Backend::RV
              CPANPLUS::Config
              CPANPLUS::Config::HomeEnv
              CPANPLUS::Configure
              CPANPLUS::Configure::Setup
              CPANPLUS::Dist
              CPANPLUS::Dist::Autobundle
              CPANPLUS::Dist::Base
              CPANPLUS::Dist::Build
              CPANPLUS::Dist::Build::Constants
              CPANPLUS::Dist::MM
              CPANPLUS::Dist::Sample
              CPANPLUS::Error
              CPANPLUS::Internals
              CPANPLUS::Internals::Constants
              CPANPLUS::Internals::Constants::Report
              CPANPLUS::Internals::Extract
              CPANPLUS::Internals::Fetch
              CPANPLUS::Internals::Report
              CPANPLUS::Internals::Search
              CPANPLUS::Internals::Source
              CPANPLUS::Internals::Source::Memory
              CPANPLUS::Internals::Source::SQLite
              CPANPLUS::Internals::Source::SQLite::Tie
              CPANPLUS::Internals::Utils
              CPANPLUS::Internals::Utils::Autoflush
              CPANPLUS::Module
              CPANPLUS::Module::Author
              CPANPLUS::Module::Author::Fake
              CPANPLUS::Module::Checksums
              CPANPLUS::Module::Fake
              CPANPLUS::Module::Signature
              CPANPLUS::Selfupdate
              CPANPLUS::Shell
              CPANPLUS::Shell::Classic
              CPANPLUS::Shell::Default
              CPANPLUS::Shell::Default::Plugins::CustomSource
              CPANPLUS::Shell::Default::Plugins::Remote
              CPANPLUS::Shell::Default::Plugins::Source
              Devel::InnerPackage
              File::CheckTree
              Log::Message
              Log::Message::Config
              Log::Message::Handlers
              Log::Message::Item
              Log::Message::Simple
              Module::Pluggable
              Module::Pluggable::Object
              Object::Accessor
              Pod::LaTeX
              Term::UI
              Term::UI::History
              Text::Soundex
          /}
      },
      5.019001 => {
          delta_from => 5.019,
          changed => {
          },
          removed => {
          }
      },
      5.019002 => {
          delta_from => 5.019001,
          changed => {
          },
          removed => {
          }
      },
      5.019003 => {
          delta_from => 5.019002,
          changed => {
          },
          removed => {
          }
      },
      5.019004 => {
          delta_from => 5.019003,
          changed => {
              'Module::Build::Base'   => '1',
              'Module::Build::Compat' => '1',
              'Module::Build::Config' => '1',
              'Module::Build::ConfigData'=> '1',
              'Module::Build::Cookbook'=> '1',
              'Module::Build::Dumper' => '1',
              'Module::Build::ModuleInfo'=> '1',
              'Module::Build::Notes'  => '1',
              'Module::Build::PPMMaker'=> '1',
              'Module::Build::Platform::Default'=> '1',
              'Module::Build::Platform::MacOS'=> '1',
              'Module::Build::Platform::Unix'=> '1',
              'Module::Build::Platform::VMS'=> '1',
              'Module::Build::Platform::VOS'=> '1',
              'Module::Build::Platform::Windows'=> '1',
              'Module::Build::Platform::aix'=> '1',
              'Module::Build::Platform::cygwin'=> '1',
              'Module::Build::Platform::darwin'=> '1',
              'Module::Build::Platform::os2'=> '1',
              'Module::Build::PodParser'=> '1',
              'Module::Build::Version'=> '1',
              'Module::Build::YAML'   => '1',
              'inc::latest'           => '1',
          },
          removed => {
          }
      },
      5.019005 => {
          delta_from => 5.019004,
          changed => {
          },
          removed => {
          }
      },
      5.019006 => {
          delta_from => 5.019005,
          changed => {
              'Package::Constants'    => '1',
          },
          removed => {
          }
      },
      5.019007 => {
          delta_from => 5.019006,
          changed => {
              'CGI'                   => '1',
              'CGI::Apache'           => '1',
              'CGI::Carp'             => '1',
              'CGI::Cookie'           => '1',
              'CGI::Fast'             => '1',
              'CGI::Pretty'           => '1',
              'CGI::Push'             => '1',
              'CGI::Switch'           => '1',
              'CGI::Util'             => '1',
          },
          removed => {
          }
      },
      5.019008 => {
          delta_from => 5.019007,
          changed => {
          },
          removed => {
          }
      },
      5.019009 => {
          delta_from => 5.019008,
          changed => {
          },
          removed => {
          }
      },
      5.01901 => {
          delta_from => 5.019009,
          changed => {
          },
          removed => {
          }
      },
      5.019011 => {
          delta_from => 5.019010,
          changed => {
          },
          removed => {
          }
      },
      5.020000 => {
          delta_from => 5.019011,
          changed => {
          },
          removed => {
          }
      },
      5.021000 => {
          delta_from => 5.020000,
          changed => {
          },
          removed => {
              'CGI'                   => 1,
              'CGI::Apache'           => 1,
              'CGI::Carp'             => 1,
              'CGI::Cookie'           => 1,
              'CGI::Fast'             => 1,
              'CGI::Pretty'           => 1,
              'CGI::Push'             => 1,
              'CGI::Switch'           => 1,
              'CGI::Util'             => 1,
              'Module::Build'         => 1,
              'Module::Build::Base'   => 1,
              'Module::Build::Compat' => 1,
              'Module::Build::Config' => 1,
              'Module::Build::ConfigData'=> 1,
              'Module::Build::Cookbook'=> 1,
              'Module::Build::Dumper' => 1,
              'Module::Build::ModuleInfo'=> 1,
              'Module::Build::Notes'  => 1,
              'Module::Build::PPMMaker'=> 1,
              'Module::Build::Platform::Default'=> 1,
              'Module::Build::Platform::MacOS'=> 1,
              'Module::Build::Platform::Unix'=> 1,
              'Module::Build::Platform::VMS'=> 1,
              'Module::Build::Platform::VOS'=> 1,
              'Module::Build::Platform::Windows'=> 1,
              'Module::Build::Platform::aix'=> 1,
              'Module::Build::Platform::cygwin'=> 1,
              'Module::Build::Platform::darwin'=> 1,
              'Module::Build::Platform::os2'=> 1,
              'Module::Build::PodParser'=> 1,
              'Module::Build::Version'=> 1,
              'Module::Build::YAML'   => 1,
              'Package::Constants'    => 1,
              'Simple'                => 1,
              'inc::latest'           => 1,
          }
      },
      5.021001 => {
          delta_from => 5.021000,
          changed => {
          },
          removed => {
          }
      },
      5.021002 => {
          delta_from => 5.021001,
          changed => {
          },
          removed => {
          }
      },
      5.021003 => {
          delta_from => 5.021002,
          changed => {
          },
          removed => {
          }
      },
      5.020001 => {
          delta_from => 5.020000,
          changed => {
          },
          removed => {
          }
      },
      5.021004 => {
          delta_from => 5.021003,
          changed => {
          },
          removed => {
          }
      },
      5.021005 => {
          delta_from => 5.021004,
          changed => {
          },
          removed => {
          }
      },
      5.021006 => {
          delta_from => 5.021005,
          changed => {
          },
          removed => {
          }
      },
      5.021007 => {
          delta_from => 5.021006,
          changed => {
          },
          removed => {
          }
      },
      5.021008 => {
          delta_from => 5.021007,
          changed => {
          },
          removed => {
          }
      },
      5.020002 => {
          delta_from => 5.020001,
          changed => {
          },
          removed => {
          }
      },
      5.021009 => {
          delta_from => 5.021008,
          changed => {
          },
          removed => {
          }
      },
      5.021010 => {
          delta_from => 5.021009,
          changed => {
          },
          removed => {
          }
      },
      5.021011 => {
          delta_from => 5.02101,
          changed => {
          },
          removed => {
          }
      },
      5.022000 => {
          delta_from => 5.021011,
          changed => {
          },
          removed => {
          }
      },
      5.023000 => {
          delta_from => 5.022000,
          changed => {
          },
          removed => {
          }
      },
  );
  
  for my $version (sort { $a <=> $b } keys %deprecated) {
      my $data = $deprecated{$version};
  
      tie %{ $deprecated{$version} }, 'Module::CoreList::TieHashDelta',
          $data->{changed}, $data->{removed},
          $data->{delta_from} ? $deprecated{ $data->{delta_from} } : undef;
  }
  
  %upstream = (
      'App::Cpan'             => 'cpan',
      'App::Prove'            => 'cpan',
      'App::Prove::State'     => 'cpan',
      'App::Prove::State::Result'=> 'cpan',
      'App::Prove::State::Result::Test'=> 'cpan',
      'Archive::Tar'          => 'cpan',
      'Archive::Tar::Constant'=> 'cpan',
      'Archive::Tar::File'    => 'cpan',
      'AutoLoader'            => 'cpan',
      'AutoSplit'             => 'cpan',
      'B::Debug'              => 'cpan',
      'CPAN'                  => 'cpan',
      'CPAN::Author'          => 'cpan',
      'CPAN::Bundle'          => 'cpan',
      'CPAN::CacheMgr'        => 'cpan',
      'CPAN::Complete'        => 'cpan',
      'CPAN::Debug'           => 'cpan',
      'CPAN::DeferredCode'    => 'cpan',
      'CPAN::Distribution'    => 'cpan',
      'CPAN::Distroprefs'     => 'cpan',
      'CPAN::Distrostatus'    => 'cpan',
      'CPAN::Exception::RecursiveDependency'=> 'cpan',
      'CPAN::Exception::blocked_urllist'=> 'cpan',
      'CPAN::Exception::yaml_not_installed'=> 'cpan',
      'CPAN::Exception::yaml_process_error'=> 'cpan',
      'CPAN::FTP'             => 'cpan',
      'CPAN::FTP::netrc'      => 'cpan',
      'CPAN::FirstTime'       => 'cpan',
      'CPAN::HTTP::Client'    => 'cpan',
      'CPAN::HTTP::Credentials'=> 'cpan',
      'CPAN::HandleConfig'    => 'cpan',
      'CPAN::Index'           => 'cpan',
      'CPAN::InfoObj'         => 'cpan',
      'CPAN::Kwalify'         => 'cpan',
      'CPAN::LWP::UserAgent'  => 'cpan',
      'CPAN::Meta'            => 'cpan',
      'CPAN::Meta::Converter' => 'cpan',
      'CPAN::Meta::Feature'   => 'cpan',
      'CPAN::Meta::History'   => 'cpan',
      'CPAN::Meta::Merge'     => 'cpan',
      'CPAN::Meta::Prereqs'   => 'cpan',
      'CPAN::Meta::Requirements'=> 'cpan',
      'CPAN::Meta::Spec'      => 'cpan',
      'CPAN::Meta::Validator' => 'cpan',
      'CPAN::Meta::YAML'      => 'cpan',
      'CPAN::Mirrors'         => 'cpan',
      'CPAN::Module'          => 'cpan',
      'CPAN::Nox'             => 'cpan',
      'CPAN::Plugin'          => 'cpan',
      'CPAN::Plugin::Specfile'=> 'cpan',
      'CPAN::Prompt'          => 'cpan',
      'CPAN::Queue'           => 'cpan',
      'CPAN::Shell'           => 'cpan',
      'CPAN::Tarzip'          => 'cpan',
      'CPAN::URL'             => 'cpan',
      'CPAN::Version'         => 'cpan',
      'Compress::Raw::Bzip2'  => 'cpan',
      'Compress::Raw::Zlib'   => 'cpan',
      'Compress::Zlib'        => 'cpan',
      'Config::Perl::V'       => 'cpan',
      'DB_File'               => 'cpan',
      'Devel::PPPort'         => 'cpan',
      'Digest'                => 'cpan',
      'Digest::MD5'           => 'cpan',
      'Digest::SHA'           => 'cpan',
      'Digest::base'          => 'cpan',
      'Digest::file'          => 'cpan',
      'Encode'                => 'cpan',
      'Encode::Alias'         => 'cpan',
      'Encode::Byte'          => 'cpan',
      'Encode::CJKConstants'  => 'cpan',
      'Encode::CN'            => 'cpan',
      'Encode::CN::HZ'        => 'cpan',
      'Encode::Config'        => 'cpan',
      'Encode::EBCDIC'        => 'cpan',
      'Encode::Encoder'       => 'cpan',
      'Encode::Encoding'      => 'cpan',
      'Encode::GSM0338'       => 'cpan',
      'Encode::Guess'         => 'cpan',
      'Encode::JP'            => 'cpan',
      'Encode::JP::H2Z'       => 'cpan',
      'Encode::JP::JIS7'      => 'cpan',
      'Encode::KR'            => 'cpan',
      'Encode::KR::2022_KR'   => 'cpan',
      'Encode::MIME::Header'  => 'cpan',
      'Encode::MIME::Header::ISO_2022_JP'=> 'cpan',
      'Encode::MIME::Name'    => 'cpan',
      'Encode::Symbol'        => 'cpan',
      'Encode::TW'            => 'cpan',
      'Encode::Unicode'       => 'cpan',
      'Encode::Unicode::UTF7' => 'cpan',
      'ExtUtils::Command'     => 'cpan',
      'ExtUtils::Command::MM' => 'cpan',
      'ExtUtils::Constant'    => 'cpan',
      'ExtUtils::Constant::Base'=> 'cpan',
      'ExtUtils::Constant::ProxySubs'=> 'cpan',
      'ExtUtils::Constant::Utils'=> 'cpan',
      'ExtUtils::Constant::XS'=> 'cpan',
      'ExtUtils::Install'     => 'cpan',
      'ExtUtils::Installed'   => 'cpan',
      'ExtUtils::Liblist'     => 'cpan',
      'ExtUtils::Liblist::Kid'=> 'cpan',
      'ExtUtils::MM'          => 'cpan',
      'ExtUtils::MM_AIX'      => 'cpan',
      'ExtUtils::MM_Any'      => 'cpan',
      'ExtUtils::MM_BeOS'     => 'cpan',
      'ExtUtils::MM_Cygwin'   => 'cpan',
      'ExtUtils::MM_DOS'      => 'cpan',
      'ExtUtils::MM_Darwin'   => 'cpan',
      'ExtUtils::MM_MacOS'    => 'cpan',
      'ExtUtils::MM_NW5'      => 'cpan',
      'ExtUtils::MM_OS2'      => 'cpan',
      'ExtUtils::MM_QNX'      => 'cpan',
      'ExtUtils::MM_UWIN'     => 'cpan',
      'ExtUtils::MM_Unix'     => 'cpan',
      'ExtUtils::MM_VMS'      => 'cpan',
      'ExtUtils::MM_VOS'      => 'cpan',
      'ExtUtils::MM_Win32'    => 'cpan',
      'ExtUtils::MM_Win95'    => 'cpan',
      'ExtUtils::MY'          => 'cpan',
      'ExtUtils::MakeMaker'   => 'cpan',
      'ExtUtils::MakeMaker::Config'=> 'cpan',
      'ExtUtils::MakeMaker::Locale'=> 'cpan',
      'ExtUtils::MakeMaker::version'=> 'cpan',
      'ExtUtils::MakeMaker::version::regex'=> 'cpan',
      'ExtUtils::MakeMaker::version::vpp'=> 'cpan',
      'ExtUtils::Manifest'    => 'cpan',
      'ExtUtils::Mkbootstrap' => 'cpan',
      'ExtUtils::Mksymlists'  => 'cpan',
      'ExtUtils::Packlist'    => 'cpan',
      'ExtUtils::testlib'     => 'cpan',
      'Fatal'                 => 'cpan',
      'File::Fetch'           => 'cpan',
      'File::GlobMapper'      => 'cpan',
      'File::Path'            => 'cpan',
      'File::Temp'            => 'cpan',
      'Filter::Util::Call'    => 'cpan',
      'Getopt::Long'          => 'cpan',
      'HTTP::Tiny'            => 'cpan',
      'IO::Compress::Adapter::Bzip2'=> 'cpan',
      'IO::Compress::Adapter::Deflate'=> 'cpan',
      'IO::Compress::Adapter::Identity'=> 'cpan',
      'IO::Compress::Base'    => 'cpan',
      'IO::Compress::Base::Common'=> 'cpan',
      'IO::Compress::Bzip2'   => 'cpan',
      'IO::Compress::Deflate' => 'cpan',
      'IO::Compress::Gzip'    => 'cpan',
      'IO::Compress::Gzip::Constants'=> 'cpan',
      'IO::Compress::RawDeflate'=> 'cpan',
      'IO::Compress::Zip'     => 'cpan',
      'IO::Compress::Zip::Constants'=> 'cpan',
      'IO::Compress::Zlib::Constants'=> 'cpan',
      'IO::Compress::Zlib::Extra'=> 'cpan',
      'IO::Socket::IP'        => 'cpan',
      'IO::Uncompress::Adapter::Bunzip2'=> 'cpan',
      'IO::Uncompress::Adapter::Identity'=> 'cpan',
      'IO::Uncompress::Adapter::Inflate'=> 'cpan',
      'IO::Uncompress::AnyInflate'=> 'cpan',
      'IO::Uncompress::AnyUncompress'=> 'cpan',
      'IO::Uncompress::Base'  => 'cpan',
      'IO::Uncompress::Bunzip2'=> 'cpan',
      'IO::Uncompress::Gunzip'=> 'cpan',
      'IO::Uncompress::Inflate'=> 'cpan',
      'IO::Uncompress::RawInflate'=> 'cpan',
      'IO::Uncompress::Unzip' => 'cpan',
      'IO::Zlib'              => 'cpan',
      'IPC::Cmd'              => 'cpan',
      'IPC::Msg'              => 'cpan',
      'IPC::Semaphore'        => 'cpan',
      'IPC::SharedMem'        => 'cpan',
      'IPC::SysV'             => 'cpan',
      'JSON::PP'              => 'cpan',
      'JSON::PP::Boolean'     => 'cpan',
      'List::Util'            => 'cpan',
      'List::Util::XS'        => 'cpan',
      'Locale::Codes'         => 'cpan',
      'Locale::Codes::Constants'=> 'cpan',
      'Locale::Codes::Country'=> 'cpan',
      'Locale::Codes::Country_Codes'=> 'cpan',
      'Locale::Codes::Country_Retired'=> 'cpan',
      'Locale::Codes::Currency'=> 'cpan',
      'Locale::Codes::Currency_Codes'=> 'cpan',
      'Locale::Codes::Currency_Retired'=> 'cpan',
      'Locale::Codes::LangExt'=> 'cpan',
      'Locale::Codes::LangExt_Codes'=> 'cpan',
      'Locale::Codes::LangExt_Retired'=> 'cpan',
      'Locale::Codes::LangFam'=> 'cpan',
      'Locale::Codes::LangFam_Codes'=> 'cpan',
      'Locale::Codes::LangFam_Retired'=> 'cpan',
      'Locale::Codes::LangVar'=> 'cpan',
      'Locale::Codes::LangVar_Codes'=> 'cpan',
      'Locale::Codes::LangVar_Retired'=> 'cpan',
      'Locale::Codes::Language'=> 'cpan',
      'Locale::Codes::Language_Codes'=> 'cpan',
      'Locale::Codes::Language_Retired'=> 'cpan',
      'Locale::Codes::Script' => 'cpan',
      'Locale::Codes::Script_Codes'=> 'cpan',
      'Locale::Codes::Script_Retired'=> 'cpan',
      'Locale::Country'       => 'cpan',
      'Locale::Currency'      => 'cpan',
      'Locale::Language'      => 'cpan',
      'Locale::Maketext::Simple'=> 'cpan',
      'Locale::Script'        => 'cpan',
      'MIME::Base64'          => 'cpan',
      'MIME::QuotedPrint'     => 'cpan',
      'Math::Complex'         => 'cpan',
      'Math::Trig'            => 'cpan',
      'Memoize'               => 'cpan',
      'Memoize::AnyDBM_File'  => 'cpan',
      'Memoize::Expire'       => 'cpan',
      'Memoize::ExpireFile'   => 'cpan',
      'Memoize::ExpireTest'   => 'cpan',
      'Memoize::NDBM_File'    => 'cpan',
      'Memoize::SDBM_File'    => 'cpan',
      'Memoize::Storable'     => 'cpan',
      'Module::Load'          => 'cpan',
      'Module::Load::Conditional'=> 'cpan',
      'Module::Loaded'        => 'cpan',
      'Module::Metadata'      => 'cpan',
      'Module::Metadata::corpus::BOMTest::UTF16BE'=> 'cpan',
      'Module::Metadata::corpus::BOMTest::UTF16LE'=> 'cpan',
      'Module::Metadata::corpus::BOMTest::UTF8'=> 'cpan',
      'NEXT'                  => 'cpan',
      'Net::Cmd'              => 'cpan',
      'Net::Config'           => 'cpan',
      'Net::Domain'           => 'cpan',
      'Net::FTP'              => 'cpan',
      'Net::FTP::A'           => 'cpan',
      'Net::FTP::E'           => 'cpan',
      'Net::FTP::I'           => 'cpan',
      'Net::FTP::L'           => 'cpan',
      'Net::FTP::dataconn'    => 'cpan',
      'Net::NNTP'             => 'cpan',
      'Net::Netrc'            => 'cpan',
      'Net::POP3'             => 'cpan',
      'Net::SMTP'             => 'cpan',
      'Net::Time'             => 'cpan',
      'Params::Check'         => 'cpan',
      'Parse::CPAN::Meta'     => 'cpan',
      'Perl::OSType'          => 'cpan',
      'PerlIO::via::QuotedPrint'=> 'cpan',
      'Pod::Checker'          => 'cpan',
      'Pod::Escapes'          => 'cpan',
      'Pod::Find'             => 'cpan',
      'Pod::InputObjects'     => 'cpan',
      'Pod::Man'              => 'cpan',
      'Pod::ParseLink'        => 'cpan',
      'Pod::ParseUtils'       => 'cpan',
      'Pod::Parser'           => 'cpan',
      'Pod::Perldoc'          => 'cpan',
      'Pod::Perldoc::BaseTo'  => 'cpan',
      'Pod::Perldoc::GetOptsOO'=> 'cpan',
      'Pod::Perldoc::ToANSI'  => 'cpan',
      'Pod::Perldoc::ToChecker'=> 'cpan',
      'Pod::Perldoc::ToMan'   => 'cpan',
      'Pod::Perldoc::ToNroff' => 'cpan',
      'Pod::Perldoc::ToPod'   => 'cpan',
      'Pod::Perldoc::ToRtf'   => 'cpan',
      'Pod::Perldoc::ToTerm'  => 'cpan',
      'Pod::Perldoc::ToText'  => 'cpan',
      'Pod::Perldoc::ToTk'    => 'cpan',
      'Pod::Perldoc::ToXml'   => 'cpan',
      'Pod::PlainText'        => 'cpan',
      'Pod::Select'           => 'cpan',
      'Pod::Simple'           => 'cpan',
      'Pod::Simple::BlackBox' => 'cpan',
      'Pod::Simple::Checker'  => 'cpan',
      'Pod::Simple::Debug'    => 'cpan',
      'Pod::Simple::DumpAsText'=> 'cpan',
      'Pod::Simple::DumpAsXML'=> 'cpan',
      'Pod::Simple::HTML'     => 'cpan',
      'Pod::Simple::HTMLBatch'=> 'cpan',
      'Pod::Simple::HTMLLegacy'=> 'cpan',
      'Pod::Simple::LinkSection'=> 'cpan',
      'Pod::Simple::Methody'  => 'cpan',
      'Pod::Simple::Progress' => 'cpan',
      'Pod::Simple::PullParser'=> 'cpan',
      'Pod::Simple::PullParserEndToken'=> 'cpan',
      'Pod::Simple::PullParserStartToken'=> 'cpan',
      'Pod::Simple::PullParserTextToken'=> 'cpan',
      'Pod::Simple::PullParserToken'=> 'cpan',
      'Pod::Simple::RTF'      => 'cpan',
      'Pod::Simple::Search'   => 'cpan',
      'Pod::Simple::SimpleTree'=> 'cpan',
      'Pod::Simple::Text'     => 'cpan',
      'Pod::Simple::TextContent'=> 'cpan',
      'Pod::Simple::TiedOutFH'=> 'cpan',
      'Pod::Simple::Transcode'=> 'cpan',
      'Pod::Simple::TranscodeDumb'=> 'cpan',
      'Pod::Simple::TranscodeSmart'=> 'cpan',
      'Pod::Simple::XHTML'    => 'cpan',
      'Pod::Simple::XMLOutStream'=> 'cpan',
      'Pod::Text'             => 'cpan',
      'Pod::Text::Color'      => 'cpan',
      'Pod::Text::Overstrike' => 'cpan',
      'Pod::Text::Termcap'    => 'cpan',
      'Pod::Usage'            => 'cpan',
      'Scalar::Util'          => 'cpan',
      'Socket'                => 'cpan',
      'Sub::Util'             => 'cpan',
      'Sys::Syslog'           => 'cpan',
      'Sys::Syslog::Win32'    => 'cpan',
      'TAP::Base'             => 'cpan',
      'TAP::Formatter::Base'  => 'cpan',
      'TAP::Formatter::Color' => 'cpan',
      'TAP::Formatter::Console'=> 'cpan',
      'TAP::Formatter::Console::ParallelSession'=> 'cpan',
      'TAP::Formatter::Console::Session'=> 'cpan',
      'TAP::Formatter::File'  => 'cpan',
      'TAP::Formatter::File::Session'=> 'cpan',
      'TAP::Formatter::Session'=> 'cpan',
      'TAP::Harness'          => 'cpan',
      'TAP::Harness::Env'     => 'cpan',
      'TAP::Object'           => 'cpan',
      'TAP::Parser'           => 'cpan',
      'TAP::Parser::Aggregator'=> 'cpan',
      'TAP::Parser::Grammar'  => 'cpan',
      'TAP::Parser::Iterator' => 'cpan',
      'TAP::Parser::Iterator::Array'=> 'cpan',
      'TAP::Parser::Iterator::Process'=> 'cpan',
      'TAP::Parser::Iterator::Stream'=> 'cpan',
      'TAP::Parser::IteratorFactory'=> 'cpan',
      'TAP::Parser::Multiplexer'=> 'cpan',
      'TAP::Parser::Result'   => 'cpan',
      'TAP::Parser::Result::Bailout'=> 'cpan',
      'TAP::Parser::Result::Comment'=> 'cpan',
      'TAP::Parser::Result::Plan'=> 'cpan',
      'TAP::Parser::Result::Pragma'=> 'cpan',
      'TAP::Parser::Result::Test'=> 'cpan',
      'TAP::Parser::Result::Unknown'=> 'cpan',
      'TAP::Parser::Result::Version'=> 'cpan',
      'TAP::Parser::Result::YAML'=> 'cpan',
      'TAP::Parser::ResultFactory'=> 'cpan',
      'TAP::Parser::Scheduler'=> 'cpan',
      'TAP::Parser::Scheduler::Job'=> 'cpan',
      'TAP::Parser::Scheduler::Spinner'=> 'cpan',
      'TAP::Parser::Source'   => 'cpan',
      'TAP::Parser::SourceHandler'=> 'cpan',
      'TAP::Parser::SourceHandler::Executable'=> 'cpan',
      'TAP::Parser::SourceHandler::File'=> 'cpan',
      'TAP::Parser::SourceHandler::Handle'=> 'cpan',
      'TAP::Parser::SourceHandler::Perl'=> 'cpan',
      'TAP::Parser::SourceHandler::RawTAP'=> 'cpan',
      'TAP::Parser::YAMLish::Reader'=> 'cpan',
      'TAP::Parser::YAMLish::Writer'=> 'cpan',
      'Term::ANSIColor'       => 'cpan',
      'Term::Cap'             => 'cpan',
      'Test'                  => 'cpan',
      'Test::Builder'         => 'cpan',
      'Test::Builder::IO::Scalar'=> 'cpan',
      'Test::Builder::Module' => 'cpan',
      'Test::Builder::Tester' => 'cpan',
      'Test::Builder::Tester::Color'=> 'cpan',
      'Test::Harness'         => 'cpan',
      'Test::More'            => 'cpan',
      'Test::Simple'          => 'cpan',
      'Test::Tester'          => 'cpan',
      'Test::Tester::Capture' => 'cpan',
      'Test::Tester::CaptureRunner'=> 'cpan',
      'Test::Tester::Delegate'=> 'cpan',
      'Test::use::ok'         => 'cpan',
      'Text::Balanced'        => 'cpan',
      'Text::ParseWords'      => 'cpan',
      'Text::Tabs'            => 'cpan',
      'Text::Wrap'            => 'cpan',
      'Tie::RefHash'          => 'cpan',
      'Time::HiRes'           => 'cpan',
      'Time::Local'           => 'cpan',
      'Time::Piece'           => 'cpan',
      'Time::Seconds'         => 'cpan',
      'Unicode::Collate'      => 'cpan',
      'Unicode::Collate::CJK::Big5'=> 'cpan',
      'Unicode::Collate::CJK::GB2312'=> 'cpan',
      'Unicode::Collate::CJK::JISX0208'=> 'cpan',
      'Unicode::Collate::CJK::Korean'=> 'cpan',
      'Unicode::Collate::CJK::Pinyin'=> 'cpan',
      'Unicode::Collate::CJK::Stroke'=> 'cpan',
      'Unicode::Collate::CJK::Zhuyin'=> 'cpan',
      'Unicode::Collate::Locale'=> 'cpan',
      'Unicode::Normalize'    => 'cpan',
      'Win32'                 => 'cpan',
      'Win32API::File'        => 'cpan',
      'Win32API::File::ExtUtils::Myconst2perl'=> 'cpan',
      'autodie'               => 'cpan',
      'autodie::Scope::Guard' => 'cpan',
      'autodie::Scope::GuardStack'=> 'cpan',
      'autodie::Util'         => 'cpan',
      'autodie::exception'    => 'cpan',
      'autodie::exception::system'=> 'cpan',
      'autodie::hints'        => 'cpan',
      'autodie::skip'         => 'cpan',
      'encoding'              => 'cpan',
      'encoding::warnings'    => 'cpan',
      'experimental'          => 'cpan',
      'ok'                    => 'cpan',
      'parent'                => 'cpan',
      'perlfaq'               => 'cpan',
      'version'               => 'cpan',
      'version::regex'        => 'cpan',
      'version::vpp'          => 'cpan',
  );
  
  %bug_tracker = (
      'App::Cpan'             => undef,
      'App::Prove'            => 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'App::Prove::State'     => 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'App::Prove::State::Result'=> 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'App::Prove::State::Result::Test'=> 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'Archive::Tar'          => undef,
      'Archive::Tar::Constant'=> undef,
      'Archive::Tar::File'    => undef,
      'B::Debug'              => undef,
      'CPAN'                  => undef,
      'CPAN::Author'          => undef,
      'CPAN::Bundle'          => undef,
      'CPAN::CacheMgr'        => undef,
      'CPAN::Complete'        => undef,
      'CPAN::Debug'           => undef,
      'CPAN::DeferredCode'    => undef,
      'CPAN::Distribution'    => undef,
      'CPAN::Distroprefs'     => undef,
      'CPAN::Distrostatus'    => undef,
      'CPAN::Exception::RecursiveDependency'=> undef,
      'CPAN::Exception::blocked_urllist'=> undef,
      'CPAN::Exception::yaml_not_installed'=> undef,
      'CPAN::Exception::yaml_process_error'=> undef,
      'CPAN::FTP'             => undef,
      'CPAN::FTP::netrc'      => undef,
      'CPAN::FirstTime'       => undef,
      'CPAN::HTTP::Client'    => undef,
      'CPAN::HTTP::Credentials'=> undef,
      'CPAN::HandleConfig'    => undef,
      'CPAN::Index'           => undef,
      'CPAN::InfoObj'         => undef,
      'CPAN::Kwalify'         => undef,
      'CPAN::LWP::UserAgent'  => undef,
      'CPAN::Meta'            => 'https://github.com/Perl-Toolchain-Gang/CPAN-Meta/issues',
      'CPAN::Meta::Converter' => 'https://github.com/Perl-Toolchain-Gang/CPAN-Meta/issues',
      'CPAN::Meta::Feature'   => 'https://github.com/Perl-Toolchain-Gang/CPAN-Meta/issues',
      'CPAN::Meta::History'   => 'https://github.com/Perl-Toolchain-Gang/CPAN-Meta/issues',
      'CPAN::Meta::Merge'     => 'https://github.com/Perl-Toolchain-Gang/CPAN-Meta/issues',
      'CPAN::Meta::Prereqs'   => 'https://github.com/Perl-Toolchain-Gang/CPAN-Meta/issues',
      'CPAN::Meta::Requirements'=> 'https://github.com/dagolden/CPAN-Meta-Requirements/issues',
      'CPAN::Meta::Spec'      => 'https://github.com/Perl-Toolchain-Gang/CPAN-Meta/issues',
      'CPAN::Meta::Validator' => 'https://github.com/Perl-Toolchain-Gang/CPAN-Meta/issues',
      'CPAN::Meta::YAML'      => 'https://github.com/Perl-Toolchain-Gang/YAML-Tiny/issues',
      'CPAN::Mirrors'         => undef,
      'CPAN::Module'          => undef,
      'CPAN::Nox'             => undef,
      'CPAN::Plugin'          => undef,
      'CPAN::Plugin::Specfile'=> undef,
      'CPAN::Prompt'          => undef,
      'CPAN::Queue'           => undef,
      'CPAN::Shell'           => undef,
      'CPAN::Tarzip'          => undef,
      'CPAN::URL'             => undef,
      'CPAN::Version'         => undef,
      'Compress::Raw::Bzip2'  => undef,
      'Compress::Raw::Zlib'   => undef,
      'Compress::Zlib'        => undef,
      'Config::Perl::V'       => undef,
      'DB_File'               => undef,
      'Devel::PPPort'         => 'https://github.com/mhx/Devel-PPPort/issues/',
      'Digest'                => undef,
      'Digest::MD5'           => undef,
      'Digest::SHA'           => undef,
      'Digest::base'          => undef,
      'Digest::file'          => undef,
      'Encode'                => undef,
      'Encode::Alias'         => undef,
      'Encode::Byte'          => undef,
      'Encode::CJKConstants'  => undef,
      'Encode::CN'            => undef,
      'Encode::CN::HZ'        => undef,
      'Encode::Config'        => undef,
      'Encode::EBCDIC'        => undef,
      'Encode::Encoder'       => undef,
      'Encode::Encoding'      => undef,
      'Encode::GSM0338'       => undef,
      'Encode::Guess'         => undef,
      'Encode::JP'            => undef,
      'Encode::JP::H2Z'       => undef,
      'Encode::JP::JIS7'      => undef,
      'Encode::KR'            => undef,
      'Encode::KR::2022_KR'   => undef,
      'Encode::MIME::Header'  => undef,
      'Encode::MIME::Header::ISO_2022_JP'=> undef,
      'Encode::MIME::Name'    => undef,
      'Encode::Symbol'        => undef,
      'Encode::TW'            => undef,
      'Encode::Unicode'       => undef,
      'Encode::Unicode::UTF7' => undef,
      'ExtUtils::Command'     => 'http://rt.perl.org/rt3/',
      'ExtUtils::Command::MM' => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-MakeMaker',
      'ExtUtils::Constant'    => undef,
      'ExtUtils::Constant::Base'=> undef,
      'ExtUtils::Constant::ProxySubs'=> undef,
      'ExtUtils::Constant::Utils'=> undef,
      'ExtUtils::Constant::XS'=> undef,
      'ExtUtils::Install'     => 'https://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-Install',
      'ExtUtils::Installed'   => 'https://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-Install',
      'ExtUtils::Liblist'     => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-MakeMaker',
      'ExtUtils::Liblist::Kid'=> 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-MakeMaker',
      'ExtUtils::MM'          => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-MakeMaker',
      'ExtUtils::MM_AIX'      => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-MakeMaker',
      'ExtUtils::MM_Any'      => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-MakeMaker',
      'ExtUtils::MM_BeOS'     => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-MakeMaker',
      'ExtUtils::MM_Cygwin'   => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-MakeMaker',
      'ExtUtils::MM_DOS'      => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-MakeMaker',
      'ExtUtils::MM_Darwin'   => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-MakeMaker',
      'ExtUtils::MM_MacOS'    => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-MakeMaker',
      'ExtUtils::MM_NW5'      => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-MakeMaker',
      'ExtUtils::MM_OS2'      => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-MakeMaker',
      'ExtUtils::MM_QNX'      => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-MakeMaker',
      'ExtUtils::MM_UWIN'     => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-MakeMaker',
      'ExtUtils::MM_Unix'     => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-MakeMaker',
      'ExtUtils::MM_VMS'      => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-MakeMaker',
      'ExtUtils::MM_VOS'      => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-MakeMaker',
      'ExtUtils::MM_Win32'    => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-MakeMaker',
      'ExtUtils::MM_Win95'    => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-MakeMaker',
      'ExtUtils::MY'          => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-MakeMaker',
      'ExtUtils::MakeMaker'   => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-MakeMaker',
      'ExtUtils::MakeMaker::Config'=> 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-MakeMaker',
      'ExtUtils::MakeMaker::Locale'=> 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-MakeMaker',
      'ExtUtils::MakeMaker::version'=> 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-MakeMaker',
      'ExtUtils::MakeMaker::version::regex'=> 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-MakeMaker',
      'ExtUtils::MakeMaker::version::vpp'=> 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-MakeMaker',
      'ExtUtils::Manifest'    => 'http://github.com/Perl-Toolchain-Gang/ExtUtils-Manifest/issues',
      'ExtUtils::Mkbootstrap' => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-MakeMaker',
      'ExtUtils::Mksymlists'  => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-MakeMaker',
      'ExtUtils::Packlist'    => 'https://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-Install',
      'ExtUtils::testlib'     => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=ExtUtils-MakeMaker',
      'Fatal'                 => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=autodie',
      'File::Fetch'           => undef,
      'File::GlobMapper'      => undef,
      'File::Path'            => undef,
      'File::Temp'            => 'http://rt.cpan.org/Public/Dist/Display.html?Name=File-Temp',
      'Filter::Util::Call'    => undef,
      'Getopt::Long'          => undef,
      'HTTP::Tiny'            => 'https://github.com/chansen/p5-http-tiny/issues',
      'IO::Compress::Adapter::Bzip2'=> undef,
      'IO::Compress::Adapter::Deflate'=> undef,
      'IO::Compress::Adapter::Identity'=> undef,
      'IO::Compress::Base'    => undef,
      'IO::Compress::Base::Common'=> undef,
      'IO::Compress::Bzip2'   => undef,
      'IO::Compress::Deflate' => undef,
      'IO::Compress::Gzip'    => undef,
      'IO::Compress::Gzip::Constants'=> undef,
      'IO::Compress::RawDeflate'=> undef,
      'IO::Compress::Zip'     => undef,
      'IO::Compress::Zip::Constants'=> undef,
      'IO::Compress::Zlib::Constants'=> undef,
      'IO::Compress::Zlib::Extra'=> undef,
      'IO::Socket::IP'        => undef,
      'IO::Uncompress::Adapter::Bunzip2'=> undef,
      'IO::Uncompress::Adapter::Identity'=> undef,
      'IO::Uncompress::Adapter::Inflate'=> undef,
      'IO::Uncompress::AnyInflate'=> undef,
      'IO::Uncompress::AnyUncompress'=> undef,
      'IO::Uncompress::Base'  => undef,
      'IO::Uncompress::Bunzip2'=> undef,
      'IO::Uncompress::Gunzip'=> undef,
      'IO::Uncompress::Inflate'=> undef,
      'IO::Uncompress::RawInflate'=> undef,
      'IO::Uncompress::Unzip' => undef,
      'IO::Zlib'              => undef,
      'IPC::Cmd'              => undef,
      'IPC::Msg'              => undef,
      'IPC::Semaphore'        => undef,
      'IPC::SharedMem'        => undef,
      'IPC::SysV'             => undef,
      'JSON::PP'              => undef,
      'JSON::PP::Boolean'     => undef,
      'List::Util'            => undef,
      'List::Util::XS'        => undef,
      'Locale::Codes'         => undef,
      'Locale::Codes::Constants'=> undef,
      'Locale::Codes::Country'=> undef,
      'Locale::Codes::Country_Codes'=> undef,
      'Locale::Codes::Country_Retired'=> undef,
      'Locale::Codes::Currency'=> undef,
      'Locale::Codes::Currency_Codes'=> undef,
      'Locale::Codes::Currency_Retired'=> undef,
      'Locale::Codes::LangExt'=> undef,
      'Locale::Codes::LangExt_Codes'=> undef,
      'Locale::Codes::LangExt_Retired'=> undef,
      'Locale::Codes::LangFam'=> undef,
      'Locale::Codes::LangFam_Codes'=> undef,
      'Locale::Codes::LangFam_Retired'=> undef,
      'Locale::Codes::LangVar'=> undef,
      'Locale::Codes::LangVar_Codes'=> undef,
      'Locale::Codes::LangVar_Retired'=> undef,
      'Locale::Codes::Language'=> undef,
      'Locale::Codes::Language_Codes'=> undef,
      'Locale::Codes::Language_Retired'=> undef,
      'Locale::Codes::Script' => undef,
      'Locale::Codes::Script_Codes'=> undef,
      'Locale::Codes::Script_Retired'=> undef,
      'Locale::Country'       => undef,
      'Locale::Currency'      => undef,
      'Locale::Language'      => undef,
      'Locale::Maketext::Simple'=> undef,
      'Locale::Script'        => undef,
      'MIME::Base64'          => undef,
      'MIME::QuotedPrint'     => undef,
      'Math::Complex'         => undef,
      'Math::Trig'            => undef,
      'Memoize'               => undef,
      'Memoize::AnyDBM_File'  => undef,
      'Memoize::Expire'       => undef,
      'Memoize::ExpireFile'   => undef,
      'Memoize::ExpireTest'   => undef,
      'Memoize::NDBM_File'    => undef,
      'Memoize::SDBM_File'    => undef,
      'Memoize::Storable'     => undef,
      'Module::Load'          => undef,
      'Module::Load::Conditional'=> undef,
      'Module::Loaded'        => undef,
      'Module::Metadata'      => 'https://rt.cpan.org/Public/Dist/Display.html?Name=Module-Metadata',
      'Module::Metadata::corpus::BOMTest::UTF16BE'=> undef,
      'Module::Metadata::corpus::BOMTest::UTF16LE'=> undef,
      'Module::Metadata::corpus::BOMTest::UTF8'=> undef,
      'NEXT'                  => undef,
      'Net::Cmd'              => undef,
      'Net::Config'           => undef,
      'Net::Domain'           => undef,
      'Net::FTP'              => undef,
      'Net::FTP::A'           => undef,
      'Net::FTP::E'           => undef,
      'Net::FTP::I'           => undef,
      'Net::FTP::L'           => undef,
      'Net::FTP::dataconn'    => undef,
      'Net::NNTP'             => undef,
      'Net::Netrc'            => undef,
      'Net::POP3'             => undef,
      'Net::SMTP'             => undef,
      'Net::Time'             => undef,
      'Params::Check'         => undef,
      'Parse::CPAN::Meta'     => 'https://github.com/Perl-Toolchain-Gang/Parse-CPAN-Meta/issues',
      'Perl::OSType'          => 'https://github.com/dagolden/Perl-OSType/issues',
      'PerlIO::via::QuotedPrint'=> undef,
      'Pod::Checker'          => undef,
      'Pod::Escapes'          => undef,
      'Pod::Find'             => undef,
      'Pod::InputObjects'     => undef,
      'Pod::Man'              => undef,
      'Pod::ParseLink'        => undef,
      'Pod::ParseUtils'       => undef,
      'Pod::Parser'           => undef,
      'Pod::Perldoc'          => undef,
      'Pod::Perldoc::BaseTo'  => undef,
      'Pod::Perldoc::GetOptsOO'=> undef,
      'Pod::Perldoc::ToANSI'  => undef,
      'Pod::Perldoc::ToChecker'=> undef,
      'Pod::Perldoc::ToMan'   => undef,
      'Pod::Perldoc::ToNroff' => undef,
      'Pod::Perldoc::ToPod'   => undef,
      'Pod::Perldoc::ToRtf'   => undef,
      'Pod::Perldoc::ToTerm'  => undef,
      'Pod::Perldoc::ToText'  => undef,
      'Pod::Perldoc::ToTk'    => undef,
      'Pod::Perldoc::ToXml'   => undef,
      'Pod::PlainText'        => undef,
      'Pod::Select'           => undef,
      'Pod::Simple'           => undef,
      'Pod::Simple::BlackBox' => undef,
      'Pod::Simple::Checker'  => undef,
      'Pod::Simple::Debug'    => undef,
      'Pod::Simple::DumpAsText'=> undef,
      'Pod::Simple::DumpAsXML'=> undef,
      'Pod::Simple::HTML'     => undef,
      'Pod::Simple::HTMLBatch'=> undef,
      'Pod::Simple::HTMLLegacy'=> undef,
      'Pod::Simple::LinkSection'=> undef,
      'Pod::Simple::Methody'  => undef,
      'Pod::Simple::Progress' => undef,
      'Pod::Simple::PullParser'=> undef,
      'Pod::Simple::PullParserEndToken'=> undef,
      'Pod::Simple::PullParserStartToken'=> undef,
      'Pod::Simple::PullParserTextToken'=> undef,
      'Pod::Simple::PullParserToken'=> undef,
      'Pod::Simple::RTF'      => undef,
      'Pod::Simple::Search'   => undef,
      'Pod::Simple::SimpleTree'=> undef,
      'Pod::Simple::Text'     => undef,
      'Pod::Simple::TextContent'=> undef,
      'Pod::Simple::TiedOutFH'=> undef,
      'Pod::Simple::Transcode'=> undef,
      'Pod::Simple::TranscodeDumb'=> undef,
      'Pod::Simple::TranscodeSmart'=> undef,
      'Pod::Simple::XHTML'    => undef,
      'Pod::Simple::XMLOutStream'=> undef,
      'Pod::Text'             => undef,
      'Pod::Text::Color'      => undef,
      'Pod::Text::Overstrike' => undef,
      'Pod::Text::Termcap'    => undef,
      'Pod::Usage'            => undef,
      'Scalar::Util'          => undef,
      'Socket'                => undef,
      'Sub::Util'             => undef,
      'Sys::Syslog'           => undef,
      'Sys::Syslog::Win32'    => undef,
      'TAP::Base'             => 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Formatter::Base'  => 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Formatter::Color' => 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Formatter::Console'=> 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Formatter::Console::ParallelSession'=> 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Formatter::Console::Session'=> 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Formatter::File'  => 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Formatter::File::Session'=> 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Formatter::Session'=> 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Harness'          => 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Harness::Env'     => 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Object'           => 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Parser'           => 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Parser::Aggregator'=> 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Parser::Grammar'  => 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Parser::Iterator' => 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Parser::Iterator::Array'=> 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Parser::Iterator::Process'=> 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Parser::Iterator::Stream'=> 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Parser::IteratorFactory'=> 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Parser::Multiplexer'=> 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Parser::Result'   => 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Parser::Result::Bailout'=> 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Parser::Result::Comment'=> 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Parser::Result::Plan'=> 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Parser::Result::Pragma'=> 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Parser::Result::Test'=> 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Parser::Result::Unknown'=> 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Parser::Result::Version'=> 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Parser::Result::YAML'=> 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Parser::ResultFactory'=> 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Parser::Scheduler'=> 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Parser::Scheduler::Job'=> 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Parser::Scheduler::Spinner'=> 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Parser::Source'   => 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Parser::SourceHandler'=> 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Parser::SourceHandler::Executable'=> 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Parser::SourceHandler::File'=> 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Parser::SourceHandler::Handle'=> 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Parser::SourceHandler::Perl'=> 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Parser::SourceHandler::RawTAP'=> 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Parser::YAMLish::Reader'=> 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'TAP::Parser::YAMLish::Writer'=> 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'Term::ANSIColor'       => 'https://rt.cpan.org/Public/Dist/Display.html?Name=Term-ANSIColor',
      'Term::Cap'             => undef,
      'Test'                  => undef,
      'Test::Builder'         => 'http://github.com/Test-More/test-more/issues/',
      'Test::Builder::IO::Scalar'=> 'http://github.com/Test-More/test-more/issues/',
      'Test::Builder::Module' => 'http://github.com/Test-More/test-more/issues/',
      'Test::Builder::Tester' => 'http://github.com/Test-More/test-more/issues/',
      'Test::Builder::Tester::Color'=> 'http://github.com/Test-More/test-more/issues/',
      'Test::Harness'         => 'http://rt.cpan.org/Public/Dist/Display.html?Name=Test-Harness',
      'Test::More'            => 'http://github.com/Test-More/test-more/issues/',
      'Test::Simple'          => 'http://github.com/Test-More/test-more/issues/',
      'Test::Tester'          => 'http://github.com/Test-More/test-more/issues/',
      'Test::Tester::Capture' => 'http://github.com/Test-More/test-more/issues/',
      'Test::Tester::CaptureRunner'=> 'http://github.com/Test-More/test-more/issues/',
      'Test::Tester::Delegate'=> 'http://github.com/Test-More/test-more/issues/',
      'Test::use::ok'         => 'http://github.com/Test-More/test-more/issues/',
      'Text::Balanced'        => undef,
      'Text::ParseWords'      => undef,
      'Text::Tabs'            => undef,
      'Text::Wrap'            => undef,
      'Tie::RefHash'          => undef,
      'Time::HiRes'           => undef,
      'Time::Local'           => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=Time-Local',
      'Time::Piece'           => undef,
      'Time::Seconds'         => undef,
      'Unicode::Collate'      => undef,
      'Unicode::Collate::CJK::Big5'=> undef,
      'Unicode::Collate::CJK::GB2312'=> undef,
      'Unicode::Collate::CJK::JISX0208'=> undef,
      'Unicode::Collate::CJK::Korean'=> undef,
      'Unicode::Collate::CJK::Pinyin'=> undef,
      'Unicode::Collate::CJK::Stroke'=> undef,
      'Unicode::Collate::CJK::Zhuyin'=> undef,
      'Unicode::Collate::Locale'=> undef,
      'Unicode::Normalize'    => undef,
      'Win32'                 => undef,
      'Win32API::File'        => undef,
      'Win32API::File::ExtUtils::Myconst2perl'=> undef,
      'autodie'               => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=autodie',
      'autodie::Scope::Guard' => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=autodie',
      'autodie::Scope::GuardStack'=> 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=autodie',
      'autodie::Util'         => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=autodie',
      'autodie::exception'    => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=autodie',
      'autodie::exception::system'=> 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=autodie',
      'autodie::hints'        => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=autodie',
      'autodie::skip'         => 'http://rt.cpan.org/NoAuth/Bugs.html?Dist=autodie',
      'encoding'              => undef,
      'encoding::warnings'    => undef,
      'experimental'          => 'http://rt.cpan.org/Public/Dist/Display.html?Name=experimental',
      'ok'                    => 'http://github.com/Test-More/test-more/issues/',
      'parent'                => undef,
      'perlfaq'               => 'https://github.com/perl-doc-cats/perlfaq/issues',
      'version'               => 'https://rt.cpan.org/Public/Dist/Display.html?Name=version',
      'version::regex'        => 'https://rt.cpan.org/Public/Dist/Display.html?Name=version',
      'version::vpp'          => 'https://rt.cpan.org/Public/Dist/Display.html?Name=version',
  );
  
  # Create aliases with trailing zeros for $] use
  
  $released{'5.000'} = $released{5};
  $version{'5.000'} = $version{5};
  
  _create_aliases(\%delta);
  _create_aliases(\%released);
  _create_aliases(\%version);
  _create_aliases(\%deprecated);
  
  sub _create_aliases {
      my ($hash) = @_;
  
      for my $version (keys %$hash) {
          next unless $version >= 5.006;
  
          my $padded = sprintf "%0.6f", $version;
  
          # If the version in string form isn't the same as the numeric version,
          # alias it.
          if ($padded ne $version && $version == $padded) {
              $hash->{$padded} = $hash->{$version};
          }
      }
  }
  
  1;
  __END__
MODULE_CORELIST

$fatpacked{"Module/CoreList/TieHashDelta.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MODULE_CORELIST_TIEHASHDELTA';
  # For internal Module::CoreList use only.
  package Module::CoreList::TieHashDelta;
  use strict;
  use vars qw($VERSION);
  
  $VERSION = '5.20150620';
  
  sub TIEHASH {
      my ($class, $changed, $removed, $parent) = @_;
  
      return bless {
          changed => $changed,
          removed => $removed,
          parent => $parent,
          keys_inflated => 0,
      }, $class;
  }
  
  sub FETCH {
      my ($self, $key) = @_;
  
      if (exists $self->{changed}{$key}) {
          return $self->{changed}{$key};
      } elsif (exists $self->{removed}{$key}) {
          return undef;
      } elsif (defined $self->{parent}) {
          return $self->{parent}{$key};
      }
      return undef;
  }
  
  sub EXISTS {
      my ($self, $key) = @_;
  
      restart:
      if (exists $self->{changed}{$key}) {
          return 1;
      } elsif (exists $self->{removed}{$key}) {
          return '';
      } elsif (defined $self->{parent}) {
          $self = tied %{$self->{parent}}; #avoid extreme magic/tie recursion
          goto restart;
      }
      return '';
  }
  
  sub FIRSTKEY {
      my ($self) = @_;
  
      if (not $self->{keys_inflated}) {
          # This inflates the whole set of hashes... Somewhat expensive, but saves
          # many tied hash calls later.
          my @parent_keys;
          if (defined $self->{parent}) {
              @parent_keys = keys %{$self->{parent}};
          }
  
          @parent_keys = grep !exists $self->{removed}{$_}, @parent_keys;
          for my $key (@parent_keys) {
              next if exists $self->{changed}->{$key};
              $self->{changed}{$key} = $self->{parent}{$key};
          }
  
          $self->{keys_inflated} = 1;
      }
  
      keys %{$self->{changed}}; # reset each
      $self->NEXTKEY;
  }
  
  sub NEXTKEY {
      my ($self) = @_;
      each %{$self->{changed}};
  }
  
  1;
MODULE_CORELIST_TIEHASHDELTA

$fatpacked{"Module/CoreList/Utils.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MODULE_CORELIST_UTILS';
  package Module::CoreList::Utils;
  
  use strict;
  use warnings;
  use vars qw[$VERSION %utilities];
  use Module::CoreList;
  use Module::CoreList::TieHashDelta;
  
  $VERSION = '5.20150620';
  
  sub utilities {
      my $perl = shift;
      $perl = shift if eval { $perl->isa(__PACKAGE__) };
      return unless $perl or exists $utilities{$perl};
      return sort keys %{ $utilities{$perl} };
  }
  
  sub _released_order {   # Sort helper, to make '?' sort after everything else
      (substr($Module::CoreList::released{$a}, 0, 1) eq "?")
      ? ((substr($Module::CoreList::released{$b}, 0, 1) eq "?")
          ? 0
          : 1)
      : ((substr($Module::CoreList::released{$b}, 0, 1) eq "?")
          ? -1
          : $Module::CoreList::released{$a} cmp $Module::CoreList::released{$b} )
  }
  
  sub first_release_raw {
      my $util = shift;
      $util = shift if eval { $util->isa(__PACKAGE__) };
        #and scalar @_ and $_[0] =~ m#\A[a-zA-Z_][0-9a-zA-Z_]*(?:(::|')[0-9a-zA-Z_]+)*\z#;
      my $version = shift;
  
      my @perls = $version
          ? grep { exists $utilities{$_}{ $util } &&
                          $utilities{$_}{ $util } ge $version } keys %utilities
          : grep { exists $utilities{$_}{ $util }             } keys %utilities;
  
      return grep { exists $Module::CoreList::released{$_} } @perls;
  }
  
  sub first_release_by_date {
      my @perls = &first_release_raw;
      return unless @perls;
      return (sort _released_order @perls)[0];
  }
  
  sub first_release {
      my @perls = &first_release_raw;
      return unless @perls;
      return (sort { $a cmp $b } @perls)[0];
  }
  
  sub removed_from {
    my @perls = &removed_raw;
    return shift @perls;
  }
  
  sub removed_from_by_date {
    my @perls = sort _released_order &removed_raw;
    return shift @perls;
  }
  
  sub removed_raw {
    my $util = shift;
    $util = shift if eval { $util->isa(__PACKAGE__) };
    return unless my @perls = sort { $a cmp $b } first_release_raw($util);
    @perls = grep { exists $Module::CoreList::released{$_} } @perls;
    my $last = pop @perls;
    my @removed = grep { $_ > $last } sort { $a cmp $b } keys %utilities;
    return @removed;
  }
  
  my %delta = (
      5 => {
          changed => {
              'a2p'                   => '1',
              'c2ph'                  => '1',
              'cppstdin'              => '1',
              'find2perl'             => '1',
              'pstruct'               => '1',
              's2p'                   => '1',
          },
          removed => {
          }
      },
  
      5.001 => {
          delta_from => 5,
          changed => {
              'h2xs'                  => '1',
          },
          removed => {
          }
      },
  
      5.002 => {
          delta_from => 5.001,
          changed => {
              'h2ph'                  => '1',
              'perlbug'               => '1',
              'perldoc'               => '1',
              'pod2html'              => '1',
              'pod2latex'             => '1',
              'pod2man'               => '1',
              'pod2text'              => '1',
          },
          removed => {
          }
      },
  
      5.00307 => {
          delta_from => 5.002,
          changed => {
              'pl2pm'                 => '1',
          },
          removed => {
             'cppstdin'              => 1,
             'pstruct'               => 1,
          }
      },
  
      5.004 => {
          delta_from => 5.00307,
          changed => {
              'splain'                => '1',
          },
          removed => {
          }
      },
  
      5.005 => {
          delta_from => 5.00405,
          changed => {
              'perlcc'                => '1',
          },
          removed => {
          }
      },
  
      5.00503 => {
          delta_from => 5.005,
          changed => {
          },
          removed => {
          }
      },
  
      5.00405 => {
          delta_from => 5.004,
          changed => {
          },
          removed => {
          }
      },
  
      5.006 => {
          delta_from => 5.00504,
          changed => {
              'dprofpp'               => '1',
              'pod2usage'             => '1',
              'podchecker'            => '1',
              'podselect'             => '1',
              'pstruct'               => '1',
          },
          removed => {
          }
      },
  
      5.006001 => {
          delta_from => 5.006,
          changed => {
          },
          removed => {
          }
      },
  
      5.007003 => {
          delta_from => 5.006002,
          changed => {
              'libnetcfg'             => '1',
              'perlivp'               => '1',
              'psed'                  => '1',
              'xsubpp'                => '1',
          },
          removed => {
          }
      },
  
      5.008 => {
          delta_from => 5.007003,
          changed => {
              'enc2xs'                => '1',
              'piconv'                => '1',
          },
          removed => {
          }
      },
  
      5.008001 => {
          delta_from => 5.008,
          changed => {
              'cpan'                  => '1',
          },
          removed => {
          }
      },
  
      5.009 => {
          delta_from => 5.008009,
          changed => {
          },
          removed => {
             'corelist'              => 1,
             'instmodsh'             => 1,
             'prove'                 => 1,
          }
      },
  
      5.008002 => {
          delta_from => 5.008001,
          changed => {
          },
          removed => {
          }
      },
  
      5.006002 => {
          delta_from => 5.006001,
          changed => {
          },
          removed => {
          }
      },
  
      5.008003 => {
          delta_from => 5.008002,
          changed => {
              'instmodsh'             => '1',
              'prove'                 => '1',
          },
          removed => {
          }
      },
  
      5.00504 => {
          delta_from => 5.00503,
          changed => {
          },
          removed => {
          }
      },
  
      5.009001 => {
          delta_from => 5.009,
          changed => {
              'instmodsh'             => '1',
              'prove'                 => '1',
          },
          removed => {
          }
      },
  
      5.008004 => {
          delta_from => 5.008003,
          changed => {
          },
          removed => {
          }
      },
  
      5.008005 => {
          delta_from => 5.008004,
          changed => {
          },
          removed => {
          }
      },
  
      5.008006 => {
          delta_from => 5.008005,
          changed => {
          },
          removed => {
          }
      },
  
      5.009002 => {
          delta_from => 5.009001,
          changed => {
              'corelist'              => '1',
          },
          removed => {
          }
      },
  
      5.008007 => {
          delta_from => 5.008006,
          changed => {
          },
          removed => {
          }
      },
  
      5.009003 => {
          delta_from => 5.009002,
          changed => {
              'ptar'                  => '1',
              'ptardiff'              => '1',
              'shasum'                => '1',
          },
          removed => {
          }
      },
  
      5.008008 => {
          delta_from => 5.008007,
          changed => {
          },
          removed => {
          }
      },
  
      5.009004 => {
          delta_from => 5.009003,
          changed => {
              'config_data'           => '1',
          },
          removed => {
          }
      },
  
      5.009005 => {
          delta_from => 5.009004,
          changed => {
              'cpan2dist'             => '1',
              'cpanp'                 => '1',
              'cpanp-run-perl'        => '1',
          },
          removed => {
             'perlcc'                => 1,
          }
      },
  
      5.010000 => {
          delta_from => 5.009005,
          changed => {
          },
          removed => {
          }
      },
  
      5.008009 => {
          delta_from => 5.008008,
          changed => {
              'corelist'              => '1',
          },
          removed => {
          }
      },
  
      5.010001 => {
          delta_from => 5.010000,
          changed => {
          },
          removed => {
          }
      },
  
      5.011 => {
          delta_from => 5.010001,
          changed => {
          },
          removed => {
          }
      },
  
      5.011001 => {
          delta_from => 5.011,
          changed => {
          },
          removed => {
          }
      },
  
      5.011002 => {
          delta_from => 5.011001,
          changed => {
              'perlthanks'            => '1',
          },
          removed => {
          }
      },
  
      5.011003 => {
          delta_from => 5.011002,
          changed => {
          },
          removed => {
          }
      },
  
      5.011004 => {
          delta_from => 5.011003,
          changed => {
          },
          removed => {
          }
      },
  
      5.011005 => {
          delta_from => 5.011004,
          changed => {
          },
          removed => {
          }
      },
  
      5.012 => {
          delta_from => 5.011005,
          changed => {
          },
          removed => {
          }
      },
  
      5.013 => {
          delta_from => 5.012005,
          changed => {
          },
          removed => {
          }
      },
  
      5.012001 => {
          delta_from => 5.012,
          changed => {
          },
          removed => {
          }
      },
  
      5.013001 => {
          delta_from => 5.013,
          changed => {
          },
          removed => {
          }
      },
  
      5.013002 => {
          delta_from => 5.013001,
          changed => {
          },
          removed => {
          }
      },
  
      5.013003 => {
          delta_from => 5.013002,
          changed => {
          },
          removed => {
          }
      },
  
      5.013004 => {
          delta_from => 5.013003,
          changed => {
          },
          removed => {
          }
      },
  
      5.012002 => {
          delta_from => 5.012001,
          changed => {
          },
          removed => {
          }
      },
  
      5.013005 => {
          delta_from => 5.013004,
          changed => {
          },
          removed => {
          }
      },
  
      5.013006 => {
          delta_from => 5.013005,
          changed => {
          },
          removed => {
          }
      },
  
      5.013007 => {
          delta_from => 5.013006,
          changed => {
              'ptargrep'              => '1',
          },
          removed => {
          }
      },
  
      5.013008 => {
          delta_from => 5.013007,
          changed => {
          },
          removed => {
          }
      },
  
      5.013009 => {
          delta_from => 5.013008,
          changed => {
              'json_pp'               => '1',
          },
          removed => {
          }
      },
  
      5.012003 => {
          delta_from => 5.012002,
          changed => {
          },
          removed => {
          }
      },
  
      5.013010 => {
          delta_from => 5.013009,
          changed => {
          },
          removed => {
          }
      },
  
      5.013011 => {
          delta_from => 5.013010,
          changed => {
          },
          removed => {
          }
      },
  
      5.014 => {
          delta_from => 5.013011,
          changed => {
          },
          removed => {
          }
      },
  
      5.014001 => {
          delta_from => 5.014,
          changed => {
          },
          removed => {
          }
      },
  
      5.015 => {
          delta_from => 5.014004,
          changed => {
          },
          removed => {
             'dprofpp'               => 1,
          }
      },
  
      5.012004 => {
          delta_from => 5.012003,
          changed => {
          },
          removed => {
          }
      },
  
      5.015001 => {
          delta_from => 5.015,
          changed => {
          },
          removed => {
          }
      },
  
      5.015002 => {
          delta_from => 5.015001,
          changed => {
          },
          removed => {
          }
      },
  
      5.015003 => {
          delta_from => 5.015002,
          changed => {
          },
          removed => {
          }
      },
  
      5.014002 => {
          delta_from => 5.014001,
          changed => {
          },
          removed => {
          }
      },
  
      5.015004 => {
          delta_from => 5.015003,
          changed => {
          },
          removed => {
          }
      },
  
      5.015005 => {
          delta_from => 5.015004,
          changed => {
          },
          removed => {
          }
      },
  
      5.015006 => {
          delta_from => 5.015005,
          changed => {
              'zipdetails'            => '1',
          },
          removed => {
          }
      },
  
      5.015007 => {
          delta_from => 5.015006,
          changed => {
          },
          removed => {
          }
      },
  
      5.015008 => {
          delta_from => 5.015007,
          changed => {
          },
          removed => {
          }
      },
  
      5.015009 => {
          delta_from => 5.015008,
          changed => {
          },
          removed => {
          }
      },
  
      5.016 => {
          delta_from => 5.015009,
          changed => {
          },
          removed => {
          }
      },
  
      5.017 => {
          delta_from => 5.016003,
          changed => {
          },
          removed => {
          }
      },
  
      5.017001 => {
          delta_from => 5.017,
          changed => {
          },
          removed => {
          }
      },
  
      5.017002 => {
          delta_from => 5.017001,
          changed => {
          },
          removed => {
          }
      },
  
      5.016001 => {
          delta_from => 5.016,
          changed => {
          },
          removed => {
          }
      },
  
      5.017003 => {
          delta_from => 5.017002,
          changed => {
          },
          removed => {
          }
      },
  
      5.017004 => {
          delta_from => 5.017003,
          changed => {
          },
          removed => {
          }
      },
  
      5.014003 => {
          delta_from => 5.014002,
          changed => {
          },
          removed => {
          }
      },
  
      5.017005 => {
          delta_from => 5.017004,
          changed => {
          },
          removed => {
          }
      },
  
      5.016002 => {
          delta_from => 5.016001,
          changed => {
          },
          removed => {
          }
      },
  
      5.012005 => {
          delta_from => 5.012004,
          changed => {
          },
          removed => {
          }
      },
  
      5.017006 => {
          delta_from => 5.017005,
          changed => {
          },
          removed => {
          }
      },
  
      5.017007 => {
          delta_from => 5.017006,
          changed => {
          },
          removed => {
          }
      },
  
      5.017008 => {
          delta_from => 5.017007,
          changed => {
          },
          removed => {
          }
      },
  
      5.017009 => {
          delta_from => 5.017008,
          changed => {
          },
          removed => {
          }
      },
  
      5.014004 => {
          delta_from => 5.014003,
          changed => {
          },
          removed => {
          }
      },
  
      5.016003 => {
          delta_from => 5.016002,
          changed => {
          },
          removed => {
          }
      },
  
      5.017010 => {
          delta_from => 5.017009,
          changed => {
          },
          removed => {
          }
      },
  
      5.017011 => {
          delta_from => 5.017010,
          changed => {
          },
          removed => {
          }
      },
      5.018000 => {
          delta_from => 5.017011,
          changed => {
          },
          removed => {
          }
      },
      5.018001 => {
          delta_from => 5.018000,
          changed => {
          },
          removed => {
          }
      },
      5.018002 => {
          delta_from => 5.018001,
          changed => {
          },
          removed => {
          }
      },
      5.018003 => {
          delta_from => 5.018000,
          changed => {
          },
          removed => {
          }
      },
      5.018004 => {
          delta_from => 5.018000,
          changed => {
          },
          removed => {
          }
      },
      5.019000 => {
          delta_from => 5.018000,
          changed => {
          },
          removed => {
              'cpan2dist'             => '1',
              'cpanp'                 => '1',
              'cpanp-run-perl'        => '1',
              'pod2latex'             => '1',
          }
      },
      5.019001 => {
          delta_from => 5.019000,
          changed => {
          },
          removed => {
          }
      },
      5.019002 => {
          delta_from => 5.019001,
          changed => {
          },
          removed => {
          }
      },
      5.019003 => {
          delta_from => 5.019002,
          changed => {
          },
          removed => {
          }
      },
      5.019004 => {
          delta_from => 5.019003,
          changed => {
          },
          removed => {
          }
      },
      5.019005 => {
          delta_from => 5.019004,
          changed => {
          },
          removed => {
          }
      },
      5.019006 => {
          delta_from => 5.019005,
          changed => {
          },
          removed => {
          }
      },
      5.019007 => {
          delta_from => 5.019006,
          changed => {
          },
          removed => {
          }
      },
      5.019008 => {
          delta_from => 5.019007,
          changed => {
          },
          removed => {
          }
      },
      5.019009 => {
          delta_from => 5.019008,
          changed => {
          },
          removed => {
          }
      },
      5.019010 => {
          delta_from => 5.019009,
          changed => {
          },
          removed => {
          }
      },
      5.019011 => {
          delta_from => 5.019010,
          changed => {
          },
          removed => {
          }
      },
      5.020000 => {
          delta_from => 5.019011,
          changed => {
          },
          removed => {
          }
      },
      5.021000 => {
          delta_from => 5.020000,
          changed => {
          },
          removed => {
          }
      },
      5.021001 => {
          delta_from => 5.021000,
          changed => {
          },
          removed => {
              'a2p'                   => 1,
              'config_data'           => 1,
              'find2perl'             => 1,
              'psed'                  => 1,
              's2p'                   => 1,
          }
      },
      5.021002 => {
          delta_from => 5.021001,
          changed => {
          },
          removed => {
          }
      },
      5.021003 => {
          delta_from => 5.021002,
          changed => {
          },
          removed => {
          }
      },
      5.020001 => {
          delta_from => 5.02,
          changed => {
          },
          removed => {
          }
      },
      5.021004 => {
          delta_from => 5.021003,
          changed => {
          },
          removed => {
          }
      },
      5.021005 => {
          delta_from => 5.021004,
          changed => {
          },
          removed => {
          }
      },
      5.021006 => {
          delta_from => 5.021005,
          changed => {
          },
          removed => {
          }
      },
      5.021007 => {
          delta_from => 5.021006,
          changed => {
          },
          removed => {
          }
      },
      5.021008 => {
          delta_from => 5.021007,
          changed => {
          },
          removed => {
          }
      },
      5.020002 => {
          delta_from => 5.020001,
          changed => {
          },
          removed => {
          }
      },
      5.021009 => {
          delta_from => 5.021008,
          changed => {
              'encguess'              => '1',
          },
          removed => {
          }
      },
      5.021010 => {
          delta_from => 5.021009,
          changed => {
          },
          removed => {
          }
      },
      5.021011 => {
          delta_from => 5.02101,
          changed => {
          },
          removed => {
          }
      },
      5.022000 => {
          delta_from => 5.021011,
          changed => {
          },
          removed => {
          }
      },
      5.023000 => {
          delta_from => 5.022000,
          changed => {
          },
          removed => {
          }
      },
  );
  
  for my $version (sort { $a <=> $b } keys %delta) {
      my $data = $delta{$version};
  
      tie %{$utilities{$version}}, 'Module::CoreList::TieHashDelta',
          $data->{changed}, $data->{removed},
          $data->{delta_from} ? $utilities{$data->{delta_from}} : undef;
  }
  
  # Create aliases with trailing zeros for $] use
  
  $utilities{'5.000'} = $utilities{5};
  
  _create_aliases(\%utilities);
  
  sub _create_aliases {
      my ($hash) = @_;
  
      for my $version (keys %$hash) {
          next unless $version >= 5.010;
  
          my $padded = sprintf "%0.6f", $version;
  
          # If the version in string form isn't the same as the numeric version,
          # alias it.
          if ($padded ne $version && $version == $padded) {
              $hash->{$padded} = $hash->{$version};
          }
      }
  }
  
  'foo';
  
  =pod
  
  =head1 NAME
  
  Module::CoreList::Utils - what utilities shipped with versions of perl
  
  =head1 SYNOPSIS
  
   use Module::CoreList::Utils;
  
   print $Module::CoreList::Utils::utilities{5.009003}{ptar}; # prints 1
  
   print Module::CoreList::Utils->first_release('corelist');           # prints 5.008009
   print Module::CoreList::Utils->first_release_by_date('corelist');   # prints 5.009002
  
  =head1 DESCRIPTION
  
  Module::CoreList::Utils provides information on which core and dual-life utilities shipped
  with each version of L<perl>.
  
  It provides a number of mechanisms for querying this information.
  
  There is a functional programming API available for programmers to query
  information.
  
  Programmers may also query the contained hash structure to find relevant
  information.
  
  =head1 FUNCTIONS API
  
  These are the functions that are available, they may either be called as functions or class methods:
  
    Module::CoreList::Utils::first_release('corelist'); # as a function
  
    Module::CoreList::Utils->first_release('corelist'); # class method
  
  =over
  
  =item C<utilities>
  
  Requires a perl version as an argument, returns a list of utilities that shipped with
  that version of perl, or undef/empty list if that perl doesn't exist.
  
  =item C<first_release( UTILITY )>
  
  Requires a UTILITY name as an argument, returns the perl version when that utility first
  appeared in core as ordered by perl version number or undef ( in scalar context )
  or an empty list ( in list context ) if that utility is not in core.
  
  =item C<first_release_by_date( UTILITY )>
  
  Requires a UTILITY name as an argument, returns the perl version when that utility first
  appeared in core as ordered by release date or undef ( in scalar context )
  or an empty list ( in list context ) if that utility is not in core.
  
  =item C<removed_from( UTILITY )>
  
  Takes a UTILITY name as an argument, returns the first perl version where that utility
  was removed from core. Returns undef if the given utility was never in core or remains
  in core.
  
  =item C<removed_from_by_date( UTILITY )>
  
  Takes a UTILITY name as an argument, returns the first perl version by release date where that
  utility was removed from core. Returns undef if the given utility was never in core or remains
  in core.
  
  =back
  
  =head1 DATA STRUCTURES
  
  These are the hash data structures that are available:
  
  =over
  
  =item C<%Module::CoreList::Utils::utilities>
  
  A hash of hashes that is keyed on perl version as indicated
  in $].  The second level hash is utility / defined pairs.
  
  =back
  
  =head1 AUTHOR
  
  Chris C<BinGOs> Williams <chris@bingosnet.co.uk>
  
  Currently maintained by the perl 5 porters E<lt>perl5-porters@perl.orgE<gt>.
  
  This module is the result of archaeology undertaken during QA Hackathon
  in Lancaster, April 2013.
  
  =head1 LICENSE
  
  Copyright (C) 2013 Chris Williams.  All Rights Reserved.
  
  This module is free software; you can redistribute it and/or modify it
  under the same terms as Perl itself.
  
  =head1 SEE ALSO
  
  L<corelist>, L<Module::CoreList>, L<perl>, L<http://perlpunks.de/corelist>
  
  =cut
MODULE_CORELIST_UTILS

$fatpacked{"Module/Metadata.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MODULE_METADATA';
  # -*- mode: cperl; tab-width: 8; indent-tabs-mode: nil; basic-offset: 2 -*-
  # vim:ts=8:sw=2:et:sta:sts=2
  package Module::Metadata; # git description: v1.000026-12-g9b12bf1
  
  # Adapted from Perl-licensed code originally distributed with
  # Module-Build by Ken Williams
  
  # This module provides routines to gather information about
  # perl modules (assuming this may be expanded in the distant
  # parrot future to look at other types of modules).
  
  sub __clean_eval { eval $_[0] }
  use strict;
  use warnings;
  
  our $VERSION = '1.000027';
  
  use Carp qw/croak/;
  use File::Spec;
  BEGIN {
         # Try really hard to not depend ony any DynaLoaded module, such as IO::File or Fcntl
         eval {
                 require Fcntl; Fcntl->import('SEEK_SET'); 1;
         } or *SEEK_SET = sub { 0 }
  }
  use version 0.87;
  BEGIN {
    if ($INC{'Log/Contextual.pm'}) {
      require "Log/Contextual/WarnLogger.pm"; # Hide from AutoPrereqs
      Log::Contextual->import('log_info',
        '-default_logger' => Log::Contextual::WarnLogger->new({ env_prefix => 'MODULE_METADATA', }),
      );
    } else {
      *log_info = sub (&) { warn $_[0]->() };
    }
  }
  use File::Find qw(find);
  
  my $V_NUM_REGEXP = qr{v?[0-9._]+};  # crudely, a v-string or decimal
  
  my $PKG_FIRST_WORD_REGEXP = qr{ # the FIRST word in a package name
    [a-zA-Z_]                     # the first word CANNOT start with a digit
      (?:
        [\w']?                    # can contain letters, digits, _, or ticks
        \w                        # But, NO multi-ticks or trailing ticks
      )*
  }x;
  
  my $PKG_ADDL_WORD_REGEXP = qr{ # the 2nd+ word in a package name
    \w                           # the 2nd+ word CAN start with digits
      (?:
        [\w']?                   # and can contain letters or ticks
        \w                       # But, NO multi-ticks or trailing ticks
      )*
  }x;
  
  my $PKG_NAME_REGEXP = qr{ # match a package name
    (?: :: )?               # a pkg name can start with arisdottle
    $PKG_FIRST_WORD_REGEXP  # a package word
    (?:
      (?: :: )+             ### arisdottle (allow one or many times)
      $PKG_ADDL_WORD_REGEXP ### a package word
    )*                      # ^ zero, one or many times
    (?:
      ::                    # allow trailing arisdottle
    )?
  }x;
  
  my $PKG_REGEXP  = qr{   # match a package declaration
    ^[\s\{;]*             # intro chars on a line
    package               # the word 'package'
    \s+                   # whitespace
    ($PKG_NAME_REGEXP)    # a package name
    \s*                   # optional whitespace
    ($V_NUM_REGEXP)?        # optional version number
    \s*                   # optional whitesapce
    [;\{]                 # semicolon line terminator or block start (since 5.16)
  }x;
  
  my $VARNAME_REGEXP = qr{ # match fully-qualified VERSION name
    ([\$*])         # sigil - $ or *
    (
      (             # optional leading package name
        (?:::|\')?  # possibly starting like just :: (a la $::VERSION)
        (?:\w+(?:::|\'))*  # Foo::Bar:: ...
      )?
      VERSION
    )\b
  }x;
  
  my $VERS_REGEXP = qr{ # match a VERSION definition
    (?:
      \(\s*$VARNAME_REGEXP\s*\) # with parens
    |
      $VARNAME_REGEXP           # without parens
    )
    \s*
    =[^=~>]  # = but not ==, nor =~, nor =>
  }x;
  
  sub new_from_file {
    my $class    = shift;
    my $filename = File::Spec->rel2abs( shift );
  
    return undef unless defined( $filename ) && -f $filename;
    return $class->_init(undef, $filename, @_);
  }
  
  sub new_from_handle {
    my $class    = shift;
    my $handle   = shift;
    my $filename = shift;
    return undef unless defined($handle) && defined($filename);
    $filename = File::Spec->rel2abs( $filename );
  
    return $class->_init(undef, $filename, @_, handle => $handle);
  
  }
  
  
  sub new_from_module {
    my $class   = shift;
    my $module  = shift;
    my %props   = @_;
  
    $props{inc} ||= \@INC;
    my $filename = $class->find_module_by_name( $module, $props{inc} );
    return undef unless defined( $filename ) && -f $filename;
    return $class->_init($module, $filename, %props);
  }
  
  {
  
    my $compare_versions = sub {
      my ($v1, $op, $v2) = @_;
      $v1 = version->new($v1)
        unless UNIVERSAL::isa($v1,'version');
  
      my $eval_str = "\$v1 $op \$v2";
      my $result   = eval $eval_str;
      log_info { "error comparing versions: '$eval_str' $@" } if $@;
  
      return $result;
    };
  
    my $normalize_version = sub {
      my ($version) = @_;
      if ( $version =~ /[=<>!,]/ ) { # logic, not just version
        # take as is without modification
      }
      elsif ( ref $version eq 'version' ) { # version objects
        $version = $version->is_qv ? $version->normal : $version->stringify;
      }
      elsif ( $version =~ /^[^v][^.]*\.[^.]+\./ ) { # no leading v, multiple dots
        # normalize string tuples without "v": "1.2.3" -> "v1.2.3"
        $version = "v$version";
      }
      else {
        # leave alone
      }
      return $version;
    };
  
    # separate out some of the conflict resolution logic
  
    my $resolve_module_versions = sub {
      my $packages = shift;
  
      my( $file, $version );
      my $err = '';
        foreach my $p ( @$packages ) {
          if ( defined( $p->{version} ) ) {
            if ( defined( $version ) ) {
              if ( $compare_versions->( $version, '!=', $p->{version} ) ) {
                $err .= "  $p->{file} ($p->{version})\n";
              } else {
                # same version declared multiple times, ignore
              }
            } else {
              $file    = $p->{file};
              $version = $p->{version};
            }
          }
        $file ||= $p->{file} if defined( $p->{file} );
      }
  
      if ( $err ) {
        $err = "  $file ($version)\n" . $err;
      }
  
      my %result = (
        file    => $file,
        version => $version,
        err     => $err
      );
  
      return \%result;
    };
  
    sub provides {
      my $class = shift;
  
      croak "provides() requires key/value pairs \n" if @_ % 2;
      my %args = @_;
  
      croak "provides() takes only one of 'dir' or 'files'\n"
        if $args{dir} && $args{files};
  
      croak "provides() requires a 'version' argument"
        unless defined $args{version};
  
      croak "provides() does not support version '$args{version}' metadata"
          unless grep { $args{version} eq $_ } qw/1.4 2/;
  
      $args{prefix} = 'lib' unless defined $args{prefix};
  
      my $p;
      if ( $args{dir} ) {
        $p = $class->package_versions_from_directory($args{dir});
      }
      else {
        croak "provides() requires 'files' to be an array reference\n"
          unless ref $args{files} eq 'ARRAY';
        $p = $class->package_versions_from_directory($args{files});
      }
  
      # Now, fix up files with prefix
      if ( length $args{prefix} ) { # check in case disabled with q{}
        $args{prefix} =~ s{/$}{};
        for my $v ( values %$p ) {
          $v->{file} = "$args{prefix}/$v->{file}";
        }
      }
  
      return $p
    }
  
    sub package_versions_from_directory {
      my ( $class, $dir, $files ) = @_;
  
      my @files;
  
      if ( $files ) {
        @files = @$files;
      } else {
        find( {
          wanted => sub {
            push @files, $_ if -f $_ && /\.pm$/;
          },
          no_chdir => 1,
        }, $dir );
      }
  
      # First, we enumerate all packages & versions,
      # separating into primary & alternative candidates
      my( %prime, %alt );
      foreach my $file (@files) {
        my $mapped_filename = File::Spec::Unix->abs2rel( $file, $dir );
        my @path = split( /\//, $mapped_filename );
        (my $prime_package = join( '::', @path )) =~ s/\.pm$//;
  
        my $pm_info = $class->new_from_file( $file );
  
        foreach my $package ( $pm_info->packages_inside ) {
          next if $package eq 'main';  # main can appear numerous times, ignore
          next if $package eq 'DB';    # special debugging package, ignore
          next if grep /^_/, split( /::/, $package ); # private package, ignore
  
          my $version = $pm_info->version( $package );
  
          $prime_package = $package if lc($prime_package) eq lc($package);
          if ( $package eq $prime_package ) {
            if ( exists( $prime{$package} ) ) {
              croak "Unexpected conflict in '$package'; multiple versions found.\n";
            } else {
              $mapped_filename = "$package.pm" if lc("$package.pm") eq lc($mapped_filename);
              $prime{$package}{file} = $mapped_filename;
              $prime{$package}{version} = $version if defined( $version );
            }
          } else {
            push( @{$alt{$package}}, {
                                      file    => $mapped_filename,
                                      version => $version,
                                     } );
          }
        }
      }
  
      # Then we iterate over all the packages found above, identifying conflicts
      # and selecting the "best" candidate for recording the file & version
      # for each package.
      foreach my $package ( keys( %alt ) ) {
        my $result = $resolve_module_versions->( $alt{$package} );
  
        if ( exists( $prime{$package} ) ) { # primary package selected
  
          if ( $result->{err} ) {
          # Use the selected primary package, but there are conflicting
          # errors among multiple alternative packages that need to be
          # reported
            log_info {
              "Found conflicting versions for package '$package'\n" .
              "  $prime{$package}{file} ($prime{$package}{version})\n" .
              $result->{err}
            };
  
          } elsif ( defined( $result->{version} ) ) {
          # There is a primary package selected, and exactly one
          # alternative package
  
          if ( exists( $prime{$package}{version} ) &&
               defined( $prime{$package}{version} ) ) {
            # Unless the version of the primary package agrees with the
            # version of the alternative package, report a conflict
          if ( $compare_versions->(
                   $prime{$package}{version}, '!=', $result->{version}
                 )
               ) {
  
              log_info {
                "Found conflicting versions for package '$package'\n" .
                "  $prime{$package}{file} ($prime{$package}{version})\n" .
                "  $result->{file} ($result->{version})\n"
              };
            }
  
          } else {
            # The prime package selected has no version so, we choose to
            # use any alternative package that does have a version
            $prime{$package}{file}    = $result->{file};
            $prime{$package}{version} = $result->{version};
          }
  
          } else {
          # no alt package found with a version, but we have a prime
          # package so we use it whether it has a version or not
          }
  
        } else { # No primary package was selected, use the best alternative
  
          if ( $result->{err} ) {
            log_info {
              "Found conflicting versions for package '$package'\n" .
              $result->{err}
            };
          }
  
          # Despite possible conflicting versions, we choose to record
          # something rather than nothing
          $prime{$package}{file}    = $result->{file};
          $prime{$package}{version} = $result->{version}
            if defined( $result->{version} );
        }
      }
  
      # Normalize versions.  Can't use exists() here because of bug in YAML::Node.
      # XXX "bug in YAML::Node" comment seems irrelevant -- dagolden, 2009-05-18
      for (grep defined $_->{version}, values %prime) {
        $_->{version} = $normalize_version->( $_->{version} );
      }
  
      return \%prime;
    }
  }
  
  
  sub _init {
    my $class    = shift;
    my $module   = shift;
    my $filename = shift;
    my %props = @_;
  
    my $handle = delete $props{handle};
    my( %valid_props, @valid_props );
    @valid_props = qw( collect_pod inc );
    @valid_props{@valid_props} = delete( @props{@valid_props} );
    warn "Unknown properties: @{[keys %props]}\n" if scalar( %props );
  
    my %data = (
      module       => $module,
      filename     => $filename,
      version      => undef,
      packages     => [],
      versions     => {},
      pod          => {},
      pod_headings => [],
      collect_pod  => 0,
  
      %valid_props,
    );
  
    my $self = bless(\%data, $class);
  
    if ( not $handle ) {
      my $filename = $self->{filename};
      open $handle, '<', $filename
        or croak( "Can't open '$filename': $!" );
  
      $self->_handle_bom($handle, $filename);
    }
    $self->_parse_fh($handle);
  
    unless($self->{module} and length($self->{module})) {
      my ($v, $d, $f) = File::Spec->splitpath($self->{filename});
      if($f =~ /\.pm$/) {
        $f =~ s/\..+$//;
        my @candidates = grep /$f$/, @{$self->{packages}};
        $self->{module} = shift(@candidates); # punt
      }
      else {
        if(grep /main/, @{$self->{packages}}) {
          $self->{module} = 'main';
        }
        else {
          $self->{module} = $self->{packages}[0] || '';
        }
      }
    }
  
    $self->{version} = $self->{versions}{$self->{module}}
        if defined( $self->{module} );
  
    return $self;
  }
  
  # class method
  sub _do_find_module {
    my $class   = shift;
    my $module  = shift || croak 'find_module_by_name() requires a package name';
    my $dirs    = shift || \@INC;
  
    my $file = File::Spec->catfile(split( /::/, $module));
    foreach my $dir ( @$dirs ) {
      my $testfile = File::Spec->catfile($dir, $file);
      return [ File::Spec->rel2abs( $testfile ), $dir ]
        if -e $testfile and !-d _;  # For stuff like ExtUtils::xsubpp
      $testfile .= '.pm';
      return [ File::Spec->rel2abs( $testfile ), $dir ]
        if -e $testfile;
    }
    return;
  }
  
  # class method
  sub find_module_by_name {
    my $found = shift()->_do_find_module(@_) or return;
    return $found->[0];
  }
  
  # class method
  sub find_module_dir_by_name {
    my $found = shift()->_do_find_module(@_) or return;
    return $found->[1];
  }
  
  
  # given a line of perl code, attempt to parse it if it looks like a
  # $VERSION assignment, returning sigil, full name, & package name
  sub _parse_version_expression {
    my $self = shift;
    my $line = shift;
  
    my( $sigil, $variable_name, $package);
    if ( $line =~ /$VERS_REGEXP/o ) {
      ( $sigil, $variable_name, $package) = $2 ? ( $1, $2, $3 ) : ( $4, $5, $6 );
      if ( $package ) {
        $package = ($package eq '::') ? 'main' : $package;
        $package =~ s/::$//;
      }
    }
  
    return ( $sigil, $variable_name, $package );
  }
  
  # Look for a UTF-8/UTF-16BE/UTF-16LE BOM at the beginning of the stream.
  # If there's one, then skip it and set the :encoding layer appropriately.
  sub _handle_bom {
    my ($self, $fh, $filename) = @_;
  
    my $pos = tell $fh;
    return unless defined $pos;
  
    my $buf = ' ' x 2;
    my $count = read $fh, $buf, length $buf;
    return unless defined $count and $count >= 2;
  
    my $encoding;
    if ( $buf eq "\x{FE}\x{FF}" ) {
      $encoding = 'UTF-16BE';
    } elsif ( $buf eq "\x{FF}\x{FE}" ) {
      $encoding = 'UTF-16LE';
    } elsif ( $buf eq "\x{EF}\x{BB}" ) {
      $buf = ' ';
      $count = read $fh, $buf, length $buf;
      if ( defined $count and $count >= 1 and $buf eq "\x{BF}" ) {
        $encoding = 'UTF-8';
      }
    }
  
    if ( defined $encoding ) {
      if ( "$]" >= 5.008 ) {
        binmode( $fh, ":encoding($encoding)" );
      }
    } else {
      seek $fh, $pos, SEEK_SET
        or croak( sprintf "Can't reset position to the top of '$filename'" );
    }
  
    return $encoding;
  }
  
  sub _parse_fh {
    my ($self, $fh) = @_;
  
    my( $in_pod, $seen_end, $need_vers ) = ( 0, 0, 0 );
    my( @packages, %vers, %pod, @pod );
    my $package = 'main';
    my $pod_sect = '';
    my $pod_data = '';
    my $in_end = 0;
  
    while (defined( my $line = <$fh> )) {
      my $line_num = $.;
  
      chomp( $line );
  
      # From toke.c : any line that begins by "=X", where X is an alphabetic
      # character, introduces a POD segment.
      my $is_cut;
      if ( $line =~ /^=([a-zA-Z].*)/ ) {
        my $cmd = $1;
        # Then it goes back to Perl code for "=cutX" where X is a non-alphabetic
        # character (which includes the newline, but here we chomped it away).
        $is_cut = $cmd =~ /^cut(?:[^a-zA-Z]|$)/;
        $in_pod = !$is_cut;
      }
  
      if ( $in_pod ) {
  
        if ( $line =~ /^=head[1-4]\s+(.+)\s*$/ ) {
          push( @pod, $1 );
          if ( $self->{collect_pod} && length( $pod_data ) ) {
            $pod{$pod_sect} = $pod_data;
            $pod_data = '';
          }
          $pod_sect = $1;
  
        } elsif ( $self->{collect_pod} ) {
          $pod_data .= "$line\n";
  
        }
  
      } elsif ( $is_cut ) {
  
        if ( $self->{collect_pod} && length( $pod_data ) ) {
          $pod{$pod_sect} = $pod_data;
          $pod_data = '';
        }
        $pod_sect = '';
  
      } else {
  
        # Skip after __END__
        next if $in_end;
  
        # Skip comments in code
        next if $line =~ /^\s*#/;
  
        # Would be nice if we could also check $in_string or something too
        if ($line eq '__END__') {
          $in_end++;
          next;
        }
        last if $line eq '__DATA__';
  
        # parse $line to see if it's a $VERSION declaration
        my( $version_sigil, $version_fullname, $version_package ) =
            index($line, 'VERSION') >= 1
                ? $self->_parse_version_expression( $line )
                : ();
  
        if ( $line =~ /$PKG_REGEXP/o ) {
          $package = $1;
          my $version = $2;
          push( @packages, $package ) unless grep( $package eq $_, @packages );
          $need_vers = defined $version ? 0 : 1;
  
          if ( not exists $vers{$package} and defined $version ){
            # Upgrade to a version object.
            my $dwim_version = eval { _dwim_version($version) };
            croak "Version '$version' from $self->{filename} does not appear to be valid:\n$line\n\nThe fatal error was: $@\n"
                unless defined $dwim_version;  # "0" is OK!
            $vers{$package} = $dwim_version;
          }
  
        # VERSION defined with full package spec, i.e. $Module::VERSION
        } elsif ( $version_fullname && $version_package ) {
          push( @packages, $version_package ) unless grep( $version_package eq $_, @packages );
          $need_vers = 0 if $version_package eq $package;
  
          unless ( defined $vers{$version_package} && length $vers{$version_package} ) {
          $vers{$version_package} = $self->_evaluate_version_line( $version_sigil, $version_fullname, $line );
        }
  
        # first non-comment line in undeclared package main is VERSION
        } elsif ( $package eq 'main' && $version_fullname && !exists($vers{main}) ) {
          $need_vers = 0;
          my $v = $self->_evaluate_version_line( $version_sigil, $version_fullname, $line );
          $vers{$package} = $v;
          push( @packages, 'main' );
  
        # first non-comment line in undeclared package defines package main
        } elsif ( $package eq 'main' && !exists($vers{main}) && $line =~ /\w/ ) {
          $need_vers = 1;
          $vers{main} = '';
          push( @packages, 'main' );
  
        # only keep if this is the first $VERSION seen
        } elsif ( $version_fullname && $need_vers ) {
          $need_vers = 0;
          my $v = $self->_evaluate_version_line( $version_sigil, $version_fullname, $line );
  
          unless ( defined $vers{$package} && length $vers{$package} ) {
            $vers{$package} = $v;
          }
        }
      }
    }
  
    if ( $self->{collect_pod} && length($pod_data) ) {
      $pod{$pod_sect} = $pod_data;
    }
  
    $self->{versions} = \%vers;
    $self->{packages} = \@packages;
    $self->{pod} = \%pod;
    $self->{pod_headings} = \@pod;
  }
  
  {
  my $pn = 0;
  sub _evaluate_version_line {
    my $self = shift;
    my( $sigil, $variable_name, $line ) = @_;
  
    # We compile into a local sub because 'use version' would cause
    # compiletime/runtime issues with local()
    $pn++; # everybody gets their own package
    my $eval = qq{ my \$dummy = q#  Hide from _packages_inside()
      #; package Module::Metadata::_version::p${pn};
      use version;
      sub {
        local $sigil$variable_name;
        $line;
        \$$variable_name
      };
    };
  
    $eval = $1 if $eval =~ m{^(.+)}s;
  
    local $^W;
    # Try to get the $VERSION
    my $vsub = __clean_eval($eval);
    # some modules say $VERSION <equal sign> $Foo::Bar::VERSION, but Foo::Bar isn't
    # installed, so we need to hunt in ./lib for it
    if ( $@ =~ /Can't locate/ && -d 'lib' ) {
      local @INC = ('lib',@INC);
      $vsub = __clean_eval($eval);
    }
    warn "Error evaling version line '$eval' in $self->{filename}: $@\n"
      if $@;
  
    (ref($vsub) eq 'CODE') or
      croak "failed to build version sub for $self->{filename}";
  
    my $result = eval { $vsub->() };
    # FIXME: $eval is not the right thing to print here
    croak "Could not get version from $self->{filename} by executing:\n$eval\n\nThe fatal error was: $@\n"
      if $@;
  
    # Upgrade it into a version object
    my $version = eval { _dwim_version($result) };
  
    # FIXME: $eval is not the right thing to print here
    croak "Version '$result' from $self->{filename} does not appear to be valid:\n$eval\n\nThe fatal error was: $@\n"
      unless defined $version; # "0" is OK!
  
    return $version;
  }
  }
  
  # Try to DWIM when things fail the lax version test in obvious ways
  {
    my @version_prep = (
      # Best case, it just works
      sub { return shift },
  
      # If we still don't have a version, try stripping any
      # trailing junk that is prohibited by lax rules
      sub {
        my $v = shift;
        $v =~ s{([0-9])[a-z-].*$}{$1}i; # 1.23-alpha or 1.23b
        return $v;
      },
  
      # Activestate apparently creates custom versions like '1.23_45_01', which
      # cause version.pm to think it's an invalid alpha.  So check for that
      # and strip them
      sub {
        my $v = shift;
        my $num_dots = () = $v =~ m{(\.)}g;
        my $num_unders = () = $v =~ m{(_)}g;
        my $leading_v = substr($v,0,1) eq 'v';
        if ( ! $leading_v && $num_dots < 2 && $num_unders > 1 ) {
          $v =~ s{_}{}g;
          $num_unders = () = $v =~ m{(_)}g;
        }
        return $v;
      },
  
      # Worst case, try numifying it like we would have before version objects
      sub {
        my $v = shift;
        no warnings 'numeric';
        return 0 + $v;
      },
  
    );
  
    sub _dwim_version {
      my ($result) = shift;
  
      return $result if ref($result) eq 'version';
  
      my ($version, $error);
      for my $f (@version_prep) {
        $result = $f->($result);
        $version = eval { version->new($result) };
        $error ||= $@ if $@; # capture first failure
        last if defined $version;
      }
  
      croak $error unless defined $version;
  
      return $version;
    }
  }
  
  ############################################################
  
  # accessors
  sub name            { $_[0]->{module}            }
  
  sub filename        { $_[0]->{filename}          }
  sub packages_inside { @{$_[0]->{packages}}       }
  sub pod_inside      { @{$_[0]->{pod_headings}}   }
  sub contains_pod    { 0+@{$_[0]->{pod_headings}} }
  
  sub version {
      my $self = shift;
      my $mod  = shift || $self->{module};
      my $vers;
      if ( defined( $mod ) && length( $mod ) &&
           exists( $self->{versions}{$mod} ) ) {
          return $self->{versions}{$mod};
      } else {
          return undef;
      }
  }
  
  sub pod {
      my $self = shift;
      my $sect = shift;
      if ( defined( $sect ) && length( $sect ) &&
           exists( $self->{pod}{$sect} ) ) {
          return $self->{pod}{$sect};
      } else {
          return undef;
      }
  }
  
  sub is_indexable {
    my ($self, $package) = @_;
  
    my @indexable_packages = grep { $_ ne 'main' } $self->packages_inside;
  
    # check for specific package, if provided
    return !! grep { $_ eq $package } @indexable_packages if $package;
  
    # otherwise, check for any indexable packages at all
    return !! @indexable_packages;
  }
  
  1;
  
  =head1 NAME
  
  Module::Metadata - Gather package and POD information from perl module files
  
  =head1 SYNOPSIS
  
    use Module::Metadata;
  
    # information about a .pm file
    my $info = Module::Metadata->new_from_file( $file );
    my $version = $info->version;
  
    # CPAN META 'provides' field for .pm files in a directory
    my $provides = Module::Metadata->provides(
      dir => 'lib', version => 2
    );
  
  =head1 DESCRIPTION
  
  This module provides a standard way to gather metadata about a .pm file through
  (mostly) static analysis and (some) code execution.  When determining the
  version of a module, the C<$VERSION> assignment is C<eval>ed, as is traditional
  in the CPAN toolchain.
  
  =head1 CLASS METHODS
  
  =head2 C<< new_from_file($filename, collect_pod => 1) >>
  
  Constructs a C<Module::Metadata> object given the path to a file.  Returns
  undef if the filename does not exist.
  
  C<collect_pod> is a optional boolean argument that determines whether POD
  data is collected and stored for reference.  POD data is not collected by
  default.  POD headings are always collected.
  
  If the file begins by an UTF-8, UTF-16BE or UTF-16LE byte-order mark, then
  it is skipped before processing, and the content of the file is also decoded
  appropriately starting from perl 5.8.
  
  =head2 C<< new_from_handle($handle, $filename, collect_pod => 1) >>
  
  This works just like C<new_from_file>, except that a handle can be provided
  as the first argument.
  
  Note that there is no validation to confirm that the handle is a handle or
  something that can act like one.  Passing something that isn't a handle will
  cause a exception when trying to read from it.  The C<filename> argument is
  mandatory or undef will be returned.
  
  You are responsible for setting the decoding layers on C<$handle> if
  required.
  
  =head2 C<< new_from_module($module, collect_pod => 1, inc => \@dirs) >>
  
  Constructs a C<Module::Metadata> object given a module or package name.
  Returns undef if the module cannot be found.
  
  In addition to accepting the C<collect_pod> argument as described above,
  this method accepts a C<inc> argument which is a reference to an array of
  directories to search for the module.  If none are given, the default is
  @INC.
  
  If the file that contains the module begins by an UTF-8, UTF-16BE or
  UTF-16LE byte-order mark, then it is skipped before processing, and the
  content of the file is also decoded appropriately starting from perl 5.8.
  
  =head2 C<< find_module_by_name($module, \@dirs) >>
  
  Returns the path to a module given the module or package name. A list
  of directories can be passed in as an optional parameter, otherwise
  @INC is searched.
  
  Can be called as either an object or a class method.
  
  =head2 C<< find_module_dir_by_name($module, \@dirs) >>
  
  Returns the entry in C<@dirs> (or C<@INC> by default) that contains
  the module C<$module>. A list of directories can be passed in as an
  optional parameter, otherwise @INC is searched.
  
  Can be called as either an object or a class method.
  
  =head2 C<< provides( %options ) >>
  
  This is a convenience wrapper around C<package_versions_from_directory>
  to generate a CPAN META C<provides> data structure.  It takes key/value
  pairs.  Valid option keys include:
  
  =over
  
  =item version B<(required)>
  
  Specifies which version of the L<CPAN::Meta::Spec> should be used as
  the format of the C<provides> output.  Currently only '1.4' and '2'
  are supported (and their format is identical).  This may change in
  the future as the definition of C<provides> changes.
  
  The C<version> option is required.  If it is omitted or if
  an unsupported version is given, then C<provides> will throw an error.
  
  =item dir
  
  Directory to search recursively for F<.pm> files.  May not be specified with
  C<files>.
  
  =item files
  
  Array reference of files to examine.  May not be specified with C<dir>.
  
  =item prefix
  
  String to prepend to the C<file> field of the resulting output. This defaults
  to F<lib>, which is the common case for most CPAN distributions with their
  F<.pm> files in F<lib>.  This option ensures the META information has the
  correct relative path even when the C<dir> or C<files> arguments are
  absolute or have relative paths from a location other than the distribution
  root.
  
  =back
  
  For example, given C<dir> of 'lib' and C<prefix> of 'lib', the return value
  is a hashref of the form:
  
    {
      'Package::Name' => {
        version => '0.123',
        file => 'lib/Package/Name.pm'
      },
      'OtherPackage::Name' => ...
    }
  
  =head2 C<< package_versions_from_directory($dir, \@files?) >>
  
  Scans C<$dir> for .pm files (unless C<@files> is given, in which case looks
  for those files in C<$dir> - and reads each file for packages and versions,
  returning a hashref of the form:
  
    {
      'Package::Name' => {
        version => '0.123',
        file => 'Package/Name.pm'
      },
      'OtherPackage::Name' => ...
    }
  
  The C<DB> and C<main> packages are always omitted, as are any "private"
  packages that have leading underscores in the namespace (e.g.
  C<Foo::_private>)
  
  Note that the file path is relative to C<$dir> if that is specified.
  This B<must not> be used directly for CPAN META C<provides>.  See
  the C<provides> method instead.
  
  =head2 C<< log_info (internal) >>
  
  Used internally to perform logging; imported from Log::Contextual if
  Log::Contextual has already been loaded, otherwise simply calls warn.
  
  =head1 OBJECT METHODS
  
  =head2 C<< name() >>
  
  Returns the name of the package represented by this module. If there
  is more than one package, it makes a best guess based on the
  filename. If it's a script (i.e. not a *.pm) the package name is
  'main'.
  
  =head2 C<< version($package) >>
  
  Returns the version as defined by the $VERSION variable for the
  package as returned by the C<name> method if no arguments are
  given. If given the name of a package it will attempt to return the
  version of that package if it is specified in the file.
  
  =head2 C<< filename() >>
  
  Returns the absolute path to the file.
  Note that this file may not actually exist on disk yet, e.g. if the module was read from an in-memory filehandle.
  
  =head2 C<< packages_inside() >>
  
  Returns a list of packages. Note: this is a raw list of packages
  discovered (or assumed, in the case of C<main>).  It is not
  filtered for C<DB>, C<main> or private packages the way the
  C<provides> method does.  Invalid package names are not returned,
  for example "Foo:Bar".  Strange but valid package names are
  returned, for example "Foo::Bar::", and are left up to the caller
  on how to handle.
  
  =head2 C<< pod_inside() >>
  
  Returns a list of POD sections.
  
  =head2 C<< contains_pod() >>
  
  Returns true if there is any POD in the file.
  
  =head2 C<< pod($section) >>
  
  Returns the POD data in the given section.
  
  =head2 C<< is_indexable($package) >> or C<< is_indexable() >>
  
  Returns a boolean indicating whether the package (if provided) or any package
  (otherwise) is eligible for indexing by PAUSE, the Perl Authors Upload Server.
  Note This only checks for valid C<package> declarations, and does not take any
  ownership information into account.
  
  =head1 AUTHOR
  
  Original code from Module::Build::ModuleInfo by Ken Williams
  <kwilliams@cpan.org>, Randy W. Sims <RandyS@ThePierianSpring.org>
  
  Released as Module::Metadata by Matt S Trout (mst) <mst@shadowcat.co.uk> with
  assistance from David Golden (xdg) <dagolden@cpan.org>.
  
  =head1 COPYRIGHT & LICENSE
  
  Original code Copyright (c) 2001-2011 Ken Williams.
  Additional code Copyright (c) 2010-2011 Matt Trout and David Golden.
  All rights reserved.
  
  This library is free software; you can redistribute it and/or
  modify it under the same terms as Perl itself.
  
  =cut
MODULE_METADATA

$fatpacked{"Module/Reader.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MODULE_READER';
  package Module::Reader;
  BEGIN { require 5.006 }
  use strict;
  use warnings;
  
  our $VERSION = '0.002003';
  $VERSION = eval $VERSION;
  
  use base 'Exporter';
  our @EXPORT_OK = qw(module_content module_handle);
  our %EXPORT_TAGS = (all => [@EXPORT_OK]);
  
  use File::Spec;
  use Scalar::Util qw(blessed reftype openhandle);
  use Carp;
  use constant _OPEN_STRING => $] >= 5.008;
  BEGIN {
      require IO::String
          if !_OPEN_STRING;
  }
  
  sub module_content {
      my $module = _get_module(@_);
      if (ref $module) {
          local $/;
          return scalar <$module>;
      }
      else {
          return $module;
      }
  }
  
  sub module_handle {
      my $module = _get_module(@_);
      if (ref $module) {
          return $module;
      }
      elsif (_OPEN_STRING) {
          open my $fh, '<', \$module;
          return $fh;
      }
      else {
          return IO::String->new($module);
      }
  }
  
  sub _get_module {
      my ($package, @inc) = @_;
      (my $module = "$package.pm") =~ s{::}{/}g;
      my $opts = ref $_[-1] && ref $_[-1] eq 'HASH' && pop @inc || {};
      if (!@inc) {
          @inc = @INC;
      }
      if (my $found = $opts->{found}) {
          if (my $full_module = $found->{$module}) {
              if (ref $full_module) {
                  @inc = $full_module;
              }
              elsif (-f $full_module) {
                  open my $fh, '<', $full_module
                      or die "Couldn't open ${full_module} for ${module}: $!";
                  return $fh;
              }
          }
      }
      for my $inc (@inc) {
          if (!ref $inc) {
              my $full_module = File::Spec->catfile($inc, $module);
              next unless -f $full_module;
              open my $fh, '<', $full_module
                  or die "Couldn't open ${full_module} for ${module}: $!";
              return $fh;
          }
  
          my @cb = ref $inc eq 'ARRAY'  ? $inc->[0]->($inc, $module)
                 : blessed $inc         ? $inc->INC($module)
                                        : $inc->($inc, $module);
  
          next
              unless ref $cb[0];
          my $fh;
          if (reftype $cb[0] eq 'GLOB' && openhandle $cb[0]) {
              $fh = shift @cb;
          }
  
          if (ref $cb[0] eq 'CODE') {
              my $cb = shift @cb;
              # require docs are wrong, perl sends 0 as the first param
              my @params = (0, @cb ? $cb[0] : ());
  
              my $module = '';
              while (1) {
                  local $_ = $fh ? <$fh> : '';
                  $_ = ''
                      if !defined;
                  last if !$cb->(@params);
                  $module .= $_;
              }
              return $module;
          }
          elsif ($fh) {
              return $fh;
          }
      }
      croak "Can't find module $module";
  }
  
  1;
  
  __END__
  
  =head1 NAME
  
  Module::Reader - Read the source of a module like perl does
  
  =head1 SYNOPSIS
  
      use Module::Reader qw(:all);
      my $io = module_handle('My::Module');
      my $content = module_content('My::Module');
      
      my $io = module_handle('My::Module', @search_dirs);
      
      my $io = module_handle('My::Module', @search_dirs, { found => \%INC });
  
  =head1 DESCRIPTION
  
  Reads the content of perl modules the same way perl does.  This
  includes reading modules available only by L<@INC hooks|perlfunc/require>, or filtered
  through them.
  
  =head1 EXPORTS
  
  =head2 module_handle( $module_name, @search_dirs, \%options )
  
  Returns an IO handle to the given module.  Searches the directories
  specified, or L<@INC|perlvar/@INC> if none are.
  
  =head3 Options
  
  =over 4
  
  =item found
  
  A reference to a hash like L<%INC|perlvar/%INC> with module file names (in the
  style 'F<My/Module.pm>') as keys and full file paths as values.
  Modules listed in this will be used in preference to searching
  through directories.
  
  =back
  
  =head2 module_content( $module_name, @search_dirs, \%options )
  
  Returns the content of the given module.  Accepts the same options as C<module_handle>.
  
  =head1 AUTHOR
  
  haarg - Graham Knop (cpan:HAARG) <haarg@haarg.org>
  
  =head2 CONTRIBUTORS
  
  None yet.
  
  =head1 COPYRIGHT
  
  Copyright (c) 2013 the Module::Reader L</AUTHOR> and L</CONTRIBUTORS>
  as listed above.
  
  =head1 LICENSE
  
  This library is free software and may be distributed under the same terms
  as perl itself.
  
  =cut
MODULE_READER

$fatpacked{"Module/Runtime.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MODULE_RUNTIME';
  =head1 NAME
  
  Module::Runtime - runtime module handling
  
  =head1 SYNOPSIS
  
  	use Module::Runtime qw(
  		$module_name_rx is_module_name check_module_name
  		module_notional_filename require_module
  	);
  
  	if($module_name =~ /\A$module_name_rx\z/o) { ...
  	if(is_module_name($module_name)) { ...
  	check_module_name($module_name);
  
  	$notional_filename = module_notional_filename($module_name);
  	require_module($module_name);
  
  	use Module::Runtime qw(use_module use_package_optimistically);
  
  	$bi = use_module("Math::BigInt", 1.31)->new("1_234");
  	$widget = use_package_optimistically("Local::Widget")->new;
  
  	use Module::Runtime qw(
  		$top_module_spec_rx $sub_module_spec_rx
  		is_module_spec check_module_spec
  		compose_module_name
  	);
  
  	if($spec =~ /\A$top_module_spec_rx\z/o) { ...
  	if($spec =~ /\A$sub_module_spec_rx\z/o) { ...
  	if(is_module_spec("Standard::Prefix", $spec)) { ...
  	check_module_spec("Standard::Prefix", $spec);
  
  	$module_name =
  		compose_module_name("Standard::Prefix", $spec);
  
  =head1 DESCRIPTION
  
  The functions exported by this module deal with runtime handling of
  Perl modules, which are normally handled at compile time.  This module
  avoids using any other modules, so that it can be used in low-level
  infrastructure.
  
  The parts of this module that work with module names apply the same syntax
  that is used for barewords in Perl source.  In principle this syntax
  can vary between versions of Perl, and this module applies the syntax of
  the Perl on which it is running.  In practice the usable syntax hasn't
  changed yet.  There's some intent for Unicode module names to be supported
  in the future, but this hasn't yet amounted to any consistent facility.
  
  The functions of this module whose purpose is to load modules include
  workarounds for three old Perl core bugs regarding C<require>.  These
  workarounds are applied on any Perl version where the bugs exist, except
  for a case where one of the bugs cannot be adequately worked around in
  pure Perl.
  
  =head2 Module name syntax
  
  The usable module name syntax has not changed from Perl 5.000 up to
  Perl 5.19.8.  The syntax is composed entirely of ASCII characters.
  From Perl 5.6 onwards there has been some attempt to allow the use of
  non-ASCII Unicode characters in Perl source, but it was fundamentally
  broken (like the entirety of Perl 5.6's Unicode handling) and remained
  pretty much entirely unusable until it got some attention in the Perl
  5.15 series.  Although Unicode is now consistently accepted by the
  parser in some places, it remains broken for module names.  Furthermore,
  there has not yet been any work on how to map Unicode module names into
  filenames, so in that respect also Unicode module names are unusable.
  
  The module name syntax is, precisely: the string must consist of one or
  more segments separated by C<::>; each segment must consist of one or more
  identifier characters (ASCII alphanumerics plus "_"); the first character
  of the string must not be a digit.  Thus "C<IO::File>", "C<warnings>",
  and "C<foo::123::x_0>" are all valid module names, whereas "C<IO::>"
  and "C<1foo::bar>" are not.  C<'> separators are not permitted by this
  module, though they remain usable in Perl source, being translated to
  C<::> in the parser.
  
  =head2 Core bugs worked around
  
  The first bug worked around is core bug [perl #68590], which causes
  lexical state in one file to leak into another that is C<require>d/C<use>d
  from it.  This bug is present from Perl 5.6 up to Perl 5.10, and is
  fixed in Perl 5.11.0.  From Perl 5.9.4 up to Perl 5.10.0 no satisfactory
  workaround is possible in pure Perl.  The workaround means that modules
  loaded via this module don't suffer this pollution of their lexical
  state.  Modules loaded in other ways, or via this module on the Perl
  versions where the pure Perl workaround is impossible, remain vulnerable.
  The module L<Lexical::SealRequireHints> provides a complete workaround
  for this bug.
  
  The second bug worked around causes some kinds of failure in module
  loading, principally compilation errors in the loaded module, to be
  recorded in C<%INC> as if they were successful, so later attempts to load
  the same module immediately indicate success.  This bug is present up
  to Perl 5.8.9, and is fixed in Perl 5.9.0.  The workaround means that a
  compilation error in a module loaded via this module won't be cached as
  a success.  Modules loaded in other ways remain liable to produce bogus
  C<%INC> entries, and if a bogus entry exists then it will mislead this
  module if it is used to re-attempt loading.
  
  The third bug worked around causes the wrong context to be seen at
  file scope of a loaded module, if C<require> is invoked in a location
  that inherits context from a higher scope.  This bug is present up to
  Perl 5.11.2, and is fixed in Perl 5.11.3.  The workaround means that
  a module loaded via this module will always see the correct context.
  Modules loaded in other ways remain vulnerable.
  
  =cut
  
  package Module::Runtime;
  
  # Don't "use 5.006" here, because Perl 5.15.6 will load feature.pm if
  # the version check is done that way.
  BEGIN { require 5.006; }
  # Don't "use warnings" here, to avoid dependencies.  Do standardise the
  # warning status by lexical override; unfortunately the only safe bitset
  # to build in is the empty set, equivalent to "no warnings".
  BEGIN { ${^WARNING_BITS} = ""; }
  # Don't "use strict" here, to avoid dependencies.
  
  our $VERSION = "0.014";
  
  # Don't use Exporter here, to avoid dependencies.
  our @EXPORT_OK = qw(
  	$module_name_rx is_module_name is_valid_module_name check_module_name
  	module_notional_filename require_module
  	use_module use_package_optimistically
  	$top_module_spec_rx $sub_module_spec_rx
  	is_module_spec is_valid_module_spec check_module_spec
  	compose_module_name
  );
  my %export_ok = map { ($_ => undef) } @EXPORT_OK;
  sub import {
  	my $me = shift;
  	my $callpkg = caller(0);
  	my $errs = "";
  	foreach(@_) {
  		if(exists $export_ok{$_}) {
  			# We would need to do "no strict 'refs'" here
  			# if we had enabled strict at file scope.
  			if(/\A\$(.*)\z/s) {
  				*{$callpkg."::".$1} = \$$1;
  			} else {
  				*{$callpkg."::".$_} = \&$_;
  			}
  		} else {
  			$errs .= "\"$_\" is not exported by the $me module\n";
  		}
  	}
  	if($errs ne "") {
  		die "${errs}Can't continue after import errors ".
  			"at @{[(caller(0))[1]]} line @{[(caller(0))[2]]}.\n";
  	}
  }
  
  # Logic duplicated from Params::Classify.  Duplicating it here avoids
  # an extensive and potentially circular dependency graph.
  sub _is_string($) {
  	my($arg) = @_;
  	return defined($arg) && ref(\$arg) eq "SCALAR";
  }
  
  =head1 REGULAR EXPRESSIONS
  
  These regular expressions do not include any anchors, so to check
  whether an entire string matches a syntax item you must supply the
  anchors yourself.
  
  =over
  
  =item $module_name_rx
  
  Matches a valid Perl module name in bareword syntax.
  
  =cut
  
  our $module_name_rx = qr/[A-Z_a-z][0-9A-Z_a-z]*(?:::[0-9A-Z_a-z]+)*/;
  
  =item $top_module_spec_rx
  
  Matches a module specification for use with L</compose_module_name>,
  where no prefix is being used.
  
  =cut
  
  my $qual_module_spec_rx =
  	qr#(?:/|::)[A-Z_a-z][0-9A-Z_a-z]*(?:(?:/|::)[0-9A-Z_a-z]+)*#;
  
  my $unqual_top_module_spec_rx =
  	qr#[A-Z_a-z][0-9A-Z_a-z]*(?:(?:/|::)[0-9A-Z_a-z]+)*#;
  
  our $top_module_spec_rx = qr/$qual_module_spec_rx|$unqual_top_module_spec_rx/o;
  
  =item $sub_module_spec_rx
  
  Matches a module specification for use with L</compose_module_name>,
  where a prefix is being used.
  
  =cut
  
  my $unqual_sub_module_spec_rx = qr#[0-9A-Z_a-z]+(?:(?:/|::)[0-9A-Z_a-z]+)*#;
  
  our $sub_module_spec_rx = qr/$qual_module_spec_rx|$unqual_sub_module_spec_rx/o;
  
  =back
  
  =head1 FUNCTIONS
  
  =head2 Basic module handling
  
  =over
  
  =item is_module_name(ARG)
  
  Returns a truth value indicating whether I<ARG> is a plain string
  satisfying Perl module name syntax as described for L</$module_name_rx>.
  
  =cut
  
  sub is_module_name($) { _is_string($_[0]) && $_[0] =~ /\A$module_name_rx\z/o }
  
  =item is_valid_module_name(ARG)
  
  Deprecated alias for L</is_module_name>.
  
  =cut
  
  *is_valid_module_name = \&is_module_name;
  
  =item check_module_name(ARG)
  
  Check whether I<ARG> is a plain string
  satisfying Perl module name syntax as described for L</$module_name_rx>.
  Return normally if it is, or C<die> if it is not.
  
  =cut
  
  sub check_module_name($) {
  	unless(&is_module_name) {
  		die +(_is_string($_[0]) ? "`$_[0]'" : "argument").
  			" is not a module name\n";
  	}
  }
  
  =item module_notional_filename(NAME)
  
  Generates a notional relative filename for a module, which is used in
  some Perl core interfaces.
  The I<NAME> is a string, which should be a valid module name (one or
  more C<::>-separated segments).  If it is not a valid name, the function
  C<die>s.
  
  The notional filename for the named module is generated and returned.
  This filename is always in Unix style, with C</> directory separators
  and a C<.pm> suffix.  This kind of filename can be used as an argument to
  C<require>, and is the key that appears in C<%INC> to identify a module,
  regardless of actual local filename syntax.
  
  =cut
  
  sub module_notional_filename($) {
  	&check_module_name;
  	my($name) = @_;
  	$name =~ s!::!/!g;
  	return $name.".pm";
  }
  
  =item require_module(NAME)
  
  This is essentially the bareword form of C<require>, in runtime form.
  The I<NAME> is a string, which should be a valid module name (one or
  more C<::>-separated segments).  If it is not a valid name, the function
  C<die>s.
  
  The module specified by I<NAME> is loaded, if it hasn't been already,
  in the manner of the bareword form of C<require>.  That means that a
  search through C<@INC> is performed, and a byte-compiled form of the
  module will be used if available.
  
  The return value is as for C<require>.  That is, it is the value returned
  by the module itself if the module is loaded anew, or C<1> if the module
  was already loaded.
  
  =cut
  
  # Don't "use constant" here, to avoid dependencies.
  BEGIN {
  	*_WORK_AROUND_HINT_LEAKAGE =
  		"$]" < 5.011 && !("$]" >= 5.009004 && "$]" < 5.010001)
  			? sub(){1} : sub(){0};
  	*_WORK_AROUND_BROKEN_MODULE_STATE = "$]" < 5.009 ? sub(){1} : sub(){0};
  }
  
  BEGIN { if(_WORK_AROUND_BROKEN_MODULE_STATE) { eval q{
  	sub Module::Runtime::__GUARD__::DESTROY {
  		delete $INC{$_[0]->[0]} if @{$_[0]};
  	}
  	1;
  }; die $@ if $@ ne ""; } }
  
  sub require_module($) {
  	# Localise %^H to work around [perl #68590], where the bug exists
  	# and this is a satisfactory workaround.  The bug consists of
  	# %^H state leaking into each required module, polluting the
  	# module's lexical state.
  	local %^H if _WORK_AROUND_HINT_LEAKAGE;
  	if(_WORK_AROUND_BROKEN_MODULE_STATE) {
  		my $notional_filename = &module_notional_filename;
  		my $guard = bless([ $notional_filename ],
  				"Module::Runtime::__GUARD__");
  		my $result = CORE::require($notional_filename);
  		pop @$guard;
  		return $result;
  	} else {
  		return scalar(CORE::require(&module_notional_filename));
  	}
  }
  
  =back
  
  =head2 Structured module use
  
  =over
  
  =item use_module(NAME[, VERSION])
  
  This is essentially C<use> in runtime form, but without the importing
  feature (which is fundamentally a compile-time thing).  The I<NAME> is
  handled just like in C<require_module> above: it must be a module name,
  and the named module is loaded as if by the bareword form of C<require>.
  
  If a I<VERSION> is specified, the C<VERSION> method of the loaded module is
  called with the specified I<VERSION> as an argument.  This normally serves to
  ensure that the version loaded is at least the version required.  This is
  the same functionality provided by the I<VERSION> parameter of C<use>.
  
  On success, the name of the module is returned.  This is unlike
  L</require_module>, and is done so that the entire call to L</use_module>
  can be used as a class name to call a constructor, as in the example in
  the synopsis.
  
  =cut
  
  sub use_module($;$) {
  	my($name, $version) = @_;
  	require_module($name);
  	$name->VERSION($version) if @_ >= 2;
  	return $name;
  }
  
  =item use_package_optimistically(NAME[, VERSION])
  
  This is an analogue of L</use_module> for the situation where there is
  uncertainty as to whether a package/class is defined in its own module
  or by some other means.  It attempts to arrange for the named package to
  be available, either by loading a module or by doing nothing and hoping.
  
  An attempt is made to load the named module (as if by the bareword form
  of C<require>).  If the module cannot be found then it is assumed that
  the package was actually already loaded by other means, and no error
  is signalled.  That's the optimistic bit.
  
  This is mostly the same operation that is performed by the L<base> pragma
  to ensure that the specified base classes are available.  The behaviour
  of L<base> was simplified in version 2.18, and later improved in version
  2.20, and on both occasions this function changed to match.
  
  If a I<VERSION> is specified, the C<VERSION> method of the loaded package is
  called with the specified I<VERSION> as an argument.  This normally serves
  to ensure that the version loaded is at least the version required.
  On success, the name of the package is returned.  These aspects of the
  function work just like L</use_module>.
  
  =cut
  
  sub use_package_optimistically($;$) {
  	my($name, $version) = @_;
  	my $fn = module_notional_filename($name);
  	eval { local $SIG{__DIE__}; require_module($name); };
  	die $@ if $@ ne "" &&
  		($@ !~ /\ACan't locate \Q$fn\E .+ at \Q@{[__FILE__]}\E line/s ||
  		 $@ =~ /^Compilation\ failed\ in\ require
  			 \ at\ \Q@{[__FILE__]}\E\ line/xm);
  	$name->VERSION($version) if @_ >= 2;
  	return $name;
  }
  
  =back
  
  =head2 Module name composition
  
  =over
  
  =item is_module_spec(PREFIX, SPEC)
  
  Returns a truth value indicating
  whether I<SPEC> is valid input for L</compose_module_name>.
  See below for what that entails.  Whether a I<PREFIX> is supplied affects
  the validity of I<SPEC>, but the exact value of the prefix is unimportant,
  so this function treats I<PREFIX> as a truth value.
  
  =cut
  
  sub is_module_spec($$) {
  	my($prefix, $spec) = @_;
  	return _is_string($spec) &&
  		$spec =~ ($prefix ? qr/\A$sub_module_spec_rx\z/o :
  				    qr/\A$top_module_spec_rx\z/o);
  }
  
  =item is_valid_module_spec(PREFIX, SPEC)
  
  Deprecated alias for L</is_module_spec>.
  
  =cut
  
  *is_valid_module_spec = \&is_module_spec;
  
  =item check_module_spec(PREFIX, SPEC)
  
  Check whether I<SPEC> is valid input for L</compose_module_name>.
  Return normally if it is, or C<die> if it is not.
  
  =cut
  
  sub check_module_spec($$) {
  	unless(&is_module_spec) {
  		die +(_is_string($_[1]) ? "`$_[1]'" : "argument").
  			" is not a module specification\n";
  	}
  }
  
  =item compose_module_name(PREFIX, SPEC)
  
  This function is intended to make it more convenient for a user to specify
  a Perl module name at runtime.  Users have greater need for abbreviations
  and context-sensitivity than programmers, and Perl module names get a
  little unwieldy.  I<SPEC> is what the user specifies, and this function
  translates it into a module name in standard form, which it returns.
  
  I<SPEC> has syntax approximately that of a standard module name: it
  should consist of one or more name segments, each of which consists
  of one or more identifier characters.  However, C</> is permitted as a
  separator, in addition to the standard C<::>.  The two separators are
  entirely interchangeable.
  
  Additionally, if I<PREFIX> is not C<undef> then it must be a module
  name in standard form, and it is prefixed to the user-specified name.
  The user can inhibit the prefix addition by starting I<SPEC> with a
  separator (either C</> or C<::>).
  
  =cut
  
  sub compose_module_name($$) {
  	my($prefix, $spec) = @_;
  	check_module_name($prefix) if defined $prefix;
  	&check_module_spec;
  	if($spec =~ s#\A(?:/|::)##) {
  		# OK
  	} else {
  		$spec = $prefix."::".$spec if defined $prefix;
  	}
  	$spec =~ s#/#::#g;
  	return $spec;
  }
  
  =back
  
  =head1 BUGS
  
  On Perl versions 5.7.2 to 5.8.8, if C<require> is overridden by the
  C<CORE::GLOBAL> mechanism, it is likely to break the heuristics used by
  L</use_package_optimistically>, making it signal an error for a missing
  module rather than assume that it was already loaded.  From Perl 5.8.9
  onwards, and on 5.7.1 and earlier, this module can avoid being confused
  by such an override.  On the affected versions, a C<require> override
  might be installed by L<Lexical::SealRequireHints>, if something requires
  its bugfix but for some reason its XS implementation isn't available.
  
  =head1 SEE ALSO
  
  L<Lexical::SealRequireHints>,
  L<base>,
  L<perlfunc/require>,
  L<perlfunc/use>
  
  =head1 AUTHOR
  
  Andrew Main (Zefram) <zefram@fysh.org>
  
  =head1 COPYRIGHT
  
  Copyright (C) 2004, 2006, 2007, 2009, 2010, 2011, 2012, 2014
  Andrew Main (Zefram) <zefram@fysh.org>
  
  =head1 LICENSE
  
  This module is free software; you can redistribute it and/or modify it
  under the same terms as Perl itself.
  
  =cut
  
  1;
MODULE_RUNTIME

$fatpacked{"Moo.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MOO';
  package Moo;
  
  use strictures 1;
  use Moo::_Utils;
  use Import::Into;
  
  our $VERSION = '1.006000';
  $VERSION = eval $VERSION;
  
  require Moo::sification;
  
  our %MAKERS;
  
  sub _install_tracked {
    my ($target, $name, $code) = @_;
    $MAKERS{$target}{exports}{$name} = $code;
    _install_coderef "${target}::${name}" => "Moo::${name}" => $code;
  }
  
  sub import {
    my $target = caller;
    my $class = shift;
    _set_loaded(caller);
    strictures->import::into(1);
    if ($INC{'Role/Tiny.pm'} and Role::Tiny->is_role($target)) {
      die "Cannot import Moo into a role";
    }
    $MAKERS{$target} ||= {};
    _install_tracked $target => extends => sub {
      $class->_set_superclasses($target, @_);
      $class->_maybe_reset_handlemoose($target);
      return;
    };
    _install_tracked $target => with => sub {
      require Moo::Role;
      Moo::Role->apply_roles_to_package($target, @_);
      $class->_maybe_reset_handlemoose($target);
    };
    _install_tracked $target => has => sub {
      my $name_proto = shift;
      my @name_proto = ref $name_proto eq 'ARRAY' ? @$name_proto : $name_proto;
      if (@_ % 2 != 0) {
        require Carp;
        Carp::croak("Invalid options for " . join(', ', map "'$_'", @name_proto)
          . " attribute(s): even number of arguments expected, got " . scalar @_)
      }
      my %spec = @_;
      foreach my $name (@name_proto) {
        # Note that when multiple attributes specified, each attribute
        # needs a separate \%specs hashref
        my $spec_ref = @name_proto > 1 ? +{%spec} : \%spec;
        $class->_constructor_maker_for($target)
              ->register_attribute_specs($name, $spec_ref);
        $class->_accessor_maker_for($target)
              ->generate_method($target, $name, $spec_ref);
        $class->_maybe_reset_handlemoose($target);
      }
      return;
    };
    foreach my $type (qw(before after around)) {
      _install_tracked $target => $type => sub {
        require Class::Method::Modifiers;
        _install_modifier($target, $type, @_);
        return;
      };
    }
    return if $MAKERS{$target}{is_class}; # already exported into this package
    my $stash = _getstash($target);
    my @not_methods = map { *$_{CODE}||() } grep !ref($_), values %$stash;
    @{$MAKERS{$target}{not_methods}={}}{@not_methods} = @not_methods;
    $MAKERS{$target}{is_class} = 1;
    {
      no strict 'refs';
      @{"${target}::ISA"} = do {
        require Moo::Object; ('Moo::Object');
      } unless @{"${target}::ISA"};
    }
    if ($INC{'Moo/HandleMoose.pm'}) {
      Moo::HandleMoose::inject_fake_metaclass_for($target);
    }
  }
  
  sub unimport {
    my $target = caller;
    _unimport_coderefs($target, $MAKERS{$target});
  }
  
  sub _set_superclasses {
    my $class = shift;
    my $target = shift;
    foreach my $superclass (@_) {
      _load_module($superclass);
      if ($INC{'Role/Tiny.pm'} && Role::Tiny->is_role($superclass)) {
        require Carp;
        Carp::croak("Can't extend role '$superclass'");
      }
    }
    # Can't do *{...} = \@_ or 5.10.0's mro.pm stops seeing @ISA
    @{*{_getglob("${target}::ISA")}{ARRAY}} = @_;
    if (my $old = delete $Moo::MAKERS{$target}{constructor}) {
      delete _getstash($target)->{new};
      Moo->_constructor_maker_for($target)
         ->register_attribute_specs(%{$old->all_attribute_specs});
    }
    elsif (!$target->isa('Moo::Object')) {
      Moo->_constructor_maker_for($target);
    }
    no warnings 'once'; # piss off. -- mst
    $Moo::HandleMoose::MOUSE{$target} = [
      grep defined, map Mouse::Util::find_meta($_), @_
    ] if Mouse::Util->can('find_meta');
  }
  
  sub _maybe_reset_handlemoose {
    my ($class, $target) = @_;
    if ($INC{"Moo/HandleMoose.pm"}) {
      Moo::HandleMoose::maybe_reinject_fake_metaclass_for($target);
    }
  }
  
  sub _accessor_maker_for {
    my ($class, $target) = @_;
    return unless $MAKERS{$target};
    $MAKERS{$target}{accessor} ||= do {
      my $maker_class = do {
        if (my $m = do {
              require Sub::Defer;
              if (my $defer_target =
                    (Sub::Defer::defer_info($target->can('new'))||[])->[0]
                ) {
                my ($pkg) = ($defer_target =~ /^(.*)::[^:]+$/);
                $MAKERS{$pkg} && $MAKERS{$pkg}{accessor};
              } else {
                undef;
              }
            }) {
          ref($m);
        } else {
          require Method::Generate::Accessor;
          'Method::Generate::Accessor'
        }
      };
      $maker_class->new;
    }
  }
  
  sub _constructor_maker_for {
    my ($class, $target) = @_;
    return unless $MAKERS{$target};
    $MAKERS{$target}{constructor} ||= do {
      require Method::Generate::Constructor;
      require Sub::Defer;
      my ($moo_constructor, $con);
  
      my $t_new = $target->can('new');
      if ($t_new) {
        if ($t_new == Moo::Object->can('new')) {
          $moo_constructor = 1;
        }
        elsif (my $defer_target = (Sub::Defer::defer_info($t_new)||[])->[0]) {
          my ($pkg) = ($defer_target =~ /^(.*)::[^:]+$/);
          if ($MAKERS{$pkg}) {
            $moo_constructor = 1;
            $con = $MAKERS{$pkg}{constructor};
          }
        }
      }
      else {
        $moo_constructor = 1; # no other constructor, make a Moo one
      }
      ($con ? ref($con) : 'Method::Generate::Constructor')
        ->new(
          package => $target,
          accessor_generator => $class->_accessor_maker_for($target),
          $moo_constructor ? (
            $con ? (construction_string => $con->construction_string) : ()
          ) : (
            construction_builder => sub {
              '$class->next::method('
                .($target->can('FOREIGNBUILDARGS') ?
                  '$class->FOREIGNBUILDARGS(@_)' : '@_')
                .')'
            },
          ),
          subconstructor_handler => (
            '      if ($Moo::MAKERS{$class}) {'."\n"
            .'        if ($Moo::MAKERS{$class}{constructor}) {'."\n"
            .'          return $class->'.$target.'::SUPER::new(@_);'."\n"
            .'        }'."\n"
            .'        '.$class.'->_constructor_maker_for($class);'."\n"
            .'        return $class->new(@_)'.";\n"
            .'      } elsif ($INC{"Moose.pm"} and my $meta = Class::MOP::get_metaclass_by_name($class)) {'."\n"
            .'        return $meta->new_object($class->BUILDARGS(@_));'."\n"
            .'      }'."\n"
          ),
        )
        ->install_delayed
        ->register_attribute_specs(%{$con?$con->all_attribute_specs:{}})
    }
  }
  
  sub _concrete_methods_of {
    my ($me, $role) = @_;
    my $makers = $MAKERS{$role};
    # grab role symbol table
    my $stash = _getstash($role);
    # reverse so our keys become the values (captured coderefs) in case
    # they got copied or re-used since
    my $not_methods = { reverse %{$makers->{not_methods}||{}} };
    +{
      # grab all code entries that aren't in the not_methods list
      map {
        my $code = *{$stash->{$_}}{CODE};
        ( ! $code or exists $not_methods->{$code} ) ? () : ($_ => $code)
      } grep !ref($stash->{$_}), keys %$stash
    };
  }
  
  1;
  __END__
  
  =pod
  
  =encoding utf-8
  
  =head1 NAME
  
  Moo - Minimalist Object Orientation (with Moose compatibility)
  
  =head1 SYNOPSIS
  
   package Cat::Food;
  
   use Moo;
   use namespace::clean;
  
   sub feed_lion {
     my $self = shift;
     my $amount = shift || 1;
  
     $self->pounds( $self->pounds - $amount );
   }
  
   has taste => (
     is => 'ro',
   );
  
   has brand => (
     is  => 'ro',
     isa => sub {
       die "Only SWEET-TREATZ supported!" unless $_[0] eq 'SWEET-TREATZ'
     },
   );
  
   has pounds => (
     is  => 'rw',
     isa => sub { die "$_[0] is too much cat food!" unless $_[0] < 15 },
   );
  
   1;
  
  And elsewhere:
  
   my $full = Cat::Food->new(
      taste  => 'DELICIOUS.',
      brand  => 'SWEET-TREATZ',
      pounds => 10,
   );
  
   $full->feed_lion;
  
   say $full->pounds;
  
  =head1 DESCRIPTION
  
  This module is an extremely light-weight subset of L<Moose> optimised for
  rapid startup and "pay only for what you use".
  
  It also avoids depending on any XS modules to allow simple deployments.  The
  name C<Moo> is based on the idea that it provides almost -- but not quite -- two
  thirds of L<Moose>.
  
  Unlike L<Mouse> this module does not aim at full compatibility with
  L<Moose>'s surface syntax, preferring instead of provide full interoperability
  via the metaclass inflation capabilities described in L</MOO AND MOOSE>.
  
  For a full list of the minor differences between L<Moose> and L<Moo>'s surface
  syntax, see L</INCOMPATIBILITIES WITH MOOSE>.
  
  =head1 WHY MOO EXISTS
  
  If you want a full object system with a rich Metaprotocol, L<Moose> is
  already wonderful.
  
  However, sometimes you're writing a command line script or a CGI script
  where fast startup is essential, or code designed to be deployed as a single
  file via L<App::FatPacker>, or you're writing a CPAN module and you want it
  to be usable by people with those constraints.
  
  I've tried several times to use L<Mouse> but it's 3x the size of Moo and
  takes longer to load than most of my Moo based CGI scripts take to run.
  
  If you don't want L<Moose>, you don't want "less metaprotocol" like L<Mouse>,
  you want "as little as possible" -- which means "no metaprotocol", which is
  what Moo provides.
  
  Better still, if you install and load L<Moose>, we set up metaclasses for your
  L<Moo> classes and L<Moo::Role> roles, so you can use them in L<Moose> code
  without ever noticing that some of your codebase is using L<Moo>.
  
  Hence, Moo exists as its name -- Minimal Object Orientation -- with a pledge
  to make it smooth to upgrade to L<Moose> when you need more than minimal
  features.
  
  =head1 MOO AND MOOSE
  
  If L<Moo> detects L<Moose> being loaded, it will automatically register
  metaclasses for your L<Moo> and L<Moo::Role> packages, so you should be able
  to use them in L<Moose> code without anybody ever noticing you aren't using
  L<Moose> everywhere.
  
  L<Moo> will also create L<Moose type constraints|Moose::Manual::Types> for
  L<Moo> classes and roles, so that in Moose classes C<< isa => 'MyMooClass' >>
  and C<< isa => 'MyMooRole' >> work the same as for L<Moose> classes and roles.
  
  Extending a L<Moose> class or consuming a L<Moose::Role> will also work.
  
  So will extending a L<Mouse> class or consuming a L<Mouse::Role> - but note
  that we don't provide L<Mouse> metaclasses or metaroles so the other way
  around doesn't work. This feature exists for L<Any::Moose> users porting to
  L<Moo>; enabling L<Mouse> users to use L<Moo> classes is not a priority for us.
  
  This means that there is no need for anything like L<Any::Moose> for Moo
  code - Moo and Moose code should simply interoperate without problem. To
  handle L<Mouse> code, you'll likely need an empty Moo role or class consuming
  or extending the L<Mouse> stuff since it doesn't register true L<Moose>
  metaclasses like L<Moo> does.
  
  If you want types to be upgraded to the L<Moose> types, use
  L<MooX::Types::MooseLike> and install the L<MooseX::Types> library to
  match the L<MooX::Types::MooseLike> library you're using - L<Moo> will
  load the L<MooseX::Types> library and use that type for the newly created
  metaclass.
  
  If you need to disable the metaclass creation, add:
  
    no Moo::sification;
  
  to your code before Moose is loaded, but bear in mind that this switch is
  currently global and turns the mechanism off entirely so don't put this
  in library code.
  
  =head1 MOO AND CLASS::XSACCESSOR
  
  If a new enough version of L<Class::XSAccessor> is available, it
  will be used to generate simple accessors, readers, and writers for
  a speed boost.  Simple accessors are those without lazy defaults,
  type checks/coercions, or triggers.  Readers and writers generated
  by L<Class::XSAccessor> will behave slightly differently: they will
  reject attempts to call them with the incorrect number of parameters.
  
  =head1 MOO VERSUS ANY::MOOSE
  
  L<Any::Moose> will load L<Mouse> normally, and L<Moose> in a program using
  L<Moose> - which theoretically allows you to get the startup time of L<Mouse>
  without disadvantaging L<Moose> users.
  
  Sadly, this doesn't entirely work, since the selection is load order dependent
  - L<Moo>'s metaclass inflation system explained above in L</MOO AND MOOSE> is
  significantly more reliable.
  
  So if you want to write a CPAN module that loads fast or has only pure perl
  dependencies but is also fully usable by L<Moose> users, you should be using
  L<Moo>.
  
  For a full explanation, see the article
  L<http://shadow.cat/blog/matt-s-trout/moo-versus-any-moose> which explains
  the differing strategies in more detail and provides a direct example of
  where L<Moo> succeeds and L<Any::Moose> fails.
  
  =head1 IMPORTED METHODS
  
  =head2 new
  
   Foo::Bar->new( attr1 => 3 );
  
  or
  
   Foo::Bar->new({ attr1 => 3 });
  
  =head2 BUILDARGS
  
   sub BUILDARGS {
     my ( $class, @args ) = @_;
  
     unshift @args, "attr1" if @args % 2 == 1;
  
     return { @args };
   };
  
   Foo::Bar->new( 3 );
  
  The default implementation of this method accepts a hash or hash reference of
  named parameters. If it receives a single argument that isn't a hash reference
  it throws an error.
  
  You can override this method in your class to handle other types of options
  passed to the constructor.
  
  This method should always return a hash reference of named options.
  
  =head2 FOREIGNBUILDARGS
  
  If you are inheriting from a non-Moo class, the arguments passed to the parent
  class constructor can be manipulated by defining a C<FOREIGNBUILDARGS> method.
  It will receive the same arguments as C<BUILDARGS>, and should return a list
  of arguments to pass to the parent class constructor.
  
  =head2 BUILD
  
  Define a C<BUILD> method on your class and the constructor will automatically
  call the C<BUILD> method from parent down to child after the object has
  been instantiated.  Typically this is used for object validation or possibly
  logging.
  
  =head2 DEMOLISH
  
  If you have a C<DEMOLISH> method anywhere in your inheritance hierarchy,
  a C<DESTROY> method is created on first object construction which will call
  C<< $instance->DEMOLISH($in_global_destruction) >> for each C<DEMOLISH>
  method from child upwards to parents.
  
  Note that the C<DESTROY> method is created on first construction of an object
  of your class in order to not add overhead to classes without C<DEMOLISH>
  methods; this may prove slightly surprising if you try and define your own.
  
  =head2 does
  
   if ($foo->does('Some::Role1')) {
     ...
   }
  
  Returns true if the object composes in the passed role.
  
  =head1 IMPORTED SUBROUTINES
  
  =head2 extends
  
   extends 'Parent::Class';
  
  Declares base class. Multiple superclasses can be passed for multiple
  inheritance (but please use roles instead).  The class will be loaded, however
  no errors will be triggered if it can't be found and there are already subs in
  the class.
  
  Calling extends more than once will REPLACE your superclasses, not add to
  them like 'use base' would.
  
  =head2 with
  
   with 'Some::Role1';
  
  or
  
   with 'Some::Role1', 'Some::Role2';
  
  Composes one or more L<Moo::Role> (or L<Role::Tiny>) roles into the current
  class.  An error will be raised if these roles have conflicting methods.  The
  roles will be loaded using the same mechansim as C<extends> uses.
  
  =head2 has
  
   has attr => (
     is => 'ro',
   );
  
  Declares an attribute for the class.
  
   package Foo;
   use Moo;
   has 'attr' => (
     is => 'ro'
   );
  
   package Bar;
   use Moo;
   extends 'Foo';
   has '+attr' => (
     default => sub { "blah" },
   );
  
  Using the C<+> notation, it's possible to override an attribute.
  
  The options for C<has> are as follows:
  
  =over 2
  
  =item * C<is>
  
  B<required>, may be C<ro>, C<lazy>, C<rwp> or C<rw>.
  
  C<ro> generates an accessor that dies if you attempt to write to it - i.e.
  a getter only - by defaulting C<reader> to the name of the attribute.
  
  C<lazy> generates a reader like C<ro>, but also sets C<lazy> to 1 and
  C<builder> to C<_build_${attribute_name}> to allow on-demand generated
  attributes.  This feature was my attempt to fix my incompetence when
  originally designing C<lazy_build>, and is also implemented by
  L<MooseX::AttributeShortcuts>. There is, however, nothing to stop you
  using C<lazy> and C<builder> yourself with C<rwp> or C<rw> - it's just that
  this isn't generally a good idea so we don't provide a shortcut for it.
  
  C<rwp> generates a reader like C<ro>, but also sets C<writer> to
  C<_set_${attribute_name}> for attributes that are designed to be written
  from inside of the class, but read-only from outside.
  This feature comes from L<MooseX::AttributeShortcuts>.
  
  C<rw> generates a normal getter/setter by defaulting C<accessor> to the
  name of the attribute.
  
  =item * C<isa>
  
  Takes a coderef which is meant to validate the attribute.  Unlike L<Moose>, Moo
  does not include a basic type system, so instead of doing C<< isa => 'Num' >>,
  one should do
  
   isa => sub {
     die "$_[0] is not a number!" unless looks_like_number $_[0]
   },
  
  Note that the return value is ignored, only whether the sub lives or
  dies matters.
  
  L<Sub::Quote aware|/SUB QUOTE AWARE>
  
  Since L<Moo> does B<not> run the C<isa> check before C<coerce> if a coercion
  subroutine has been supplied, C<isa> checks are not structural to your code
  and can, if desired, be omitted on non-debug builds (although if this results
  in an uncaught bug causing your program to break, the L<Moo> authors guarantee
  nothing except that you get to keep both halves).
  
  If you want L<MooseX::Types> style named types, look at
  L<MooX::Types::MooseLike>.
  
  To cause your C<isa> entries to be automatically mapped to named
  L<Moose::Meta::TypeConstraint> objects (rather than the default behaviour
  of creating an anonymous type), set:
  
    $Moo::HandleMoose::TYPE_MAP{$isa_coderef} = sub {
      require MooseX::Types::Something;
      return MooseX::Types::Something::TypeName();
    };
  
  Note that this example is purely illustrative; anything that returns a
  L<Moose::Meta::TypeConstraint> object or something similar enough to it to
  make L<Moose> happy is fine.
  
  =item * C<coerce>
  
  Takes a coderef which is meant to coerce the attribute.  The basic idea is to
  do something like the following:
  
   coerce => sub {
     $_[0] % 2 ? $_[0] : $_[0] + 1
   },
  
  Note that L<Moo> will always fire your coercion: this is to permit
  C<isa> entries to be used purely for bug trapping, whereas coercions are
  always structural to your code. We do, however, apply any supplied C<isa>
  check after the coercion has run to ensure that it returned a valid value.
  
  L<Sub::Quote aware|/SUB QUOTE AWARE>
  
  If the C<isa> option is a blessed object providing a C<coerce> or
  C<coercion> method, then the C<coerce> option may be set to just C<1>.
  
  =item * C<handles>
  
  Takes a string
  
    handles => 'RobotRole'
  
  Where C<RobotRole> is a role (L<Moo::Role>) that defines an interface which
  becomes the list of methods to handle.
  
  Takes a list of methods
  
   handles => [ qw( one two ) ]
  
  Takes a hashref
  
   handles => {
     un => 'one',
   }
  
  =item * C<trigger>
  
  Takes a coderef which will get called any time the attribute is set. This
  includes the constructor, but not default or built values. Coderef will be
  invoked against the object with the new value as an argument.
  
  If you set this to just C<1>, it generates a trigger which calls the
  C<_trigger_${attr_name}> method on C<$self>. This feature comes from
  L<MooseX::AttributeShortcuts>.
  
  Note that Moose also passes the old value, if any; this feature is not yet
  supported.
  
  L<Sub::Quote aware|/SUB QUOTE AWARE>
  
  =item * C<default>
  
  Takes a coderef which will get called with $self as its only argument
  to populate an attribute if no value is supplied to the constructor - or
  if the attribute is lazy, when the attribute is first retrieved if no
  value has yet been provided.
  
  If a simple scalar is provided, it will be inlined as a string. Any non-code
  reference (hash, array) will result in an error - for that case instead use
  a code reference that returns the desired value.
  
  Note that if your default is fired during new() there is no guarantee that
  other attributes have been populated yet so you should not rely on their
  existence.
  
  L<Sub::Quote aware|/SUB QUOTE AWARE>
  
  =item * C<predicate>
  
  Takes a method name which will return true if an attribute has a value.
  
  If you set this to just C<1>, the predicate is automatically named
  C<has_${attr_name}> if your attribute's name does not start with an
  underscore, or C<_has_${attr_name_without_the_underscore}> if it does.
  This feature comes from L<MooseX::AttributeShortcuts>.
  
  =item * C<builder>
  
  Takes a method name which will be called to create the attribute - functions
  exactly like default except that instead of calling
  
    $default->($self);
  
  Moo will call
  
    $self->$builder;
  
  The following features come from L<MooseX::AttributeShortcuts>:
  
  If you set this to just C<1>, the builder is automatically named
  C<_build_${attr_name}>.
  
  If you set this to a coderef or code-convertible object, that variable will be
  installed under C<$class::_build_${attr_name}> and the builder set to the same
  name.
  
  =item * C<clearer>
  
  Takes a method name which will clear the attribute.
  
  If you set this to just C<1>, the clearer is automatically named
  C<clear_${attr_name}> if your attribute's name does not start with an
  underscore, or C<_clear_${attr_name_without_the_underscore}> if it does.
  This feature comes from L<MooseX::AttributeShortcuts>.
  
  =item * C<lazy>
  
  B<Boolean>.  Set this if you want values for the attribute to be grabbed
  lazily.  This is usually a good idea if you have a L</builder> which requires
  another attribute to be set.
  
  =item * C<required>
  
  B<Boolean>.  Set this if the attribute must be passed on instantiation.
  
  =item * C<reader>
  
  The value of this attribute will be the name of the method to get the value of
  the attribute.  If you like Java style methods, you might set this to
  C<get_foo>
  
  =item * C<writer>
  
  The value of this attribute will be the name of the method to set the value of
  the attribute.  If you like Java style methods, you might set this to
  C<set_foo>.
  
  =item * C<weak_ref>
  
  B<Boolean>.  Set this if you want the reference that the attribute contains to
  be weakened; use this when circular references are possible, which will cause
  leaks.
  
  =item * C<init_arg>
  
  Takes the name of the key to look for at instantiation time of the object.  A
  common use of this is to make an underscored attribute have a non-underscored
  initialization name. C<undef> means that passing the value in on instantiation
  is ignored.
  
  =item * C<moosify>
  
  Takes either a coderef or array of coderefs which is meant to transform the
  given attributes specifications if necessary when upgrading to a Moose role or
  class. You shouldn't need this by default, but is provided as a means of
  possible extensibility.
  
  =back
  
  =head2 before
  
   before foo => sub { ... };
  
  See L<< Class::Method::Modifiers/before method(s) => sub { ... } >> for full
  documentation.
  
  =head2 around
  
   around foo => sub { ... };
  
  See L<< Class::Method::Modifiers/around method(s) => sub { ... } >> for full
  documentation.
  
  =head2 after
  
   after foo => sub { ... };
  
  See L<< Class::Method::Modifiers/after method(s) => sub { ... } >> for full
  documentation.
  
  =head1 SUB QUOTE AWARE
  
  L<Sub::Quote/quote_sub> allows us to create coderefs that are "inlineable,"
  giving us a handy, XS-free speed boost.  Any option that is L<Sub::Quote>
  aware can take advantage of this.
  
  To do this, you can write
  
    use Sub::Quote;
  
    use Moo;
    use namespace::clean;
  
    has foo => (
      is => 'ro',
      isa => quote_sub(q{ die "Not <3" unless $_[0] < 3 })
    );
  
  which will be inlined as
  
    do {
      local @_ = ($_[0]->{foo});
      die "Not <3" unless $_[0] < 3;
    }
  
  or to avoid localizing @_,
  
    has foo => (
      is => 'ro',
      isa => quote_sub(q{ my ($val) = @_; die "Not <3" unless $val < 3 })
    );
  
  which will be inlined as
  
    do {
      my ($val) = ($_[0]->{foo});
      die "Not <3" unless $val < 3;
    }
  
  See L<Sub::Quote> for more information, including how to pass lexical
  captures that will also be compiled into the subroutine.
  
  =head1 CLEANING UP IMPORTS
  
  L<Moo> will not clean up imported subroutines for you; you will have
  to do that manually. The recommended way to do this is to declare your
  imports first, then C<use Moo>, then C<use namespace::clean>.
  Anything imported before L<namespace::clean> will be scrubbed.
  Anything imported or declared after will be still be available.
  
   package Record;
  
   use Digest::MD5 qw(md5_hex);
  
   use Moo;
   use namespace::clean;
  
   has name => (is => 'ro', required => 1);
   has id => (is => 'lazy');
   sub _build_id {
     my ($self) = @_;
     return md5_hex($self->name);
   }
  
   1;
  
  If you were to import C<md5_hex> after L<namespace::clean> you would
  be able to call C<< ->md5_hex() >> on your C<Record> instances (and it
  probably wouldn't do what you expect!).
  
  L<Moo::Role>s behave slightly differently.  Since their methods are
  composed into the consuming class, they can do a little more for you
  automatically.  As long as you declare your imports before calling
  C<use Moo::Role>, those imports and the ones L<Moo::Role> itself
  provides will not be composed into consuming classes, so there's usually
  no need to use L<namespace::clean>.
  
  B<On L<namespace::autoclean>:> If you're coming to Moo from the Moose
  world, you may be accustomed to using L<namespace::autoclean> in all
  your packages. This is not recommended for L<Moo> packages, because
  L<namespace::autoclean> will inflate your class to a full L<Moose>
  class.  It'll work, but you will lose the benefits of L<Moo>.  Instead
  you are recommended to just use L<namespace::clean>.
  
  =head1 INCOMPATIBILITIES WITH MOOSE
  
  There is no built-in type system.  C<isa> is verified with a coderef; if you
  need complex types, just make a library of coderefs, or better yet, functions
  that return quoted subs. L<MooX::Types::MooseLike> provides a similar API
  to L<MooseX::Types::Moose> so that you can write
  
    has days_to_live => (is => 'ro', isa => Int);
  
  and have it work with both; it is hoped that providing only subrefs as an
  API will encourage the use of other type systems as well, since it's
  probably the weakest part of Moose design-wise.
  
  C<initializer> is not supported in core since the author considers it to be a
  bad idea and Moose best practices recommend avoiding it. Meanwhile C<trigger> or
  C<coerce> are more likely to be able to fulfill your needs.
  
  There is no meta object.  If you need this level of complexity you wanted
  L<Moose> - Moo succeeds at being small because it explicitly does not
  provide a metaprotocol. However, if you load L<Moose>, then
  
    Class::MOP::class_of($moo_class_or_role)
  
  will return an appropriate metaclass pre-populated by L<Moo>.
  
  No support for C<super>, C<override>, C<inner>, or C<augment> - the author
  considers augment to be a bad idea, and override can be translated:
  
    override foo => sub {
      ...
      super();
      ...
    };
  
    around foo => sub {
      my ($orig, $self) = (shift, shift);
      ...
      $self->$orig(@_);
      ...
    };
  
  The C<dump> method is not provided by default. The author suggests loading
  L<Devel::Dwarn> into C<main::> (via C<perl -MDevel::Dwarn ...> for example) and
  using C<$obj-E<gt>$::Dwarn()> instead.
  
  L</default> only supports coderefs and plain scalars, because passing a hash
  or array reference as a default is almost always incorrect since the value is
  then shared between all objects using that default.
  
  C<lazy_build> is not supported; you are instead encouraged to use the
  C<< is => 'lazy' >> option supported by L<Moo> and
  L<MooseX::AttributeShortcuts>.
  
  C<auto_deref> is not supported since the author considers it a bad idea and
  it has been considered best practice to avoid it for some time.
  
  C<documentation> will show up in a L<Moose> metaclass created from your class
  but is otherwise ignored. Then again, L<Moose> ignores it as well, so this
  is arguably not an incompatibility.
  
  Since C<coerce> does not require C<isa> to be defined but L<Moose> does
  require it, the metaclass inflation for coerce alone is a trifle insane
  and if you attempt to subtype the result will almost certainly break.
  
  C<BUILDARGS> is not triggered if your class does not have any attributes.
  Without attributes, C<BUILDARGS> return value would be ignored, so we just
  skip calling the method instead.
  
  Handling of warnings: when you C<use Moo> we enable FATAL warnings, and some
  several extra pragmas when used in development: L<indirect>,
  L<multidimensional>, and L<bareword::filehandles>.  See the L<strictures>
  documentation for the details on this.
  
  A similar invocation for L<Moose> would be:
  
    use Moose;
    use warnings FATAL => "all";
  
  Additionally, L<Moo> supports a set of attribute option shortcuts intended to
  reduce common boilerplate.  The set of shortcuts is the same as in the L<Moose>
  module L<MooseX::AttributeShortcuts> as of its version 0.009+.  So if you:
  
      package MyClass;
      use Moo;
  
  The nearest L<Moose> invocation would be:
  
      package MyClass;
  
      use Moose;
      use warnings FATAL => "all";
      use MooseX::AttributeShortcuts;
  
  or, if you're inheriting from a non-Moose class,
  
      package MyClass;
  
      use Moose;
      use MooseX::NonMoose;
      use warnings FATAL => "all";
      use MooseX::AttributeShortcuts;
  
  Finally, Moose requires you to call
  
      __PACKAGE__->meta->make_immutable;
  
  at the end of your class to get an inlined (i.e. not horribly slow)
  constructor. Moo does it automatically the first time ->new is called
  on your class. (C<make_immutable> is a no-op in Moo to ease migration.)
  
  An extension L<MooX::late> exists to ease translating Moose packages
  to Moo by providing a more Moose-like interface.
  
  =head1 SUPPORT
  
  Users' IRC: #moose on irc.perl.org
  
  =for html <a href="http://chat.mibbit.com/#moose@irc.perl.org">(click for
  instant chatroom login)</a>
  
  Development and contribution IRC: #web-simple on irc.perl.org
  
  =for html <a href="http://chat.mibbit.com/#web-simple@irc.perl.org">(click for
  instant chatroom login)</a>
  
  Bugtracker: L<https://rt.cpan.org/Public/Dist/Display.html?Name=Moo>
  
  Git repository: L<git://github.com/moose/Moo.git>
  
  Git browser: L<https://github.com/moose/Moo>
  
  =head1 AUTHOR
  
  mst - Matt S. Trout (cpan:MSTROUT) <mst@shadowcat.co.uk>
  
  =head1 CONTRIBUTORS
  
  dg - David Leadbeater (cpan:DGL) <dgl@dgl.cx>
  
  frew - Arthur Axel "fREW" Schmidt (cpan:FREW) <frioux@gmail.com>
  
  hobbs - Andrew Rodland (cpan:ARODLAND) <arodland@cpan.org>
  
  jnap - John Napiorkowski (cpan:JJNAPIORK) <jjn1056@yahoo.com>
  
  ribasushi - Peter Rabbitson (cpan:RIBASUSHI) <ribasushi@cpan.org>
  
  chip - Chip Salzenberg (cpan:CHIPS) <chip@pobox.com>
  
  ajgb - Alex J. G. Burzyński (cpan:AJGB) <ajgb@cpan.org>
  
  doy - Jesse Luehrs (cpan:DOY) <doy at tozt dot net>
  
  perigrin - Chris Prather (cpan:PERIGRIN) <chris@prather.org>
  
  Mithaldu - Christian Walde (cpan:MITHALDU) <walde.christian@googlemail.com>
  
  ilmari - Dagfinn Ilmari Mannsåker (cpan:ILMARI) <ilmari@ilmari.org>
  
  tobyink - Toby Inkster (cpan:TOBYINK) <tobyink@cpan.org>
  
  haarg - Graham Knop (cpan:HAARG) <haarg@cpan.org>
  
  mattp - Matt Phillips (cpan:MATTP) <mattp@cpan.org>
  
  bluefeet - Aran Deltac (cpan:BLUEFEET) <bluefeet@gmail.com>
  
  =head1 COPYRIGHT
  
  Copyright (c) 2010-2011 the Moo L</AUTHOR> and L</CONTRIBUTORS>
  as listed above.
  
  =head1 LICENSE
  
  This library is free software and may be distributed under the same terms
  as perl itself. See L<http://dev.perl.org/licenses/>.
  
  =cut
MOO

$fatpacked{"Moo/HandleMoose.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MOO_HANDLEMOOSE';
  package Moo::HandleMoose;
  
  use strictures 1;
  use Moo::_Utils;
  use Sub::Quote qw(quotify);
  
  our %TYPE_MAP;
  
  our $SETUP_DONE;
  
  sub import { return if $SETUP_DONE; inject_all(); $SETUP_DONE = 1; }
  
  sub inject_all {
    require Class::MOP;
    inject_fake_metaclass_for($_)
      for grep $_ ne 'Moo::Object', do { no warnings 'once'; keys %Moo::MAKERS };
    inject_fake_metaclass_for($_) for keys %Moo::Role::INFO;
    require Moose::Meta::Method::Constructor;
    @Moo::HandleMoose::FakeConstructor::ISA = 'Moose::Meta::Method::Constructor';
  }
  
  sub maybe_reinject_fake_metaclass_for {
    my ($name) = @_;
    our %DID_INJECT;
    if (delete $DID_INJECT{$name}) {
      unless ($Moo::Role::INFO{$name}) {
        Moo->_constructor_maker_for($name)->install_delayed;
      }
      inject_fake_metaclass_for($name);
    }
  }
  
  sub inject_fake_metaclass_for {
    my ($name) = @_;
    require Class::MOP;
    require Moo::HandleMoose::FakeMetaClass;
    Class::MOP::store_metaclass_by_name(
      $name, bless({ name => $name }, 'Moo::HandleMoose::FakeMetaClass')
    );
    require Moose::Util::TypeConstraints;
    if ($Moo::Role::INFO{$name}) {
      Moose::Util::TypeConstraints::find_or_create_does_type_constraint($name);
    } else {
      Moose::Util::TypeConstraints::find_or_create_isa_type_constraint($name);
    }
  }
  
  {
    package Moo::HandleMoose::FakeConstructor;
  
    sub _uninlined_body { \&Moose::Object::new }
  }
  
  sub inject_real_metaclass_for {
    my ($name) = @_;
    our %DID_INJECT;
    return Class::MOP::get_metaclass_by_name($name) if $DID_INJECT{$name};
    require Moose; require Moo; require Moo::Role; require Scalar::Util;
    Class::MOP::remove_metaclass_by_name($name);
    my ($am_role, $meta, $attr_specs, $attr_order) = do {
      if (my $info = $Moo::Role::INFO{$name}) {
        my @attr_info = @{$info->{attributes}||[]};
        (1, Moose::Meta::Role->initialize($name),
         { @attr_info },
         [ @attr_info[grep !($_ % 2), 0..$#attr_info] ]
        )
      } elsif ( my $cmaker = Moo->_constructor_maker_for($name) ) {
        my $specs = $cmaker->all_attribute_specs;
        (0, Moose::Meta::Class->initialize($name), $specs,
         [ sort { $specs->{$a}{index} <=> $specs->{$b}{index} } keys %$specs ]
        );
      } else {
         # This codepath is used if $name does not exist in $Moo::MAKERS
         (0, Moose::Meta::Class->initialize($name), {}, [] )
      }
    };
  
    for my $spec (values %$attr_specs) {
      if (my $inflators = delete $spec->{moosify}) {
        $_->($spec) for @$inflators;
      }
    }
  
    my %methods
      = %{($am_role ? 'Moo::Role' : 'Moo')->_concrete_methods_of($name)};
  
    # if stuff gets added afterwards, _maybe_reset_handlemoose should
    # trigger the recreation of the metaclass but we need to ensure the
    # Moo::Role cache is cleared so we don't confuse Moo itself.
    if (my $info = $Moo::Role::INFO{$name}) {
      delete $info->{methods};
    }
  
    # needed to ensure the method body is stable and get things named
    Sub::Defer::undefer_sub($_) for grep defined, values %methods;
    my @attrs;
    {
      # This local is completely not required for roles but harmless
      local @{_getstash($name)}{keys %methods};
      my %seen_name;
      foreach my $name (@$attr_order) {
        $seen_name{$name} = 1;
        my %spec = %{$attr_specs->{$name}};
        my %spec_map = (
          map { $_->name => $_->init_arg||$_->name }
          (
            (grep { $_->has_init_arg }
               $meta->attribute_metaclass->meta->get_all_attributes),
            grep { exists($_->{init_arg}) ? defined($_->init_arg) : 1 }
            map {
              my $meta = Moose::Util::resolve_metatrait_alias('Attribute', $_)
                           ->meta;
              map $meta->get_attribute($_), $meta->get_attribute_list
            }  @{$spec{traits}||[]}
          )
        );
        # have to hard code this because Moose's role meta-model is lacking
        $spec_map{traits} ||= 'traits';
  
        $spec{is} = 'ro' if $spec{is} eq 'lazy' or $spec{is} eq 'rwp';
        my $coerce = $spec{coerce};
        if (my $isa = $spec{isa}) {
          my $tc = $spec{isa} = do {
            if (my $mapped = $TYPE_MAP{$isa}) {
              my $type = $mapped->();
              unless ( Scalar::Util::blessed($type)
                  && $type->isa("Moose::Meta::TypeConstraint") ) {
                die "error inflating attribute '$name' for package '$_[0]': "
                  ."\$TYPE_MAP{$isa} did not return a valid type constraint'";
              }
              $coerce ? $type->create_child_type(name => $type->name) : $type;
            } else {
              Moose::Meta::TypeConstraint->new(
                constraint => sub { eval { &$isa; 1 } }
              );
            }
          };
          if ($coerce) {
            $tc->coercion(Moose::Meta::TypeCoercion->new)
               ->_compiled_type_coercion($coerce);
            $spec{coerce} = 1;
          }
        } elsif ($coerce) {
          my $attr = quotify($name);
          my $tc = Moose::Meta::TypeConstraint->new(
                     constraint => sub { die "This is not going to work" },
                     inlined => sub {
                        'my $r = $_[42]{'.$attr.'}; $_[42]{'.$attr.'} = 1; $r'
                     },
                   );
          $tc->coercion(Moose::Meta::TypeCoercion->new)
             ->_compiled_type_coercion($coerce);
          $spec{isa} = $tc;
          $spec{coerce} = 1;
        }
        %spec =
          map { $spec_map{$_} => $spec{$_} }
          grep { exists $spec_map{$_} }
          keys %spec;
        push @attrs, $meta->add_attribute($name => %spec);
      }
      foreach my $mouse (do { our %MOUSE; @{$MOUSE{$name}||[]} }) {
        foreach my $attr ($mouse->get_all_attributes) {
          my %spec = %{$attr};
          delete @spec{qw(
            associated_class associated_methods __METACLASS__
            provides curries
          )};
          my $name = delete $spec{name};
          next if $seen_name{$name}++;
          push @attrs, $meta->add_attribute($name => %spec);
        }
      }
    }
    for my $meth_name (keys %methods) {
      my $meth_code = $methods{$meth_name};
      $meta->add_method($meth_name, $meth_code) if $meth_code;
    }
  
    if ($am_role) {
      my $info = $Moo::Role::INFO{$name};
      $meta->add_required_methods(@{$info->{requires}});
      foreach my $modifier (@{$info->{modifiers}}) {
        my ($type, @args) = @$modifier;
        my $code = pop @args;
        $meta->${\"add_${type}_method_modifier"}($_, $code) for @args;
      }
    } else {
      foreach my $attr (@attrs) {
        foreach my $method (@{$attr->associated_methods}) {
          $method->{body} = $name->can($method->name);
        }
      }
      bless(
        $meta->find_method_by_name('new'),
        'Moo::HandleMoose::FakeConstructor',
      );
      # a combination of Moo and Moose may bypass a Moo constructor but still
      # use a Moo DEMOLISHALL.  We need to make sure this is loaded before
      # global destruction.
      require Method::Generate::DemolishAll;
    }
    $meta->add_role(Class::MOP::class_of($_))
      for grep !/\|/ && $_ ne $name, # reject Foo|Bar and same-role-as-self
        do { no warnings 'once'; keys %{$Moo::Role::APPLIED_TO{$name}} };
    $DID_INJECT{$name} = 1;
    $meta;
  }
  
  1;
MOO_HANDLEMOOSE

$fatpacked{"Moo/HandleMoose/FakeMetaClass.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MOO_HANDLEMOOSE_FAKEMETACLASS';
  package Moo::HandleMoose::FakeMetaClass;
  use strictures 1;
  
  sub DESTROY { }
  
  sub AUTOLOAD {
    my ($meth) = (our $AUTOLOAD =~ /([^:]+)$/);
    require Moo::HandleMoose;
    Moo::HandleMoose::inject_real_metaclass_for((shift)->{name})->$meth(@_)
  }
  sub can {
    require Moo::HandleMoose;
    Moo::HandleMoose::inject_real_metaclass_for((shift)->{name})->can(@_)
  }
  sub isa {
    require Moo::HandleMoose;
    Moo::HandleMoose::inject_real_metaclass_for((shift)->{name})->isa(@_)
  }
  sub make_immutable { $_[0] }
  
  1;
MOO_HANDLEMOOSE_FAKEMETACLASS

$fatpacked{"Moo/HandleMoose/_TypeMap.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MOO_HANDLEMOOSE__TYPEMAP';
  package Moo::HandleMoose::_TypeMap;
  use strictures 1;
  
  package
    Moo::HandleMoose;
  our %TYPE_MAP;
  
  package Moo::HandleMoose::_TypeMap;
  
  use Scalar::Util ();
  
  our %WEAK_TYPES;
  
  sub _str_to_ref {
    my $in = shift;
    return $in
      if ref $in;
  
    if ($in =~ /(?:^|=)[A-Z]+\(0x([0-9a-zA-Z]+)\)$/) {
      my $id = do { no warnings 'portable'; hex "$1" };
      require B;
      my $sv = bless \$id, 'B::SV';
      my $ref = eval { $sv->object_2svref };
      if (!defined $ref) {
        die <<'END_ERROR';
  Moo initialization encountered types defined in a parent thread - ensure that
  Moo is require()d before any further thread spawns following a type definition.
  END_ERROR
      }
      return $ref;
    }
    return $in;
  }
  
  sub TIEHASH  { bless {}, $_[0] }
  
  sub STORE {
    my ($self, $key, $value) = @_;
    my $type = _str_to_ref($key);
    $WEAK_TYPES{$type} = $type;
    Scalar::Util::weaken($WEAK_TYPES{$type})
      if ref $type;
    $self->{$key} = $value;
  }
  
  sub FETCH    { $_[0]->{$_[1]} }
  sub FIRSTKEY { my $a = scalar keys %{$_[0]}; each %{$_[0]} }
  sub NEXTKEY  { each %{$_[0]} }
  sub EXISTS   { exists $_[0]->{$_[1]} }
  sub DELETE   { delete $_[0]->{$_[1]} }
  sub CLEAR    { %{$_[0]} = () }
  sub SCALAR   { scalar %{$_[0]} }
  
  sub CLONE {
    my @types = map {
      defined $WEAK_TYPES{$_} ? ($WEAK_TYPES{$_} => $TYPE_MAP{$_}) : ()
    } keys %TYPE_MAP;
    %WEAK_TYPES = ();
    %TYPE_MAP = @types;
  }
  
  sub DESTROY {
    my %types = %{$_[0]};
    untie %TYPE_MAP;
    %TYPE_MAP = %types;
  }
  
  my @types = %TYPE_MAP;
  tie %TYPE_MAP, __PACKAGE__;
  %TYPE_MAP = @types;
  
  1;
MOO_HANDLEMOOSE__TYPEMAP

$fatpacked{"Moo/Object.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MOO_OBJECT';
  package Moo::Object;
  
  use strictures 1;
  
  our %NO_BUILD;
  our %NO_DEMOLISH;
  our $BUILD_MAKER;
  our $DEMOLISH_MAKER;
  
  sub new {
    my $class = shift;
    unless (exists $NO_DEMOLISH{$class}) {
      unless ($NO_DEMOLISH{$class} = !$class->can('DEMOLISH')) {
        ($DEMOLISH_MAKER ||= do {
          require Method::Generate::DemolishAll;
          Method::Generate::DemolishAll->new
        })->generate_method($class);
      }
    }
    $NO_BUILD{$class} and
      return bless({ ref($_[0]) eq 'HASH' ? %{$_[0]} : @_ }, $class);
    $NO_BUILD{$class} = !$class->can('BUILD') unless exists $NO_BUILD{$class};
    $NO_BUILD{$class}
      ? bless({ ref($_[0]) eq 'HASH' ? %{$_[0]} : @_ }, $class)
      : do {
          my $proto = ref($_[0]) eq 'HASH' ? $_[0] : { @_ };
          bless({ %$proto }, $class)->BUILDALL($proto);
        };
  }
  
  # Inlined into Method::Generate::Constructor::_generate_args() - keep in sync
  sub BUILDARGS {
      my $class = shift;
      if ( scalar @_ == 1 ) {
          unless ( defined $_[0] && ref $_[0] eq 'HASH' ) {
              die "Single parameters to new() must be a HASH ref"
                  ." data => ". $_[0] ."\n";
          }
          return { %{ $_[0] } };
      }
      elsif ( @_ % 2 ) {
          die "The new() method for $class expects a hash reference or a"
            . " key/value list. You passed an odd number of arguments\n";
      }
      else {
          return {@_};
      }
  }
  
  sub BUILDALL {
    my $self = shift;
    $self->${\(($BUILD_MAKER ||= do {
      require Method::Generate::BuildAll;
      Method::Generate::BuildAll->new
    })->generate_method(ref($self)))}(@_);
  }
  
  sub DEMOLISHALL {
    my $self = shift;
    $self->${\(($DEMOLISH_MAKER ||= do {
      require Method::Generate::DemolishAll;
      Method::Generate::DemolishAll->new
    })->generate_method(ref($self)))}(@_);
  }
  
  sub does {
    require Moo::Role;
    my $does = Moo::Role->can("does_role");
    { no warnings 'redefine'; *does = $does }
    goto &$does;
  }
  
  # duplicated in Moo::Role
  sub meta {
    require Moo::HandleMoose::FakeMetaClass;
    my $class = ref($_[0])||$_[0];
    bless({ name => $class }, 'Moo::HandleMoose::FakeMetaClass');
  }
  
  1;
MOO_OBJECT

$fatpacked{"Moo/Role.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MOO_ROLE';
  package Moo::Role;
  
  use strictures 1;
  use Moo::_Utils;
  use Role::Tiny ();
  use base qw(Role::Tiny);
  use Import::Into;
  
  our $VERSION = '1.006000';
  $VERSION = eval $VERSION;
  
  require Moo::sification;
  
  BEGIN {
      *INFO = \%Role::Tiny::INFO;
      *APPLIED_TO = \%Role::Tiny::APPLIED_TO;
      *ON_ROLE_CREATE = \@Role::Tiny::ON_ROLE_CREATE;
  }
  
  our %INFO;
  our %APPLIED_TO;
  our %APPLY_DEFAULTS;
  our @ON_ROLE_CREATE;
  
  sub _install_tracked {
    my ($target, $name, $code) = @_;
    $INFO{$target}{exports}{$name} = $code;
    _install_coderef "${target}::${name}" => "Moo::Role::${name}" => $code;
  }
  
  sub import {
    my $target = caller;
    my ($me) = @_;
    _set_loaded(caller);
    strictures->import::into(1);
    if ($Moo::MAKERS{$target} and $Moo::MAKERS{$target}{is_class}) {
      die "Cannot import Moo::Role into a Moo class";
    }
    $INFO{$target} ||= {};
    # get symbol table reference
    my $stash = _getstash($target);
    _install_tracked $target => has => sub {
      my $name_proto = shift;
      my @name_proto = ref $name_proto eq 'ARRAY' ? @$name_proto : $name_proto;
      if (@_ % 2 != 0) {
        require Carp;
        Carp::croak("Invalid options for " . join(', ', map "'$_'", @name_proto)
          . " attribute(s): even number of arguments expected, got " . scalar @_)
      }
      my %spec = @_;
      foreach my $name (@name_proto) {
        my $spec_ref = @name_proto > 1 ? +{%spec} : \%spec;
        ($INFO{$target}{accessor_maker} ||= do {
          require Method::Generate::Accessor;
          Method::Generate::Accessor->new
        })->generate_method($target, $name, $spec_ref);
        push @{$INFO{$target}{attributes}||=[]}, $name, $spec_ref;
        $me->_maybe_reset_handlemoose($target);
      }
    };
    # install before/after/around subs
    foreach my $type (qw(before after around)) {
      _install_tracked $target => $type => sub {
        require Class::Method::Modifiers;
        push @{$INFO{$target}{modifiers}||=[]}, [ $type => @_ ];
        $me->_maybe_reset_handlemoose($target);
      };
    }
    _install_tracked $target => requires => sub {
      push @{$INFO{$target}{requires}||=[]}, @_;
      $me->_maybe_reset_handlemoose($target);
    };
    _install_tracked $target => with => sub {
      $me->apply_roles_to_package($target, @_);
      $me->_maybe_reset_handlemoose($target);
    };
    return if $me->is_role($target); # already exported into this package
    $INFO{$target}{is_role} = 1;
    *{_getglob("${target}::meta")} = $me->can('meta');
    # grab all *non-constant* (stash slot is not a scalarref) subs present
    # in the symbol table and store their refaddrs (no need to forcibly
    # inflate constant subs into real subs) - also add '' to here (this
    # is used later) with a map to the coderefs in case of copying or re-use
    my @not_methods = ('', map { *$_{CODE}||() } grep !ref($_), values %$stash);
    @{$INFO{$target}{not_methods}={}}{@not_methods} = @not_methods;
    # a role does itself
    $APPLIED_TO{$target} = { $target => undef };
  
    $_->($target)
      for @ON_ROLE_CREATE;
  }
  
  push @ON_ROLE_CREATE, sub {
    my $target = shift;
    if ($INC{'Moo/HandleMoose.pm'}) {
      Moo::HandleMoose::inject_fake_metaclass_for($target);
    }
  };
  
  # duplicate from Moo::Object
  sub meta {
    require Moo::HandleMoose::FakeMetaClass;
    my $class = ref($_[0])||$_[0];
    bless({ name => $class }, 'Moo::HandleMoose::FakeMetaClass');
  }
  
  sub unimport {
    my $target = caller;
    _unimport_coderefs($target, $INFO{$target});
  }
  
  sub _maybe_reset_handlemoose {
    my ($class, $target) = @_;
    if ($INC{"Moo/HandleMoose.pm"}) {
      Moo::HandleMoose::maybe_reinject_fake_metaclass_for($target);
    }
  }
  
  sub methods_provided_by {
    my ($self, $role) = @_;
    _load_module($role);
    $self->_inhale_if_moose($role);
    die "${role} is not a Moo::Role" unless $self->is_role($role);
    return $self->SUPER::methods_provided_by($role);
  }
  
  sub is_role {
    my ($self, $role) = @_;
    $self->_inhale_if_moose($role);
    $self->SUPER::is_role($role);
  }
  
  sub _inhale_if_moose {
    my ($self, $role) = @_;
    my $meta;
    if (!$self->SUPER::is_role($role)
        and (
          $INC{"Moose.pm"}
          and $meta = Class::MOP::class_of($role)
          and ref $meta ne 'Moo::HandleMoose::FakeMetaClass'
          and $meta->isa('Moose::Meta::Role')
        )
        or (
          Mouse::Util->can('find_meta')
          and $meta = Mouse::Util::find_meta($role)
          and $meta->isa('Mouse::Meta::Role')
       )
    ) {
      my $is_mouse = $meta->isa('Mouse::Meta::Role');
      $INFO{$role}{methods} = {
        map +($_ => $role->can($_)),
          grep $role->can($_),
          grep !($is_mouse && $_ eq 'meta'),
          grep !$meta->get_method($_)->isa('Class::MOP::Method::Meta'),
            $meta->get_method_list
      };
      $APPLIED_TO{$role} = {
        map +($_->name => 1), $meta->calculate_all_roles
      };
      $INFO{$role}{requires} = [ $meta->get_required_method_list ];
      $INFO{$role}{attributes} = [
        map +($_ => do {
          my $attr = $meta->get_attribute($_);
          my $spec = { %{ $is_mouse ? $attr : $attr->original_options } };
  
          if ($spec->{isa}) {
  
            my $get_constraint = do {
              my $pkg = $is_mouse
                          ? 'Mouse::Util::TypeConstraints'
                          : 'Moose::Util::TypeConstraints';
              _load_module($pkg);
              $pkg->can('find_or_create_isa_type_constraint');
            };
  
            my $tc = $get_constraint->($spec->{isa});
            my $check = $tc->_compiled_type_constraint;
  
            $spec->{isa} = sub {
              &$check or die "Type constraint failed for $_[0]"
            };
  
            if ($spec->{coerce}) {
  
               # Mouse has _compiled_type_coercion straight on the TC object
               $spec->{coerce} = $tc->${\(
                 $tc->can('coercion')||sub { $_[0] }
               )}->_compiled_type_coercion;
            }
          }
          $spec;
        }), $meta->get_attribute_list
      ];
      my $mods = $INFO{$role}{modifiers} = [];
      foreach my $type (qw(before after around)) {
        # Mouse pokes its own internals so we have to fall back to doing
        # the same thing in the absence of the Moose API method
        my $map = $meta->${\(
          $meta->can("get_${type}_method_modifiers_map")
          or sub { shift->{"${type}_method_modifiers"} }
        )};
        foreach my $method (keys %$map) {
          foreach my $mod (@{$map->{$method}}) {
            push @$mods, [ $type => $method => $mod ];
          }
        }
      }
      require Class::Method::Modifiers if @$mods;
      $INFO{$role}{inhaled_from_moose} = 1;
      $INFO{$role}{is_role} = 1;
    }
  }
  
  sub _maybe_make_accessors {
    my ($self, $target, $role) = @_;
    my $m;
    if ($INFO{$role} && $INFO{$role}{inhaled_from_moose}
        or $INC{"Moo.pm"}
        and $m = Moo->_accessor_maker_for($target)
        and ref($m) ne 'Method::Generate::Accessor') {
      $self->_make_accessors($target, $role);
    }
  }
  
  sub _make_accessors_if_moose {
    my ($self, $target, $role) = @_;
    if ($INFO{$role} && $INFO{$role}{inhaled_from_moose}) {
      $self->_make_accessors($target, $role);
    }
  }
  
  sub _make_accessors {
    my ($self, $target, $role) = @_;
    my $acc_gen = ($Moo::MAKERS{$target}{accessor} ||= do {
      require Method::Generate::Accessor;
      Method::Generate::Accessor->new
    });
    my $con_gen = $Moo::MAKERS{$target}{constructor};
    my @attrs = @{$INFO{$role}{attributes}||[]};
    while (my ($name, $spec) = splice @attrs, 0, 2) {
      # needed to ensure we got an index for an arrayref based generator
      if ($con_gen) {
        $spec = $con_gen->all_attribute_specs->{$name};
      }
      $acc_gen->generate_method($target, $name, $spec);
    }
  }
  
  sub role_application_steps {
    qw(_handle_constructor _maybe_make_accessors),
      $_[0]->SUPER::role_application_steps;
  }
  
  sub apply_roles_to_package {
    my ($me, $to, @roles) = @_;
    foreach my $role (@roles) {
      _load_module($role);
      $me->_inhale_if_moose($role);
      die "${role} is not a Moo::Role" unless $me->is_role($role);
    }
    $me->SUPER::apply_roles_to_package($to, @roles);
  }
  
  sub apply_single_role_to_package {
    my ($me, $to, $role) = @_;
    _load_module($role);
    $me->_inhale_if_moose($role);
    die "${role} is not a Moo::Role" unless $me->is_role($role);
    $me->SUPER::apply_single_role_to_package($to, $role);
  }
  
  sub create_class_with_roles {
    my ($me, $superclass, @roles) = @_;
  
    my ($new_name, $compose_name) = $me->_composite_name($superclass, @roles);
  
    return $new_name if $Role::Tiny::COMPOSED{class}{$new_name};
  
    foreach my $role (@roles) {
        _load_module($role);
        $me->_inhale_if_moose($role);
    }
  
    my $m;
    if ($INC{"Moo.pm"}
        and $m = Moo->_accessor_maker_for($superclass)
        and ref($m) ne 'Method::Generate::Accessor') {
      # old fashioned way time.
      *{_getglob("${new_name}::ISA")} = [ $superclass ];
      $Moo::MAKERS{$new_name} = {is_class => 1};
      $me->apply_roles_to_package($new_name, @roles);
      _set_loaded($new_name, (caller)[1]);
      return $new_name;
    }
  
    $me->SUPER::create_class_with_roles($superclass, @roles);
  
    foreach my $role (@roles) {
      die "${role} is not a Moo::Role" unless $me->is_role($role);
    }
  
    $Moo::MAKERS{$new_name} = {is_class => 1};
  
    $me->_handle_constructor($new_name, $_) for @roles;
  
    _set_loaded($new_name, (caller)[1]);
    return $new_name;
  }
  
  sub apply_roles_to_object {
    my ($me, $object, @roles) = @_;
    my $new = $me->SUPER::apply_roles_to_object($object, @roles);
    _set_loaded(ref $new, (caller)[1]);
  
    my $apply_defaults = $APPLY_DEFAULTS{ref $new} ||= do {
      my %attrs = map { @{$INFO{$_}{attributes}||[]} } @roles;
  
      if ($INC{'Moo.pm'}
          and keys %attrs
          and my $con_gen = Moo->_constructor_maker_for(ref $new)
          and my $m = Moo->_accessor_maker_for(ref $new)) {
        require Sub::Quote;
  
        my $specs = $con_gen->all_attribute_specs;
  
        my $assign = '';
        my %captures;
        foreach my $name ( keys %attrs ) {
          my $spec = $specs->{$name};
          if ($m->has_eager_default($name, $spec)) {
            my ($has, $has_cap)
              = $m->generate_simple_has('$_[0]', $name, $spec);
            my ($code, $pop_cap)
              = $m->generate_use_default('$_[0]', $name, $spec, $has);
  
            $assign .= $code;
            @captures{keys %$has_cap, keys %$pop_cap}
              = (values %$has_cap, values %$pop_cap);
          }
        }
        Sub::Quote::quote_sub($assign, \%captures);
      }
      else {
        sub {};
      }
    };
    $new->$apply_defaults;
    return $new;
  }
  
  sub _composable_package_for {
    my ($self, $role) = @_;
    my $composed_name = 'Role::Tiny::_COMPOSABLE::'.$role;
    return $composed_name if $Role::Tiny::COMPOSED{role}{$composed_name};
    $self->_make_accessors_if_moose($composed_name, $role);
    $self->SUPER::_composable_package_for($role);
  }
  
  sub _install_single_modifier {
    my ($me, @args) = @_;
    _install_modifier(@args);
  }
  
  sub _handle_constructor {
    my ($me, $to, $role) = @_;
    my $attr_info = $INFO{$role} && $INFO{$role}{attributes};
    return unless $attr_info && @$attr_info;
    if ($INFO{$to}) {
      push @{$INFO{$to}{attributes}||=[]}, @$attr_info;
    } else {
      # only fiddle with the constructor if the target is a Moo class
      if ($INC{"Moo.pm"}
          and my $con = Moo->_constructor_maker_for($to)) {
        # shallow copy of the specs since the constructor will assign an index
        $con->register_attribute_specs(map ref() ? { %$_ } : $_, @$attr_info);
      }
    }
  }
  
  1;
  __END__
  
  =head1 NAME
  
  Moo::Role - Minimal Object Orientation support for Roles
  
  =head1 SYNOPSIS
  
   package My::Role;
  
   use Moo::Role;
  
   sub foo { ... }
  
   sub bar { ... }
  
   has baz => (
     is => 'ro',
   );
  
   1;
  
  And elsewhere:
  
   package Some::Class;
  
   use Moo;
  
   # bar gets imported, but not foo
   with('My::Role');
  
   sub foo { ... }
  
   1;
  
  =head1 DESCRIPTION
  
  C<Moo::Role> builds upon L<Role::Tiny>, so look there for most of the
  documentation on how this works.  The main addition here is extra bits to make
  the roles more "Moosey;" which is to say, it adds L</has>.
  
  =head1 IMPORTED SUBROUTINES
  
  See L<Role::Tiny/IMPORTED SUBROUTINES> for all the other subroutines that are
  imported by this module.
  
  =head2 has
  
   has attr => (
     is => 'ro',
   );
  
  Declares an attribute for the class to be composed into.  See
  L<Moo/has> for all options.
  
  =head1 CLEANING UP IMPORTS
  
  L<Moo::Role> cleans up its own imported methods and any imports
  declared before the C<use Moo::Role> statement automatically.
  Anything imported after C<use Moo::Role> will be composed into
  consuming packages.  A package that consumes this role:
  
   package My::Role::ID;
  
   use Digest::MD5 qw(md5_hex);
   use Moo::Role;
   use Digest::SHA qw(sha1_hex);
  
   requires 'name';
  
   sub as_md5  { my ($self) = @_; return md5_hex($self->name);  }
   sub as_sha1 { my ($self) = @_; return sha1_hex($self->name); }
  
   1;
  
  ..will now have a C<< $self->sha1_hex() >> method available to it
  that probably does not do what you expect.  On the other hand, a call
  to C<< $self->md5_hex() >> will die with the helpful error message:
  C<Can't locate object method "md5_hex">.
  
  See L<Moo/"CLEANING UP IMPORTS"> for more details.
  
  =head1 SUPPORT
  
  See L<Moo> for support and contact information.
  
  =head1 AUTHORS
  
  See L<Moo> for authors.
  
  =head1 COPYRIGHT AND LICENSE
  
  See L<Moo> for the copyright and license.
  
  =cut
MOO_ROLE

$fatpacked{"Moo/_Utils.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MOO__UTILS';
  package Moo::_Utils;
  
  no warnings 'once'; # guard against -w
  
  sub _getglob { \*{$_[0]} }
  sub _getstash { \%{"$_[0]::"} }
  
  use constant lt_5_8_3 => ( $] < 5.008003 or $ENV{MOO_TEST_PRE_583} ) ? 1 : 0;
  use constant can_haz_subname => eval { require Sub::Name };
  
  use strictures 1;
  use Module::Runtime qw(use_package_optimistically module_notional_filename);
  
  use Devel::GlobalDestruction ();
  use base qw(Exporter);
  use Moo::_mro;
  use Config;
  
  our @EXPORT = qw(
      _getglob _install_modifier _load_module _maybe_load_module
      _get_linear_isa _getstash _install_coderef _name_coderef
      _unimport_coderefs _in_global_destruction _set_loaded
  );
  
  sub _in_global_destruction ();
  *_in_global_destruction = \&Devel::GlobalDestruction::in_global_destruction;
  
  sub _install_modifier {
    my ($into, $type, $name, $code) = @_;
  
    if (my $to_modify = $into->can($name)) { # CMM will throw for us if not
      require Sub::Defer;
      Sub::Defer::undefer_sub($to_modify);
    }
  
    Class::Method::Modifiers::install_modifier(@_);
  }
  
  our %MAYBE_LOADED;
  
  sub _load_module {
    my $module = $_[0];
    my $file = module_notional_filename($module);
    use_package_optimistically($module);
    return 1
      if $INC{$file};
    my $error = $@ || "Can't locate $file";
  
    # can't just ->can('can') because a sub-package Foo::Bar::Baz
    # creates a 'Baz::' key in Foo::Bar's symbol table
    my $stash = _getstash($module)||{};
    return 1 if grep +(!ref($_) and *$_{CODE}), values %$stash;
    return 1
      if $INC{"Moose.pm"} && Class::MOP::class_of($module)
      or Mouse::Util->can('find_meta') && Mouse::Util::find_meta($module);
    die $error;
  }
  
  sub _maybe_load_module {
    my $module = $_[0];
    return $MAYBE_LOADED{$module}
      if exists $MAYBE_LOADED{$module};
    if(! eval { use_package_optimistically($module) }) {
      warn "$module exists but failed to load with error: $@";
    }
    elsif ( $INC{module_notional_filename($module)} ) {
      return $MAYBE_LOADED{$module} = 1;
    }
    return $MAYBE_LOADED{$module} = 0;
  }
  
  sub _set_loaded {
    $INC{Module::Runtime::module_notional_filename($_[0])} ||= $_[1];
  }
  
  sub _get_linear_isa {
    return mro::get_linear_isa($_[0]);
  }
  
  sub _install_coderef {
    my ($glob, $code) = (_getglob($_[0]), _name_coderef(@_));
    no warnings 'redefine';
    if (*{$glob}{CODE}) {
      *{$glob} = $code;
    }
    # perl will sometimes warn about mismatched prototypes coming from the
    # inheritance cache, so disable them if we aren't redefining a sub
    else {
      no warnings 'prototype';
      *{$glob} = $code;
    }
  }
  
  sub _name_coderef {
    shift if @_ > 2; # three args is (target, name, sub)
    can_haz_subname ? Sub::Name::subname(@_) : $_[1];
  }
  
  sub _unimport_coderefs {
    my ($target, $info) = @_;
    return unless $info and my $exports = $info->{exports};
    my %rev = reverse %$exports;
    my $stash = _getstash($target);
    foreach my $name (keys %$exports) {
      if ($stash->{$name} and defined(&{$stash->{$name}})) {
        if ($rev{$target->can($name)}) {
          my $old = delete $stash->{$name};
          my $full_name = join('::',$target,$name);
          # Copy everything except the code slot back into place (e.g. $has)
          foreach my $type (qw(SCALAR HASH ARRAY IO)) {
            next unless defined(*{$old}{$type});
            no strict 'refs';
            *$full_name = *{$old}{$type};
          }
        }
      }
    }
  }
  
  if ($Config{useithreads}) {
    require Moo::HandleMoose::_TypeMap;
  }
  
  1;
MOO__UTILS

$fatpacked{"Moo/_mro.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MOO__MRO';
  package Moo::_mro;
  use strictures 1;
  
  if ($] >= 5.010) {
    require mro;
  } else {
    require MRO::Compat;
  }
  
  1;
MOO__MRO

$fatpacked{"Moo/sification.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'MOO_SIFICATION';
  package Moo::sification;
  
  use strictures 1;
  use Moo::_Utils ();
  
  sub unimport { our $disarmed = 1 }
  
  sub Moo::HandleMoose::AuthorityHack::DESTROY {
    unless (our $disarmed or Moo::_Utils::_in_global_destruction) {
      require Moo::HandleMoose;
      Moo::HandleMoose->import;
    }
  }
  
  if ($INC{"Moose.pm"}) {
    require Moo::HandleMoose;
    Moo::HandleMoose->import;
  } else {
    $Moose::AUTHORITY = bless({}, 'Moo::HandleMoose::AuthorityHack');
  }
  
  1;
MOO_SIFICATION

$fatpacked{"Parse/CPAN/Meta.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'PARSE_CPAN_META';
  use 5.008001;
  use strict;
  package Parse::CPAN::Meta;
  # ABSTRACT: Parse META.yml and META.json CPAN metadata files
  
  our $VERSION = '1.4417';
  
  use Exporter;
  use Carp 'croak';
  
  our @ISA = qw/Exporter/;
  our @EXPORT_OK = qw/Load LoadFile/;
  
  sub load_file {
    my ($class, $filename) = @_;
  
    my $meta = _slurp($filename);
  
    if ($filename =~ /\.ya?ml$/) {
      return $class->load_yaml_string($meta);
    }
    elsif ($filename =~ /\.json$/) {
      return $class->load_json_string($meta);
    }
    else {
      $class->load_string($meta); # try to detect yaml/json
    }
  }
  
  sub load_string {
    my ($class, $string) = @_;
    if ( $string =~ /^---/ ) { # looks like YAML
      return $class->load_yaml_string($string);
    }
    elsif ( $string =~ /^\s*\{/ ) { # looks like JSON
      return $class->load_json_string($string);
    }
    else { # maybe doc-marker-free YAML
      return $class->load_yaml_string($string);
    }
  }
  
  sub load_yaml_string {
    my ($class, $string) = @_;
    my $backend = $class->yaml_backend();
    my $data = eval { no strict 'refs'; &{"$backend\::Load"}($string) };
    croak $@ if $@;
    return $data || {}; # in case document was valid but empty
  }
  
  sub load_json_string {
    my ($class, $string) = @_;
    my $data = eval { $class->json_backend()->new->decode($string) };
    croak $@ if $@;
    return $data || {};
  }
  
  sub yaml_backend {
    if (! defined $ENV{PERL_YAML_BACKEND} ) {
      _can_load( 'CPAN::Meta::YAML', 0.011 )
        or croak "CPAN::Meta::YAML 0.011 is not available\n";
      return "CPAN::Meta::YAML";
    }
    else {
      my $backend = $ENV{PERL_YAML_BACKEND};
      _can_load( $backend )
        or croak "Could not load PERL_YAML_BACKEND '$backend'\n";
      $backend->can("Load")
        or croak "PERL_YAML_BACKEND '$backend' does not implement Load()\n";
      return $backend;
    }
  }
  
  sub json_backend {
    if (! $ENV{PERL_JSON_BACKEND} or $ENV{PERL_JSON_BACKEND} eq 'JSON::PP') {
      _can_load( 'JSON::PP' => 2.27103 )
        or croak "JSON::PP 2.27103 is not available\n";
      return 'JSON::PP';
    }
    else {
      _can_load( 'JSON' => 2.5 )
        or croak  "JSON 2.5 is required for " .
                  "\$ENV{PERL_JSON_BACKEND} = '$ENV{PERL_JSON_BACKEND}'\n";
      return "JSON";
    }
  }
  
  sub _slurp {
    require Encode;
    open my $fh, "<:raw", "$_[0]" ## no critic
      or die "can't open $_[0] for reading: $!";
    my $content = do { local $/; <$fh> };
    $content = Encode::decode('UTF-8', $content, Encode::PERLQQ());
    return $content;
  }
    
  sub _can_load {
    my ($module, $version) = @_;
    (my $file = $module) =~ s{::}{/}g;
    $file .= ".pm";
    return 1 if $INC{$file};
    return 0 if exists $INC{$file}; # prior load failed
    eval { require $file; 1 }
      or return 0;
    if ( defined $version ) {
      eval { $module->VERSION($version); 1 }
        or return 0;
    }
    return 1;
  }
  
  # Kept for backwards compatibility only
  # Create an object from a file
  sub LoadFile ($) { ## no critic
    return Load(_slurp(shift));
  }
  
  # Parse a document from a string.
  sub Load ($) { ## no critic
    require CPAN::Meta::YAML;
    my $object = eval { CPAN::Meta::YAML::Load(shift) };
    croak $@ if $@;
    return $object;
  }
  
  1;
  
  __END__
  
  =pod
  
  =encoding UTF-8
  
  =head1 NAME
  
  Parse::CPAN::Meta - Parse META.yml and META.json CPAN metadata files
  
  =head1 VERSION
  
  version 1.4417
  
  =head1 SYNOPSIS
  
      #############################################
      # In your file
      
      ---
      name: My-Distribution
      version: 1.23
      resources:
        homepage: "http://example.com/dist/My-Distribution"
      
      
      #############################################
      # In your program
      
      use Parse::CPAN::Meta;
      
      my $distmeta = Parse::CPAN::Meta->load_file('META.yml');
      
      # Reading properties
      my $name     = $distmeta->{name};
      my $version  = $distmeta->{version};
      my $homepage = $distmeta->{resources}{homepage};
  
  =head1 DESCRIPTION
  
  B<Parse::CPAN::Meta> is a parser for F<META.json> and F<META.yml> files, using
  L<JSON::PP> and/or L<CPAN::Meta::YAML>.
  
  B<Parse::CPAN::Meta> provides three methods: C<load_file>, C<load_json_string>,
  and C<load_yaml_string>.  These will read and deserialize CPAN metafiles, and
  are described below in detail.
  
  B<Parse::CPAN::Meta> provides a legacy API of only two functions,
  based on the YAML functions of the same name. Wherever possible,
  identical calling semantics are used.  These may only be used with YAML sources.
  
  All error reporting is done with exceptions (die'ing).
  
  Note that META files are expected to be in UTF-8 encoding, only.  When
  converted string data, it must first be decoded from UTF-8.
  
  =begin Pod::Coverage
  
  
  
  
  =end Pod::Coverage
  
  =head1 METHODS
  
  =head2 load_file
  
    my $metadata_structure = Parse::CPAN::Meta->load_file('META.json');
  
    my $metadata_structure = Parse::CPAN::Meta->load_file('META.yml');
  
  This method will read the named file and deserialize it to a data structure,
  determining whether it should be JSON or YAML based on the filename.
  The file will be read using the ":utf8" IO layer.
  
  =head2 load_yaml_string
  
    my $metadata_structure = Parse::CPAN::Meta->load_yaml_string($yaml_string);
  
  This method deserializes the given string of YAML and returns the first
  document in it.  (CPAN metadata files should always have only one document.)
  If the source was UTF-8 encoded, the string must be decoded before calling
  C<load_yaml_string>.
  
  =head2 load_json_string
  
    my $metadata_structure = Parse::CPAN::Meta->load_json_string($json_string);
  
  This method deserializes the given string of JSON and the result.  
  If the source was UTF-8 encoded, the string must be decoded before calling
  C<load_json_string>.
  
  =head2 load_string
  
    my $metadata_structure = Parse::CPAN::Meta->load_string($some_string);
  
  If you don't know whether a string contains YAML or JSON data, this method
  will use some heuristics and guess.  If it can't tell, it assumes YAML.
  
  =head2 yaml_backend
  
    my $backend = Parse::CPAN::Meta->yaml_backend;
  
  Returns the module name of the YAML serializer. See L</ENVIRONMENT>
  for details.
  
  =head2 json_backend
  
    my $backend = Parse::CPAN::Meta->json_backend;
  
  Returns the module name of the JSON serializer.  This will either
  be L<JSON::PP> or L<JSON>.  Even if C<PERL_JSON_BACKEND> is set,
  this will return L<JSON> as further delegation is handled by
  the L<JSON> module.  See L</ENVIRONMENT> for details.
  
  =head1 FUNCTIONS
  
  For maintenance clarity, no functions are exported by default.  These functions
  are available for backwards compatibility only and are best avoided in favor of
  C<load_file>.
  
  =head2 Load
  
    my @yaml = Parse::CPAN::Meta::Load( $string );
  
  Parses a string containing a valid YAML stream into a list of Perl data
  structures.
  
  =head2 LoadFile
  
    my @yaml = Parse::CPAN::Meta::LoadFile( 'META.yml' );
  
  Reads the YAML stream from a file instead of a string.
  
  =head1 ENVIRONMENT
  
  =head2 PERL_JSON_BACKEND
  
  By default, L<JSON::PP> will be used for deserializing JSON data. If the
  C<PERL_JSON_BACKEND> environment variable exists, is true and is not
  "JSON::PP", then the L<JSON> module (version 2.5 or greater) will be loaded and
  used to interpret C<PERL_JSON_BACKEND>.  If L<JSON> is not installed or is too
  old, an exception will be thrown.
  
  =head2 PERL_YAML_BACKEND
  
  By default, L<CPAN::Meta::YAML> will be used for deserializing YAML data. If
  the C<PERL_YAML_BACKEND> environment variable is defined, then it is interpreted
  as a module to use for deserialization.  The given module must be installed,
  must load correctly and must implement the C<Load()> function or an exception
  will be thrown.
  
  =for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan
  
  =head1 SUPPORT
  
  =head2 Bugs / Feature Requests
  
  Please report any bugs or feature requests through the issue tracker
  at L<https://github.com/Perl-Toolchain-Gang/Parse-CPAN-Meta/issues>.
  You will be notified automatically of any progress on your issue.
  
  =head2 Source Code
  
  This is open source software.  The code repository is available for
  public review and contribution under the terms of the license.
  
  L<https://github.com/Perl-Toolchain-Gang/Parse-CPAN-Meta>
  
    git clone https://github.com/Perl-Toolchain-Gang/Parse-CPAN-Meta.git
  
  =head1 AUTHORS
  
  =over 4
  
  =item *
  
  Adam Kennedy <adamk@cpan.org>
  
  =item *
  
  David Golden <dagolden@cpan.org>
  
  =back
  
  =head1 CONTRIBUTORS
  
  =for stopwords Graham Knop Joshua ben Jore Karen Etheridge Neil Bowers Ricardo Signes Steffen Mueller
  
  =over 4
  
  =item *
  
  Graham Knop <haarg@haarg.org>
  
  =item *
  
  Joshua ben Jore <jjore@cpan.org>
  
  =item *
  
  Karen Etheridge <ether@cpan.org>
  
  =item *
  
  Neil Bowers <neil@bowers.com>
  
  =item *
  
  Ricardo Signes <rjbs@cpan.org>
  
  =item *
  
  Steffen Mueller <smueller@cpan.org>
  
  =back
  
  =head1 COPYRIGHT AND LICENSE
  
  This software is copyright (c) 2015 by Adam Kennedy and Contributors.
  
  This is free software; you can redistribute it and/or modify it under
  the same terms as the Perl 5 programming language system itself.
  
  =cut
PARSE_CPAN_META

$fatpacked{"Path/Tiny.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'PATH_TINY';
  use 5.008001;
  use strict;
  use warnings;
  
  package Path::Tiny;
  # ABSTRACT: File path utility
  
  our $VERSION = '0.086';
  
  # Dependencies
  use Config;
  use Exporter 5.57   (qw/import/);
  use File::Spec 0.86 ();          # shipped with 5.8.1
  use Carp ();
  
  our @EXPORT    = qw/path/;
  our @EXPORT_OK = qw/cwd rootdir tempfile tempdir/;
  
  use constant {
      PATH     => 0,
      CANON    => 1,
      VOL      => 2,
      DIR      => 3,
      FILE     => 4,
      TEMP     => 5,
      IS_BSD   => ( scalar $^O =~ /bsd$/ ),
      IS_WIN32 => ( $^O eq 'MSWin32' ),
  };
  
  use overload (
      q{""}    => sub    { $_[0]->[PATH] },
      bool     => sub () { 1 },
      fallback => 1,
  );
  
  # FREEZE/THAW per Sereal/CBOR/Types::Serialiser protocol
  sub FREEZE { return $_[0]->[PATH] }
  sub THAW   { return path( $_[2] ) }
  { no warnings 'once'; *TO_JSON = *FREEZE };
  
  my $HAS_UU; # has Unicode::UTF8; lazily populated
  
  sub _check_UU {
      !!eval { require Unicode::UTF8; Unicode::UTF8->VERSION(0.58); 1 };
  }
  
  my $HAS_FLOCK = $Config{d_flock} || $Config{d_fcntl_can_lock} || $Config{d_lockf};
  
  # notions of "root" directories differ on Win32: \\server\dir\ or C:\ or \
  my $SLASH      = qr{[\\/]};
  my $NOTSLASH   = qr{[^\\/]};
  my $DRV_VOL    = qr{[a-z]:}i;
  my $UNC_VOL    = qr{$SLASH $SLASH $NOTSLASH+ $SLASH $NOTSLASH+}x;
  my $WIN32_ROOT = qr{(?: $UNC_VOL $SLASH | $DRV_VOL $SLASH | $SLASH )}x;
  
  sub _win32_vol {
      my ( $path, $drv ) = @_;
      require Cwd;
      my $dcwd = eval { Cwd::getdcwd($drv) }; # C: -> C:\some\cwd
      # getdcwd on non-existent drive returns empty string
      # so just use the original drive Z: -> Z:
      $dcwd = "$drv" unless defined $dcwd && length $dcwd;
      # normalize dwcd to end with a slash: might be C:\some\cwd or D:\ or Z:
      $dcwd =~ s{$SLASH?$}{/};
      # make the path absolute with dcwd
      $path =~ s{^$DRV_VOL}{$dcwd};
      return $path;
  }
  
  # This is a string test for before we have the object; see is_rootdir for well-formed
  # object test
  sub _is_root {
      return IS_WIN32() ? ( $_[0] =~ /^$WIN32_ROOT$/ ) : ( $_[0] eq '/' );
  }
  
  BEGIN {
      *_same = IS_WIN32() ? sub { lc( $_[0] ) eq lc( $_[1] ) } : sub { $_[0] eq $_[1] };
  }
  
  # mode bits encoded for chmod in symbolic mode
  my %MODEBITS = ( om => 0007, gm => 0070, um => 0700 ); ## no critic
  { my $m = 0; $MODEBITS{$_} = ( 1 << $m++ ) for qw/ox ow or gx gw gr ux uw ur/ };
  
  sub _symbolic_chmod {
      my ( $mode, $symbolic ) = @_;
      for my $clause ( split /,\s*/, $symbolic ) {
          if ( $clause =~ m{\A([augo]+)([=+-])([rwx]+)\z} ) {
              my ( $who, $action, $perms ) = ( $1, $2, $3 );
              $who =~ s/a/ugo/g;
              for my $w ( split //, $who ) {
                  my $p = 0;
                  $p |= $MODEBITS{"$w$_"} for split //, $perms;
                  if ( $action eq '=' ) {
                      $mode = ( $mode & ~$MODEBITS{"${w}m"} ) | $p;
                  }
                  else {
                      $mode = $action eq "+" ? ( $mode | $p ) : ( $mode & ~$p );
                  }
              }
          }
          else {
              Carp::croak("Invalid mode clause '$clause' for chmod()");
          }
      }
      return $mode;
  }
  
  # flock doesn't work on NFS on BSD.  Since program authors often can't control
  # or detect that, we warn once instead of being fatal if we can detect it and
  # people who need it strict can fatalize the 'flock' category
  
  #<<< No perltidy
  { package flock; use if Path::Tiny::IS_BSD(), 'warnings::register' }
  #>>>
  
  my $WARNED_BSD_NFS = 0;
  
  sub _throw {
      my ( $self, $function, $file ) = @_;
      if (   IS_BSD()
          && $function =~ /^flock/
          && $! =~ /operation not supported/i
          && !warnings::fatal_enabled('flock') )
      {
          if ( !$WARNED_BSD_NFS ) {
              warnings::warn( flock => "No flock for NFS on BSD: continuing in unsafe mode" );
              $WARNED_BSD_NFS++;
          }
      }
      else {
          Path::Tiny::Error->throw( $function, ( defined $file ? $file : $self->[PATH] ), $! );
      }
      return;
  }
  
  # cheapo option validation
  sub _get_args {
      my ( $raw, @valid ) = @_;
      if ( defined($raw) && ref($raw) ne 'HASH' ) {
          my ( undef, undef, undef, $called_as ) = caller(1);
          $called_as =~ s{^.*::}{};
          Carp::croak("Options for $called_as must be a hash reference");
      }
      my $cooked = {};
      for my $k (@valid) {
          $cooked->{$k} = delete $raw->{$k} if exists $raw->{$k};
      }
      if ( keys %$raw ) {
          my ( undef, undef, undef, $called_as ) = caller(1);
          $called_as =~ s{^.*::}{};
          Carp::croak( "Invalid option(s) for $called_as: " . join( ", ", keys %$raw ) );
      }
      return $cooked;
  }
  
  #--------------------------------------------------------------------------#
  # Constructors
  #--------------------------------------------------------------------------#
  
  #pod =construct path
  #pod
  #pod     $path = path("foo/bar");
  #pod     $path = path("/tmp", "file.txt"); # list
  #pod     $path = path(".");                # cwd
  #pod     $path = path("~user/file.txt");   # tilde processing
  #pod
  #pod Constructs a C<Path::Tiny> object.  It doesn't matter if you give a file or
  #pod directory path.  It's still up to you to call directory-like methods only on
  #pod directories and file-like methods only on files.  This function is exported
  #pod automatically by default.
  #pod
  #pod The first argument must be defined and have non-zero length or an exception
  #pod will be thrown.  This prevents subtle, dangerous errors with code like
  #pod C<< path( maybe_undef() )->remove_tree >>.
  #pod
  #pod If the first component of the path is a tilde ('~') then the component will be
  #pod replaced with the output of C<glob('~')>.  If the first component of the path
  #pod is a tilde followed by a user name then the component will be replaced with
  #pod output of C<glob('~username')>.  Behaviour for non-existent users depends on
  #pod the output of C<glob> on the system.
  #pod
  #pod On Windows, if the path consists of a drive identifier without a path component
  #pod (C<C:> or C<D:>), it will be expanded to the absolute path of the current
  #pod directory on that volume using C<Cwd::getdcwd()>.
  #pod
  #pod If called with a single C<Path::Tiny> argument, the original is returned unless
  #pod the original is holding a temporary file or directory reference in which case a
  #pod stringified copy is made.
  #pod
  #pod     $path = path("foo/bar");
  #pod     $temp = Path::Tiny->tempfile;
  #pod
  #pod     $p2 = path($path); # like $p2 = $path
  #pod     $t2 = path($temp); # like $t2 = path( "$temp" )
  #pod
  #pod This optimizes copies without proliferating references unexpectedly if a copy is
  #pod made by code outside your control.
  #pod
  #pod Current API available since 0.017.
  #pod
  #pod =cut
  
  sub path {
      my $path = shift;
      Carp::croak("Path::Tiny paths require defined, positive-length parts")
        unless 1 + @_ == grep { defined && length } $path, @_;
  
      # non-temp Path::Tiny objects are effectively immutable and can be reused
      if ( !@_ && ref($path) eq __PACKAGE__ && !$path->[TEMP] ) {
          return $path;
      }
  
      # stringify objects
      $path = "$path";
  
      # expand relative volume paths on windows; put trailing slash on UNC root
      if ( IS_WIN32() ) {
          $path = _win32_vol( $path, $1 ) if $path =~ m{^($DRV_VOL)(?:$NOTSLASH|$)};
          $path .= "/" if $path =~ m{^$UNC_VOL$};
      }
  
      # concatenations stringifies objects, too
      if (@_) {
          $path .= ( _is_root($path) ? "" : "/" ) . join( "/", @_ );
      }
  
      # canonicalize, but with unix slashes and put back trailing volume slash
      my $cpath = $path = File::Spec->canonpath($path);
      $path =~ tr[\\][/] if IS_WIN32();
      $path = "/" if $path eq '/..'; # for old File::Spec
      $path .= "/" if IS_WIN32() && $path =~ m{^$UNC_VOL$};
  
      # root paths must always have a trailing slash, but other paths must not
      if ( _is_root($path) ) {
          $path =~ s{/?$}{/};
      }
      else {
          $path =~ s{/$}{};
      }
  
      # do any tilde expansions
      if ( $path =~ m{^(~[^/]*).*} ) {
          require File::Glob;
          my ($homedir) = File::Glob::bsd_glob($1);
          $homedir =~ tr[\\][/] if IS_WIN32();
          $path =~ s{^(~[^/]*)}{$homedir};
      }
  
      bless [ $path, $cpath ], __PACKAGE__;
  }
  
  #pod =construct new
  #pod
  #pod     $path = Path::Tiny->new("foo/bar");
  #pod
  #pod This is just like C<path>, but with method call overhead.  (Why would you
  #pod do that?)
  #pod
  #pod Current API available since 0.001.
  #pod
  #pod =cut
  
  sub new { shift; path(@_) }
  
  #pod =construct cwd
  #pod
  #pod     $path = Path::Tiny->cwd; # path( Cwd::getcwd )
  #pod     $path = cwd; # optional export
  #pod
  #pod Gives you the absolute path to the current directory as a C<Path::Tiny> object.
  #pod This is slightly faster than C<< path(".")->absolute >>.
  #pod
  #pod C<cwd> may be exported on request and used as a function instead of as a
  #pod method.
  #pod
  #pod Current API available since 0.018.
  #pod
  #pod =cut
  
  sub cwd {
      require Cwd;
      return path( Cwd::getcwd() );
  }
  
  #pod =construct rootdir
  #pod
  #pod     $path = Path::Tiny->rootdir; # /
  #pod     $path = rootdir;             # optional export 
  #pod
  #pod Gives you C<< File::Spec->rootdir >> as a C<Path::Tiny> object if you're too
  #pod picky for C<path("/")>.
  #pod
  #pod C<rootdir> may be exported on request and used as a function instead of as a
  #pod method.
  #pod
  #pod Current API available since 0.018.
  #pod
  #pod =cut
  
  sub rootdir { path( File::Spec->rootdir ) }
  
  #pod =construct tempfile, tempdir
  #pod
  #pod     $temp = Path::Tiny->tempfile( @options );
  #pod     $temp = Path::Tiny->tempdir( @options );
  #pod     $temp = tempfile( @options ); # optional export
  #pod     $temp = tempdir( @options );  # optional export
  #pod
  #pod C<tempfile> passes the options to C<< File::Temp->new >> and returns a C<Path::Tiny>
  #pod object with the file name.  The C<TMPDIR> option is enabled by default.
  #pod
  #pod The resulting C<File::Temp> object is cached. When the C<Path::Tiny> object is
  #pod destroyed, the C<File::Temp> object will be as well.
  #pod
  #pod C<File::Temp> annoyingly requires you to specify a custom template in slightly
  #pod different ways depending on which function or method you call, but
  #pod C<Path::Tiny> lets you ignore that and can take either a leading template or a
  #pod C<TEMPLATE> option and does the right thing.
  #pod
  #pod     $temp = Path::Tiny->tempfile( "customXXXXXXXX" );             # ok
  #pod     $temp = Path::Tiny->tempfile( TEMPLATE => "customXXXXXXXX" ); # ok
  #pod
  #pod The tempfile path object will be normalized to have an absolute path, even if
  #pod created in a relative directory using C<DIR>.
  #pod
  #pod C<tempdir> is just like C<tempfile>, except it calls
  #pod C<< File::Temp->newdir >> instead.
  #pod
  #pod Both C<tempfile> and C<tempdir> may be exported on request and used as
  #pod functions instead of as methods.
  #pod
  #pod B<Note>: for tempfiles, the filehandles from File::Temp are closed and not
  #pod reused.  This is not as secure as using File::Temp handles directly, but is
  #pod less prone to deadlocks or access problems on some platforms.  Think of what
  #pod C<Path::Tiny> gives you to be just a temporary file B<name> that gets cleaned
  #pod up.
  #pod
  #pod B<Note 2>: if you don't want these cleaned up automatically when the object
  #pod is destroyed, File::Temp requires different options for directories and
  #pod files.  Use C<< CLEANUP => 0 >> for directories and C<< UNLINK => 0 >> for
  #pod files.
  #pod
  #pod Current API available since 0.018.
  #pod
  #pod =cut
  
  sub tempfile {
      shift if @_ && $_[0] eq 'Path::Tiny'; # called as method
      my ( $maybe_template, $args ) = _parse_file_temp_args(@_);
      # File::Temp->new demands TEMPLATE
      $args->{TEMPLATE} = $maybe_template->[0] if @$maybe_template;
  
      require File::Temp;
      my $temp = File::Temp->new( TMPDIR => 1, %$args );
      close $temp;
      my $self = path($temp)->absolute;
      $self->[TEMP] = $temp;                # keep object alive while we are
      return $self;
  }
  
  sub tempdir {
      shift if @_ && $_[0] eq 'Path::Tiny'; # called as method
      my ( $maybe_template, $args ) = _parse_file_temp_args(@_);
  
      # File::Temp->newdir demands leading template
      require File::Temp;
      my $temp = File::Temp->newdir( @$maybe_template, TMPDIR => 1, %$args );
      my $self = path($temp)->absolute;
      $self->[TEMP] = $temp;                # keep object alive while we are
      # Some ActiveState Perls for Windows break Cwd in ways that lead
      # File::Temp to get confused about what path to remove; this
      # monkey-patches the object with our own view of the absolute path
      $temp->{REALNAME} = $self->[CANON] if IS_WIN32;
      return $self;
  }
  
  # normalize the various ways File::Temp does templates
  sub _parse_file_temp_args {
      my $leading_template = ( scalar(@_) % 2 == 1 ? shift(@_) : '' );
      my %args = @_;
      %args = map { uc($_), $args{$_} } keys %args;
      my @template = (
            exists $args{TEMPLATE} ? delete $args{TEMPLATE}
          : $leading_template      ? $leading_template
          :                          ()
      );
      return ( \@template, \%args );
  }
  
  #--------------------------------------------------------------------------#
  # Private methods
  #--------------------------------------------------------------------------#
  
  sub _splitpath {
      my ($self) = @_;
      @{$self}[ VOL, DIR, FILE ] = File::Spec->splitpath( $self->[PATH] );
  }
  
  #--------------------------------------------------------------------------#
  # Public methods
  #--------------------------------------------------------------------------#
  
  #pod =method absolute
  #pod
  #pod     $abs = path("foo/bar")->absolute;
  #pod     $abs = path("foo/bar")->absolute("/tmp");
  #pod
  #pod Returns a new C<Path::Tiny> object with an absolute path (or itself if already
  #pod absolute).  Unless an argument is given, the current directory is used as the
  #pod absolute base path.  The argument must be absolute or you won't get an absolute
  #pod result.
  #pod
  #pod This will not resolve upward directories ("foo/../bar") unless C<canonpath>
  #pod in L<File::Spec> would normally do so on your platform.  If you need them
  #pod resolved, you must call the more expensive C<realpath> method instead.
  #pod
  #pod On Windows, an absolute path without a volume component will have it added
  #pod based on the current drive.
  #pod
  #pod Current API available since 0.001.
  #pod
  #pod =cut
  
  sub absolute {
      my ( $self, $base ) = @_;
  
      # absolute paths handled differently by OS
      if (IS_WIN32) {
          return $self if length $self->volume;
          # add missing volume
          if ( $self->is_absolute ) {
              require Cwd;
              # use Win32::GetCwd not Cwd::getdcwd because we're sure
              # to have the former but not necessarily the latter
              my ($drv) = Win32::GetCwd() =~ /^($DRV_VOL | $UNC_VOL)/x;
              return path( $drv . $self->[PATH] );
          }
      }
      else {
          return $self if $self->is_absolute;
      }
  
      # relative path on any OS
      require Cwd;
      return path( ( defined($base) ? $base : Cwd::getcwd() ), $_[0]->[PATH] );
  }
  
  #pod =method append, append_raw, append_utf8
  #pod
  #pod     path("foo.txt")->append(@data);
  #pod     path("foo.txt")->append(\@data);
  #pod     path("foo.txt")->append({binmode => ":raw"}, @data);
  #pod     path("foo.txt")->append_raw(@data);
  #pod     path("foo.txt")->append_utf8(@data);
  #pod
  #pod Appends data to a file.  The file is locked with C<flock> prior to writing.  An
  #pod optional hash reference may be used to pass options.  Valid options are:
  #pod
  #pod =for :list
  #pod * C<binmode>: passed to C<binmode()> on the handle used for writing.
  #pod * C<truncate>: truncates the file after locking and before appending
  #pod
  #pod The C<truncate> option is a way to replace the contents of a file
  #pod B<in place>, unlike L</spew> which writes to a temporary file and then
  #pod replaces the original (if it exists).
  #pod
  #pod C<append_raw> is like C<append> with a C<binmode> of C<:unix> for fast,
  #pod unbuffered, raw write.
  #pod
  #pod C<append_utf8> is like C<append> with a C<binmode> of
  #pod C<:unix:encoding(UTF-8)>.  If L<Unicode::UTF8> 0.58+ is installed, a raw
  #pod append will be done instead on the data encoded with C<Unicode::UTF8>.
  #pod
  #pod Current API available since 0.060.
  #pod
  #pod =cut
  
  sub append {
      my ( $self, @data ) = @_;
      my $args = ( @data && ref $data[0] eq 'HASH' ) ? shift @data : {};
      $args = _get_args( $args, qw/binmode truncate/ );
      my $binmode = $args->{binmode};
      $binmode = ( ( caller(0) )[10] || {} )->{'open>'} unless defined $binmode;
      my $mode = $args->{truncate} ? ">" : ">>";
      my $fh = $self->filehandle( { locked => 1 }, $mode, $binmode );
      print {$fh} map { ref eq 'ARRAY' ? @$_ : $_ } @data;
      close $fh or $self->_throw('close');
  }
  
  sub append_raw {
      my ( $self, @data ) = @_;
      my $args = ( @data && ref $data[0] eq 'HASH' ) ? shift @data : {};
      $args = _get_args( $args, qw/binmode truncate/ );
      $args->{binmode} = ':unix';
      append( $self, $args, @data );
  }
  
  sub append_utf8 {
      my ( $self, @data ) = @_;
      my $args = ( @data && ref $data[0] eq 'HASH' ) ? shift @data : {};
      $args = _get_args( $args, qw/binmode truncate/ );
      if ( defined($HAS_UU) ? $HAS_UU : ( $HAS_UU = _check_UU() ) ) {
          $args->{binmode} = ":unix";
          append( $self, $args, map { Unicode::UTF8::encode_utf8($_) } @data );
      }
      else {
          $args->{binmode} = ":unix:encoding(UTF-8)";
          append( $self, $args, @data );
      }
  }
  
  #pod =method assert
  #pod
  #pod     $path = path("foo.txt")->assert( sub { $_->exists } );
  #pod
  #pod Returns the invocant after asserting that a code reference argument returns
  #pod true.  When the assertion code reference runs, it will have the invocant
  #pod object in the C<$_> variable.  If it returns false, an exception will be
  #pod thrown.  The assertion code reference may also throw its own exception.
  #pod
  #pod If no assertion is provided, the invocant is returned without error.
  #pod
  #pod Current API available since 0.062.
  #pod
  #pod =cut
  
  sub assert {
      my ( $self, $assertion ) = @_;
      return $self unless $assertion;
      if ( ref $assertion eq 'CODE' ) {
          local $_ = $self;
          $assertion->()
            or Path::Tiny::Error->throw( "assert", $self->[PATH], "failed assertion" );
      }
      else {
          Carp::croak("argument to assert must be a code reference argument");
      }
      return $self;
  }
  
  #pod =method basename
  #pod
  #pod     $name = path("foo/bar.txt")->basename;        # bar.txt
  #pod     $name = path("foo.txt")->basename('.txt');    # foo
  #pod     $name = path("foo.txt")->basename(qr/.txt/);  # foo
  #pod     $name = path("foo.txt")->basename(@suffixes);
  #pod
  #pod Returns the file portion or last directory portion of a path.
  #pod
  #pod Given a list of suffixes as strings or regular expressions, any that match at
  #pod the end of the file portion or last directory portion will be removed before
  #pod the result is returned.
  #pod
  #pod Current API available since 0.054.
  #pod
  #pod =cut
  
  sub basename {
      my ( $self, @suffixes ) = @_;
      $self->_splitpath unless defined $self->[FILE];
      my $file = $self->[FILE];
      for my $s (@suffixes) {
          my $re = ref($s) eq 'Regexp' ? qr/$s$/ : qr/\Q$s\E$/;
          last if $file =~ s/$re//;
      }
      return $file;
  }
  
  #pod =method canonpath
  #pod
  #pod     $canonical = path("foo/bar")->canonpath; # foo\bar on Windows
  #pod
  #pod Returns a string with the canonical format of the path name for
  #pod the platform.  In particular, this means directory separators
  #pod will be C<\> on Windows.
  #pod
  #pod Current API available since 0.001.
  #pod
  #pod =cut
  
  sub canonpath { $_[0]->[CANON] }
  
  #pod =method child
  #pod
  #pod     $file = path("/tmp")->child("foo.txt"); # "/tmp/foo.txt"
  #pod     $file = path("/tmp")->child(@parts);
  #pod
  #pod Returns a new C<Path::Tiny> object relative to the original.  Works
  #pod like C<catfile> or C<catdir> from File::Spec, but without caring about
  #pod file or directories.
  #pod
  #pod Current API available since 0.001.
  #pod
  #pod =cut
  
  sub child {
      my ( $self, @parts ) = @_;
      return path( $self->[PATH], @parts );
  }
  
  #pod =method children
  #pod
  #pod     @paths = path("/tmp")->children;
  #pod     @paths = path("/tmp")->children( qr/\.txt$/ );
  #pod
  #pod Returns a list of C<Path::Tiny> objects for all files and directories
  #pod within a directory.  Excludes "." and ".." automatically.
  #pod
  #pod If an optional C<qr//> argument is provided, it only returns objects for child
  #pod names that match the given regular expression.  Only the base name is used
  #pod for matching:
  #pod
  #pod     @paths = path("/tmp")->children( qr/^foo/ );
  #pod     # matches children like the glob foo*
  #pod
  #pod Current API available since 0.028.
  #pod
  #pod =cut
  
  sub children {
      my ( $self, $filter ) = @_;
      my $dh;
      opendir $dh, $self->[PATH] or $self->_throw('opendir');
      my @children = readdir $dh;
      closedir $dh or $self->_throw('closedir');
  
      if ( not defined $filter ) {
          @children = grep { $_ ne '.' && $_ ne '..' } @children;
      }
      elsif ( $filter && ref($filter) eq 'Regexp' ) {
          @children = grep { $_ ne '.' && $_ ne '..' && $_ =~ $filter } @children;
      }
      else {
          Carp::croak("Invalid argument '$filter' for children()");
      }
  
      return map { path( $self->[PATH], $_ ) } @children;
  }
  
  #pod =method chmod
  #pod
  #pod     path("foo.txt")->chmod(0777);
  #pod     path("foo.txt")->chmod("0755");
  #pod     path("foo.txt")->chmod("go-w");
  #pod     path("foo.txt")->chmod("a=r,u+wx");
  #pod
  #pod Sets file or directory permissions.  The argument can be a numeric mode, a
  #pod octal string beginning with a "0" or a limited subset of the symbolic mode use
  #pod by F</bin/chmod>.
  #pod
  #pod The symbolic mode must be a comma-delimited list of mode clauses.  Clauses must
  #pod match C<< qr/\A([augo]+)([=+-])([rwx]+)\z/ >>, which defines "who", "op" and
  #pod "perms" parameters for each clause.  Unlike F</bin/chmod>, all three parameters
  #pod are required for each clause, multiple ops are not allowed and permissions
  #pod C<stugoX> are not supported.  (See L<File::chmod> for more complex needs.)
  #pod
  #pod Current API available since 0.053.
  #pod
  #pod =cut
  
  sub chmod {
      my ( $self, $new_mode ) = @_;
  
      my $mode;
      if ( $new_mode =~ /\d/ ) {
          $mode = ( $new_mode =~ /^0/ ? oct($new_mode) : $new_mode );
      }
      elsif ( $new_mode =~ /[=+-]/ ) {
          $mode = _symbolic_chmod( $self->stat->mode & 07777, $new_mode ); ## no critic
      }
      else {
          Carp::croak("Invalid mode argument '$new_mode' for chmod()");
      }
  
      CORE::chmod( $mode, $self->[PATH] ) or $self->_throw("chmod");
  
      return 1;
  }
  
  #pod =method copy
  #pod
  #pod     path("/tmp/foo.txt")->copy("/tmp/bar.txt");
  #pod
  #pod Copies the current path to the given destination using L<File::Copy>'s
  #pod C<copy> function. Upon success, returns the C<Path::Tiny> object for the
  #pod newly copied file.
  #pod
  #pod Current API available since 0.070.
  #pod
  #pod =cut
  
  # XXX do recursively for directories?
  sub copy {
      my ( $self, $dest ) = @_;
      require File::Copy;
      File::Copy::copy( $self->[PATH], $dest )
        or Carp::croak("copy failed for $self to $dest: $!");
  
      return -d $dest ? path( $dest, $self->basename ) : path($dest);
  }
  
  #pod =method digest
  #pod
  #pod     $obj = path("/tmp/foo.txt")->digest;        # SHA-256
  #pod     $obj = path("/tmp/foo.txt")->digest("MD5"); # user-selected
  #pod     $obj = path("/tmp/foo.txt")->digest( { chunk_size => 1e6 }, "MD5" );
  #pod
  #pod Returns a hexadecimal digest for a file.  An optional hash reference of options may
  #pod be given.  The only option is C<chunk_size>.  If C<chunk_size> is given, that many
  #pod bytes will be read at a time.  If not provided, the entire file will be slurped
  #pod into memory to compute the digest.
  #pod
  #pod Any subsequent arguments are passed to the constructor for L<Digest> to select
  #pod an algorithm.  If no arguments are given, the default is SHA-256.
  #pod
  #pod Current API available since 0.056.
  #pod
  #pod =cut
  
  sub digest {
      my ( $self, @opts ) = @_;
      my $args = ( @opts && ref $opts[0] eq 'HASH' ) ? shift @opts : {};
      $args = _get_args( $args, qw/chunk_size/ );
      unshift @opts, 'SHA-256' unless @opts;
      require Digest;
      my $digest = Digest->new(@opts);
      if ( $args->{chunk_size} ) {
          my $fh = $self->filehandle( { locked => 1 }, "<", ":unix" );
          my $buf;
          $digest->add($buf) while read $fh, $buf, $args->{chunk_size};
      }
      else {
          $digest->add( $self->slurp_raw );
      }
      return $digest->hexdigest;
  }
  
  #pod =method dirname (deprecated)
  #pod
  #pod     $name = path("/tmp/foo.txt")->dirname; # "/tmp/"
  #pod
  #pod Returns the directory portion you would get from calling
  #pod C<< File::Spec->splitpath( $path->stringify ) >> or C<"."> for a path without a
  #pod parent directory portion.  Because L<File::Spec> is inconsistent, the result
  #pod might or might not have a trailing slash.  Because of this, this method is
  #pod B<deprecated>.
  #pod
  #pod A better, more consistently approach is likely C<< $path->parent->stringify >>,
  #pod which will not have a trailing slash except for a root directory.
  #pod
  #pod Deprecated in 0.056.
  #pod
  #pod =cut
  
  sub dirname {
      my ($self) = @_;
      $self->_splitpath unless defined $self->[DIR];
      return length $self->[DIR] ? $self->[DIR] : ".";
  }
  
  #pod =method edit, edit_raw, edit_utf8
  #pod
  #pod     path("foo.txt")->edit( \&callback, $options );
  #pod     path("foo.txt")->edit_utf8( \&callback );
  #pod     path("foo.txt")->edit_raw( \&callback );
  #pod
  #pod These are convenience methods that allow "editing" a file using a single
  #pod callback argument. They slurp the file using C<slurp>, place the contents
  #pod inside a localized C<$_> variable, call the callback function (without
  #pod arguments), and then write C<$_> (presumably mutated) back to the
  #pod file with C<spew>.
  #pod
  #pod An optional hash reference may be used to pass options.  The only option is
  #pod C<binmode>, which is passed to C<slurp> and C<spew>.
  #pod
  #pod C<edit_utf8> and C<edit_raw> act like their respective C<slurp_*> and
  #pod C<spew_*> methods.
  #pod
  #pod Current API available since 0.077.
  #pod
  #pod =cut
  
  sub edit {
      my $self = shift;
      my $cb   = shift;
      my $args = _get_args( shift, qw/binmode/ );
      Carp::croak("Callback for edit() must be a code reference")
        unless defined($cb) && ref($cb) eq 'CODE';
  
      local $_ =
        $self->slurp( exists( $args->{binmode} ) ? { binmode => $args->{binmode} } : () );
      $cb->();
      $self->spew( $args, $_ );
  
      return;
  }
  
  # this is done long-hand to benefit from slurp_utf8 optimizations
  sub edit_utf8 {
      my ( $self, $cb ) = @_;
      Carp::croak("Callback for edit_utf8() must be a code reference")
        unless defined($cb) && ref($cb) eq 'CODE';
  
      local $_ = $self->slurp_utf8;
      $cb->();
      $self->spew_utf8($_);
  
      return;
  }
  
  sub edit_raw { $_[2] = { binmode => ":unix" }; goto &edit }
  
  #pod =method edit_lines, edit_lines_utf8, edit_lines_raw
  #pod
  #pod     path("foo.txt")->edit_lines( \&callback, $options );
  #pod     path("foo.txt")->edit_lines_utf8( \&callback );
  #pod     path("foo.txt")->edit_lines_raw( \&callback );
  #pod
  #pod These are convenience methods that allow "editing" a file's lines using a
  #pod single callback argument.  They iterate over the file: for each line, the
  #pod line is put into a localized C<$_> variable, the callback function is
  #pod executed (without arguments) and then C<$_> is written to a temporary file.
  #pod When iteration is finished, the temporary file is atomically renamed over
  #pod the original.
  #pod
  #pod An optional hash reference may be used to pass options.  The only option is
  #pod C<binmode>, which is passed to the method that open handles for reading and
  #pod writing.
  #pod
  #pod C<edit_lines_utf8> and C<edit_lines_raw> act like their respective
  #pod C<slurp_*> and C<spew_*> methods.
  #pod
  #pod Current API available since 0.077.
  #pod
  #pod =cut
  
  sub edit_lines {
      my $self = shift;
      my $cb   = shift;
      my $args = _get_args( shift, qw/binmode/ );
      Carp::croak("Callback for edit_lines() must be a code reference")
        unless defined($cb) && ref($cb) eq 'CODE';
  
      my $binmode = $args->{binmode};
      # get default binmode from caller's lexical scope (see "perldoc open")
      $binmode = ( ( caller(0) )[10] || {} )->{'open>'} unless defined $binmode;
  
      # writing need to follow the link and create the tempfile in the same
      # dir for later atomic rename
      my $resolved_path = $self->[PATH];
      $resolved_path = readlink $resolved_path while -l $resolved_path;
      my $temp = path( $resolved_path . $$ . int( rand( 2**31 ) ) );
  
      my $temp_fh = $temp->filehandle( { exclusive => 1, locked => 1 }, ">", $binmode );
      my $in_fh = $self->filehandle( { locked => 1 }, '<', $binmode );
  
      local $_;
      while (<$in_fh>) {
          $cb->();
          $temp_fh->print($_);
      }
  
      close $temp_fh or $self->_throw( 'close', $temp );
      close $in_fh or $self->_throw('close');
  
      return $temp->move($resolved_path);
  }
  
  sub edit_lines_raw { $_[2] = { binmode => ":unix" }; goto &edit_lines }
  
  sub edit_lines_utf8 {
      $_[2] = { binmode => ":raw:encoding(UTF-8)" };
      goto &edit_lines;
  }
  
  #pod =method exists, is_file, is_dir
  #pod
  #pod     if ( path("/tmp")->exists ) { ... }     # -e
  #pod     if ( path("/tmp")->is_dir ) { ... }     # -d
  #pod     if ( path("/tmp")->is_file ) { ... }    # -e && ! -d
  #pod
  #pod Implements file test operations, this means the file or directory actually has
  #pod to exist on the filesystem.  Until then, it's just a path.
  #pod
  #pod B<Note>: C<is_file> is not C<-f> because C<-f> is not the opposite of C<-d>.
  #pod C<-f> means "plain file", excluding symlinks, devices, etc. that often can be
  #pod read just like files.
  #pod
  #pod Use C<-f> instead if you really mean to check for a plain file.
  #pod
  #pod Current API available since 0.053.
  #pod
  #pod =cut
  
  sub exists { -e $_[0]->[PATH] }
  
  sub is_file { -e $_[0]->[PATH] && !-d _ }
  
  sub is_dir { -d $_[0]->[PATH] }
  
  #pod =method filehandle
  #pod
  #pod     $fh = path("/tmp/foo.txt")->filehandle($mode, $binmode);
  #pod     $fh = path("/tmp/foo.txt")->filehandle({ locked => 1 }, $mode, $binmode);
  #pod     $fh = path("/tmp/foo.txt")->filehandle({ exclusive => 1  }, $mode, $binmode);
  #pod
  #pod Returns an open file handle.  The C<$mode> argument must be a Perl-style
  #pod read/write mode string ("<" ,">", "<<", etc.).  If a C<$binmode>
  #pod is given, it is set during the C<open> call.
  #pod
  #pod An optional hash reference may be used to pass options.
  #pod
  #pod The C<locked> option governs file locking; if true, handles opened for writing,
  #pod appending or read-write are locked with C<LOCK_EX>; otherwise, they are
  #pod locked with C<LOCK_SH>.  When using C<locked>, ">" or "+>" modes will delay
  #pod truncation until after the lock is acquired.
  #pod
  #pod The C<exclusive> option causes the open() call to fail if the file already
  #pod exists.  This corresponds to the O_EXCL flag to sysopen / open(2).
  #pod C<exclusive> implies C<locked> and will set it for you if you forget it.
  #pod
  #pod See C<openr>, C<openw>, C<openrw>, and C<opena> for sugar.
  #pod
  #pod Current API available since 0.066.
  #pod
  #pod =cut
  
  # Note: must put binmode on open line, not subsequent binmode() call, so things
  # like ":unix" actually stop perlio/crlf from being added
  
  sub filehandle {
      my ( $self, @args ) = @_;
      my $args = ( @args && ref $args[0] eq 'HASH' ) ? shift @args : {};
      $args = _get_args( $args, qw/locked exclusive/ );
      $args->{locked} = 1 if $args->{exclusive};
      my ( $opentype, $binmode ) = @args;
  
      $opentype = "<" unless defined $opentype;
      Carp::croak("Invalid file mode '$opentype'")
        unless grep { $opentype eq $_ } qw/< +< > +> >> +>>/;
  
      $binmode = ( ( caller(0) )[10] || {} )->{ 'open' . substr( $opentype, -1, 1 ) }
        unless defined $binmode;
      $binmode = "" unless defined $binmode;
  
      my ( $fh, $lock, $trunc );
      if ( $HAS_FLOCK && $args->{locked} ) {
          require Fcntl;
          # truncating file modes shouldn't truncate until lock acquired
          if ( grep { $opentype eq $_ } qw( > +> ) ) {
              # sysopen in write mode without truncation
              my $flags = $opentype eq ">" ? Fcntl::O_WRONLY() : Fcntl::O_RDWR();
              $flags |= Fcntl::O_CREAT();
              $flags |= Fcntl::O_EXCL() if $args->{exclusive};
              sysopen( $fh, $self->[PATH], $flags ) or $self->_throw("sysopen");
  
              # fix up the binmode since sysopen() can't specify layers like
              # open() and binmode() can't start with just :unix like open()
              if ( $binmode =~ s/^:unix// ) {
                  # eliminate pseudo-layers
                  binmode( $fh, ":raw" ) or $self->_throw("binmode (:raw)");
                  # strip off real layers until only :unix is left
                  while ( 1 < ( my $layers =()= PerlIO::get_layers( $fh, output => 1 ) ) ) {
                      binmode( $fh, ":pop" ) or $self->_throw("binmode (:pop)");
                  }
              }
  
              # apply any remaining binmode layers
              if ( length $binmode ) {
                  binmode( $fh, $binmode ) or $self->_throw("binmode ($binmode)");
              }
  
              # ask for lock and truncation
              $lock  = Fcntl::LOCK_EX();
              $trunc = 1;
          }
          elsif ( $^O eq 'aix' && $opentype eq "<" ) {
              # AIX can only lock write handles, so upgrade to RW and LOCK_EX if
              # the file is writable; otherwise give up on locking.  N.B.
              # checking -w before open to determine the open mode is an
              # unavoidable race condition
              if ( -w $self->[PATH] ) {
                  $opentype = "+<";
                  $lock     = Fcntl::LOCK_EX();
              }
          }
          else {
              $lock = $opentype eq "<" ? Fcntl::LOCK_SH() : Fcntl::LOCK_EX();
          }
      }
  
      unless ($fh) {
          my $mode = $opentype . $binmode;
          open $fh, $mode, $self->[PATH] or $self->_throw("open ($mode)");
      }
  
      do { flock( $fh, $lock ) or $self->_throw("flock ($lock)") } if $lock;
      do { truncate( $fh, 0 ) or $self->_throw("truncate") } if $trunc;
  
      return $fh;
  }
  
  #pod =method is_absolute, is_relative
  #pod
  #pod     if ( path("/tmp")->is_absolute ) { ... }
  #pod     if ( path("/tmp")->is_relative ) { ... }
  #pod
  #pod Booleans for whether the path appears absolute or relative.
  #pod
  #pod Current API available since 0.001.
  #pod
  #pod =cut
  
  sub is_absolute { substr( $_[0]->dirname, 0, 1 ) eq '/' }
  
  sub is_relative { substr( $_[0]->dirname, 0, 1 ) ne '/' }
  
  #pod =method is_rootdir
  #pod
  #pod     while ( ! $path->is_rootdir ) {
  #pod         $path = $path->parent;
  #pod         ...
  #pod     }
  #pod
  #pod Boolean for whether the path is the root directory of the volume.  I.e. the
  #pod C<dirname> is C<q[/]> and the C<basename> is C<q[]>.
  #pod
  #pod This works even on C<MSWin32> with drives and UNC volumes:
  #pod
  #pod     path("C:/")->is_rootdir;             # true
  #pod     path("//server/share/")->is_rootdir; #true
  #pod
  #pod Current API available since 0.038.
  #pod
  #pod =cut
  
  sub is_rootdir {
      my ($self) = @_;
      $self->_splitpath unless defined $self->[DIR];
      return $self->[DIR] eq '/' && $self->[FILE] eq '';
  }
  
  #pod =method iterator
  #pod
  #pod     $iter = path("/tmp")->iterator( \%options );
  #pod
  #pod Returns a code reference that walks a directory lazily.  Each invocation
  #pod returns a C<Path::Tiny> object or undef when the iterator is exhausted.
  #pod
  #pod     $iter = path("/tmp")->iterator;
  #pod     while ( $path = $iter->() ) {
  #pod         ...
  #pod     }
  #pod
  #pod The current and parent directory entries ("." and "..") will not
  #pod be included.
  #pod
  #pod If the C<recurse> option is true, the iterator will walk the directory
  #pod recursively, breadth-first.  If the C<follow_symlinks> option is also true,
  #pod directory links will be followed recursively.  There is no protection against
  #pod loops when following links. If a directory is not readable, it will not be
  #pod followed.
  #pod
  #pod The default is the same as:
  #pod
  #pod     $iter = path("/tmp")->iterator( {
  #pod         recurse         => 0,
  #pod         follow_symlinks => 0,
  #pod     } );
  #pod
  #pod For a more powerful, recursive iterator with built-in loop avoidance, see
  #pod L<Path::Iterator::Rule>.
  #pod
  #pod See also L</visit>.
  #pod
  #pod Current API available since 0.016.
  #pod
  #pod =cut
  
  sub iterator {
      my $self = shift;
      my $args = _get_args( shift, qw/recurse follow_symlinks/ );
      my @dirs = $self;
      my $current;
      return sub {
          my $next;
          while (@dirs) {
              if ( ref $dirs[0] eq 'Path::Tiny' ) {
                  if ( !-r $dirs[0] ) {
                      # Directory is missing or not readable, so skip it.  There
                      # is still a race condition possible between the check and
                      # the opendir, but we can't easily differentiate between
                      # error cases that are OK to skip and those that we want
                      # to be exceptions, so we live with the race and let opendir
                      # be fatal.
                      shift @dirs and next;
                  }
                  $current = $dirs[0];
                  my $dh;
                  opendir( $dh, $current->[PATH] )
                    or $self->_throw( 'opendir', $current->[PATH] );
                  $dirs[0] = $dh;
                  if ( -l $current->[PATH] && !$args->{follow_symlinks} ) {
                      # Symlink attack! It was a real dir, but is now a symlink!
                      # N.B. we check *after* opendir so the attacker has to win
                      # two races: replace dir with symlink before opendir and
                      # replace symlink with dir before -l check above
                      shift @dirs and next;
                  }
              }
              while ( defined( $next = readdir $dirs[0] ) ) {
                  next if $next eq '.' || $next eq '..';
                  my $path = $current->child($next);
                  push @dirs, $path
                    if $args->{recurse} && -d $path && !( !$args->{follow_symlinks} && -l $path );
                  return $path;
              }
              shift @dirs;
          }
          return;
      };
  }
  
  #pod =method lines, lines_raw, lines_utf8
  #pod
  #pod     @contents = path("/tmp/foo.txt")->lines;
  #pod     @contents = path("/tmp/foo.txt")->lines(\%options);
  #pod     @contents = path("/tmp/foo.txt")->lines_raw;
  #pod     @contents = path("/tmp/foo.txt")->lines_utf8;
  #pod
  #pod     @contents = path("/tmp/foo.txt")->lines( { chomp => 1, count => 4 } );
  #pod
  #pod Returns a list of lines from a file.  Optionally takes a hash-reference of
  #pod options.  Valid options are C<binmode>, C<count> and C<chomp>.
  #pod
  #pod If C<binmode> is provided, it will be set on the handle prior to reading.
  #pod
  #pod If a positive C<count> is provided, that many lines will be returned from the
  #pod start of the file.  If a negative C<count> is provided, the entire file will be
  #pod read, but only C<abs(count)> will be kept and returned.  If C<abs(count)>
  #pod exceeds the number of lines in the file, all lines will be returned.
  #pod
  #pod If C<chomp> is set, any end-of-line character sequences (C<CR>, C<CRLF>, or
  #pod C<LF>) will be removed from the lines returned.
  #pod
  #pod Because the return is a list, C<lines> in scalar context will return the number
  #pod of lines (and throw away the data).
  #pod
  #pod     $number_of_lines = path("/tmp/foo.txt")->lines;
  #pod
  #pod C<lines_raw> is like C<lines> with a C<binmode> of C<:raw>.  We use C<:raw>
  #pod instead of C<:unix> so PerlIO buffering can manage reading by line.
  #pod
  #pod C<lines_utf8> is like C<lines> with a C<binmode> of
  #pod C<:raw:encoding(UTF-8)>.  If L<Unicode::UTF8> 0.58+ is installed, a raw
  #pod UTF-8 slurp will be done and then the lines will be split.  This is
  #pod actually faster than relying on C<:encoding(UTF-8)>, though a bit memory
  #pod intensive.  If memory use is a concern, consider C<openr_utf8> and
  #pod iterating directly on the handle.
  #pod
  #pod Current API available since 0.065.
  #pod
  #pod =cut
  
  sub lines {
      my $self    = shift;
      my $args    = _get_args( shift, qw/binmode chomp count/ );
      my $binmode = $args->{binmode};
      $binmode = ( ( caller(0) )[10] || {} )->{'open<'} unless defined $binmode;
      my $fh = $self->filehandle( { locked => 1 }, "<", $binmode );
      my $chomp = $args->{chomp};
      # XXX more efficient to read @lines then chomp(@lines) vs map?
      if ( $args->{count} ) {
          my ( $counter, $mod, @result ) = ( 0, abs( $args->{count} ) );
          while ( my $line = <$fh> ) {
              $line =~ s/(?:\x{0d}?\x{0a}|\x{0d})$// if $chomp;
              $result[ $counter++ ] = $line;
              # for positive count, terminate after right number of lines
              last if $counter == $args->{count};
              # for negative count, eventually wrap around in the result array
              $counter %= $mod;
          }
          # reorder results if full and wrapped somewhere in the middle
          splice( @result, 0, 0, splice( @result, $counter ) )
            if @result == $mod && $counter % $mod;
          return @result;
      }
      elsif ($chomp) {
          return map { s/(?:\x{0d}?\x{0a}|\x{0d})$//; $_ } <$fh>; ## no critic
      }
      else {
          return wantarray ? <$fh> : ( my $count =()= <$fh> );
      }
  }
  
  sub lines_raw {
      my $self = shift;
      my $args = _get_args( shift, qw/binmode chomp count/ );
      if ( $args->{chomp} && !$args->{count} ) {
          return split /\n/, slurp_raw($self);                    ## no critic
      }
      else {
          $args->{binmode} = ":raw";
          return lines( $self, $args );
      }
  }
  
  my $CRLF = qr/(?:\x{0d}?\x{0a}|\x{0d})/;
  
  sub lines_utf8 {
      my $self = shift;
      my $args = _get_args( shift, qw/binmode chomp count/ );
      if (   ( defined($HAS_UU) ? $HAS_UU : ( $HAS_UU = _check_UU() ) )
          && $args->{chomp}
          && !$args->{count} )
      {
          my $slurp = slurp_utf8($self);
          $slurp =~ s/$CRLF$//; # like chomp, but full CR?LF|CR
          return split $CRLF, $slurp, -1; ## no critic
      }
      else {
          $args->{binmode} = ":raw:encoding(UTF-8)";
          return lines( $self, $args );
      }
  }
  
  #pod =method mkpath
  #pod
  #pod     path("foo/bar/baz")->mkpath;
  #pod     path("foo/bar/baz")->mkpath( \%options );
  #pod
  #pod Like calling C<make_path> from L<File::Path>.  An optional hash reference
  #pod is passed through to C<make_path>.  Errors will be trapped and an exception
  #pod thrown.  Returns the list of directories created or an empty list if
  #pod the directories already exist, just like C<make_path>.
  #pod
  #pod Current API available since 0.001.
  #pod
  #pod =cut
  
  sub mkpath {
      my ( $self, $args ) = @_;
      $args = {} unless ref $args eq 'HASH';
      my $err;
      $args->{error} = \$err unless defined $args->{error};
      require File::Path;
      my @dirs = File::Path::make_path( $self->[PATH], $args );
      if ( $err && @$err ) {
          my ( $file, $message ) = %{ $err->[0] };
          Carp::croak("mkpath failed for $file: $message");
      }
      return @dirs;
  }
  
  #pod =method move
  #pod
  #pod     path("foo.txt")->move("bar.txt");
  #pod
  #pod Move the current path to the given destination path using Perl's
  #pod built-in L<rename|perlfunc/rename> function. Returns the result
  #pod of the C<rename> function.
  #pod
  #pod Current API available since 0.001.
  #pod
  #pod =cut
  
  sub move {
      my ( $self, $dst ) = @_;
  
      return rename( $self->[PATH], $dst )
        || $self->_throw( 'rename', $self->[PATH] . "' -> '$dst" );
  }
  
  #pod =method openr, openw, openrw, opena
  #pod
  #pod     $fh = path("foo.txt")->openr($binmode);  # read
  #pod     $fh = path("foo.txt")->openr_raw;
  #pod     $fh = path("foo.txt")->openr_utf8;
  #pod
  #pod     $fh = path("foo.txt")->openw($binmode);  # write
  #pod     $fh = path("foo.txt")->openw_raw;
  #pod     $fh = path("foo.txt")->openw_utf8;
  #pod
  #pod     $fh = path("foo.txt")->opena($binmode);  # append
  #pod     $fh = path("foo.txt")->opena_raw;
  #pod     $fh = path("foo.txt")->opena_utf8;
  #pod
  #pod     $fh = path("foo.txt")->openrw($binmode); # read/write
  #pod     $fh = path("foo.txt")->openrw_raw;
  #pod     $fh = path("foo.txt")->openrw_utf8;
  #pod
  #pod Returns a file handle opened in the specified mode.  The C<openr> style methods
  #pod take a single C<binmode> argument.  All of the C<open*> methods have
  #pod C<open*_raw> and C<open*_utf8> equivalents that use C<:raw> and
  #pod C<:raw:encoding(UTF-8)>, respectively.
  #pod
  #pod An optional hash reference may be used to pass options.  The only option is
  #pod C<locked>.  If true, handles opened for writing, appending or read-write are
  #pod locked with C<LOCK_EX>; otherwise, they are locked for C<LOCK_SH>.
  #pod
  #pod     $fh = path("foo.txt")->openrw_utf8( { locked => 1 } );
  #pod
  #pod See L</filehandle> for more on locking.
  #pod
  #pod Current API available since 0.011.
  #pod
  #pod =cut
  
  # map method names to corresponding open mode
  my %opens = (
      opena  => ">>",
      openr  => "<",
      openw  => ">",
      openrw => "+<"
  );
  
  while ( my ( $k, $v ) = each %opens ) {
      no strict 'refs';
      # must check for lexical IO mode hint
      *{$k} = sub {
          my ( $self, @args ) = @_;
          my $args = ( @args && ref $args[0] eq 'HASH' ) ? shift @args : {};
          $args = _get_args( $args, qw/locked/ );
          my ($binmode) = @args;
          $binmode = ( ( caller(0) )[10] || {} )->{ 'open' . substr( $v, -1, 1 ) }
            unless defined $binmode;
          $self->filehandle( $args, $v, $binmode );
      };
      *{ $k . "_raw" } = sub {
          my ( $self, @args ) = @_;
          my $args = ( @args && ref $args[0] eq 'HASH' ) ? shift @args : {};
          $args = _get_args( $args, qw/locked/ );
          $self->filehandle( $args, $v, ":raw" );
      };
      *{ $k . "_utf8" } = sub {
          my ( $self, @args ) = @_;
          my $args = ( @args && ref $args[0] eq 'HASH' ) ? shift @args : {};
          $args = _get_args( $args, qw/locked/ );
          $self->filehandle( $args, $v, ":raw:encoding(UTF-8)" );
      };
  }
  
  #pod =method parent
  #pod
  #pod     $parent = path("foo/bar/baz")->parent; # foo/bar
  #pod     $parent = path("foo/wibble.txt")->parent; # foo
  #pod
  #pod     $parent = path("foo/bar/baz")->parent(2); # foo
  #pod
  #pod Returns a C<Path::Tiny> object corresponding to the parent directory of the
  #pod original directory or file. An optional positive integer argument is the number
  #pod of parent directories upwards to return.  C<parent> by itself is equivalent to
  #pod C<parent(1)>.
  #pod
  #pod Current API available since 0.014.
  #pod
  #pod =cut
  
  # XXX this is ugly and coverage is incomplete.  I think it's there for windows
  # so need to check coverage there and compare
  sub parent {
      my ( $self, $level ) = @_;
      $level = 1 unless defined $level && $level > 0;
      $self->_splitpath unless defined $self->[FILE];
      my $parent;
      if ( length $self->[FILE] ) {
          if ( $self->[FILE] eq '.' || $self->[FILE] eq ".." ) {
              $parent = path( $self->[PATH] . "/.." );
          }
          else {
              $parent = path( _non_empty( $self->[VOL] . $self->[DIR] ) );
          }
      }
      elsif ( length $self->[DIR] ) {
          # because of symlinks, any internal updir requires us to
          # just add more updirs at the end
          if ( $self->[DIR] =~ m{(?:^\.\./|/\.\./|/\.\.$)} ) {
              $parent = path( $self->[VOL] . $self->[DIR] . "/.." );
          }
          else {
              ( my $dir = $self->[DIR] ) =~ s{/[^\/]+/$}{/};
              $parent = path( $self->[VOL] . $dir );
          }
      }
      else {
          $parent = path( _non_empty( $self->[VOL] ) );
      }
      return $level == 1 ? $parent : $parent->parent( $level - 1 );
  }
  
  sub _non_empty {
      my ($string) = shift;
      return ( ( defined($string) && length($string) ) ? $string : "." );
  }
  
  #pod =method realpath
  #pod
  #pod     $real = path("/baz/foo/../bar")->realpath;
  #pod     $real = path("foo/../bar")->realpath;
  #pod
  #pod Returns a new C<Path::Tiny> object with all symbolic links and upward directory
  #pod parts resolved using L<Cwd>'s C<realpath>.  Compared to C<absolute>, this is
  #pod more expensive as it must actually consult the filesystem.
  #pod
  #pod If the parent path can't be resolved (e.g. if it includes directories that
  #pod don't exist), an exception will be thrown:
  #pod
  #pod     $real = path("doesnt_exist/foo")->realpath; # dies
  #pod
  #pod However, if the parent path exists and only the last component (e.g. filename)
  #pod doesn't exist, the realpath will be the realpath of the parent plus the
  #pod non-existent last component:
  #pod
  #pod     $real = path("./aasdlfasdlf")->realpath; # works
  #pod
  #pod The underlying L<Cwd> module usually worked this way on Unix, but died on
  #pod Windows (and some Unixes) if the full path didn't exist.  As of version 0.064,
  #pod it's safe to use anywhere.
  #pod
  #pod Current API available since 0.001.
  #pod
  #pod =cut
  
  # Win32 and some Unixes need parent path resolved separately so realpath
  # doesn't throw an error resolving non-existent basename
  sub realpath {
      my $self = shift;
      while ( -l $self->[PATH] ) {
          my $resolved = readlink $self->[PATH] or $self->_throw( 'readlink', $self->[PATH] );
          $self = path($resolved);
      }
      require Cwd;
      $self->_splitpath if !defined $self->[FILE];
      my $check_parent =
        length $self->[FILE] && $self->[FILE] ne '.' && $self->[FILE] ne '..';
      my $realpath = eval {
          # pure-perl Cwd can carp
          local $SIG{__WARN__} = sub { };
          Cwd::realpath( $check_parent ? $self->parent->[PATH] : $self->[PATH] );
      };
      # parent realpath must exist; not all Cwd::realpath will error if it doesn't
      $self->_throw("resolving realpath")
        unless defined $realpath && length $realpath && -e $realpath;
      return ( $check_parent ? path( $realpath, $self->[FILE] ) : path($realpath) );
  }
  
  #pod =method relative
  #pod
  #pod     $rel = path("/tmp/foo/bar")->relative("/tmp"); # foo/bar
  #pod
  #pod Returns a C<Path::Tiny> object with a path relative to a new base path
  #pod given as an argument.  If no argument is given, the current directory will
  #pod be used as the new base path.
  #pod
  #pod If either path is already relative, it will be made absolute based on the
  #pod current directly before determining the new relative path.
  #pod
  #pod The algorithm is roughly as follows:
  #pod
  #pod =for :list
  #pod * If the original and new base path are on different volumes, an exception
  #pod   will be thrown.
  #pod * If the original and new base are identical, the relative path is C<".">.
  #pod * If the new base subsumes the original, the relative path is the original
  #pod   path with the new base chopped off the front
  #pod * If the new base does not subsume the original, a common prefix path is
  #pod   determined (possibly the root directory) and the relative path will
  #pod   consist of updirs (C<"..">) to reach the common prefix, followed by the
  #pod   original path less the common prefix.
  #pod
  #pod Unlike C<File::Spec::rel2abs>, in the last case above, the calculation based
  #pod on a common prefix takes into account symlinks that could affect the updir
  #pod process.  Given an original path "/A/B" and a new base "/A/C",
  #pod (where "A", "B" and "C" could each have multiple path components):
  #pod
  #pod =for :list
  #pod * Symlinks in "A" don't change the result unless the last component of A is
  #pod   a symlink and the first component of "C" is an updir.
  #pod * Symlinks in "B" don't change the result and will exist in the result as
  #pod   given.
  #pod * Symlinks and updirs in "C" must be resolved to actual paths, taking into
  #pod   account the possibility that not all path components might exist on the
  #pod   filesystem.
  #pod
  #pod Current API available since 0.001.  New algorithm (that accounts for
  #pod symlinks) available since 0.079.
  #pod
  #pod =cut
  
  sub relative {
      my ( $self, $base ) = @_;
      $base = path( defined $base && length $base ? $base : '.' );
  
      # relative paths must be converted to absolute first
      $self = $self->absolute if $self->is_relative;
      $base = $base->absolute if $base->is_relative;
  
      # normalize volumes if they exist
      $self = $self->absolute if !length $self->volume && length $base->volume;
      $base = $base->absolute if length $self->volume  && !length $base->volume;
  
      # can't make paths relative across volumes
      if ( !_same( $self->volume, $base->volume ) ) {
          Carp::croak("relative() can't cross volumes: '$self' vs '$base'");
      }
  
      # if same absolute path, relative is current directory
      return path(".") if _same( $self->[PATH], $base->[PATH] );
  
      # if base is a prefix of self, chop prefix off self
      if ( $base->subsumes($self) ) {
          $base = "" if $base->is_rootdir;
          my $relative = "$self";
          $relative =~ s{\A\Q$base/}{};
          return path($relative);
      }
  
      # base is not a prefix, so must find a common prefix (even if root)
      my ( @common, @self_parts, @base_parts );
      @base_parts = split /\//, $base->_just_filepath;
  
      # if self is rootdir, then common directory is root (shown as empty
      # string for later joins); otherwise, must be computed from path parts.
      if ( $self->is_rootdir ) {
          @common = ("");
          shift @base_parts;
      }
      else {
          @self_parts = split /\//, $self->_just_filepath;
  
          while ( @self_parts && @base_parts && _same( $self_parts[0], $base_parts[0] ) ) {
              push @common, shift @base_parts;
              shift @self_parts;
          }
      }
  
      # if there are any symlinks from common to base, we have a problem, as
      # you can't guarantee that updir from base reaches the common prefix;
      # we must resolve symlinks and try again; likewise, any updirs are
      # a problem as it throws off calculation of updirs needed to get from
      # self's path to the common prefix.
      if ( my $new_base = $self->_resolve_between( \@common, \@base_parts ) ) {
          return $self->relative($new_base);
      }
  
      # otherwise, symlinks in common or from common to A don't matter as
      # those don't involve updirs
      my @new_path = ( ("..") x ( 0+ @base_parts ), @self_parts );
      return path(@new_path);
  }
  
  sub _just_filepath {
      my $self     = shift;
      my $self_vol = $self->volume;
      return "$self" if !length $self_vol;
  
      ( my $self_path = "$self" ) =~ s{\A\Q$self_vol}{};
  
      return $self_path;
  }
  
  sub _resolve_between {
      my ( $self, $common, $base ) = @_;
      my $path = $self->volume . join( "/", @$common );
      my $changed = 0;
      for my $p (@$base) {
          $path .= "/$p";
          if ( $p eq '..' ) {
              $changed = 1;
              if ( -e $path ) {
                  $path = path($path)->realpath->[PATH];
              }
              else {
                  $path =~ s{/[^/]+/..$}{/};
              }
          }
          if ( -l $path ) {
              $changed = 1;
              $path    = path($path)->realpath->[PATH];
          }
      }
      return $changed ? path($path) : undef;
  }
  
  #pod =method remove
  #pod
  #pod     path("foo.txt")->remove;
  #pod
  #pod This is just like C<unlink>, except for its error handling: if the path does
  #pod not exist, it returns false; if deleting the file fails, it throws an
  #pod exception.
  #pod
  #pod Current API available since 0.012.
  #pod
  #pod =cut
  
  sub remove {
      my $self = shift;
  
      return 0 if !-e $self->[PATH] && !-l $self->[PATH];
  
      return unlink( $self->[PATH] ) || $self->_throw('unlink');
  }
  
  #pod =method remove_tree
  #pod
  #pod     # directory
  #pod     path("foo/bar/baz")->remove_tree;
  #pod     path("foo/bar/baz")->remove_tree( \%options );
  #pod     path("foo/bar/baz")->remove_tree( { safe => 0 } ); # force remove
  #pod
  #pod Like calling C<remove_tree> from L<File::Path>, but defaults to C<safe> mode.
  #pod An optional hash reference is passed through to C<remove_tree>.  Errors will be
  #pod trapped and an exception thrown.  Returns the number of directories deleted,
  #pod just like C<remove_tree>.
  #pod
  #pod If you want to remove a directory only if it is empty, use the built-in
  #pod C<rmdir> function instead.
  #pod
  #pod     rmdir path("foo/bar/baz/");
  #pod
  #pod Current API available since 0.013.
  #pod
  #pod =cut
  
  sub remove_tree {
      my ( $self, $args ) = @_;
      return 0 if !-e $self->[PATH] && !-l $self->[PATH];
      $args = {} unless ref $args eq 'HASH';
      my $err;
      $args->{error} = \$err unless defined $args->{error};
      $args->{safe}  = 1     unless defined $args->{safe};
      require File::Path;
      my $count = File::Path::remove_tree( $self->[PATH], $args );
  
      if ( $err && @$err ) {
          my ( $file, $message ) = %{ $err->[0] };
          Carp::croak("remove_tree failed for $file: $message");
      }
      return $count;
  }
  
  #pod =method sibling
  #pod
  #pod     $foo = path("/tmp/foo.txt");
  #pod     $sib = $foo->sibling("bar.txt");        # /tmp/bar.txt
  #pod     $sib = $foo->sibling("baz", "bam.txt"); # /tmp/baz/bam.txt
  #pod
  #pod Returns a new C<Path::Tiny> object relative to the parent of the original.
  #pod This is slightly more efficient than C<< $path->parent->child(...) >>.
  #pod
  #pod Current API available since 0.058.
  #pod
  #pod =cut
  
  sub sibling {
      my $self = shift;
      return path( $self->parent->[PATH], @_ );
  }
  
  #pod =method slurp, slurp_raw, slurp_utf8
  #pod
  #pod     $data = path("foo.txt")->slurp;
  #pod     $data = path("foo.txt")->slurp( {binmode => ":raw"} );
  #pod     $data = path("foo.txt")->slurp_raw;
  #pod     $data = path("foo.txt")->slurp_utf8;
  #pod
  #pod Reads file contents into a scalar.  Takes an optional hash reference which may
  #pod be used to pass options.  The only available option is C<binmode>, which is
  #pod passed to C<binmode()> on the handle used for reading.
  #pod
  #pod C<slurp_raw> is like C<slurp> with a C<binmode> of C<:unix> for
  #pod a fast, unbuffered, raw read.
  #pod
  #pod C<slurp_utf8> is like C<slurp> with a C<binmode> of
  #pod C<:unix:encoding(UTF-8)>.  If L<Unicode::UTF8> 0.58+ is installed, a raw
  #pod slurp will be done instead and the result decoded with C<Unicode::UTF8>.
  #pod This is just as strict and is roughly an order of magnitude faster than
  #pod using C<:encoding(UTF-8)>.
  #pod
  #pod B<Note>: C<slurp> and friends lock the filehandle before slurping.  If
  #pod you plan to slurp from a file created with L<File::Temp>, be sure to
  #pod close other handles or open without locking to avoid a deadlock:
  #pod
  #pod     my $tempfile = File::Temp->new(EXLOCK => 0);
  #pod     my $guts = path($tempfile)->slurp;
  #pod
  #pod Current API available since 0.004.
  #pod
  #pod =cut
  
  sub slurp {
      my $self    = shift;
      my $args    = _get_args( shift, qw/binmode/ );
      my $binmode = $args->{binmode};
      $binmode = ( ( caller(0) )[10] || {} )->{'open<'} unless defined $binmode;
      my $fh = $self->filehandle( { locked => 1 }, "<", $binmode );
      if ( ( defined($binmode) ? $binmode : "" ) eq ":unix"
          and my $size = -s $fh )
      {
          my $buf;
          read $fh, $buf, $size; # File::Slurp in a nutshell
          return $buf;
      }
      else {
          local $/;
          return scalar <$fh>;
      }
  }
  
  sub slurp_raw { $_[1] = { binmode => ":unix" }; goto &slurp }
  
  sub slurp_utf8 {
      if ( defined($HAS_UU) ? $HAS_UU : ( $HAS_UU = _check_UU() ) ) {
          return Unicode::UTF8::decode_utf8( slurp( $_[0], { binmode => ":unix" } ) );
      }
      else {
          $_[1] = { binmode => ":raw:encoding(UTF-8)" };
          goto &slurp;
      }
  }
  
  #pod =method spew, spew_raw, spew_utf8
  #pod
  #pod     path("foo.txt")->spew(@data);
  #pod     path("foo.txt")->spew(\@data);
  #pod     path("foo.txt")->spew({binmode => ":raw"}, @data);
  #pod     path("foo.txt")->spew_raw(@data);
  #pod     path("foo.txt")->spew_utf8(@data);
  #pod
  #pod Writes data to a file atomically.  The file is written to a temporary file in
  #pod the same directory, then renamed over the original.  An optional hash reference
  #pod may be used to pass options.  The only option is C<binmode>, which is passed to
  #pod C<binmode()> on the handle used for writing.
  #pod
  #pod C<spew_raw> is like C<spew> with a C<binmode> of C<:unix> for a fast,
  #pod unbuffered, raw write.
  #pod
  #pod C<spew_utf8> is like C<spew> with a C<binmode> of C<:unix:encoding(UTF-8)>.
  #pod If L<Unicode::UTF8> 0.58+ is installed, a raw spew will be done instead on
  #pod the data encoded with C<Unicode::UTF8>.
  #pod
  #pod B<NOTE>: because the file is written to a temporary file and then renamed, the
  #pod new file will wind up with permissions based on your current umask.  This is a
  #pod feature to protect you from a race condition that would otherwise give
  #pod different permissions than you might expect.  If you really want to keep the
  #pod original mode flags, use L</append> with the C<truncate> option.
  #pod
  #pod Current API available since 0.011.
  #pod
  #pod =cut
  
  # XXX add "unsafe" option to disable flocking and atomic?  Check benchmarks on append() first.
  sub spew {
      my ( $self, @data ) = @_;
      my $args = ( @data && ref $data[0] eq 'HASH' ) ? shift @data : {};
      $args = _get_args( $args, qw/binmode/ );
      my $binmode = $args->{binmode};
      # get default binmode from caller's lexical scope (see "perldoc open")
      $binmode = ( ( caller(0) )[10] || {} )->{'open>'} unless defined $binmode;
  
      # spewing need to follow the link
      # and create the tempfile in the same dir
      my $resolved_path = $self->[PATH];
      $resolved_path = readlink $resolved_path while -l $resolved_path;
  
      my $temp = path( $resolved_path . $$ . int( rand( 2**31 ) ) );
      my $fh = $temp->filehandle( { exclusive => 1, locked => 1 }, ">", $binmode );
      print {$fh} map { ref eq 'ARRAY' ? @$_ : $_ } @data;
      close $fh or $self->_throw( 'close', $temp->[PATH] );
  
      return $temp->move($resolved_path);
  }
  
  sub spew_raw { splice @_, 1, 0, { binmode => ":unix" }; goto &spew }
  
  sub spew_utf8 {
      if ( defined($HAS_UU) ? $HAS_UU : ( $HAS_UU = _check_UU() ) ) {
          my $self = shift;
          spew( $self, { binmode => ":unix" }, map { Unicode::UTF8::encode_utf8($_) } @_ );
      }
      else {
          splice @_, 1, 0, { binmode => ":unix:encoding(UTF-8)" };
          goto &spew;
      }
  }
  
  #pod =method stat, lstat
  #pod
  #pod     $stat = path("foo.txt")->stat;
  #pod     $stat = path("/some/symlink")->lstat;
  #pod
  #pod Like calling C<stat> or C<lstat> from L<File::stat>.
  #pod
  #pod Current API available since 0.001.
  #pod
  #pod =cut
  
  # XXX break out individual stat() components as subs?
  sub stat {
      my $self = shift;
      require File::stat;
      return File::stat::stat( $self->[PATH] ) || $self->_throw('stat');
  }
  
  sub lstat {
      my $self = shift;
      require File::stat;
      return File::stat::lstat( $self->[PATH] ) || $self->_throw('lstat');
  }
  
  #pod =method stringify
  #pod
  #pod     $path = path("foo.txt");
  #pod     say $path->stringify; # same as "$path"
  #pod
  #pod Returns a string representation of the path.  Unlike C<canonpath>, this method
  #pod returns the path standardized with Unix-style C</> directory separators.
  #pod
  #pod Current API available since 0.001.
  #pod
  #pod =cut
  
  sub stringify { $_[0]->[PATH] }
  
  #pod =method subsumes
  #pod
  #pod     path("foo/bar")->subsumes("foo/bar/baz"); # true
  #pod     path("/foo/bar")->subsumes("/foo/baz");   # false
  #pod
  #pod Returns true if the first path is a prefix of the second path at a directory
  #pod boundary.
  #pod
  #pod This B<does not> resolve parent directory entries (C<..>) or symlinks:
  #pod
  #pod     path("foo/bar")->subsumes("foo/bar/../baz"); # true
  #pod
  #pod If such things are important to you, ensure that both paths are resolved to
  #pod the filesystem with C<realpath>:
  #pod
  #pod     my $p1 = path("foo/bar")->realpath;
  #pod     my $p2 = path("foo/bar/../baz")->realpath;
  #pod     if ( $p1->subsumes($p2) ) { ... }
  #pod
  #pod Current API available since 0.048.
  #pod
  #pod =cut
  
  sub subsumes {
      my $self = shift;
      Carp::croak("subsumes() requires a defined, positive-length argument")
        unless defined $_[0];
      my $other = path(shift);
  
      # normalize absolute vs relative
      if ( $self->is_absolute && !$other->is_absolute ) {
          $other = $other->absolute;
      }
      elsif ( $other->is_absolute && !$self->is_absolute ) {
          $self = $self->absolute;
      }
  
      # normalize volume vs non-volume; do this after absolute path
      # adjustments above since that might add volumes already
      if ( length $self->volume && !length $other->volume ) {
          $other = $other->absolute;
      }
      elsif ( length $other->volume && !length $self->volume ) {
          $self = $self->absolute;
      }
  
      if ( $self->[PATH] eq '.' ) {
          return !!1; # cwd subsumes everything relative
      }
      elsif ( $self->is_rootdir ) {
          # a root directory ("/", "c:/") already ends with a separator
          return $other->[PATH] =~ m{^\Q$self->[PATH]\E};
      }
      else {
          # exact match or prefix breaking at a separator
          return $other->[PATH] =~ m{^\Q$self->[PATH]\E(?:/|$)};
      }
  }
  
  #pod =method touch
  #pod
  #pod     path("foo.txt")->touch;
  #pod     path("foo.txt")->touch($epoch_secs);
  #pod
  #pod Like the Unix C<touch> utility.  Creates the file if it doesn't exist, or else
  #pod changes the modification and access times to the current time.  If the first
  #pod argument is the epoch seconds then it will be used.
  #pod
  #pod Returns the path object so it can be easily chained with other methods:
  #pod
  #pod     # won't die if foo.txt doesn't exist
  #pod     $content = path("foo.txt")->touch->slurp;
  #pod
  #pod Current API available since 0.015.
  #pod
  #pod =cut
  
  sub touch {
      my ( $self, $epoch ) = @_;
      if ( !-e $self->[PATH] ) {
          my $fh = $self->openw;
          close $fh or $self->_throw('close');
      }
      $epoch = defined($epoch) ? $epoch : time();
      utime $epoch, $epoch, $self->[PATH]
        or $self->_throw("utime ($epoch)");
      return $self;
  }
  
  #pod =method touchpath
  #pod
  #pod     path("bar/baz/foo.txt")->touchpath;
  #pod
  #pod Combines C<mkpath> and C<touch>.  Creates the parent directory if it doesn't exist,
  #pod before touching the file.  Returns the path object like C<touch> does.
  #pod
  #pod Current API available since 0.022.
  #pod
  #pod =cut
  
  sub touchpath {
      my ($self) = @_;
      my $parent = $self->parent;
      $parent->mkpath unless $parent->exists;
      $self->touch;
  }
  
  #pod =method visit
  #pod
  #pod     path("/tmp")->visit( \&callback, \%options );
  #pod
  #pod Wraps the L</iterator> method to execute a callback for each directory entry.
  #pod It returns a hash reference with any state accumulated during
  #pod iteration.
  #pod
  #pod The options are the same as for L</iterator>: C<recurse> and
  #pod C<follow_symlinks>.  Both default to false.
  #pod
  #pod The callback function will receive a C<Path::Tiny> object as the first argument
  #pod and a hash reference to accumulate state as the second argument.  For example:
  #pod
  #pod     # collect files sizes
  #pod     my $sizes = path("/tmp")->visit(
  #pod         sub {
  #pod             my ($path, $state) = @_;
  #pod             return if $path->is_dir;
  #pod             $state->{$path} = -s $path;
  #pod         },
  #pod         { recurse => 1 }
  #pod     );
  #pod
  #pod For convenience, the C<Path::Tiny> object will also be locally aliased as the
  #pod C<$_> global variable:
  #pod
  #pod     # print paths matching /foo/
  #pod     path("/tmp")->visit( sub { say if /foo/ }, { recurse => 1} );
  #pod
  #pod If the callback returns a B<reference> to a false scalar value, iteration will
  #pod terminate.  This is not the same as "pruning" a directory search; this just
  #pod stops all iteration and returns the state hash reference.
  #pod
  #pod     # find up to 10 files larger than 100K
  #pod     my $files = path("/tmp")->visit(
  #pod         sub {
  #pod             my ($path, $state) = @_;
  #pod             $state->{$path}++ if -s $path > 102400
  #pod             return \0 if keys %$state == 10;
  #pod         },
  #pod         { recurse => 1 }
  #pod     );
  #pod
  #pod If you want more flexible iteration, use a module like L<Path::Iterator::Rule>.
  #pod
  #pod Current API available since 0.062.
  #pod
  #pod =cut
  
  sub visit {
      my $self = shift;
      my $cb   = shift;
      my $args = _get_args( shift, qw/recurse follow_symlinks/ );
      Carp::croak("Callback for visit() must be a code reference")
        unless defined($cb) && ref($cb) eq 'CODE';
      my $next  = $self->iterator($args);
      my $state = {};
      while ( my $file = $next->() ) {
          local $_ = $file;
          my $r = $cb->( $file, $state );
          last if ref($r) eq 'SCALAR' && !$$r;
      }
      return $state;
  }
  
  #pod =method volume
  #pod
  #pod     $vol = path("/tmp/foo.txt")->volume;   # ""
  #pod     $vol = path("C:/tmp/foo.txt")->volume; # "C:"
  #pod
  #pod Returns the volume portion of the path.  This is equivalent
  #pod to what L<File::Spec> would give from C<splitpath> and thus
  #pod usually is the empty string on Unix-like operating systems or the
  #pod drive letter for an absolute path on C<MSWin32>.
  #pod
  #pod Current API available since 0.001.
  #pod
  #pod =cut
  
  sub volume {
      my ($self) = @_;
      $self->_splitpath unless defined $self->[VOL];
      return $self->[VOL];
  }
  
  package Path::Tiny::Error;
  
  our @CARP_NOT = qw/Path::Tiny/;
  
  use overload ( q{""} => sub { (shift)->{msg} }, fallback => 1 );
  
  sub throw {
      my ( $class, $op, $file, $err ) = @_;
      chomp( my $trace = Carp::shortmess );
      my $msg = "Error $op on '$file': $err$trace\n";
      die bless { op => $op, file => $file, err => $err, msg => $msg }, $class;
  }
  
  1;
  
  
  # vim: ts=4 sts=4 sw=4 et:
  
  __END__
  
  =pod
  
  =encoding UTF-8
  
  =head1 NAME
  
  Path::Tiny - File path utility
  
  =head1 VERSION
  
  version 0.086
  
  =head1 SYNOPSIS
  
    use Path::Tiny;
  
    # creating Path::Tiny objects
  
    $dir = path("/tmp");
    $foo = path("foo.txt");
  
    $subdir = $dir->child("foo");
    $bar = $subdir->child("bar.txt");
  
    # stringifies as cleaned up path
  
    $file = path("./foo.txt");
    print $file; # "foo.txt"
  
    # reading files
  
    $guts = $file->slurp;
    $guts = $file->slurp_utf8;
  
    @lines = $file->lines;
    @lines = $file->lines_utf8;
  
    ($head) = $file->lines( {count => 1} );
    ($tail) = $file->lines( {count => -1} );
  
    # writing files
  
    $bar->spew( @data );
    $bar->spew_utf8( @data );
  
    # reading directories
  
    for ( $dir->children ) { ... }
  
    $iter = $dir->iterator;
    while ( my $next = $iter->() ) { ... }
  
  =head1 DESCRIPTION
  
  This module provides a small, fast utility for working with file paths.  It is
  friendlier to use than L<File::Spec> and provides easy access to functions from
  several other core file handling modules.  It aims to be smaller and faster
  than many alternatives on CPAN, while helping people do many common things in
  consistent and less error-prone ways.
  
  Path::Tiny does not try to work for anything except Unix-like and Win32
  platforms.  Even then, it might break if you try something particularly obscure
  or tortuous.  (Quick!  What does this mean:
  C<< ///../../..//./././a//b/.././c/././ >>?  And how does it differ on Win32?)
  
  All paths are forced to have Unix-style forward slashes.  Stringifying
  the object gives you back the path (after some clean up).
  
  File input/output methods C<flock> handles before reading or writing,
  as appropriate (if supported by the platform).
  
  The C<*_utf8> methods (C<slurp_utf8>, C<lines_utf8>, etc.) operate in raw mode.
  On Windows, that means they will not have CRLF translation from the C<:crlf> IO
  layer.  Installing L<Unicode::UTF8> 0.58 or later will speed up C<*_utf8>
  situations in many cases and is highly recommended.
  
  This module depends heavily on PerlIO layers for correct operation and thus
  requires Perl 5.008001 or later.
  
  =head1 CONSTRUCTORS
  
  =head2 path
  
      $path = path("foo/bar");
      $path = path("/tmp", "file.txt"); # list
      $path = path(".");                # cwd
      $path = path("~user/file.txt");   # tilde processing
  
  Constructs a C<Path::Tiny> object.  It doesn't matter if you give a file or
  directory path.  It's still up to you to call directory-like methods only on
  directories and file-like methods only on files.  This function is exported
  automatically by default.
  
  The first argument must be defined and have non-zero length or an exception
  will be thrown.  This prevents subtle, dangerous errors with code like
  C<< path( maybe_undef() )->remove_tree >>.
  
  If the first component of the path is a tilde ('~') then the component will be
  replaced with the output of C<glob('~')>.  If the first component of the path
  is a tilde followed by a user name then the component will be replaced with
  output of C<glob('~username')>.  Behaviour for non-existent users depends on
  the output of C<glob> on the system.
  
  On Windows, if the path consists of a drive identifier without a path component
  (C<C:> or C<D:>), it will be expanded to the absolute path of the current
  directory on that volume using C<Cwd::getdcwd()>.
  
  If called with a single C<Path::Tiny> argument, the original is returned unless
  the original is holding a temporary file or directory reference in which case a
  stringified copy is made.
  
      $path = path("foo/bar");
      $temp = Path::Tiny->tempfile;
  
      $p2 = path($path); # like $p2 = $path
      $t2 = path($temp); # like $t2 = path( "$temp" )
  
  This optimizes copies without proliferating references unexpectedly if a copy is
  made by code outside your control.
  
  Current API available since 0.017.
  
  =head2 new
  
      $path = Path::Tiny->new("foo/bar");
  
  This is just like C<path>, but with method call overhead.  (Why would you
  do that?)
  
  Current API available since 0.001.
  
  =head2 cwd
  
      $path = Path::Tiny->cwd; # path( Cwd::getcwd )
      $path = cwd; # optional export
  
  Gives you the absolute path to the current directory as a C<Path::Tiny> object.
  This is slightly faster than C<< path(".")->absolute >>.
  
  C<cwd> may be exported on request and used as a function instead of as a
  method.
  
  Current API available since 0.018.
  
  =head2 rootdir
  
      $path = Path::Tiny->rootdir; # /
      $path = rootdir;             # optional export 
  
  Gives you C<< File::Spec->rootdir >> as a C<Path::Tiny> object if you're too
  picky for C<path("/")>.
  
  C<rootdir> may be exported on request and used as a function instead of as a
  method.
  
  Current API available since 0.018.
  
  =head2 tempfile, tempdir
  
      $temp = Path::Tiny->tempfile( @options );
      $temp = Path::Tiny->tempdir( @options );
      $temp = tempfile( @options ); # optional export
      $temp = tempdir( @options );  # optional export
  
  C<tempfile> passes the options to C<< File::Temp->new >> and returns a C<Path::Tiny>
  object with the file name.  The C<TMPDIR> option is enabled by default.
  
  The resulting C<File::Temp> object is cached. When the C<Path::Tiny> object is
  destroyed, the C<File::Temp> object will be as well.
  
  C<File::Temp> annoyingly requires you to specify a custom template in slightly
  different ways depending on which function or method you call, but
  C<Path::Tiny> lets you ignore that and can take either a leading template or a
  C<TEMPLATE> option and does the right thing.
  
      $temp = Path::Tiny->tempfile( "customXXXXXXXX" );             # ok
      $temp = Path::Tiny->tempfile( TEMPLATE => "customXXXXXXXX" ); # ok
  
  The tempfile path object will be normalized to have an absolute path, even if
  created in a relative directory using C<DIR>.
  
  C<tempdir> is just like C<tempfile>, except it calls
  C<< File::Temp->newdir >> instead.
  
  Both C<tempfile> and C<tempdir> may be exported on request and used as
  functions instead of as methods.
  
  B<Note>: for tempfiles, the filehandles from File::Temp are closed and not
  reused.  This is not as secure as using File::Temp handles directly, but is
  less prone to deadlocks or access problems on some platforms.  Think of what
  C<Path::Tiny> gives you to be just a temporary file B<name> that gets cleaned
  up.
  
  B<Note 2>: if you don't want these cleaned up automatically when the object
  is destroyed, File::Temp requires different options for directories and
  files.  Use C<< CLEANUP => 0 >> for directories and C<< UNLINK => 0 >> for
  files.
  
  Current API available since 0.018.
  
  =head1 METHODS
  
  =head2 absolute
  
      $abs = path("foo/bar")->absolute;
      $abs = path("foo/bar")->absolute("/tmp");
  
  Returns a new C<Path::Tiny> object with an absolute path (or itself if already
  absolute).  Unless an argument is given, the current directory is used as the
  absolute base path.  The argument must be absolute or you won't get an absolute
  result.
  
  This will not resolve upward directories ("foo/../bar") unless C<canonpath>
  in L<File::Spec> would normally do so on your platform.  If you need them
  resolved, you must call the more expensive C<realpath> method instead.
  
  On Windows, an absolute path without a volume component will have it added
  based on the current drive.
  
  Current API available since 0.001.
  
  =head2 append, append_raw, append_utf8
  
      path("foo.txt")->append(@data);
      path("foo.txt")->append(\@data);
      path("foo.txt")->append({binmode => ":raw"}, @data);
      path("foo.txt")->append_raw(@data);
      path("foo.txt")->append_utf8(@data);
  
  Appends data to a file.  The file is locked with C<flock> prior to writing.  An
  optional hash reference may be used to pass options.  Valid options are:
  
  =over 4
  
  =item *
  
  C<binmode>: passed to C<binmode()> on the handle used for writing.
  
  =item *
  
  C<truncate>: truncates the file after locking and before appending
  
  =back
  
  The C<truncate> option is a way to replace the contents of a file
  B<in place>, unlike L</spew> which writes to a temporary file and then
  replaces the original (if it exists).
  
  C<append_raw> is like C<append> with a C<binmode> of C<:unix> for fast,
  unbuffered, raw write.
  
  C<append_utf8> is like C<append> with a C<binmode> of
  C<:unix:encoding(UTF-8)>.  If L<Unicode::UTF8> 0.58+ is installed, a raw
  append will be done instead on the data encoded with C<Unicode::UTF8>.
  
  Current API available since 0.060.
  
  =head2 assert
  
      $path = path("foo.txt")->assert( sub { $_->exists } );
  
  Returns the invocant after asserting that a code reference argument returns
  true.  When the assertion code reference runs, it will have the invocant
  object in the C<$_> variable.  If it returns false, an exception will be
  thrown.  The assertion code reference may also throw its own exception.
  
  If no assertion is provided, the invocant is returned without error.
  
  Current API available since 0.062.
  
  =head2 basename
  
      $name = path("foo/bar.txt")->basename;        # bar.txt
      $name = path("foo.txt")->basename('.txt');    # foo
      $name = path("foo.txt")->basename(qr/.txt/);  # foo
      $name = path("foo.txt")->basename(@suffixes);
  
  Returns the file portion or last directory portion of a path.
  
  Given a list of suffixes as strings or regular expressions, any that match at
  the end of the file portion or last directory portion will be removed before
  the result is returned.
  
  Current API available since 0.054.
  
  =head2 canonpath
  
      $canonical = path("foo/bar")->canonpath; # foo\bar on Windows
  
  Returns a string with the canonical format of the path name for
  the platform.  In particular, this means directory separators
  will be C<\> on Windows.
  
  Current API available since 0.001.
  
  =head2 child
  
      $file = path("/tmp")->child("foo.txt"); # "/tmp/foo.txt"
      $file = path("/tmp")->child(@parts);
  
  Returns a new C<Path::Tiny> object relative to the original.  Works
  like C<catfile> or C<catdir> from File::Spec, but without caring about
  file or directories.
  
  Current API available since 0.001.
  
  =head2 children
  
      @paths = path("/tmp")->children;
      @paths = path("/tmp")->children( qr/\.txt$/ );
  
  Returns a list of C<Path::Tiny> objects for all files and directories
  within a directory.  Excludes "." and ".." automatically.
  
  If an optional C<qr//> argument is provided, it only returns objects for child
  names that match the given regular expression.  Only the base name is used
  for matching:
  
      @paths = path("/tmp")->children( qr/^foo/ );
      # matches children like the glob foo*
  
  Current API available since 0.028.
  
  =head2 chmod
  
      path("foo.txt")->chmod(0777);
      path("foo.txt")->chmod("0755");
      path("foo.txt")->chmod("go-w");
      path("foo.txt")->chmod("a=r,u+wx");
  
  Sets file or directory permissions.  The argument can be a numeric mode, a
  octal string beginning with a "0" or a limited subset of the symbolic mode use
  by F</bin/chmod>.
  
  The symbolic mode must be a comma-delimited list of mode clauses.  Clauses must
  match C<< qr/\A([augo]+)([=+-])([rwx]+)\z/ >>, which defines "who", "op" and
  "perms" parameters for each clause.  Unlike F</bin/chmod>, all three parameters
  are required for each clause, multiple ops are not allowed and permissions
  C<stugoX> are not supported.  (See L<File::chmod> for more complex needs.)
  
  Current API available since 0.053.
  
  =head2 copy
  
      path("/tmp/foo.txt")->copy("/tmp/bar.txt");
  
  Copies the current path to the given destination using L<File::Copy>'s
  C<copy> function. Upon success, returns the C<Path::Tiny> object for the
  newly copied file.
  
  Current API available since 0.070.
  
  =head2 digest
  
      $obj = path("/tmp/foo.txt")->digest;        # SHA-256
      $obj = path("/tmp/foo.txt")->digest("MD5"); # user-selected
      $obj = path("/tmp/foo.txt")->digest( { chunk_size => 1e6 }, "MD5" );
  
  Returns a hexadecimal digest for a file.  An optional hash reference of options may
  be given.  The only option is C<chunk_size>.  If C<chunk_size> is given, that many
  bytes will be read at a time.  If not provided, the entire file will be slurped
  into memory to compute the digest.
  
  Any subsequent arguments are passed to the constructor for L<Digest> to select
  an algorithm.  If no arguments are given, the default is SHA-256.
  
  Current API available since 0.056.
  
  =head2 dirname (deprecated)
  
      $name = path("/tmp/foo.txt")->dirname; # "/tmp/"
  
  Returns the directory portion you would get from calling
  C<< File::Spec->splitpath( $path->stringify ) >> or C<"."> for a path without a
  parent directory portion.  Because L<File::Spec> is inconsistent, the result
  might or might not have a trailing slash.  Because of this, this method is
  B<deprecated>.
  
  A better, more consistently approach is likely C<< $path->parent->stringify >>,
  which will not have a trailing slash except for a root directory.
  
  Deprecated in 0.056.
  
  =head2 edit, edit_raw, edit_utf8
  
      path("foo.txt")->edit( \&callback, $options );
      path("foo.txt")->edit_utf8( \&callback );
      path("foo.txt")->edit_raw( \&callback );
  
  These are convenience methods that allow "editing" a file using a single
  callback argument. They slurp the file using C<slurp>, place the contents
  inside a localized C<$_> variable, call the callback function (without
  arguments), and then write C<$_> (presumably mutated) back to the
  file with C<spew>.
  
  An optional hash reference may be used to pass options.  The only option is
  C<binmode>, which is passed to C<slurp> and C<spew>.
  
  C<edit_utf8> and C<edit_raw> act like their respective C<slurp_*> and
  C<spew_*> methods.
  
  Current API available since 0.077.
  
  =head2 edit_lines, edit_lines_utf8, edit_lines_raw
  
      path("foo.txt")->edit_lines( \&callback, $options );
      path("foo.txt")->edit_lines_utf8( \&callback );
      path("foo.txt")->edit_lines_raw( \&callback );
  
  These are convenience methods that allow "editing" a file's lines using a
  single callback argument.  They iterate over the file: for each line, the
  line is put into a localized C<$_> variable, the callback function is
  executed (without arguments) and then C<$_> is written to a temporary file.
  When iteration is finished, the temporary file is atomically renamed over
  the original.
  
  An optional hash reference may be used to pass options.  The only option is
  C<binmode>, which is passed to the method that open handles for reading and
  writing.
  
  C<edit_lines_utf8> and C<edit_lines_raw> act like their respective
  C<slurp_*> and C<spew_*> methods.
  
  Current API available since 0.077.
  
  =head2 exists, is_file, is_dir
  
      if ( path("/tmp")->exists ) { ... }     # -e
      if ( path("/tmp")->is_dir ) { ... }     # -d
      if ( path("/tmp")->is_file ) { ... }    # -e && ! -d
  
  Implements file test operations, this means the file or directory actually has
  to exist on the filesystem.  Until then, it's just a path.
  
  B<Note>: C<is_file> is not C<-f> because C<-f> is not the opposite of C<-d>.
  C<-f> means "plain file", excluding symlinks, devices, etc. that often can be
  read just like files.
  
  Use C<-f> instead if you really mean to check for a plain file.
  
  Current API available since 0.053.
  
  =head2 filehandle
  
      $fh = path("/tmp/foo.txt")->filehandle($mode, $binmode);
      $fh = path("/tmp/foo.txt")->filehandle({ locked => 1 }, $mode, $binmode);
      $fh = path("/tmp/foo.txt")->filehandle({ exclusive => 1  }, $mode, $binmode);
  
  Returns an open file handle.  The C<$mode> argument must be a Perl-style
  read/write mode string ("<" ,">", "<<", etc.).  If a C<$binmode>
  is given, it is set during the C<open> call.
  
  An optional hash reference may be used to pass options.
  
  The C<locked> option governs file locking; if true, handles opened for writing,
  appending or read-write are locked with C<LOCK_EX>; otherwise, they are
  locked with C<LOCK_SH>.  When using C<locked>, ">" or "+>" modes will delay
  truncation until after the lock is acquired.
  
  The C<exclusive> option causes the open() call to fail if the file already
  exists.  This corresponds to the O_EXCL flag to sysopen / open(2).
  C<exclusive> implies C<locked> and will set it for you if you forget it.
  
  See C<openr>, C<openw>, C<openrw>, and C<opena> for sugar.
  
  Current API available since 0.066.
  
  =head2 is_absolute, is_relative
  
      if ( path("/tmp")->is_absolute ) { ... }
      if ( path("/tmp")->is_relative ) { ... }
  
  Booleans for whether the path appears absolute or relative.
  
  Current API available since 0.001.
  
  =head2 is_rootdir
  
      while ( ! $path->is_rootdir ) {
          $path = $path->parent;
          ...
      }
  
  Boolean for whether the path is the root directory of the volume.  I.e. the
  C<dirname> is C<q[/]> and the C<basename> is C<q[]>.
  
  This works even on C<MSWin32> with drives and UNC volumes:
  
      path("C:/")->is_rootdir;             # true
      path("//server/share/")->is_rootdir; #true
  
  Current API available since 0.038.
  
  =head2 iterator
  
      $iter = path("/tmp")->iterator( \%options );
  
  Returns a code reference that walks a directory lazily.  Each invocation
  returns a C<Path::Tiny> object or undef when the iterator is exhausted.
  
      $iter = path("/tmp")->iterator;
      while ( $path = $iter->() ) {
          ...
      }
  
  The current and parent directory entries ("." and "..") will not
  be included.
  
  If the C<recurse> option is true, the iterator will walk the directory
  recursively, breadth-first.  If the C<follow_symlinks> option is also true,
  directory links will be followed recursively.  There is no protection against
  loops when following links. If a directory is not readable, it will not be
  followed.
  
  The default is the same as:
  
      $iter = path("/tmp")->iterator( {
          recurse         => 0,
          follow_symlinks => 0,
      } );
  
  For a more powerful, recursive iterator with built-in loop avoidance, see
  L<Path::Iterator::Rule>.
  
  See also L</visit>.
  
  Current API available since 0.016.
  
  =head2 lines, lines_raw, lines_utf8
  
      @contents = path("/tmp/foo.txt")->lines;
      @contents = path("/tmp/foo.txt")->lines(\%options);
      @contents = path("/tmp/foo.txt")->lines_raw;
      @contents = path("/tmp/foo.txt")->lines_utf8;
  
      @contents = path("/tmp/foo.txt")->lines( { chomp => 1, count => 4 } );
  
  Returns a list of lines from a file.  Optionally takes a hash-reference of
  options.  Valid options are C<binmode>, C<count> and C<chomp>.
  
  If C<binmode> is provided, it will be set on the handle prior to reading.
  
  If a positive C<count> is provided, that many lines will be returned from the
  start of the file.  If a negative C<count> is provided, the entire file will be
  read, but only C<abs(count)> will be kept and returned.  If C<abs(count)>
  exceeds the number of lines in the file, all lines will be returned.
  
  If C<chomp> is set, any end-of-line character sequences (C<CR>, C<CRLF>, or
  C<LF>) will be removed from the lines returned.
  
  Because the return is a list, C<lines> in scalar context will return the number
  of lines (and throw away the data).
  
      $number_of_lines = path("/tmp/foo.txt")->lines;
  
  C<lines_raw> is like C<lines> with a C<binmode> of C<:raw>.  We use C<:raw>
  instead of C<:unix> so PerlIO buffering can manage reading by line.
  
  C<lines_utf8> is like C<lines> with a C<binmode> of
  C<:raw:encoding(UTF-8)>.  If L<Unicode::UTF8> 0.58+ is installed, a raw
  UTF-8 slurp will be done and then the lines will be split.  This is
  actually faster than relying on C<:encoding(UTF-8)>, though a bit memory
  intensive.  If memory use is a concern, consider C<openr_utf8> and
  iterating directly on the handle.
  
  Current API available since 0.065.
  
  =head2 mkpath
  
      path("foo/bar/baz")->mkpath;
      path("foo/bar/baz")->mkpath( \%options );
  
  Like calling C<make_path> from L<File::Path>.  An optional hash reference
  is passed through to C<make_path>.  Errors will be trapped and an exception
  thrown.  Returns the list of directories created or an empty list if
  the directories already exist, just like C<make_path>.
  
  Current API available since 0.001.
  
  =head2 move
  
      path("foo.txt")->move("bar.txt");
  
  Move the current path to the given destination path using Perl's
  built-in L<rename|perlfunc/rename> function. Returns the result
  of the C<rename> function.
  
  Current API available since 0.001.
  
  =head2 openr, openw, openrw, opena
  
      $fh = path("foo.txt")->openr($binmode);  # read
      $fh = path("foo.txt")->openr_raw;
      $fh = path("foo.txt")->openr_utf8;
  
      $fh = path("foo.txt")->openw($binmode);  # write
      $fh = path("foo.txt")->openw_raw;
      $fh = path("foo.txt")->openw_utf8;
  
      $fh = path("foo.txt")->opena($binmode);  # append
      $fh = path("foo.txt")->opena_raw;
      $fh = path("foo.txt")->opena_utf8;
  
      $fh = path("foo.txt")->openrw($binmode); # read/write
      $fh = path("foo.txt")->openrw_raw;
      $fh = path("foo.txt")->openrw_utf8;
  
  Returns a file handle opened in the specified mode.  The C<openr> style methods
  take a single C<binmode> argument.  All of the C<open*> methods have
  C<open*_raw> and C<open*_utf8> equivalents that use C<:raw> and
  C<:raw:encoding(UTF-8)>, respectively.
  
  An optional hash reference may be used to pass options.  The only option is
  C<locked>.  If true, handles opened for writing, appending or read-write are
  locked with C<LOCK_EX>; otherwise, they are locked for C<LOCK_SH>.
  
      $fh = path("foo.txt")->openrw_utf8( { locked => 1 } );
  
  See L</filehandle> for more on locking.
  
  Current API available since 0.011.
  
  =head2 parent
  
      $parent = path("foo/bar/baz")->parent; # foo/bar
      $parent = path("foo/wibble.txt")->parent; # foo
  
      $parent = path("foo/bar/baz")->parent(2); # foo
  
  Returns a C<Path::Tiny> object corresponding to the parent directory of the
  original directory or file. An optional positive integer argument is the number
  of parent directories upwards to return.  C<parent> by itself is equivalent to
  C<parent(1)>.
  
  Current API available since 0.014.
  
  =head2 realpath
  
      $real = path("/baz/foo/../bar")->realpath;
      $real = path("foo/../bar")->realpath;
  
  Returns a new C<Path::Tiny> object with all symbolic links and upward directory
  parts resolved using L<Cwd>'s C<realpath>.  Compared to C<absolute>, this is
  more expensive as it must actually consult the filesystem.
  
  If the parent path can't be resolved (e.g. if it includes directories that
  don't exist), an exception will be thrown:
  
      $real = path("doesnt_exist/foo")->realpath; # dies
  
  However, if the parent path exists and only the last component (e.g. filename)
  doesn't exist, the realpath will be the realpath of the parent plus the
  non-existent last component:
  
      $real = path("./aasdlfasdlf")->realpath; # works
  
  The underlying L<Cwd> module usually worked this way on Unix, but died on
  Windows (and some Unixes) if the full path didn't exist.  As of version 0.064,
  it's safe to use anywhere.
  
  Current API available since 0.001.
  
  =head2 relative
  
      $rel = path("/tmp/foo/bar")->relative("/tmp"); # foo/bar
  
  Returns a C<Path::Tiny> object with a path relative to a new base path
  given as an argument.  If no argument is given, the current directory will
  be used as the new base path.
  
  If either path is already relative, it will be made absolute based on the
  current directly before determining the new relative path.
  
  The algorithm is roughly as follows:
  
  =over 4
  
  =item *
  
  If the original and new base path are on different volumes, an exception will be thrown.
  
  =item *
  
  If the original and new base are identical, the relative path is C<".">.
  
  =item *
  
  If the new base subsumes the original, the relative path is the original path with the new base chopped off the front
  
  =item *
  
  If the new base does not subsume the original, a common prefix path is determined (possibly the root directory) and the relative path will consist of updirs (C<"..">) to reach the common prefix, followed by the original path less the common prefix.
  
  =back
  
  Unlike C<File::Spec::rel2abs>, in the last case above, the calculation based
  on a common prefix takes into account symlinks that could affect the updir
  process.  Given an original path "/A/B" and a new base "/A/C",
  (where "A", "B" and "C" could each have multiple path components):
  
  =over 4
  
  =item *
  
  Symlinks in "A" don't change the result unless the last component of A is a symlink and the first component of "C" is an updir.
  
  =item *
  
  Symlinks in "B" don't change the result and will exist in the result as given.
  
  =item *
  
  Symlinks and updirs in "C" must be resolved to actual paths, taking into account the possibility that not all path components might exist on the filesystem.
  
  =back
  
  Current API available since 0.001.  New algorithm (that accounts for
  symlinks) available since 0.079.
  
  =head2 remove
  
      path("foo.txt")->remove;
  
  This is just like C<unlink>, except for its error handling: if the path does
  not exist, it returns false; if deleting the file fails, it throws an
  exception.
  
  Current API available since 0.012.
  
  =head2 remove_tree
  
      # directory
      path("foo/bar/baz")->remove_tree;
      path("foo/bar/baz")->remove_tree( \%options );
      path("foo/bar/baz")->remove_tree( { safe => 0 } ); # force remove
  
  Like calling C<remove_tree> from L<File::Path>, but defaults to C<safe> mode.
  An optional hash reference is passed through to C<remove_tree>.  Errors will be
  trapped and an exception thrown.  Returns the number of directories deleted,
  just like C<remove_tree>.
  
  If you want to remove a directory only if it is empty, use the built-in
  C<rmdir> function instead.
  
      rmdir path("foo/bar/baz/");
  
  Current API available since 0.013.
  
  =head2 sibling
  
      $foo = path("/tmp/foo.txt");
      $sib = $foo->sibling("bar.txt");        # /tmp/bar.txt
      $sib = $foo->sibling("baz", "bam.txt"); # /tmp/baz/bam.txt
  
  Returns a new C<Path::Tiny> object relative to the parent of the original.
  This is slightly more efficient than C<< $path->parent->child(...) >>.
  
  Current API available since 0.058.
  
  =head2 slurp, slurp_raw, slurp_utf8
  
      $data = path("foo.txt")->slurp;
      $data = path("foo.txt")->slurp( {binmode => ":raw"} );
      $data = path("foo.txt")->slurp_raw;
      $data = path("foo.txt")->slurp_utf8;
  
  Reads file contents into a scalar.  Takes an optional hash reference which may
  be used to pass options.  The only available option is C<binmode>, which is
  passed to C<binmode()> on the handle used for reading.
  
  C<slurp_raw> is like C<slurp> with a C<binmode> of C<:unix> for
  a fast, unbuffered, raw read.
  
  C<slurp_utf8> is like C<slurp> with a C<binmode> of
  C<:unix:encoding(UTF-8)>.  If L<Unicode::UTF8> 0.58+ is installed, a raw
  slurp will be done instead and the result decoded with C<Unicode::UTF8>.
  This is just as strict and is roughly an order of magnitude faster than
  using C<:encoding(UTF-8)>.
  
  B<Note>: C<slurp> and friends lock the filehandle before slurping.  If
  you plan to slurp from a file created with L<File::Temp>, be sure to
  close other handles or open without locking to avoid a deadlock:
  
      my $tempfile = File::Temp->new(EXLOCK => 0);
      my $guts = path($tempfile)->slurp;
  
  Current API available since 0.004.
  
  =head2 spew, spew_raw, spew_utf8
  
      path("foo.txt")->spew(@data);
      path("foo.txt")->spew(\@data);
      path("foo.txt")->spew({binmode => ":raw"}, @data);
      path("foo.txt")->spew_raw(@data);
      path("foo.txt")->spew_utf8(@data);
  
  Writes data to a file atomically.  The file is written to a temporary file in
  the same directory, then renamed over the original.  An optional hash reference
  may be used to pass options.  The only option is C<binmode>, which is passed to
  C<binmode()> on the handle used for writing.
  
  C<spew_raw> is like C<spew> with a C<binmode> of C<:unix> for a fast,
  unbuffered, raw write.
  
  C<spew_utf8> is like C<spew> with a C<binmode> of C<:unix:encoding(UTF-8)>.
  If L<Unicode::UTF8> 0.58+ is installed, a raw spew will be done instead on
  the data encoded with C<Unicode::UTF8>.
  
  B<NOTE>: because the file is written to a temporary file and then renamed, the
  new file will wind up with permissions based on your current umask.  This is a
  feature to protect you from a race condition that would otherwise give
  different permissions than you might expect.  If you really want to keep the
  original mode flags, use L</append> with the C<truncate> option.
  
  Current API available since 0.011.
  
  =head2 stat, lstat
  
      $stat = path("foo.txt")->stat;
      $stat = path("/some/symlink")->lstat;
  
  Like calling C<stat> or C<lstat> from L<File::stat>.
  
  Current API available since 0.001.
  
  =head2 stringify
  
      $path = path("foo.txt");
      say $path->stringify; # same as "$path"
  
  Returns a string representation of the path.  Unlike C<canonpath>, this method
  returns the path standardized with Unix-style C</> directory separators.
  
  Current API available since 0.001.
  
  =head2 subsumes
  
      path("foo/bar")->subsumes("foo/bar/baz"); # true
      path("/foo/bar")->subsumes("/foo/baz");   # false
  
  Returns true if the first path is a prefix of the second path at a directory
  boundary.
  
  This B<does not> resolve parent directory entries (C<..>) or symlinks:
  
      path("foo/bar")->subsumes("foo/bar/../baz"); # true
  
  If such things are important to you, ensure that both paths are resolved to
  the filesystem with C<realpath>:
  
      my $p1 = path("foo/bar")->realpath;
      my $p2 = path("foo/bar/../baz")->realpath;
      if ( $p1->subsumes($p2) ) { ... }
  
  Current API available since 0.048.
  
  =head2 touch
  
      path("foo.txt")->touch;
      path("foo.txt")->touch($epoch_secs);
  
  Like the Unix C<touch> utility.  Creates the file if it doesn't exist, or else
  changes the modification and access times to the current time.  If the first
  argument is the epoch seconds then it will be used.
  
  Returns the path object so it can be easily chained with other methods:
  
      # won't die if foo.txt doesn't exist
      $content = path("foo.txt")->touch->slurp;
  
  Current API available since 0.015.
  
  =head2 touchpath
  
      path("bar/baz/foo.txt")->touchpath;
  
  Combines C<mkpath> and C<touch>.  Creates the parent directory if it doesn't exist,
  before touching the file.  Returns the path object like C<touch> does.
  
  Current API available since 0.022.
  
  =head2 visit
  
      path("/tmp")->visit( \&callback, \%options );
  
  Wraps the L</iterator> method to execute a callback for each directory entry.
  It returns a hash reference with any state accumulated during
  iteration.
  
  The options are the same as for L</iterator>: C<recurse> and
  C<follow_symlinks>.  Both default to false.
  
  The callback function will receive a C<Path::Tiny> object as the first argument
  and a hash reference to accumulate state as the second argument.  For example:
  
      # collect files sizes
      my $sizes = path("/tmp")->visit(
          sub {
              my ($path, $state) = @_;
              return if $path->is_dir;
              $state->{$path} = -s $path;
          },
          { recurse => 1 }
      );
  
  For convenience, the C<Path::Tiny> object will also be locally aliased as the
  C<$_> global variable:
  
      # print paths matching /foo/
      path("/tmp")->visit( sub { say if /foo/ }, { recurse => 1} );
  
  If the callback returns a B<reference> to a false scalar value, iteration will
  terminate.  This is not the same as "pruning" a directory search; this just
  stops all iteration and returns the state hash reference.
  
      # find up to 10 files larger than 100K
      my $files = path("/tmp")->visit(
          sub {
              my ($path, $state) = @_;
              $state->{$path}++ if -s $path > 102400
              return \0 if keys %$state == 10;
          },
          { recurse => 1 }
      );
  
  If you want more flexible iteration, use a module like L<Path::Iterator::Rule>.
  
  Current API available since 0.062.
  
  =head2 volume
  
      $vol = path("/tmp/foo.txt")->volume;   # ""
      $vol = path("C:/tmp/foo.txt")->volume; # "C:"
  
  Returns the volume portion of the path.  This is equivalent
  to what L<File::Spec> would give from C<splitpath> and thus
  usually is the empty string on Unix-like operating systems or the
  drive letter for an absolute path on C<MSWin32>.
  
  Current API available since 0.001.
  
  =for Pod::Coverage openr_utf8 opena_utf8 openw_utf8 openrw_utf8
  openr_raw opena_raw openw_raw openrw_raw
  IS_BSD IS_WIN32 FREEZE THAW TO_JSON abs2rel
  
  =head1 EXCEPTION HANDLING
  
  Simple usage errors will generally croak.  Failures of underlying Perl
  functions will be thrown as exceptions in the class
  C<Path::Tiny::Error>.
  
  A C<Path::Tiny::Error> object will be a hash reference with the following fields:
  
  =over 4
  
  =item *
  
  C<op> — a description of the operation, usually function call and any extra info
  
  =item *
  
  C<file> — the file or directory relating to the error
  
  =item *
  
  C<err> — hold C<$!> at the time the error was thrown
  
  =item *
  
  C<msg> — a string combining the above data and a Carp-like short stack trace
  
  =back
  
  Exception objects will stringify as the C<msg> field.
  
  =head1 CAVEATS
  
  =head2 Subclassing not supported
  
  For speed, this class is implemented as an array based object and uses many
  direction function calls internally.  You must not subclass it and expect
  things to work properly.
  
  =head2 File locking
  
  If flock is not supported on a platform, it will not be used, even if
  locking is requested.
  
  See additional caveats below.
  
  =head3 NFS and BSD
  
  On BSD, Perl's flock implementation may not work to lock files on an
  NFS filesystem.  Path::Tiny has some heuristics to detect this
  and will warn once and let you continue in an unsafe mode.  If you
  want this failure to be fatal, you can fatalize the 'flock' warnings
  category:
  
      use warnings FATAL => 'flock';
  
  =head3 AIX and locking
  
  AIX requires a write handle for locking.  Therefore, calls that normally
  open a read handle and take a shared lock instead will open a read-write
  handle and take an exclusive lock.  If the user does not have write
  permission, no lock will be used.
  
  =head2 utf8 vs UTF-8
  
  All the C<*_utf8> methods use C<:encoding(UTF-8)> -- either as
  C<:unix:encoding(UTF-8)> (unbuffered) or C<:raw:encoding(UTF-8)> (buffered) --
  which is strict against the Unicode spec and disallows illegal Unicode
  codepoints or UTF-8 sequences.
  
  Unfortunately, C<:encoding(UTF-8)> is very, very slow.  If you install
  L<Unicode::UTF8> 0.58 or later, that module will be used by some C<*_utf8>
  methods to encode or decode data after a raw, binary input/output operation,
  which is much faster.
  
  If you need the performance and can accept the security risk,
  C<< slurp({binmode => ":unix:utf8"}) >> will be faster than C<:unix:encoding(UTF-8)>
  (but not as fast as C<Unicode::UTF8>).
  
  Note that the C<*_utf8> methods read in B<raw> mode.  There is no CRLF
  translation on Windows.  If you must have CRLF translation, use the regular
  input/output methods with an appropriate binmode:
  
    $path->spew_utf8($data);                            # raw
    $path->spew({binmode => ":encoding(UTF-8)"}, $data; # LF -> CRLF
  
  Consider L<PerlIO::utf8_strict> for a faster L<PerlIO> layer alternative to
  C<:encoding(UTF-8)>, though it does not appear to be as fast as the
  C<Unicode::UTF8> approach.
  
  =head2 Default IO layers and the open pragma
  
  If you have Perl 5.10 or later, file input/output methods (C<slurp>, C<spew>,
  etc.) and high-level handle opening methods ( C<filehandle>, C<openr>,
  C<openw>, etc. ) respect default encodings set by the C<-C> switch or lexical
  L<open> settings of the caller.  For UTF-8, this is almost certainly slower
  than using the dedicated C<_utf8> methods if you have L<Unicode::UTF8>.
  
  =head1 TYPE CONSTRAINTS AND COERCION
  
  A standard L<MooseX::Types> library is available at
  L<MooseX::Types::Path::Tiny>.  A L<Type::Tiny> equivalent is available as
  L<Types::Path::Tiny>.
  
  =head1 SEE ALSO
  
  These are other file/path utilities, which may offer a different feature
  set than C<Path::Tiny>.
  
  =over 4
  
  =item *
  
  L<File::chmod>
  
  =item *
  
  L<File::Fu>
  
  =item *
  
  L<IO::All>
  
  =item *
  
  L<Path::Class>
  
  =back
  
  These iterators may be slightly faster than the recursive iterator in
  C<Path::Tiny>:
  
  =over 4
  
  =item *
  
  L<Path::Iterator::Rule>
  
  =item *
  
  L<File::Next>
  
  =back
  
  There are probably comparable, non-Tiny tools.  Let me know if you want me to
  add a module to the list.
  
  This module was featured in the L<2013 Perl Advent Calendar|http://www.perladvent.org/2013/2013-12-18.html>.
  
  =for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan
  
  =head1 SUPPORT
  
  =head2 Bugs / Feature Requests
  
  Please report any bugs or feature requests through the issue tracker
  at L<https://github.com/dagolden/Path-Tiny/issues>.
  You will be notified automatically of any progress on your issue.
  
  =head2 Source Code
  
  This is open source software.  The code repository is available for
  public review and contribution under the terms of the license.
  
  L<https://github.com/dagolden/Path-Tiny>
  
    git clone https://github.com/dagolden/Path-Tiny.git
  
  =head1 AUTHOR
  
  David Golden <dagolden@cpan.org>
  
  =head1 CONTRIBUTORS
  
  =for stopwords Alex Efros Chris Williams David Golden Steinbrunner Doug Bell Gabor Szabo Gabriel Andrade George Hartzell Geraud Continsouzas Goro Fuji Graham Knop James Hunt John Karr Karen Etheridge Mark Ellis Martin Kjeldsen Michael G. Schwern Nigel Gregoire Philippe Bruhat (BooK) Regina Verbae Roy Ivy III Shlomi Fish Smylers Tatsuhiko Miyagawa Toby Inkster Yanick Champoux 김도형 - Keedi Kim
  
  =over 4
  
  =item *
  
  Alex Efros <powerman@powerman.name>
  
  =item *
  
  Chris Williams <bingos@cpan.org>
  
  =item *
  
  David Golden <xdg@xdg.me>
  
  =item *
  
  David Steinbrunner <dsteinbrunner@pobox.com>
  
  =item *
  
  Doug Bell <madcityzen@gmail.com>
  
  =item *
  
  Gabor Szabo <szabgab@cpan.org>
  
  =item *
  
  Gabriel Andrade <gabiruh@gmail.com>
  
  =item *
  
  George Hartzell <hartzell@cpan.org>
  
  =item *
  
  Geraud Continsouzas <geraud@scsi.nc>
  
  =item *
  
  Goro Fuji <gfuji@cpan.org>
  
  =item *
  
  Graham Knop <haarg@haarg.org>
  
  =item *
  
  James Hunt <james@niftylogic.com>
  
  =item *
  
  John Karr <brainbuz@brainbuz.org>
  
  =item *
  
  Karen Etheridge <ether@cpan.org>
  
  =item *
  
  Mark Ellis <mark.ellis@cartridgesave.co.uk>
  
  =item *
  
  Martin Kjeldsen <mk@bluepipe.dk>
  
  =item *
  
  Michael G. Schwern <mschwern@cpan.org>
  
  =item *
  
  Nigel Gregoire <nigelgregoire@gmail.com>
  
  =item *
  
  Philippe Bruhat (BooK) <book@cpan.org>
  
  =item *
  
  Regina Verbae <regina-verbae@users.noreply.github.com>
  
  =item *
  
  Roy Ivy III <RIVY.dev@gmail.com>
  
  =item *
  
  Shlomi Fish <shlomif@shlomifish.org>
  
  =item *
  
  Smylers <Smylers@stripey.com>
  
  =item *
  
  Tatsuhiko Miyagawa <miyagawa@bulknews.net>
  
  =item *
  
  Toby Inkster <tobyink@cpan.org>
  
  =item *
  
  Yanick Champoux <yanick@babyl.dyndns.org>
  
  =item *
  
  김도형 - Keedi Kim <keedi@cpan.org>
  
  =back
  
  =head1 COPYRIGHT AND LICENSE
  
  This software is Copyright (c) 2014 by David Golden.
  
  This is free software, licensed under:
  
    The Apache License, Version 2.0, January 2004
  
  =cut
PATH_TINY

$fatpacked{"Sub/Defer.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'SUB_DEFER';
  package Sub::Defer;
  
  use strictures 1;
  use base qw(Exporter);
  use Moo::_Utils;
  use Scalar::Util qw(weaken);
  
  our $VERSION = '1.006000';
  $VERSION = eval $VERSION;
  
  our @EXPORT = qw(defer_sub undefer_sub undefer_all);
  
  our %DEFERRED;
  
  sub undefer_sub {
    my ($deferred) = @_;
    my ($target, $maker, $undeferred_ref) = @{
      $DEFERRED{$deferred}||return $deferred
    };
    return ${$undeferred_ref}
      if ${$undeferred_ref};
    ${$undeferred_ref} = my $made = $maker->();
  
    # make sure the method slot has not changed since deferral time
    if (defined($target) && $deferred eq *{_getglob($target)}{CODE}||'') {
      no warnings 'redefine';
  
      # I believe $maker already evals with the right package/name, so that
      # _install_coderef calls are not necessary --ribasushi
      *{_getglob($target)} = $made;
    }
    $DEFERRED{$made} = $DEFERRED{$deferred};
    weaken $DEFERRED{$made}
      unless $target;
  
    return $made;
  }
  
  sub undefer_all {
    undefer_sub($_) for keys %DEFERRED;
    return;
  }
  
  sub defer_info {
    my ($deferred) = @_;
    my $info = $DEFERRED{$deferred||''} or return undef;
    [ @$info ];
  }
  
  sub defer_sub {
    my ($target, $maker) = @_;
    my $undeferred;
    my $deferred_info;
    my $deferred = sub {
      $undeferred ||= undefer_sub($deferred_info->[3]);
      goto &$undeferred;
    };
    $deferred_info = [ $target, $maker, \$undeferred, $deferred ];
    weaken($deferred_info->[3]);
    weaken($DEFERRED{$deferred} = $deferred_info);
    _install_coderef($target => $deferred) if defined $target;
    return $deferred;
  }
  
  sub CLONE {
    %DEFERRED = map { defined $_ && $_->[3] ? ($_->[3] => $_) : () } values %DEFERRED;
    for my $info (values %DEFERRED) {
      weaken($info)
        unless $info->[0] && ${$info->[2]};
    }
  }
  
  1;
  __END__
  
  =head1 NAME
  
  Sub::Defer - defer generation of subroutines until they are first called
  
  =head1 SYNOPSIS
  
   use Sub::Defer;
  
   my $deferred = defer_sub 'Logger::time_since_first_log' => sub {
      my $t = time;
      sub { time - $t };
   };
  
    Logger->time_since_first_log; # returns 0 and replaces itself
    Logger->time_since_first_log; # returns time - $t
  
  =head1 DESCRIPTION
  
  These subroutines provide the user with a convenient way to defer creation of
  subroutines and methods until they are first called.
  
  =head1 SUBROUTINES
  
  =head2 defer_sub
  
   my $coderef = defer_sub $name => sub { ... };
  
  This subroutine returns a coderef that encapsulates the provided sub - when
  it is first called, the provided sub is called and is -itself- expected to
  return a subroutine which will be goto'ed to on subsequent calls.
  
  If a name is provided, this also installs the sub as that name - and when
  the subroutine is undeferred will re-install the final version for speed.
  
  =head2 undefer_sub
  
   my $coderef = undefer_sub \&Foo::name;
  
  If the passed coderef has been L<deferred|/defer_sub> this will "undefer" it.
  If the passed coderef has not been deferred, this will just return it.
  
  If this is confusing, take a look at the example in the L</SYNOPSIS>.
  
  =head2 undefer_all
  
   undefer_all();
  
  This will undefer all defered subs in one go.  This can be very useful in a
  forking environment where child processes would each have to undefer the same
  subs.  By calling this just before you start forking children you can undefer
  all currently deferred subs in the parent so that the children do not have to
  do it.
  
  =head1 SUPPORT
  
  See L<Moo> for support and contact information.
  
  =head1 AUTHORS
  
  See L<Moo> for authors.
  
  =head1 COPYRIGHT AND LICENSE
  
  See L<Moo> for the copyright and license.
  
  =cut
SUB_DEFER

$fatpacked{"Sub/Exporter/Progressive.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'SUB_EXPORTER_PROGRESSIVE';
  package Sub::Exporter::Progressive;
  
  use strict;
  use warnings;
  
  our $VERSION = '0.001010';
  
  use Carp 'croak';
  use List::Util 'first';
  
  sub import {
     my ($self, @args) = @_;
  
     my $inner_target = caller;
     my $export_data = sub_export_options($inner_target, @args);
  
     my $full_exporter;
     no strict 'refs';
     @{"${inner_target}::EXPORT_OK"} = @{$export_data->{exports}};
     @{"${inner_target}::EXPORT"} = @{$export_data->{defaults}};
     %{"${inner_target}::EXPORT_TAGS"} = %{$export_data->{tags}};
     *{"${inner_target}::import"} = sub {
        use strict;
        my ($self, @args) = @_;
  
        if (first { ref || !m/ \A [:-]? \w+ \z /xm } @args) {
           croak 'your usage of Sub::Exporter::Progressive requires Sub::Exporter to be installed'
              unless eval { require Sub::Exporter };
           $full_exporter ||= Sub::Exporter::build_exporter($export_data->{original});
  
           goto $full_exporter;
        } elsif (defined(my $num = first { !ref and m/^\d/ } @args)) {
           die "cannot export symbols with a leading digit: '$num'";
        } else {
           require Exporter;
           s/ \A - /:/xm for @args;
           @_ = ($self, @args);
           goto \&Exporter::import;
        }
     };
     return;
  }
  
  my $too_complicated = <<'DEATH';
  You are using Sub::Exporter::Progressive, but the features your program uses from
  Sub::Exporter cannot be implemented without Sub::Exporter, so you might as well
  just use vanilla Sub::Exporter
  DEATH
  
  sub sub_export_options {
     my ($inner_target, $setup, $options) = @_;
  
     my @exports;
     my @defaults;
     my %tags;
  
     if ($setup eq '-setup') {
        my %options = %$options;
  
        OPTIONS:
        for my $opt (keys %options) {
           if ($opt eq 'exports') {
  
              croak $too_complicated if ref $options{exports} ne 'ARRAY';
              @exports = @{$options{exports}};
              croak $too_complicated if first { ref } @exports;
  
           } elsif ($opt eq 'groups') {
              %tags = %{$options{groups}};
              for my $tagset (values %tags) {
                 croak $too_complicated if first { / \A - (?! all \b ) /x || ref } @{$tagset};
              }
              @defaults = @{$tags{default} || [] };
           } else {
              croak $too_complicated;
           }
        }
        @{$_} = map { / \A  [:-] all \z /x ? @exports : $_ } @{$_} for \@defaults, values %tags;
        $tags{all} ||= [ @exports ];
        my %exports = map { $_ => 1 } @exports;
        my @errors = grep { not $exports{$_} } @defaults;
        croak join(', ', @errors) . " is not exported by the $inner_target module\n" if @errors;
     }
  
     return {
        exports => \@exports,
        defaults => \@defaults,
        original => $options,
        tags => \%tags,
     };
  }
  
  1;
  
  =encoding utf8
  
  =head1 NAME
  
  Sub::Exporter::Progressive - Only use Sub::Exporter if you need it
  
  =head1 SYNOPSIS
  
   package Syntax::Keyword::Gather;
  
   use Sub::Exporter::Progressive -setup => {
     exports => [qw( break gather gathered take )],
     groups => {
       defaults => [qw( break gather gathered take )],
     },
   };
  
   # elsewhere
  
   # uses Exporter for speed
   use Syntax::Keyword::Gather;
  
   # somewhere else
  
   # uses Sub::Exporter for features
   use Syntax::Keyword::Gather 'gather', take => { -as => 'grab' };
  
  =head1 DESCRIPTION
  
  L<Sub::Exporter> is an incredibly powerful module, but with that power comes
  great responsibility, er- as well as some runtime penalties.  This module
  is a C<Sub::Exporter> wrapper that will let your users just use L<Exporter>
  if all they are doing is picking exports, but use C<Sub::Exporter> if your
  users try to use C<Sub::Exporter>'s more advanced features features, like
  renaming exports, if they try to use them.
  
  Note that this module will export C<@EXPORT>, C<@EXPORT_OK> and
  C<%EXPORT_TAGS> package variables for C<Exporter> to work.  Additionally, if
  your package uses advanced C<Sub::Exporter> features like currying, this module
  will only ever use C<Sub::Exporter>, so you might as well use it directly.
  
  =head1 AUTHOR
  
  frew - Arthur Axel Schmidt (cpan:FREW) <frioux+cpan@gmail.com>
  
  =head1 CONTRIBUTORS
  
  ilmari - Dagfinn Ilmari Mannsåker (cpan:ILMARI) <ilmari@ilmari.org>
  
  mst - Matt S. Trout (cpan:MSTROUT) <mst@shadowcat.co.uk>
  
  leont - Leon Timmermans (cpan:LEONT) <leont@cpan.org>
  
  =head1 COPYRIGHT
  
  Copyright (c) 2012 the Sub::Exporter::Progressive L</AUTHOR> and
  L</CONTRIBUTORS> as listed above.
  
  =head1 LICENSE
  
  This library is free software and may be distributed under the same terms
  as perl itself.
  
  =cut
SUB_EXPORTER_PROGRESSIVE

$fatpacked{"Sub/Quote.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'SUB_QUOTE';
  package Sub::Quote;
  
  use strictures 1;
  
  sub _clean_eval { eval $_[0] }
  
  use Sub::Defer;
  use Scalar::Util qw(weaken);
  use base qw(Exporter);
  use B ();
  BEGIN {
    *_HAVE_PERLSTRING = defined &B::perlstring ? sub(){1} : sub(){0};
  }
  
  our $VERSION = '1.006000';
  $VERSION = eval $VERSION;
  
  our @EXPORT = qw(quote_sub unquote_sub quoted_from_sub qsub);
  our @EXPORT_OK = qw(quotify capture_unroll inlinify);
  
  our %QUOTED;
  
  sub quotify {
    ! defined $_[0]     ? 'undef()'
    : _HAVE_PERLSTRING  ? B::perlstring($_[0])
    : qq["\Q$_[0]\E"];
  }
  
  sub capture_unroll {
    my ($from, $captures, $indent) = @_;
    join(
      '',
      map {
        /^([\@\%\$])/
          or die "capture key should start with \@, \% or \$: $_";
        (' ' x $indent).qq{my ${_} = ${1}{${from}->{${\quotify $_}}};\n};
      } keys %$captures
    );
  }
  
  sub inlinify {
    my ($code, $args, $extra, $local) = @_;
    my $do = 'do { '.($extra||'');
    if ($code =~ s/^(\s*package\s+([a-zA-Z0-9:]+);)//) {
      $do .= $1;
    }
    if ($code =~ s{(\A\s*|\A# BEGIN quote_sub PRELUDE\n.*?# END quote_sub PRELUDE\n\s*)(^\s*)(my\s*\(([^)]+)\)\s*=\s*\@_;)$}{
      my ($pre, $indent, $assign, $code_args) = ($1, $2, $3, $4);
      if ($code_args eq $args) {
        $pre . $indent . ($local ? 'local ' : '').'@_ = ('.$args.");\n"
        . $indent . $assign;
      }
      else {
        $pre . 'my ('.$code_args.') = ('.$args.'); ';
      }
    }mse) {
      #done
    }
    elsif ($local || $args ne '@_') {
      $do .= ($local ? 'local ' : '').'@_ = ('.$args.'); ';
    }
    $do.$code.' }';
  }
  
  sub quote_sub {
    # HOLY DWIMMERY, BATMAN!
    # $name => $code => \%captures => \%options
    # $name => $code => \%captures
    # $name => $code
    # $code => \%captures => \%options
    # $code
    my $options =
      (ref($_[-1]) eq 'HASH' and ref($_[-2]) eq 'HASH')
        ? pop
        : {};
    my $captures = ref($_[-1]) eq 'HASH' ? pop : undef;
    undef($captures) if $captures && !keys %$captures;
    my $code = pop;
    my $name = $_[0];
    my ($package, $hints, $bitmask, $hintshash) = (caller(0))[0,8,9,10];
    my $context
      ="# BEGIN quote_sub PRELUDE\n"
      ."package $package;\n"
      ."BEGIN {\n"
      ."  \$^H = ".quotify($hints).";\n"
      ."  \${^WARNING_BITS} = ".quotify($bitmask).";\n"
      ."  \%^H = (\n"
      . join('', map
       "    ".quotify($_)." => ".quotify($hintshash->{$_}).",",
        keys %$hintshash)
      ."  );\n"
      ."}\n"
      ."# END quote_sub PRELUDE\n";
    $code = "$context$code";
    my $quoted_info;
    my $unquoted;
    my $deferred = defer_sub +($options->{no_install} ? undef : $name) => sub {
      $unquoted if 0;
      unquote_sub($quoted_info->[4]);
    };
    $quoted_info = [ $name, $code, $captures, \$unquoted, $deferred ];
    weaken($quoted_info->[3]);
    weaken($quoted_info->[4]);
    weaken($QUOTED{$deferred} = $quoted_info);
    return $deferred;
  }
  
  sub quoted_from_sub {
    my ($sub) = @_;
    my $quoted_info = $QUOTED{$sub||''} or return undef;
    my ($name, $code, $captured, $unquoted, $deferred) = @{$quoted_info};
    $unquoted &&= $$unquoted;
    if (($deferred && $deferred eq $sub)
        || ($unquoted && $unquoted eq $sub)) {
      return [ $name, $code, $captured, $unquoted, $deferred ];
    }
    return undef;
  }
  
  sub unquote_sub {
    my ($sub) = @_;
    my $quoted = $QUOTED{$sub} or return undef;
    my $unquoted = $quoted->[3];
    unless ($unquoted && $$unquoted) {
      my ($name, $code, $captures) = @$quoted;
  
      my $make_sub = "{\n";
  
      my %captures = $captures ? %$captures : ();
      $captures{'$_UNQUOTED'} = \$unquoted;
      $captures{'$_QUOTED'} = \$quoted;
      $make_sub .= capture_unroll("\$_[1]", \%captures, 2);
  
      $make_sub .= (
        $name
            # disable the 'variable $x will not stay shared' warning since
            # we're not letting it escape from this scope anyway so there's
            # nothing trying to share it
          ? "  no warnings 'closure';\n  sub ${name} {\n"
          : "  \$\$_UNQUOTED = sub {\n"
      );
      $make_sub .= "  \$_QUOTED if 0;\n";
      $make_sub .= "  \$_UNQUOTED if 0;\n";
      $make_sub .= $code;
      $make_sub .= "  }".($name ? '' : ';')."\n";
      if ($name) {
        $make_sub .= "  \$\$_UNQUOTED = \\&${name}\n";
      }
      $make_sub .= "}\n1;\n";
      $ENV{SUB_QUOTE_DEBUG} && warn $make_sub;
      {
        no strict 'refs';
        local *{$name} if $name;
        my ($success, $e);
        {
          local $@;
          $success = _clean_eval($make_sub, \%captures);
          $e = $@;
        }
        unless ($success) {
          die "Eval went very, very wrong:\n\n${make_sub}\n\n$e";
        }
        weaken($QUOTED{$$unquoted} = $quoted);
      }
    }
    $$unquoted;
  }
  
  sub qsub ($) {
    goto &quote_sub;
  }
  
  sub CLONE {
    %QUOTED = map { defined $_ ? (
      $_->[3] && ${$_->[3]} ? (${ $_->[3] } => $_) : (),
      $_->[4] ? ($_->[4] => $_) : (),
    ) : () } values %QUOTED;
    weaken($_) for values %QUOTED;
  }
  
  1;
  __END__
  
  =head1 NAME
  
  Sub::Quote - efficient generation of subroutines via string eval
  
  =head1 SYNOPSIS
  
   package Silly;
  
   use Sub::Quote qw(quote_sub unquote_sub quoted_from_sub);
  
   quote_sub 'Silly::kitty', q{ print "meow" };
  
   quote_sub 'Silly::doggy', q{ print "woof" };
  
   my $sound = 0;
  
   quote_sub 'Silly::dagron',
     q{ print ++$sound % 2 ? 'burninate' : 'roar' },
     { '$sound' => \$sound };
  
  And elsewhere:
  
   Silly->kitty;  # meow
   Silly->doggy;  # woof
   Silly->dagron; # burninate
   Silly->dagron; # roar
   Silly->dagron; # burninate
  
  =head1 DESCRIPTION
  
  This package provides performant ways to generate subroutines from strings.
  
  =head1 SUBROUTINES
  
  =head2 quote_sub
  
   my $coderef = quote_sub 'Foo::bar', q{ print $x++ . "\n" }, { '$x' => \0 };
  
  Arguments: ?$name, $code, ?\%captures, ?\%options
  
  C<$name> is the subroutine where the coderef will be installed.
  
  C<$code> is a string that will be turned into code.
  
  C<\%captures> is a hashref of variables that will be made available to the
  code.  The keys should be the full name of the variable to be made available,
  including the sigil.  The values should be references to the values.  The
  variables will contain copies of the values.  See the L</SYNOPSIS>'s
  C<Silly::dagron> for an example using captures.
  
  =head3 options
  
  =over 2
  
  =item * no_install
  
  B<Boolean>.  Set this option to not install the generated coderef into the
  passed subroutine name on undefer.
  
  =back
  
  =head2 unquote_sub
  
   my $coderef = unquote_sub $sub;
  
  Forcibly replace subroutine with actual code.
  
  If $sub is not a quoted sub, this is a no-op.
  
  =head2 quoted_from_sub
  
   my $data = quoted_from_sub $sub;
  
   my ($name, $code, $captures, $compiled_sub) = @$data;
  
  Returns original arguments to quote_sub, plus the compiled version if this
  sub has already been unquoted.
  
  Note that $sub can be either the original quoted version or the compiled
  version for convenience.
  
  =head2 inlinify
  
   my $prelude = capture_unroll '$captures', {
     '$x' => 1,
     '$y' => 2,
   };
  
   my $inlined_code = inlinify q{
     my ($x, $y) = @_;
  
     print $x + $y . "\n";
   }, '$x, $y', $prelude;
  
  Takes a string of code, a string of arguments, a string of code which acts as a
  "prelude", and a B<Boolean> representing whether or not to localize the
  arguments.
  
  =head2 quotify
  
   my $quoted_value = quotify $value;
  
  Quotes a single (non-reference) scalar value for use in a code string.  Numbers
  aren't treated specially and will be quoted as strings, but undef will quoted as
  C<undef()>.
  
  =head2 capture_unroll
  
   my $prelude = capture_unroll '$captures', {
     '$x' => 1,
     '$y' => 2,
   }, 4;
  
  Arguments: $from, \%captures, $indent
  
  Generates a snippet of code which is suitable to be used as a prelude for
  L</inlinify>.  C<$from> is a string will be used as a hashref in the resulting
  code.  The keys of C<%captures> are the names of the variables and the values
  are ignored.  C<$indent> is the number of spaces to indent the result by.
  
  =head2 qsub
  
   my $hash = {
    coderef => qsub q{ print "hello"; },
    other   => 5,
   };
  
  Arguments: $code
  
  Works exactly like L</quote_sub>, but includes a prototype to only accept a
  single parameter.  This makes it easier to include in hash structures or lists.
  
  =head1 CAVEATS
  
  Much of this is just string-based code-generation, and as a result, a few
  caveats apply.
  
  =head2 return
  
  Calling C<return> from a quote_sub'ed sub will not likely do what you intend.
  Instead of returning from the code you defined in C<quote_sub>, it will return
  from the overall function it is composited into.
  
  So when you pass in:
  
     quote_sub q{  return 1 if $condition; $morecode }
  
  It might turn up in the intended context as follows:
  
    sub foo {
  
      <important code a>
      do {
        return 1 if $condition;
        $morecode
      };
      <important code b>
  
    }
  
  Which will obviously return from foo, when all you meant to do was return from
  the code context in quote_sub and proceed with running important code b.
  
  =head2 pragmas
  
  C<Sub::Quote> preserves the environment of the code creating the
  quoted subs.  This includes the package, strict, warnings, and any
  other lexical pragmas.  This is done by prefixing the code with a
  block that sets up a matching environment.  When inlining C<Sub::Quote>
  subs, care should be taken that user pragmas won't effect the rest
  of the code.
  
  =head1 SUPPORT
  
  See L<Moo> for support and contact information.
  
  =head1 AUTHORS
  
  See L<Moo> for authors.
  
  =head1 COPYRIGHT AND LICENSE
  
  See L<Moo> for the copyright and license.
  
  =cut
SUB_QUOTE

$fatpacked{"Try/Tiny.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'TRY_TINY';
  package Try::Tiny; # git description: v0.23-3-g5ee27f1
  use 5.006;
  # ABSTRACT: minimal try/catch with proper preservation of $@
  
  our $VERSION = '0.24';
  
  use strict;
  use warnings;
  
  use Exporter 5.57 'import';
  our @EXPORT = our @EXPORT_OK = qw(try catch finally);
  
  use Carp;
  $Carp::Internal{+__PACKAGE__}++;
  
  BEGIN {
    my $su = $INC{'Sub/Util.pm'} && defined &Sub::Util::set_subname;
    my $sn = $INC{'Sub/Name.pm'} && eval { Sub::Name->VERSION(0.08) };
    unless ($su || $sn) {
      $su = eval { require Sub::Util; } && defined &Sub::Util::set_subname;
      unless ($su) {
        $sn = eval { require Sub::Name; Sub::Name->VERSION(0.08) };
      }
    }
  
    *_subname = $su ? \&Sub::Util::set_subname
              : $sn ? \&Sub::Name::subname
              : sub { $_[1] };
    *_HAS_SUBNAME = ($su || $sn) ? sub(){1} : sub(){0};
  }
  
  # Need to prototype as @ not $$ because of the way Perl evaluates the prototype.
  # Keeping it at $$ means you only ever get 1 sub because we need to eval in a list
  # context & not a scalar one
  
  sub try (&;@) {
    my ( $try, @code_refs ) = @_;
  
    # we need to save this here, the eval block will be in scalar context due
    # to $failed
    my $wantarray = wantarray;
  
    # work around perl bug by explicitly initializing these, due to the likelyhood
    # this will be used in global destruction (perl rt#119311)
    my ( $catch, @finally ) = ();
  
    # find labeled blocks in the argument list.
    # catch and finally tag the blocks by blessing a scalar reference to them.
    foreach my $code_ref (@code_refs) {
  
      if ( ref($code_ref) eq 'Try::Tiny::Catch' ) {
        croak 'A try() may not be followed by multiple catch() blocks'
          if $catch;
        $catch = ${$code_ref};
      } elsif ( ref($code_ref) eq 'Try::Tiny::Finally' ) {
        push @finally, ${$code_ref};
      } else {
        croak(
          'try() encountered an unexpected argument ('
        . ( defined $code_ref ? $code_ref : 'undef' )
        . ') - perhaps a missing semi-colon before or'
        );
      }
    }
  
    # FIXME consider using local $SIG{__DIE__} to accumulate all errors. It's
    # not perfect, but we could provide a list of additional errors for
    # $catch->();
  
    # name the blocks if we have Sub::Name installed
    my $caller = caller;
    _subname("${caller}::try {...} " => $try)
      if _HAS_SUBNAME;
  
    # save the value of $@ so we can set $@ back to it in the beginning of the eval
    # and restore $@ after the eval finishes
    my $prev_error = $@;
  
    my ( @ret, $error );
  
    # failed will be true if the eval dies, because 1 will not be returned
    # from the eval body
    my $failed = not eval {
      $@ = $prev_error;
  
      # evaluate the try block in the correct context
      if ( $wantarray ) {
        @ret = $try->();
      } elsif ( defined $wantarray ) {
        $ret[0] = $try->();
      } else {
        $try->();
      };
  
      return 1; # properly set $failed to false
    };
  
    # preserve the current error and reset the original value of $@
    $error = $@;
    $@ = $prev_error;
  
    # set up a scope guard to invoke the finally block at the end
    my @guards =
      map { Try::Tiny::ScopeGuard->_new($_, $failed ? $error : ()) }
      @finally;
  
    # at this point $failed contains a true value if the eval died, even if some
    # destructor overwrote $@ as the eval was unwinding.
    if ( $failed ) {
      # if we got an error, invoke the catch block.
      if ( $catch ) {
        # This works like given($error), but is backwards compatible and
        # sets $_ in the dynamic scope for the body of C<$catch>
        for ($error) {
          return $catch->($error);
        }
  
        # in case when() was used without an explicit return, the C<for>
        # loop will be aborted and there's no useful return value
      }
  
      return;
    } else {
      # no failure, $@ is back to what it was, everything is fine
      return $wantarray ? @ret : $ret[0];
    }
  }
  
  sub catch (&;@) {
    my ( $block, @rest ) = @_;
  
    croak 'Useless bare catch()' unless wantarray;
  
    my $caller = caller;
    _subname("${caller}::catch {...} " => $block)
      if _HAS_SUBNAME;
    return (
      bless(\$block, 'Try::Tiny::Catch'),
      @rest,
    );
  }
  
  sub finally (&;@) {
    my ( $block, @rest ) = @_;
  
    croak 'Useless bare finally()' unless wantarray;
  
    my $caller = caller;
    _subname("${caller}::finally {...} " => $block)
      if _HAS_SUBNAME;
    return (
      bless(\$block, 'Try::Tiny::Finally'),
      @rest,
    );
  }
  
  {
    package # hide from PAUSE
      Try::Tiny::ScopeGuard;
  
    use constant UNSTABLE_DOLLARAT => ($] < '5.013002') ? 1 : 0;
  
    sub _new {
      shift;
      bless [ @_ ];
    }
  
    sub DESTROY {
      my ($code, @args) = @{ $_[0] };
  
      local $@ if UNSTABLE_DOLLARAT;
      eval {
        $code->(@args);
        1;
      } or do {
        warn
          "Execution of finally() block $code resulted in an exception, which "
        . '*CAN NOT BE PROPAGATED* due to fundamental limitations of Perl. '
        . 'Your program will continue as if this event never took place. '
        . "Original exception text follows:\n\n"
        . (defined $@ ? $@ : '$@ left undefined...')
        . "\n"
        ;
      }
    }
  }
  
  __PACKAGE__
  
  __END__
  
  =pod
  
  =encoding UTF-8
  
  =head1 NAME
  
  Try::Tiny - minimal try/catch with proper preservation of $@
  
  =head1 VERSION
  
  version 0.24
  
  =head1 SYNOPSIS
  
  You can use Try::Tiny's C<try> and C<catch> to expect and handle exceptional
  conditions, avoiding quirks in Perl and common mistakes:
  
    # handle errors with a catch handler
    try {
      die "foo";
    } catch {
      warn "caught error: $_"; # not $@
    };
  
  You can also use it like a standalone C<eval> to catch and ignore any error
  conditions.  Obviously, this is an extreme measure not to be undertaken
  lightly:
  
    # just silence errors
    try {
      die "foo";
    };
  
  =head1 DESCRIPTION
  
  This module provides bare bones C<try>/C<catch>/C<finally> statements that are designed to
  minimize common mistakes with eval blocks, and NOTHING else.
  
  This is unlike L<TryCatch> which provides a nice syntax and avoids adding
  another call stack layer, and supports calling C<return> from the C<try> block to
  return from the parent subroutine. These extra features come at a cost of a few
  dependencies, namely L<Devel::Declare> and L<Scope::Upper> which are
  occasionally problematic, and the additional catch filtering uses L<Moose>
  type constraints which may not be desirable either.
  
  The main focus of this module is to provide simple and reliable error handling
  for those having a hard time installing L<TryCatch>, but who still want to
  write correct C<eval> blocks without 5 lines of boilerplate each time.
  
  It's designed to work as correctly as possible in light of the various
  pathological edge cases (see L</BACKGROUND>) and to be compatible with any style
  of error values (simple strings, references, objects, overloaded objects, etc).
  
  If the C<try> block dies, it returns the value of the last statement executed in
  the C<catch> block, if there is one. Otherwise, it returns C<undef> in scalar
  context or the empty list in list context. The following examples all
  assign C<"bar"> to C<$x>:
  
    my $x = try { die "foo" } catch { "bar" };
    my $x = try { die "foo" } || "bar";
    my $x = (try { die "foo" }) // "bar";
  
    my $x = eval { die "foo" } || "bar";
  
  You can add C<finally> blocks, yielding the following:
  
    my $x;
    try { die 'foo' } finally { $x = 'bar' };
    try { die 'foo' } catch { warn "Got a die: $_" } finally { $x = 'bar' };
  
  C<finally> blocks are always executed making them suitable for cleanup code
  which cannot be handled using local.  You can add as many C<finally> blocks to a
  given C<try> block as you like.
  
  Note that adding a C<finally> block without a preceding C<catch> block
  suppresses any errors. This behaviour is consistent with using a standalone
  C<eval>, but it is not consistent with C<try>/C<finally> patterns found in
  other programming languages, such as Java, Python, Javascript or C#. If you
  learnt the C<try>/C<finally> pattern from one of these languages, watch out for
  this.
  
  =head1 EXPORTS
  
  All functions are exported by default using L<Exporter>.
  
  If you need to rename the C<try>, C<catch> or C<finally> keyword consider using
  L<Sub::Import> to get L<Sub::Exporter>'s flexibility.
  
  =over 4
  
  =item try (&;@)
  
  Takes one mandatory C<try> subroutine, an optional C<catch> subroutine and C<finally>
  subroutine.
  
  The mandatory subroutine is evaluated in the context of an C<eval> block.
  
  If no error occurred the value from the first block is returned, preserving
  list/scalar context.
  
  If there was an error and the second subroutine was given it will be invoked
  with the error in C<$_> (localized) and as that block's first and only
  argument.
  
  C<$@> does B<not> contain the error. Inside the C<catch> block it has the same
  value it had before the C<try> block was executed.
  
  Note that the error may be false, but if that happens the C<catch> block will
  still be invoked.
  
  Once all execution is finished then the C<finally> block, if given, will execute.
  
  =item catch (&;@)
  
  Intended to be used in the second argument position of C<try>.
  
  Returns a reference to the subroutine it was given but blessed as
  C<Try::Tiny::Catch> which allows try to decode correctly what to do
  with this code reference.
  
    catch { ... }
  
  Inside the C<catch> block the caught error is stored in C<$_>, while previous
  value of C<$@> is still available for use.  This value may or may not be
  meaningful depending on what happened before the C<try>, but it might be a good
  idea to preserve it in an error stack.
  
  For code that captures C<$@> when throwing new errors (i.e.
  L<Class::Throwable>), you'll need to do:
  
    local $@ = $_;
  
  =item finally (&;@)
  
    try     { ... }
    catch   { ... }
    finally { ... };
  
  Or
  
    try     { ... }
    finally { ... };
  
  Or even
  
    try     { ... }
    finally { ... }
    catch   { ... };
  
  Intended to be the second or third element of C<try>. C<finally> blocks are always
  executed in the event of a successful C<try> or if C<catch> is run. This allows
  you to locate cleanup code which cannot be done via C<local()> e.g. closing a file
  handle.
  
  When invoked, the C<finally> block is passed the error that was caught.  If no
  error was caught, it is passed nothing.  (Note that the C<finally> block does not
  localize C<$_> with the error, since unlike in a C<catch> block, there is no way
  to know if C<$_ == undef> implies that there were no errors.) In other words,
  the following code does just what you would expect:
  
    try {
      die_sometimes();
    } catch {
      # ...code run in case of error
    } finally {
      if (@_) {
        print "The try block died with: @_\n";
      } else {
        print "The try block ran without error.\n";
      }
    };
  
  B<You must always do your own error handling in the C<finally> block>. C<Try::Tiny> will
  not do anything about handling possible errors coming from code located in these
  blocks.
  
  Furthermore B<exceptions in C<finally> blocks are not trappable and are unable
  to influence the execution of your program>. This is due to limitation of
  C<DESTROY>-based scope guards, which C<finally> is implemented on top of. This
  may change in a future version of Try::Tiny.
  
  In the same way C<catch()> blesses the code reference this subroutine does the same
  except it bless them as C<Try::Tiny::Finally>.
  
  =back
  
  =head1 BACKGROUND
  
  There are a number of issues with C<eval>.
  
  =head2 Clobbering $@
  
  When you run an C<eval> block and it succeeds, C<$@> will be cleared, potentially
  clobbering an error that is currently being caught.
  
  This causes action at a distance, clearing previous errors your caller may have
  not yet handled.
  
  C<$@> must be properly localized before invoking C<eval> in order to avoid this
  issue.
  
  More specifically, C<$@> is clobbered at the beginning of the C<eval>, which
  also makes it impossible to capture the previous error before you die (for
  instance when making exception objects with error stacks).
  
  For this reason C<try> will actually set C<$@> to its previous value (the one
  available before entering the C<try> block) in the beginning of the C<eval>
  block.
  
  =head2 Localizing $@ silently masks errors
  
  Inside an C<eval> block, C<die> behaves sort of like:
  
    sub die {
      $@ = $_[0];
      return_undef_from_eval();
    }
  
  This means that if you were polite and localized C<$@> you can't die in that
  scope, or your error will be discarded (printing "Something's wrong" instead).
  
  The workaround is very ugly:
  
    my $error = do {
      local $@;
      eval { ... };
      $@;
    };
  
    ...
    die $error;
  
  =head2 $@ might not be a true value
  
  This code is wrong:
  
    if ( $@ ) {
      ...
    }
  
  because due to the previous caveats it may have been unset.
  
  C<$@> could also be an overloaded error object that evaluates to false, but
  that's asking for trouble anyway.
  
  The classic failure mode is:
  
    sub Object::DESTROY {
      eval { ... }
    }
  
    eval {
      my $obj = Object->new;
  
      die "foo";
    };
  
    if ( $@ ) {
  
    }
  
  In this case since C<Object::DESTROY> is not localizing C<$@> but still uses
  C<eval>, it will set C<$@> to C<"">.
  
  The destructor is called when the stack is unwound, after C<die> sets C<$@> to
  C<"foo at Foo.pm line 42\n">, so by the time C<if ( $@ )> is evaluated it has
  been cleared by C<eval> in the destructor.
  
  The workaround for this is even uglier than the previous ones. Even though we
  can't save the value of C<$@> from code that doesn't localize, we can at least
  be sure the C<eval> was aborted due to an error:
  
    my $failed = not eval {
      ...
  
      return 1;
    };
  
  This is because an C<eval> that caught a C<die> will always return a false
  value.
  
  =head1 SHINY SYNTAX
  
  Using Perl 5.10 you can use L<perlsyn/"Switch statements">.
  
  =for stopwords topicalizer
  
  The C<catch> block is invoked in a topicalizer context (like a C<given> block),
  but note that you can't return a useful value from C<catch> using the C<when>
  blocks without an explicit C<return>.
  
  This is somewhat similar to Perl 6's C<CATCH> blocks. You can use it to
  concisely match errors:
  
    try {
      require Foo;
    } catch {
      when (/^Can't locate .*?\.pm in \@INC/) { } # ignore
      default { die $_ }
    };
  
  =head1 CAVEATS
  
  =over 4
  
  =item *
  
  C<@_> is not available within the C<try> block, so you need to copy your
  argument list. In case you want to work with argument values directly via C<@_>
  aliasing (i.e. allow C<$_[1] = "foo">), you need to pass C<@_> by reference:
  
    sub foo {
      my ( $self, @args ) = @_;
      try { $self->bar(@args) }
    }
  
  or
  
    sub bar_in_place {
      my $self = shift;
      my $args = \@_;
      try { $_ = $self->bar($_) for @$args }
    }
  
  =item *
  
  C<return> returns from the C<try> block, not from the parent sub (note that
  this is also how C<eval> works, but not how L<TryCatch> works):
  
    sub parent_sub {
      try {
        die;
      }
      catch {
        return;
      };
  
      say "this text WILL be displayed, even though an exception is thrown";
    }
  
  Instead, you should capture the return value:
  
    sub parent_sub {
      my $success = try {
        die;
        1;
      };
      return unless $success;
  
      say "This text WILL NEVER appear!";
    }
    # OR
    sub parent_sub_with_catch {
      my $success = try {
        die;
        1;
      }
      catch {
        # do something with $_
        return undef; #see note
      };
      return unless $success;
  
      say "This text WILL NEVER appear!";
    }
  
  Note that if you have a C<catch> block, it must return C<undef> for this to work,
  since if a C<catch> block exists, its return value is returned in place of C<undef>
  when an exception is thrown.
  
  =item *
  
  C<try> introduces another caller stack frame. L<Sub::Uplevel> is not used. L<Carp>
  will not report this when using full stack traces, though, because
  C<%Carp::Internal> is used. This lack of magic is considered a feature.
  
  =for stopwords unhygienically
  
  =item *
  
  The value of C<$_> in the C<catch> block is not guaranteed to be the value of
  the exception thrown (C<$@>) in the C<try> block.  There is no safe way to
  ensure this, since C<eval> may be used unhygienically in destructors.  The only
  guarantee is that the C<catch> will be called if an exception is thrown.
  
  =item *
  
  The return value of the C<catch> block is not ignored, so if testing the result
  of the expression for truth on success, be sure to return a false value from
  the C<catch> block:
  
    my $obj = try {
      MightFail->new;
    } catch {
      ...
  
      return; # avoid returning a true value;
    };
  
    return unless $obj;
  
  =item *
  
  C<$SIG{__DIE__}> is still in effect.
  
  Though it can be argued that C<$SIG{__DIE__}> should be disabled inside of
  C<eval> blocks, since it isn't people have grown to rely on it. Therefore in
  the interests of compatibility, C<try> does not disable C<$SIG{__DIE__}> for
  the scope of the error throwing code.
  
  =item *
  
  Lexical C<$_> may override the one set by C<catch>.
  
  For example Perl 5.10's C<given> form uses a lexical C<$_>, creating some
  confusing behavior:
  
    given ($foo) {
      when (...) {
        try {
          ...
        } catch {
          warn $_; # will print $foo, not the error
          warn $_[0]; # instead, get the error like this
        }
      }
    }
  
  Note that this behavior was changed once again in L<Perl5 version 18
  |https://metacpan.org/module/perldelta#given-now-aliases-the-global-_>.
  However, since the entirety of lexical C<$_> is now L<considered experimental
  |https://metacpan.org/module/perldelta#Lexical-_-is-now-experimental>, it
  is unclear whether the new version 18 behavior is final.
  
  =back
  
  =head1 SEE ALSO
  
  =over 4
  
  =item L<TryCatch>
  
  Much more feature complete, more convenient semantics, but at the cost of
  implementation complexity.
  
  =item L<autodie>
  
  Automatic error throwing for builtin functions and more. Also designed to
  work well with C<given>/C<when>.
  
  =item L<Throwable>
  
  A lightweight role for rolling your own exception classes.
  
  =item L<Error>
  
  Exception object implementation with a C<try> statement. Does not localize
  C<$@>.
  
  =item L<Exception::Class::TryCatch>
  
  Provides a C<catch> statement, but properly calling C<eval> is your
  responsibility.
  
  The C<try> keyword pushes C<$@> onto an error stack, avoiding some of the
  issues with C<$@>, but you still need to localize to prevent clobbering.
  
  =back
  
  =head1 LIGHTNING TALK
  
  I gave a lightning talk about this module, you can see the slides (Firefox
  only):
  
  L<http://web.archive.org/web/20100628040134/http://nothingmuch.woobling.org/talks/takahashi.xul>
  
  Or read the source:
  
  L<http://web.archive.org/web/20100305133605/http://nothingmuch.woobling.org/talks/yapc_asia_2009/try_tiny.yml>
  
  =head1 VERSION CONTROL
  
  L<http://github.com/doy/try-tiny/>
  
  =head1 SUPPORT
  
  Bugs may be submitted through L<the RT bug tracker|https://rt.cpan.org/Public/Dist/Display.html?Name=Try-Tiny>
  (or L<bug-Try-Tiny@rt.cpan.org|mailto:bug-Try-Tiny@rt.cpan.org>).
  
  =head1 AUTHORS
  
  =over 4
  
  =item *
  
  יובל קוג'מן (Yuval Kogman) <nothingmuch@woobling.org>
  
  =item *
  
  Jesse Luehrs <doy@tozt.net>
  
  =back
  
  =head1 CONTRIBUTORS
  
  =for stopwords Karen Etheridge Peter Rabbitson Ricardo Signes Mark Fowler Graham Knop Dagfinn Ilmari Mannsåker Paul Howarth Rudolf Leermakers anaxagoras awalker chromatic Alex cm-perl Andrew Yates David Lowe Glenn Hans Dieter Pearcey Jonathan Yu Marc Mims Stosberg
  
  =over 4
  
  =item *
  
  Karen Etheridge <ether@cpan.org>
  
  =item *
  
  Peter Rabbitson <ribasushi@cpan.org>
  
  =item *
  
  Ricardo Signes <rjbs@cpan.org>
  
  =item *
  
  Mark Fowler <mark@twoshortplanks.com>
  
  =item *
  
  Graham Knop <haarg@haarg.org>
  
  =item *
  
  Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
  
  =item *
  
  Paul Howarth <paul@city-fan.org>
  
  =item *
  
  Rudolf Leermakers <rudolf@hatsuseno.org>
  
  =item *
  
  anaxagoras <walkeraj@gmail.com>
  
  =item *
  
  awalker <awalker@sourcefire.com>
  
  =item *
  
  chromatic <chromatic@wgz.org>
  
  =item *
  
  Alex <alex@koban.(none)>
  
  =item *
  
  cm-perl <cm-perl@users.noreply.github.com>
  
  =item *
  
  Andrew Yates <ayates@haddock.local>
  
  =item *
  
  David Lowe <davidl@lokku.com>
  
  =item *
  
  Glenn Fowler <cebjyre@cpan.org>
  
  =item *
  
  Hans Dieter Pearcey <hdp@weftsoar.net>
  
  =item *
  
  Jonathan Yu <JAWNSY@cpan.org>
  
  =item *
  
  Marc Mims <marc@questright.com>
  
  =item *
  
  Mark Stosberg <mark@stosberg.com>
  
  =back
  
  =head1 COPYRIGHT AND LICENCE
  
  This software is Copyright (c) 2009 by יובל קוג'מן (Yuval Kogman).
  
  This is free software, licensed under:
  
    The MIT (X11) License
  
  =cut
TRY_TINY

$fatpacked{"i686-linux/Class/XSAccessor.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'I686-LINUX_CLASS_XSACCESSOR';
  package Class::XSAccessor;
  use 5.008;
  use strict;
  use warnings;
  use Carp qw/croak/;
  use Class::XSAccessor::Heavy;
  use XSLoader;
  
  our $VERSION = '1.19';
  
  XSLoader::load('Class::XSAccessor', $VERSION);
  
  sub _make_hash {
    my $ref = shift;
  
    if (ref ($ref)) {
      if (ref($ref) eq 'ARRAY') {
        $ref = { map { $_ => $_ } @$ref }
      } 
    } else {
      $ref = { $ref, $ref };
    }
  
    return $ref;
  }
  
  sub import {
    my $own_class = shift;
    my ($caller_pkg) = caller();
  
    # Support both { getters => ... } and plain getters => ...
    my %opts = ref($_[0]) eq 'HASH' ? %{$_[0]} : @_;
  
    $caller_pkg = $opts{class} if defined $opts{class};
  
    # TODO: Refactor. Move more duplicated code to ::Heavy
    my $read_subs      = _make_hash($opts{getters} || {});
    my $set_subs       = _make_hash($opts{setters} || {});
    my $acc_subs       = _make_hash($opts{accessors} || {});
    my $lvacc_subs     = _make_hash($opts{lvalue_accessors} || {});
    my $pred_subs      = _make_hash($opts{predicates} || {});
    my $ex_pred_subs   = _make_hash($opts{exists_predicates} || {});
    my $def_pred_subs  = _make_hash($opts{defined_predicates} || {});
    my $test_subs      = _make_hash($opts{__tests__} || {});
    my $construct_subs = $opts{constructors} || [defined($opts{constructor}) ? $opts{constructor} : ()];
    my $true_subs      = $opts{true} || [];
    my $false_subs     = $opts{false} || [];
  
    foreach my $subtype ( ["getter", $read_subs],
                          ["setter", $set_subs],
                          ["accessor", $acc_subs],
                          ["lvalue_accessor", $lvacc_subs],
                          ["test", $test_subs],
                          ["ex_predicate", $ex_pred_subs],
                          ["def_predicate", $def_pred_subs],
                          ["def_predicate", $pred_subs] )
    {
      my $subs = $subtype->[1];
      foreach my $subname (keys %$subs) {
        my $hashkey = $subs->{$subname};
        _generate_method($caller_pkg, $subname, $hashkey, \%opts, $subtype->[0]);
      }
    }
  
    foreach my $subtype ( ["constructor", $construct_subs],
                          ["true", $true_subs],
                          ["false", $false_subs] )
    {
      foreach my $subname (@{$subtype->[1]}) {
        _generate_method($caller_pkg, $subname, "", \%opts, $subtype->[0]);
      }
    }
  }
  
  sub _generate_method {
    my ($caller_pkg, $subname, $hashkey, $opts, $type) = @_;
  
    croak("Cannot use undef as a hash key for generating an XS $type accessor. (Sub: $subname)")
      if not defined $hashkey;
  
    $subname = "${caller_pkg}::$subname" if $subname !~ /::/;
  
    Class::XSAccessor::Heavy::check_sub_existence($subname) if not $opts->{replace};
    no warnings 'redefine'; # don't warn about an explicitly requested redefine
  
    if ($type eq 'getter') {
      newxs_getter($subname, $hashkey);
    }
    elsif ($type eq 'lvalue_accessor') {
      newxs_lvalue_accessor($subname, $hashkey);
    }
    elsif ($type eq 'setter') {
      newxs_setter($subname, $hashkey, $opts->{chained}||0);
    }
    elsif ($type eq 'def_predicate') {
      newxs_defined_predicate($subname, $hashkey);
    }
    elsif ($type eq 'ex_predicate') {
      newxs_exists_predicate($subname, $hashkey);
    }
    elsif ($type eq 'constructor') {
      newxs_constructor($subname);
    }
    elsif ($type eq 'true') {
      newxs_boolean($subname, 1);
    }
    elsif ($type eq 'false') {
      newxs_boolean($subname, 0);
    }
    elsif ($type eq 'test') {
      newxs_test($subname, $hashkey);
    }
    else {
      newxs_accessor($subname, $hashkey, $opts->{chained}||0);
    }
  }
  
  1;
  
  __END__
  
  =head1 NAME
  
  Class::XSAccessor - Generate fast XS accessors without runtime compilation
  
  =head1 SYNOPSIS
  
    package MyClass;
    use Class::XSAccessor
      replace     => 1,   # Replace existing methods (if any)
      constructor => 'new',
      getters     => {
        get_foo => 'foo', # 'foo' is the hash key to access
        get_bar => 'bar',
      },
      setters => {
        set_foo => 'foo',
        set_bar => 'bar',
      },
      accessors => {
        foo => 'foo',
        bar => 'bar',
      },
      # "predicates" is an alias for "defined_predicates"
      defined_predicates => {
        defined_foo => 'foo',
        defined_bar => 'bar',
      },
      exists_predicates => {
        has_foo => 'foo',
        has_bar => 'bar',
      },
      lvalue_accessors => { # see below
        baz => 'baz', # ...
      },
      true  => [ 'is_token', 'is_whitespace' ],
      false => [ 'significant' ];
    
    # The imported methods are implemented in fast XS.
    
    # normal class code here.
  
  As of version 1.05, some alternative syntax forms are available:
  
    package MyClass;
    
    # Options can be passed as a HASH reference, if preferred,
    # which can also help Perl::Tidy to format the statement correctly.
    use Class::XSAccessor {
       # If the name => key values are always identical,
       # the following shorthand can be used.
       accessors => [ 'foo', 'bar' ],
    };
  
  =head1 DESCRIPTION
  
  Class::XSAccessor implements fast read, write and read/write accessors in XS.
  Additionally, it can provide predicates such as C<has_foo()> for testing
  whether the attribute C<foo> exists in the object (which is different from
  "is defined within the object").
  It only works with objects that are implemented as ordinary hashes.
  L<Class::XSAccessor::Array> implements the same interface for objects
  that use arrays for their internal representation.
  
  Since version 0.10, the module can also generate simple constructors
  (implemented in XS). Simply supply the
  C<constructor =E<gt> 'constructor_name'> option or the
  C<constructors =E<gt> ['new', 'create', 'spawn']> option.
  These constructors do the equivalent of the following Perl code:
  
    sub new {
      my $class = shift;
      return bless { @_ }, ref($class)||$class;
    }
  
  That means they can be called on objects and classes but will not
  clone objects entirely. Parameters to C<new()> are added to the
  object.
  
  The XS accessor methods are between 3 and 4 times faster than typical
  pure-Perl accessors in some simple benchmarking.
  The lower factor applies to the potentially slightly obscure
  C<sub set_foo_pp {$_[0]-E<gt>{foo} = $_[1]}>, so if you usually
  write clear code, a factor of 3.5 speed-up is a good estimate.
  If in doubt, do your own benchmarking!
  
  The method names may be fully qualified. The example in the synopsis could
  have been written as C<MyClass::get_foo> instead
  of C<get_foo>. This way, methods can be installed in classes other
  than the current class. See also: the C<class> option below.
  
  By default, the setters return the new value that was set,
  and the accessors (mutators) do the same. This behaviour can be changed
  with the C<chained> option - see below. The predicates return a boolean.
  
  Since version 1.01, C<Class::XSAccessor> can generate extremely simple methods which
  just return true or false (and always do so). If that seems like a
  really superfluous thing to you, then consider a large class hierarchy
  with interfaces such as L<PPI>. These methods are provided by the C<true>
  and C<false> options - see the synopsis.
  
  C<defined_predicates> check whether a given object attribute is defined.
  C<predicates> is an alias for C<defined_predicates> for compatibility with
  older versions of C<Class::XSAccessor>. C<exists_predicates> checks
  whether the given attribute exists in the object using C<exists>.
  
  =head1 OPTIONS
  
  In addition to specifying the types and names of accessors, additional options
  can be supplied which modify behaviour. The options are specified as key/value pairs
  in the same manner as the accessor declaration. For example:
  
    use Class::XSAccessor
      getters => {
        get_foo => 'foo',
      },
      replace => 1;
  
  The list of available options is:
  
  =head2 replace
  
  Set this to a true value to prevent C<Class::XSAccessor> from
  complaining about replacing existing subroutines.
  
  =head2 chained
  
  Set this to a true value to change the return value of setters
  and mutators (when called with an argument).
  If C<chained> is enabled, the setters and accessors/mutators will
  return the object. Mutators called without an argument still
  return the value of the associated attribute.
  
  As with the other options, C<chained> affects all methods generated
  in the same C<use Class::XSAccessor ...> statement.
  
  =head2 class
  
  By default, the accessors are generated in the calling class. The
  the C<class> option allows the target class to be specified.
  
  =head1 LVALUES
  
  Support for lvalue accessors via the keyword C<lvalue_accessors>
  was added in version 1.08. At this point, B<THEY ARE CONSIDERED HIGHLY
  EXPERIMENTAL>. Furthermore, their performance hasn't been benchmarked
  yet.
  
  The following example demonstrates an lvalue accessor:
  
    package Address;
    use Class::XSAccessor
      constructor => 'new',
      lvalue_accessors => { zip_code => 'zip' };
    
    package main;
    my $address = Address->new(zip => 2);
    print $address->zip_code, "\n"; # prints 2
    $address->zip_code = 76135; # <--- This is it!
    print $address->zip_code, "\n"; # prints 76135
  
  =head1 CAVEATS
  
  Probably won't work for objects based on I<tied> hashes. But that's a strange thing to do anyway.
  
  Scary code exploiting strange XS features.
  
  If you think writing an accessor in XS should be a laughably simple exercise, then
  please contemplate how you could instantiate a new XS accessor for a new hash key
  that's only known at run-time. Note that compiling C code at run-time a la L<Inline::C|Inline::C>
  is a no go.
  
  Threading. With version 1.00, a memory leak has been B<fixed>. Previously, a small amount of
  memory would leak if C<Class::XSAccessor>-based classes were loaded in a subthread without having
  been loaded in the "main" thread. If the subthread then terminated, a hash key and an int per
  associated method used to be lost. Note that this mattered only if classes were B<only> loaded
  in a sort of throw-away thread.
  
  In the new implementation, as of 1.00, the memory will still not be released, in the same situation,
  but it will be recycled when the same class, or a similar class, is loaded again in B<any> thread.
  
  =head1 SEE ALSO
  
  =over
  
  =item * L<Class::XSAccessor::Array>
  
  =item * L<AutoXS>
  
  =back
  
  =head1 AUTHOR
  
  Steffen Mueller E<lt>smueller@cpan.orgE<gt>
  
  chocolateboy E<lt>chocolate@cpan.orgE<gt>
  
  =head1 COPYRIGHT AND LICENSE
  
  Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013 by Steffen Mueller
  
  This library is free software; you can redistribute it and/or modify
  it under the same terms as Perl itself, either Perl version 5.8 or,
  at your option, any later version of Perl 5 you may have available.
  
  =cut
I686-LINUX_CLASS_XSACCESSOR

$fatpacked{"i686-linux/Class/XSAccessor/Array.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'I686-LINUX_CLASS_XSACCESSOR_ARRAY';
  package Class::XSAccessor::Array;
  use 5.008;
  use strict;
  use warnings;
  use Carp qw/croak/;
  use Class::XSAccessor;
  use Class::XSAccessor::Heavy;
  
  our $VERSION = '1.19';
  
  sub import {
    my $own_class = shift;
    my ($caller_pkg) = caller();
  
    # Support both { getters => ... } and plain getters => ...
    my %opts = ref($_[0]) eq 'HASH' ? %{$_[0]} : @_;
  
    $caller_pkg = $opts{class} if defined $opts{class};
  
    my $read_subs      = $opts{getters} || {};
    my $set_subs       = $opts{setters} || {};
    my $acc_subs       = $opts{accessors} || {};
    my $lvacc_subs     = $opts{lvalue_accessors} || {};
    my $pred_subs      = $opts{predicates} || {};
    my $construct_subs = $opts{constructors} || [defined($opts{constructor}) ? $opts{constructor} : ()];  
    my $true_subs      = $opts{true} || [];
    my $false_subs     = $opts{false} || [];
  
  
    foreach my $subtype ( ["getter", $read_subs],
                          ["setter", $set_subs],
                          ["accessor", $acc_subs],
                          ["lvalue_accessor", $lvacc_subs],
                          ["pred_subs", $pred_subs] )
    {
      my $subs = $subtype->[1];
      foreach my $subname (keys %$subs) {
        my $array_index = $subs->{$subname};
        _generate_method($caller_pkg, $subname, $array_index, \%opts, $subtype->[0]);
      }
    }
     
    foreach my $subtype ( ["constructor", $construct_subs],
                          ["true", $true_subs],
                          ["false", $false_subs] )
    {
      foreach my $subname (@{$subtype->[1]}) {
        _generate_method($caller_pkg, $subname, "", \%opts, $subtype->[0]);
      }
    }
  }
  
  sub _generate_method {
    my ($caller_pkg, $subname, $array_index, $opts, $type) = @_;
  
    croak("Cannot use undef as a array index for generating an XS $type accessor. (Sub: $subname)")
      if not defined $array_index;
  
    $subname = "${caller_pkg}::$subname" if $subname !~ /::/;
  
    Class::XSAccessor::Heavy::check_sub_existence($subname) if not $opts->{replace};
    no warnings 'redefine'; # don't warn about an explicitly requested redefine
  
    if ($type eq 'getter') {
      newxs_getter($subname, $array_index);
    }
    if ($type eq 'lvalue_accessor') {
      newxs_lvalue_accessor($subname, $array_index);
    }
    elsif ($type eq 'setter') {
      newxs_setter($subname, $array_index, $opts->{chained}||0);
    }
    elsif ($type eq 'predicate') {
      newxs_predicate($subname, $array_index);
    }
    elsif ($type eq 'constructor') {
      newxs_constructor($subname);
    }
    elsif ($type eq 'true') {
      Class::XSAccessor::newxs_boolean($subname, 1);
    }
    elsif ($type eq 'false') {
      Class::XSAccessor::newxs_boolean($subname, 0);
    }
    else {
      newxs_accessor($subname, $array_index, $opts->{chained}||0);
    }
  }
  
  1;
  
  __END__
  
  =head1 NAME
  
  Class::XSAccessor::Array - Generate fast XS accessors without runtime compilation
  
  =head1 SYNOPSIS
    
    package MyClassUsingArraysAsInternalStorage;
    use Class::XSAccessor::Array
      constructor => 'new',
      getters => {
        get_foo => 0, # 0 is the array index to access
        get_bar => 1,
      },
      setters => {
        set_foo => 0,
        set_bar => 1,
      },
      accessors => { # a mutator
        buz => 2,
      },
      predicates => { # test for definedness
        has_buz => 2,
      },
      lvalue_accessors => { # see below
        baz => 3,
      },
      true => [ 'is_token', 'is_whitespace' ],
      false => [ 'significant' ];
    
    # The imported methods are implemented in fast XS.
    
    # normal class code here.
  
  As of version 1.05, some alternative syntax forms are available:
  
    package MyClass;
    
    # Options can be passed as a HASH reference if you prefer it,
    # which can also help PerlTidy to flow the statement correctly.
    use Class::XSAccessor {
      getters => {
        get_foo => 0,
        get_bar => 1,
      },
    };
  
  =head1 DESCRIPTION
  
  The module implements fast XS accessors both for getting at and
  setting an object attribute. Additionally, the module supports
  mutators and simple predicates (C<has_foo()> like tests for definedness
  of an attributes).
  The module works only with objects
  that are implemented as B<arrays>. Using it on hash-based objects is
  bound to make your life miserable. Refer to L<Class::XSAccessor> for
  an implementation that works with hash-based objects.
  
  A simple benchmark showed a significant performance
  advantage over writing accessors in Perl.
  
  Since version 0.10, the module can also generate simple constructors
  (implemented in XS) for you. Simply supply the
  C<constructor =E<gt> 'constructor_name'> option or the
  C<constructors =E<gt> ['new', 'create', 'spawn']> option.
  These constructors do the equivalent of the following Perl code:
  
    sub new {
      my $class = shift;
      return bless [], ref($class)||$class;
    }
  
  That means they can be called on objects and classes but will not
  clone objects entirely. Note that any parameters to new() will be
  discarded! If there is a better idiom for array-based objects, let
  me know.
  
  While generally more obscure than hash-based objects,
  objects using blessed arrays as internal representation
  are a bit faster as its somewhat faster to access arrays than hashes.
  Accordingly, this module is slightly faster (~10-15%) than
  L<Class::XSAccessor>, which works on hash-based objects.
  
  The method names may be fully qualified. In the example of the
  synopsis, you could have written C<MyClass::get_foo> instead
  of C<get_foo>. This way, you can install methods in classes other
  than the current class. See also: The C<class> option below.
  
  Since version 1.01, you can generate extremely simple methods which
  just return true or false (and always do so). If that seems like a
  really superfluous thing to you, then think of a large class hierarchy
  with interfaces such as PPI. This is implemented as the C<true>
  and C<false> options, see synopsis.
  
  =head1 OPTIONS
  
  In addition to specifying the types and names of accessors, you can add options
  which modify behaviour. The options are specified as key/value pairs just as the
  accessor declaration. Example:
  
    use Class::XSAccessor::Array
      getters => {
        get_foo => 0,
      },
      replace => 1;
  
  The list of available options is:
  
  =head2 replace
  
  Set this to a true value to prevent C<Class::XSAccessor::Array> from
  complaining about replacing existing subroutines.
  
  =head2 chained
  
  Set this to a true value to change the return value of setters
  and mutators (when called with an argument).
  If C<chained> is enabled, the setters and accessors/mutators will
  return the object. Mutators called without an argument still
  return the value of the associated attribute.
  
  As with the other options, C<chained> affects all methods generated
  in the same C<use Class::XSAccessor::Array ...> statement.
  
  =head2 class
  
  By default, the accessors are generated in the calling class. Using
  the C<class> option, you can explicitly specify where the methods
  are to be generated.
  
  =head1 LVALUES
  
  Support for lvalue accessors via the keyword C<lvalue_accessors>
  was added in version 1.08. At this point, B<THEY ARE CONSIDERED HIGHLY
  EXPERIMENTAL>. Furthermore, their performance hasn't been benchmarked
  yet.
  
  The following example demonstrates an lvalue accessor:
  
    package Address;
    use Class::XSAccessor
      constructor => 'new',
      lvalue_accessors => { zip_code => 0 };
    
    package main;
    my $address = Address->new(2);
    print $address->zip_code, "\n"; # prints 2
    $address->zip_code = 76135; # <--- This is it!
    print $address->zip_code, "\n"; # prints 76135
  
  =head1 CAVEATS
  
  Probably wouldn't work if your objects are I<tied>. But that's a strange thing to do anyway.
  
  Scary code exploiting strange XS features.
  
  If you think writing an accessor in XS should be a laughably simple exercise, then
  please contemplate how you could instantiate a new XS accessor for a new hash key
  or array index that's only known at run-time. Note that compiling C code at run-time
  a la Inline::C is a no go.
  
  Threading. With version 1.00, a memory leak has been B<fixed> that would leak a small amount of
  memory if you loaded C<Class::XSAccessor>-based classes in a subthread that hadn't been loaded
  in the "main" thread before. If the subthread then terminated, a hash key and an int per
  associated method used to be lost. Note that this mattered only if classes were B<only> loaded
  in a sort of throw-away thread.
  
  In the new implementation as of 1.00, the memory will not be released again either in the above
  situation. But it will be recycled when the same class or a similar class is loaded
  again in B<any> thread.
  
  =head1 SEE ALSO
  
  L<Class::XSAccessor>
  
  L<AutoXS>
  
  =head1 AUTHOR
  
  Steffen Mueller E<lt>smueller@cpan.orgE<gt>
  
  chocolateboy E<lt>chocolate@cpan.orgE<gt>
  
  =head1 COPYRIGHT AND LICENSE
  
  Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013 by Steffen Mueller
  
  This library is free software; you can redistribute it and/or modify
  it under the same terms as Perl itself, either Perl version 5.8 or,
  at your option, any later version of Perl 5 you may have available.
  
  =cut
I686-LINUX_CLASS_XSACCESSOR_ARRAY

$fatpacked{"i686-linux/Class/XSAccessor/Heavy.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'I686-LINUX_CLASS_XSACCESSOR_HEAVY';
  package # hide from PAUSE
      Class::XSAccessor::Heavy;
  
  use 5.008;
  use strict;
  use warnings;
  use Carp;
  
  our $VERSION  = '1.19';
  our @CARP_NOT = qw(
          Class::XSAccessor
          Class::XSAccessor::Array
  );
  
  # TODO Move more duplicated code from XSA and XSA::Array here
  
  
  sub check_sub_existence {
    my $subname = shift;
  
    my $sub_package = $subname;
    $sub_package =~ s/([^:]+)$// or die;
    my $bare_subname = $1;
      
    my $sym;
    {
      no strict 'refs';
      $sym = \%{"$sub_package"};
    }
    no warnings;
    local *s = $sym->{$bare_subname};
    my $coderef = *s{CODE};
    if ($coderef) {
      $sub_package =~ s/::$//;
      Carp::croak("Cannot replace existing subroutine '$bare_subname' in package '$sub_package' with an XS implementation. If you wish to force a replacement, add the 'replace => 1' parameter to the arguments of 'use ".(caller())[0]."'.");
    }
  }
  
  1;
  
  __END__
  
  =head1 NAME
  
  Class::XSAccessor::Heavy - Guts you don't care about
  
  =head1 SYNOPSIS
    
    use Class::XSAccessor!
  
  =head1 DESCRIPTION
  
  Common guts for Class::XSAccessor and Class::XSAccessor::Array.
  No user-serviceable parts inside!
  
  =head1 SEE ALSO
  
  L<Class::XSAccessor>
  L<Class::XSAccessor::Array>
  
  =head1 AUTHOR
  
  Steffen Mueller, E<lt>smueller@cpan.orgE<gt>
  
  chocolateboy, E<lt>chocolate@cpan.orgE<gt>
  
  =head1 COPYRIGHT AND LICENSE
  
  Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013 by Steffen Mueller
  
  This library is free software; you can redistribute it and/or modify
  it under the same terms as Perl itself, either Perl version 5.8 or,
  at your option, any later version of Perl 5 you may have available.
  
  =cut
  
I686-LINUX_CLASS_XSACCESSOR_HEAVY

$fatpacked{"i686-linux/List/Util.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'I686-LINUX_LIST_UTIL';
  # Copyright (c) 1997-2009 Graham Barr <gbarr@pobox.com>. All rights reserved.
  # This program is free software; you can redistribute it and/or
  # modify it under the same terms as Perl itself.
  #
  # Maintained since 2013 by Paul Evans <leonerd@leonerd.org.uk>
  
  package List::Util;
  
  use strict;
  require Exporter;
  
  our @ISA        = qw(Exporter);
  our @EXPORT_OK  = qw(
    all any first min max minstr maxstr none notall product reduce sum sum0 shuffle
    pairmap pairgrep pairfirst pairs pairkeys pairvalues
  );
  our $VERSION    = "1.41";
  our $XS_VERSION = $VERSION;
  $VERSION    = eval $VERSION;
  
  require XSLoader;
  XSLoader::load('List::Util', $XS_VERSION);
  
  sub import
  {
    my $pkg = caller;
  
    # (RT88848) Touch the caller's $a and $b, to avoid the warning of
    #   Name "main::a" used only once: possible typo" warning
    no strict 'refs';
    ${"${pkg}::a"} = ${"${pkg}::a"};
    ${"${pkg}::b"} = ${"${pkg}::b"};
  
    goto &Exporter::import;
  }
  
  # For objects returned by pairs()
  sub List::Util::_Pair::key   { shift->[0] }
  sub List::Util::_Pair::value { shift->[1] }
  
  1;
  
  __END__
  
  =head1 NAME
  
  List::Util - A selection of general-utility list subroutines
  
  =head1 SYNOPSIS
  
      use List::Util qw(first max maxstr min minstr reduce shuffle sum);
  
  =head1 DESCRIPTION
  
  C<List::Util> contains a selection of subroutines that people have expressed
  would be nice to have in the perl core, but the usage would not really be high
  enough to warrant the use of a keyword, and the size so small such that being
  individual extensions would be wasteful.
  
  By default C<List::Util> does not export any subroutines.
  
  =cut
  
  =head1 LIST-REDUCTION FUNCTIONS
  
  The following set of functions all reduce a list down to a single value.
  
  =cut
  
  =head2 $result = reduce { BLOCK } @list
  
  Reduces C<@list> by calling C<BLOCK> in a scalar context multiple times,
  setting C<$a> and C<$b> each time. The first call will be with C<$a> and C<$b>
  set to the first two elements of the list, subsequent calls will be done by
  setting C<$a> to the result of the previous call and C<$b> to the next element
  in the list.
  
  Returns the result of the last call to the C<BLOCK>. If C<@list> is empty then
  C<undef> is returned. If C<@list> only contains one element then that element
  is returned and C<BLOCK> is not executed.
  
  The following examples all demonstrate how C<reduce> could be used to implement
  the other list-reduction functions in this module. (They are not in fact
  implemented like this, but instead in a more efficient manner in individual C
  functions).
  
      $foo = reduce { defined($a)            ? $a :
                      $code->(local $_ = $b) ? $b :
                                               undef } undef, @list # first
  
      $foo = reduce { $a > $b ? $a : $b } 1..10       # max
      $foo = reduce { $a gt $b ? $a : $b } 'A'..'Z'   # maxstr
      $foo = reduce { $a < $b ? $a : $b } 1..10       # min
      $foo = reduce { $a lt $b ? $a : $b } 'aa'..'zz' # minstr
      $foo = reduce { $a + $b } 1 .. 10               # sum
      $foo = reduce { $a . $b } @bar                  # concat
  
      $foo = reduce { $a || $code->(local $_ = $b) } 0, @bar   # any
      $foo = reduce { $a && $code->(local $_ = $b) } 1, @bar   # all
      $foo = reduce { $a && !$code->(local $_ = $b) } 1, @bar  # none
      $foo = reduce { $a || !$code->(local $_ = $b) } 0, @bar  # notall
         # Note that these implementations do not fully short-circuit
  
  If your algorithm requires that C<reduce> produce an identity value, then make
  sure that you always pass that identity value as the first argument to prevent
  C<undef> being returned
  
    $foo = reduce { $a + $b } 0, @values;             # sum with 0 identity value
  
  The remaining list-reduction functions are all specialisations of this generic
  idea.
  
  =head2 any
  
      my $bool = any { BLOCK } @list;
  
  I<Since version 1.33.>
  
  Similar to C<grep> in that it evaluates C<BLOCK> setting C<$_> to each element
  of C<@list> in turn. C<any> returns true if any element makes the C<BLOCK>
  return a true value. If C<BLOCK> never returns true or C<@list> was empty then
  it returns false.
  
  Many cases of using C<grep> in a conditional can be written using C<any>
  instead, as it can short-circuit after the first true result.
  
      if( any { length > 10 } @strings ) {
          # at least one string has more than 10 characters
      }
  
  =head2 all
  
      my $bool = all { BLOCK } @list;
  
  I<Since version 1.33.>
  
  Similar to L</any>, except that it requires all elements of the C<@list> to
  make the C<BLOCK> return true. If any element returns false, then it returns
  false. If the C<BLOCK> never returns false or the C<@list> was empty then it
  returns true.
  
  =head2 none
  
  =head2 notall
  
      my $bool = none { BLOCK } @list;
  
      my $bool = notall { BLOCK } @list;
  
  I<Since version 1.33.>
  
  Similar to L</any> and L</all>, but with the return sense inverted. C<none>
  returns true only if no value in the C<@list> causes the C<BLOCK> to return
  true, and C<notall> returns true only if not all of the values do.
  
  =head2 first
  
      my $val = first { BLOCK } @list;
  
  Similar to C<grep> in that it evaluates C<BLOCK> setting C<$_> to each element
  of C<@list> in turn. C<first> returns the first element where the result from
  C<BLOCK> is a true value. If C<BLOCK> never returns true or C<@list> was empty
  then C<undef> is returned.
  
      $foo = first { defined($_) } @list    # first defined value in @list
      $foo = first { $_ > $value } @list    # first value in @list which
                                            # is greater than $value
  
  =head2 max
  
      my $num = max @list;
  
  Returns the entry in the list with the highest numerical value. If the list is
  empty then C<undef> is returned.
  
      $foo = max 1..10                # 10
      $foo = max 3,9,12               # 12
      $foo = max @bar, @baz           # whatever
  
  =head2 maxstr
  
      my $str = maxstr @list;
  
  Similar to L</max>, but treats all the entries in the list as strings and
  returns the highest string as defined by the C<gt> operator. If the list is
  empty then C<undef> is returned.
  
      $foo = maxstr 'A'..'Z'          # 'Z'
      $foo = maxstr "hello","world"   # "world"
      $foo = maxstr @bar, @baz        # whatever
  
  =head2 min
  
      my $num = min @list;
  
  Similar to L</max> but returns the entry in the list with the lowest numerical
  value. If the list is empty then C<undef> is returned.
  
      $foo = min 1..10                # 1
      $foo = min 3,9,12               # 3
      $foo = min @bar, @baz           # whatever
  
  =head2 minstr
  
      my $str = minstr @list;
  
  Similar to L</min>, but treats all the entries in the list as strings and
  returns the lowest string as defined by the C<lt> operator. If the list is
  empty then C<undef> is returned.
  
      $foo = minstr 'A'..'Z'          # 'A'
      $foo = minstr "hello","world"   # "hello"
      $foo = minstr @bar, @baz        # whatever
  
  =head2 product
  
      my $num = product @list;
  
  I<Since version 1.35.>
  
  Returns the numerical product of all the elements in C<@list>. If C<@list> is
  empty then C<1> is returned.
  
      $foo = product 1..10            # 3628800
      $foo = product 3,9,12           # 324
  
  =head2 sum
  
      my $num_or_undef = sum @list;
  
  Returns the numerical sum of all the elements in C<@list>. For backwards
  compatibility, if C<@list> is empty then C<undef> is returned.
  
      $foo = sum 1..10                # 55
      $foo = sum 3,9,12               # 24
      $foo = sum @bar, @baz           # whatever
  
  =head2 sum0
  
      my $num = sum0 @list;
  
  I<Since version 1.26.>
  
  Similar to L</sum>, except this returns 0 when given an empty list, rather
  than C<undef>.
  
  =cut
  
  =head1 KEY/VALUE PAIR LIST FUNCTIONS
  
  The following set of functions, all inspired by L<List::Pairwise>, consume an
  even-sized list of pairs. The pairs may be key/value associations from a hash,
  or just a list of values. The functions will all preserve the original ordering
  of the pairs, and will not be confused by multiple pairs having the same "key"
  value - nor even do they require that the first of each pair be a plain string.
  
  =cut
  
  =head2 pairgrep
  
      my @kvlist = pairgrep { BLOCK } @kvlist;
  
      my $count = pairgrep { BLOCK } @kvlist;
  
  I<Since version 1.29.>
  
  Similar to perl's C<grep> keyword, but interprets the given list as an
  even-sized list of pairs. It invokes the C<BLOCK> multiple times, in scalar
  context, with C<$a> and C<$b> set to successive pairs of values from the
  C<@kvlist>.
  
  Returns an even-sized list of those pairs for which the C<BLOCK> returned true
  in list context, or the count of the B<number of pairs> in scalar context.
  (Note, therefore, in scalar context that it returns a number half the size of
  the count of items it would have returned in list context).
  
      @subset = pairgrep { $a =~ m/^[[:upper:]]+$/ } @kvlist
  
  As with C<grep> aliasing C<$_> to list elements, C<pairgrep> aliases C<$a> and
  C<$b> to elements of the given list. Any modifications of it by the code block
  will be visible to the caller.
  
  =head2 pairfirst
  
      my ( $key, $val ) = pairfirst { BLOCK } @kvlist;
  
      my $found = pairfirst { BLOCK } @kvlist;
  
  I<Since version 1.30.>
  
  Similar to the L</first> function, but interprets the given list as an
  even-sized list of pairs. It invokes the C<BLOCK> multiple times, in scalar
  context, with C<$a> and C<$b> set to successive pairs of values from the
  C<@kvlist>.
  
  Returns the first pair of values from the list for which the C<BLOCK> returned
  true in list context, or an empty list of no such pair was found. In scalar
  context it returns a simple boolean value, rather than either the key or the
  value found.
  
      ( $key, $value ) = pairfirst { $a =~ m/^[[:upper:]]+$/ } @kvlist
  
  As with C<grep> aliasing C<$_> to list elements, C<pairfirst> aliases C<$a> and
  C<$b> to elements of the given list. Any modifications of it by the code block
  will be visible to the caller.
  
  =head2 pairmap
  
      my @list = pairmap { BLOCK } @kvlist;
  
      my $count = pairmap { BLOCK } @kvlist;
  
  I<Since version 1.29.>
  
  Similar to perl's C<map> keyword, but interprets the given list as an
  even-sized list of pairs. It invokes the C<BLOCK> multiple times, in list
  context, with C<$a> and C<$b> set to successive pairs of values from the
  C<@kvlist>.
  
  Returns the concatenation of all the values returned by the C<BLOCK> in list
  context, or the count of the number of items that would have been returned in
  scalar context.
  
      @result = pairmap { "The key $a has value $b" } @kvlist
  
  As with C<map> aliasing C<$_> to list elements, C<pairmap> aliases C<$a> and
  C<$b> to elements of the given list. Any modifications of it by the code block
  will be visible to the caller.
  
  See L</KNOWN BUGS> for a known-bug with C<pairmap>, and a workaround.
  
  =head2 pairs
  
      my @pairs = pairs @kvlist;
  
  I<Since version 1.29.>
  
  A convenient shortcut to operating on even-sized lists of pairs, this function
  returns a list of ARRAY references, each containing two items from the given
  list. It is a more efficient version of
  
      @pairs = pairmap { [ $a, $b ] } @kvlist
  
  It is most convenient to use in a C<foreach> loop, for example:
  
      foreach my $pair ( pairs @KVLIST ) {
         my ( $key, $value ) = @$pair;
         ...
      }
  
  Since version C<1.39> these ARRAY references are blessed objects, recognising
  the two methods C<key> and C<value>. The following code is equivalent:
  
      foreach my $pair ( pairs @KVLIST ) {
         my $key   = $pair->key;
         my $value = $pair->value;
         ...
      }
  
  =head2 pairkeys
  
      my @keys = pairkeys @kvlist;
  
  I<Since version 1.29.>
  
  A convenient shortcut to operating on even-sized lists of pairs, this function
  returns a list of the the first values of each of the pairs in the given list.
  It is a more efficient version of
  
      @keys = pairmap { $a } @kvlist
  
  =head2 pairvalues
  
      my @values = pairvalues @kvlist;
  
  I<Since version 1.29.>
  
  A convenient shortcut to operating on even-sized lists of pairs, this function
  returns a list of the the second values of each of the pairs in the given list.
  It is a more efficient version of
  
      @values = pairmap { $b } @kvlist
  
  =cut
  
  =head1 OTHER FUNCTIONS
  
  =cut
  
  =head2 shuffle
  
      my @values = shuffle @values;
  
  Returns the values of the input in a random order
  
      @cards = shuffle 0..51      # 0..51 in a random order
  
  =cut
  
  =head1 KNOWN BUGS
  
  =head2 RT #95409
  
  L<https://rt.cpan.org/Ticket/Display.html?id=95409>
  
  If the block of code given to L</pairmap> contains lexical variables that are
  captured by a returned closure, and the closure is executed after the block
  has been re-used for the next iteration, these lexicals will not see the
  correct values. For example:
  
   my @subs = pairmap {
      my $var = "$a is $b";
      sub { print "$var\n" };
   } one => 1, two => 2, three => 3;
  
   $_->() for @subs;
  
  Will incorrectly print
  
   three is 3
   three is 3
   three is 3
  
  This is due to the performance optimisation of using C<MULTICALL> for the code
  block, which means that fresh SVs do not get allocated for each call to the
  block. Instead, the same SV is re-assigned for each iteration, and all the
  closures will share the value seen on the final iteration.
  
  To work around this bug, surround the code with a second set of braces. This
  creates an inner block that defeats the C<MULTICALL> logic, and does get fresh
  SVs allocated each time:
  
   my @subs = pairmap {
      {
         my $var = "$a is $b";
         sub { print "$var\n"; }
      }
   } one => 1, two => 2, three => 3;
  
  This bug only affects closures that are generated by the block but used
  afterwards. Lexical variables that are only used during the lifetime of the
  block's execution will take their individual values for each invocation, as
  normal.
  
  =head1 SUGGESTED ADDITIONS
  
  The following are additions that have been requested, but I have been reluctant
  to add due to them being very simple to implement in perl
  
    # How many elements are true
  
    sub true { scalar grep { $_ } @_ }
  
    # How many elements are false
  
    sub false { scalar grep { !$_ } @_ }
  
  =head1 SEE ALSO
  
  L<Scalar::Util>, L<List::MoreUtils>
  
  =head1 COPYRIGHT
  
  Copyright (c) 1997-2007 Graham Barr <gbarr@pobox.com>. All rights reserved.
  This program is free software; you can redistribute it and/or
  modify it under the same terms as Perl itself.
  
  Recent additions and current maintenance by
  Paul Evans, <leonerd@leonerd.org.uk>.
  
  =cut
I686-LINUX_LIST_UTIL

$fatpacked{"i686-linux/List/Util/XS.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'I686-LINUX_LIST_UTIL_XS';
  package List::Util::XS;
  use strict;
  use List::Util;
  
  our $VERSION = "1.41";       # FIXUP
  $VERSION = eval $VERSION;    # FIXUP
  
  1;
  __END__
  
  =head1 NAME
  
  List::Util::XS - Indicate if List::Util was compiled with a C compiler
  
  =head1 SYNOPSIS
  
      use List::Util::XS 1.20;
  
  =head1 DESCRIPTION
  
  C<List::Util::XS> can be used as a dependency to ensure List::Util was
  installed using a C compiler and that the XS version is installed.
  
  During installation C<$List::Util::XS::VERSION> will be set to
  C<undef> if the XS was not compiled.
  
  Starting with release 1.23_03, Scalar-List-Util is B<always> using
  the XS implementation, but for backwards compatibility, we still
  ship the C<List::Util::XS> module which just loads C<List::Util>.
  
  =head1 SEE ALSO
  
  L<Scalar::Util>, L<List::Util>, L<List::MoreUtils>
  
  =head1 COPYRIGHT
  
  Copyright (c) 2008 Graham Barr <gbarr@pobox.com>. All rights reserved.
  This program is free software; you can redistribute it and/or
  modify it under the same terms as Perl itself.
  
  =cut
I686-LINUX_LIST_UTIL_XS

$fatpacked{"i686-linux/Scalar/Util.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'I686-LINUX_SCALAR_UTIL';
  # Copyright (c) 1997-2007 Graham Barr <gbarr@pobox.com>. All rights reserved.
  # This program is free software; you can redistribute it and/or
  # modify it under the same terms as Perl itself.
  #
  # Maintained since 2013 by Paul Evans <leonerd@leonerd.org.uk>
  
  package Scalar::Util;
  
  use strict;
  require Exporter;
  require List::Util; # List::Util loads the XS
  
  our @ISA       = qw(Exporter);
  our @EXPORT_OK = qw(
    blessed refaddr reftype weaken unweaken isweak
  
    dualvar isdual isvstring looks_like_number openhandle readonly set_prototype
    tainted
  );
  our $VERSION    = "1.41";
  $VERSION   = eval $VERSION;
  
  our @EXPORT_FAIL;
  
  unless (defined &weaken) {
    push @EXPORT_FAIL, qw(weaken);
  }
  unless (defined &isweak) {
    push @EXPORT_FAIL, qw(isweak isvstring);
  }
  unless (defined &isvstring) {
    push @EXPORT_FAIL, qw(isvstring);
  }
  
  sub export_fail {
    if (grep { /^(?:weaken|isweak)$/ } @_ ) {
      require Carp;
      Carp::croak("Weak references are not implemented in the version of perl");
    }
  
    if (grep { /^isvstring$/ } @_ ) {
      require Carp;
      Carp::croak("Vstrings are not implemented in the version of perl");
    }
  
    @_;
  }
  
  # set_prototype has been moved to Sub::Util with a different interface
  sub set_prototype(&$)
  {
    my ( $code, $proto ) = @_;
    return Sub::Util::set_prototype( $proto, $code );
  }
  
  1;
  
  __END__
  
  =head1 NAME
  
  Scalar::Util - A selection of general-utility scalar subroutines
  
  =head1 SYNOPSIS
  
      use Scalar::Util qw(blessed dualvar isdual readonly refaddr reftype
                          tainted weaken isweak isvstring looks_like_number
                          set_prototype);
                          # and other useful utils appearing below
  
  =head1 DESCRIPTION
  
  C<Scalar::Util> contains a selection of subroutines that people have expressed
  would be nice to have in the perl core, but the usage would not really be high
  enough to warrant the use of a keyword, and the size so small such that being
  individual extensions would be wasteful.
  
  By default C<Scalar::Util> does not export any subroutines.
  
  =cut
  
  =head1 FUNCTIONS FOR REFERENCES
  
  The following functions all perform some useful activity on reference values.
  
  =head2 blessed
  
      my $pkg = blessed( $ref );
  
  If C<$ref> is a blessed reference the name of the package that it is blessed
  into is returned. Otherwise C<undef> is returned.
  
      $scalar = "foo";
      $class  = blessed $scalar;           # undef
  
      $ref    = [];
      $class  = blessed $ref;              # undef
  
      $obj    = bless [], "Foo";
      $class  = blessed $obj;              # "Foo"
  
  Take care when using this function simply as a truth test (such as in
  C<if(blessed $ref)...>) because the package name C<"0"> is defined yet false.
  
  =head2 refaddr
  
      my $addr = refaddr( $ref );
  
  If C<$ref> is reference the internal memory address of the referenced value is
  returned as a plain integer. Otherwise C<undef> is returned.
  
      $addr = refaddr "string";           # undef
      $addr = refaddr \$var;              # eg 12345678
      $addr = refaddr [];                 # eg 23456784
  
      $obj  = bless {}, "Foo";
      $addr = refaddr $obj;               # eg 88123488
  
  =head2 reftype
  
      my $type = reftype( $ref );
  
  If C<$ref> is a reference the basic Perl type of the variable referenced is
  returned as a plain string (such as C<ARRAY> or C<HASH>). Otherwise C<undef>
  is returned.
  
      $type = reftype "string";           # undef
      $type = reftype \$var;              # SCALAR
      $type = reftype [];                 # ARRAY
  
      $obj  = bless {}, "Foo";
      $type = reftype $obj;               # HASH
  
  =head2 weaken
  
      weaken( $ref );
  
  The lvalue C<$ref> will be turned into a weak reference. This means that it
  will not hold a reference count on the object it references. Also when the
  reference count on that object reaches zero, the reference will be set to
  undef. This function mutates the lvalue passed as its argument and returns no
  value.
  
  This is useful for keeping copies of references, but you don't want to prevent
  the object being DESTROY-ed at its usual time.
  
      {
        my $var;
        $ref = \$var;
        weaken($ref);                     # Make $ref a weak reference
      }
      # $ref is now undef
  
  Note that if you take a copy of a scalar with a weakened reference, the copy
  will be a strong reference.
  
      my $var;
      my $foo = \$var;
      weaken($foo);                       # Make $foo a weak reference
      my $bar = $foo;                     # $bar is now a strong reference
  
  This may be less obvious in other situations, such as C<grep()>, for instance
  when grepping through a list of weakened references to objects that may have
  been destroyed already:
  
      @object = grep { defined } @object;
  
  This will indeed remove all references to destroyed objects, but the remaining
  references to objects will be strong, causing the remaining objects to never be
  destroyed because there is now always a strong reference to them in the @object
  array.
  
  =head2 unweaken
  
      unweaken( $ref );
  
  I<Since version 1.36.>
  
  The lvalue C<REF> will be turned from a weak reference back into a normal
  (strong) reference again. This function mutates the lvalue passed as its
  argument and returns no value. This undoes the action performed by
  L</weaken>.
  
  This function is slightly neater and more convenient than the
  otherwise-equivalent code
  
      my $tmp = $REF;
      undef $REF;
      $REF = $tmp;
  
  (because in particular, simply assigning a weak reference back to itself does
  not work to unweaken it; C<$REF = $REF> does not work).
  
  =head2 isweak
  
      my $weak = isweak( $ref );
  
  Returns true if C<$ref> is a weak reference.
  
      $ref  = \$foo;
      $weak = isweak($ref);               # false
      weaken($ref);
      $weak = isweak($ref);               # true
  
  B<NOTE>: Copying a weak reference creates a normal, strong, reference.
  
      $copy = $ref;
      $weak = isweak($copy);              # false
  
  =head1 OTHER FUNCTIONS
  
  =head2 dualvar
  
      my $var = dualvar( $num, $string );
  
  Returns a scalar that has the value C<$num> in a numeric context and the value
  C<$string> in a string context.
  
      $foo = dualvar 10, "Hello";
      $num = $foo + 2;                    # 12
      $str = $foo . " world";             # Hello world
  
  =head2 isdual
  
      my $dual = isdual( $var );
  
  I<Since version 1.26.>
  
  If C<$var> is a scalar that has both numeric and string values, the result is
  true.
  
      $foo = dualvar 86, "Nix";
      $dual = isdual($foo);               # true
  
  Note that a scalar can be made to have both string and numeric content through
  numeric operations:
  
      $foo = "10";
      $dual = isdual($foo);               # false
      $bar = $foo + 0;
      $dual = isdual($foo);               # true
  
  Note that although C<$!> appears to be dual-valued variable, it is actually
  implemented using a tied scalar:
  
      $! = 1;
      print("$!\n");                      # "Operation not permitted"
      $dual = isdual($!);                 # false
  
  You can capture its numeric and string content using:
  
      $err = dualvar $!, $!;
      $dual = isdual($err);               # true
  
  =head2 isvstring
  
      my $vstring = isvstring( $var );
  
  If C<$var> is a scalar which was coded as a vstring the result is true.
  
      $vs   = v49.46.48;
      $fmt  = isvstring($vs) ? "%vd" : "%s"; #true
      printf($fmt,$vs);
  
  =head2 looks_like_number
  
      my $isnum = looks_like_number( $var );
  
  Returns true if perl thinks C<$var> is a number. See
  L<perlapi/looks_like_number>.
  
  =head2 openhandle
  
      my $fh = openhandle( $fh );
  
  Returns C<$fh> itself if C<$fh> may be used as a filehandle and is open, or is
  is a tied handle. Otherwise C<undef> is returned.
  
      $fh = openhandle(*STDIN);           # \*STDIN
      $fh = openhandle(\*STDIN);          # \*STDIN
      $fh = openhandle(*NOTOPEN);         # undef
      $fh = openhandle("scalar");         # undef
  
  =head2 readonly
  
      my $ro = readonly( $var );
  
  Returns true if C<$var> is readonly.
  
      sub foo { readonly($_[0]) }
  
      $readonly = foo($bar);              # false
      $readonly = foo(0);                 # true
  
  =head2 set_prototype
  
      my $code = set_prototype( $code, $prototype );
  
  Sets the prototype of the function given by the C<$code> reference, or deletes
  it if C<$prototype> is C<undef>. Returns the C<$code> reference itself.
  
      set_prototype \&foo, '$$';
  
  =head2 tainted
  
      my $t = tainted( $var );
  
  Return true if C<$var> is tainted.
  
      $taint = tainted("constant");       # false
      $taint = tainted($ENV{PWD});        # true if running under -T
  
  =head1 DIAGNOSTICS
  
  Module use may give one of the following errors during import.
  
  =over
  
  =item Weak references are not implemented in the version of perl
  
  The version of perl that you are using does not implement weak references, to
  use L</isweak> or L</weaken> you will need to use a newer release of perl.
  
  =item Vstrings are not implemented in the version of perl
  
  The version of perl that you are using does not implement Vstrings, to use
  L</isvstring> you will need to use a newer release of perl.
  
  =item C<NAME> is only available with the XS version of Scalar::Util
  
  C<Scalar::Util> contains both perl and C implementations of many of its
  functions so that those without access to a C compiler may still use it.
  However some of the functions are only available when a C compiler was
  available to compile the XS version of the extension.
  
  At present that list is: weaken, isweak, dualvar, isvstring, set_prototype
  
  =back
  
  =head1 KNOWN BUGS
  
  There is a bug in perl5.6.0 with UV's that are >= 1<<31. This will
  show up as tests 8 and 9 of dualvar.t failing
  
  =head1 SEE ALSO
  
  L<List::Util>
  
  =head1 COPYRIGHT
  
  Copyright (c) 1997-2007 Graham Barr <gbarr@pobox.com>. All rights reserved.
  This program is free software; you can redistribute it and/or modify it
  under the same terms as Perl itself.
  
  Additionally L</weaken> and L</isweak> which are
  
  Copyright (c) 1999 Tuomas J. Lukka <lukka@iki.fi>. All rights reserved.
  This program is free software; you can redistribute it and/or modify it
  under the same terms as perl itself.
  
  Copyright (C) 2004, 2008  Matthijs van Duin.  All rights reserved.
  Copyright (C) 2014 cPanel Inc.  All rights reserved.
  This program is free software; you can redistribute it and/or modify
  it under the same terms as Perl itself.
  
  =cut
I686-LINUX_SCALAR_UTIL

$fatpacked{"i686-linux/Sub/Name.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'I686-LINUX_SUB_NAME';
  package Sub::Name;
  
  =head1 NAME
  
  Sub::Name - (re)name a sub
  
  =head1 SYNOPSIS
  
      use Sub::Name;
  
      subname $name, $subref;
  
      $subref = subname foo => sub { ... };
  
  =head1 DESCRIPTION
  
  This module has only one function, which is also exported by default:
  
  =head2 subname NAME, CODEREF
  
  Assigns a new name to referenced sub.  If package specification is omitted in 
  the name, then the current package is used.  The return value is the sub.
  
  The name is only used for informative routines (caller, Carp, etc).  You won't 
  be able to actually invoke the sub by the given name.  To allow that, you need 
  to do glob-assignment yourself.
  
  Note that for anonymous closures (subs that reference lexicals declared outside 
  the sub itself) you can name each instance of the closure differently, which 
  can be very useful for debugging.
  
  =head1 AUTHOR
  
  Matthijs van Duin <xmath@cpan.org>
  
  Copyright (C) 2004, 2008  Matthijs van Duin.  All rights reserved.
  This program is free software; you can redistribute it and/or modify 
  it under the same terms as Perl itself.
  
  =cut
  
  use 5.006;
  
  use strict;
  use warnings;
  
  our $VERSION = '0.05';
  
  use base 'Exporter';
  use base 'DynaLoader';
  
  our @EXPORT = qw(subname);
  our @EXPORT_OK = @EXPORT;
  
  bootstrap Sub::Name $VERSION;
  
  1;
I686-LINUX_SUB_NAME

$fatpacked{"i686-linux/Sub/Util.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'I686-LINUX_SUB_UTIL';
  # Copyright (c) 2014 Paul Evans <leonerd@leonerd.org.uk>. All rights reserved.
  # This program is free software; you can redistribute it and/or
  # modify it under the same terms as Perl itself.
  
  package Sub::Util;
  
  use strict;
  use warnings;
  
  require Exporter;
  require List::Util; # as it has the XS
  
  our @ISA = qw( Exporter );
  our @EXPORT_OK = qw(
    prototype set_prototype
    subname set_subname
  );
  
  our $VERSION    = "1.41";
  $VERSION   = eval $VERSION;
  
  =head1 NAME
  
  Sub::Util - A selection of utility subroutines for subs and CODE references
  
  =head1 SYNOPSIS
  
      use Sub::Util qw( prototype set_prototype subname set_subname );
  
  =head1 DESCRIPTION
  
  C<Sub::Util> contains a selection of utility subroutines that are useful for
  operating on subs and CODE references.
  
  The rationale for inclusion in this module is that the function performs some
  work for which an XS implementation is essential because it cannot be
  implemented in Pure Perl, and which is sufficiently-widely used across CPAN
  that its popularity warrants inclusion in a core module, which this is.
  
  =cut
  
  =head1 FUNCTIONS
  
  =cut
  
  =head2 prototype
  
      my $proto = prototype( $code )
  
  I<Since version 1.40.>
  
  Returns the prototype of the given C<$code> reference, if it has one, as a
  string. This is the same as the C<CORE::prototype> operator; it is included
  here simply for symmetry and completeness with the other functions.
  
  =cut
  
  sub prototype
  {
    my ( $code ) = @_;
    return CORE::prototype( $code );
  }
  
  =head2 set_prototype
  
      my $code = set_prototype $prototype, $code;
  
  I<Since version 1.40.>
  
  Sets the prototype of the function given by the C<$code> reference, or deletes
  it if C<$prototype> is C<undef>. Returns the C<$code> reference itself.
  
  I<Caution>: This function takes arguments in a different order to the previous
  copy of the code from C<Scalar::Util>. This is to match the order of
  C<set_subname>, and other potential additions in this file. This order has
  been chosen as it allows a neat and simple chaining of other
  C<Sub::Util::set_*> functions as might become available, such as:
  
   my $code =
      set_subname   name_here =>
      set_prototype '&@'      =>
      set_attribute ':lvalue' =>
         sub { ...... };
  
  =cut
  
  =head2 subname
  
      my $name = subname( $code )
  
  I<Since version 1.40.>
  
  Returns the name of the given C<$code> reference, if it has one. Normal named
  subs will give a fully-qualified name consisting of the package and the
  localname separated by C<::>. Anonymous code references will give C<__ANON__>
  as the localname. If a name has been set using L</set_subname>, this name will
  be returned instead.
  
  This function was inspired by C<sub_fullname> from L<Sub::Identify>. The
  remaining functions that C<Sub::Identify> implements can easily be emulated
  using regexp operations, such as
  
   sub get_code_info { return (subname $_[0]) =~ m/^(.+)::(.+?)$/ }
   sub sub_name      { return (get_code_info $_[0])[0] }
   sub stash_name    { return (get_code_info $_[0])[1] }
  
  I<Users of Sub::Name beware>: This function is B<not> the same as
  C<Sub::Name::subname>; it returns the existing name of the sub rather than
  changing it. To set or change a name, see instead L</set_subname>.
  
  =cut
  
  =head2 set_subname
  
      my $code = set_subname $name, $code;
  
  I<Since version 1.40.>
  
  Sets the name of the function given by the C<$code> reference. Returns the
  C<$code> reference itself. If the C<$name> is unqualified, the package of the
  caller is used to qualify it.
  
  This is useful for applying names to anonymous CODE references so that stack
  traces and similar situations, to give a useful name rather than having the
  default of C<__ANON__>. Note that this name is only used for this situation;
  the C<set_subname> will not install it into the symbol table; you will have to
  do that yourself if required.
  
  However, since the name is not used by perl except as the return value of
  C<caller>, for stack traces or similar, there is no actual requirement that
  the name be syntactically valid as a perl function name. This could be used to
  attach extra information that could be useful in debugging stack traces.
  
  This function was copied from C<Sub::Name::subname> and renamed to the naming
  convention of this module.
  
  =cut
  
  =head1 AUTHOR
  
  The general structure of this module was written by Paul Evans
  <leonerd@leonerd.org.uk>.
  
  The XS implementation of L</set_subname> was copied from L<Sub::Name> by
  Matthijs van Duin <xmath@cpan.org>
  
  =cut
  
  1;
I686-LINUX_SUB_UTIL

$fatpacked{"i686-linux/version.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'I686-LINUX_VERSION';
  #!perl -w
  package version;
  
  use 5.006002;
  use strict;
  use warnings::register;
  if ($] >= 5.015) {
      warnings::register_categories(qw/version/);
  }
  
  use vars qw(@ISA $VERSION $CLASS $STRICT $LAX *declare *qv);
  
  $VERSION = 0.9912;
  $CLASS = 'version';
  
  # !!!!Delete this next block completely when adding to Perl core!!!!
  {
      local $SIG{'__DIE__'};
      eval "use version::vxs $VERSION";
      if ( $@ ) { # don't have the XS version installed
  	eval "use version::vpp $VERSION"; # don't tempt fate
  	die "$@" if ( $@ );
  	push @ISA, "version::vpp";
  	local $^W;
  	*version::qv = \&version::vpp::qv;
  	*version::declare = \&version::vpp::declare;
  	*version::_VERSION = \&version::vpp::_VERSION;
  	*version::vcmp = \&version::vpp::vcmp;
  	*version::new = \&version::vpp::new;
  	*version::numify = \&version::vpp::numify;
  	*version::normal = \&version::vpp::normal;
  	if ($] >= 5.009000) {
  	    no strict 'refs';
  	    *version::stringify = \&version::vpp::stringify;
  	    *{'version::(""'} = \&version::vpp::stringify;
  	    *{'version::(<=>'} = \&version::vpp::vcmp;
  	    *version::parse = \&version::vpp::parse;
  	}
      }
      else { # use XS module
  	push @ISA, "version::vxs";
  	local $^W;
  	*version::declare = \&version::vxs::declare;
  	*version::qv = \&version::vxs::qv;
  	*version::_VERSION = \&version::vxs::_VERSION;
  	*version::vcmp = \&version::vxs::VCMP;
  	*version::new = \&version::vxs::new;
  	*version::numify = \&version::vxs::numify;
  	*version::normal = \&version::vxs::normal;
  	if ($] >= 5.009000) {
  	    no strict 'refs';
  	    *version::stringify = \&version::vxs::stringify;
  	    *{'version::(""'} = \&version::vxs::stringify;
  	    *{'version::(<=>'} = \&version::vxs::VCMP;
  	    *version::parse = \&version::vxs::parse;
  	}
      }
  }
  
  # avoid using Exporter
  require version::regex;
  *version::is_lax = \&version::regex::is_lax;
  *version::is_strict = \&version::regex::is_strict;
  *LAX = \$version::regex::LAX;
  *STRICT = \$version::regex::STRICT;
  
  sub import {
      no strict 'refs';
      my ($class) = shift;
  
      # Set up any derived class
      unless ($class eq $CLASS) {
  	local $^W;
  	*{$class.'::declare'} =  \&{$CLASS.'::declare'};
  	*{$class.'::qv'} = \&{$CLASS.'::qv'};
      }
  
      my %args;
      if (@_) { # any remaining terms are arguments
  	map { $args{$_} = 1 } @_
      }
      else { # no parameters at all on use line
  	%args =
  	(
  	    qv => 1,
  	    'UNIVERSAL::VERSION' => 1,
  	);
      }
  
      my $callpkg = caller();
  
      if (exists($args{declare})) {
  	*{$callpkg.'::declare'} =
  	    sub {return $class->declare(shift) }
  	  unless defined(&{$callpkg.'::declare'});
      }
  
      if (exists($args{qv})) {
  	*{$callpkg.'::qv'} =
  	    sub {return $class->qv(shift) }
  	  unless defined(&{$callpkg.'::qv'});
      }
  
      if (exists($args{'UNIVERSAL::VERSION'})) {
  	local $^W;
  	*UNIVERSAL::VERSION
  		= \&{$CLASS.'::_VERSION'};
      }
  
      if (exists($args{'VERSION'})) {
  	*{$callpkg.'::VERSION'} = \&{$CLASS.'::_VERSION'};
      }
  
      if (exists($args{'is_strict'})) {
  	*{$callpkg.'::is_strict'} = \&{$CLASS.'::is_strict'}
  	  unless defined(&{$callpkg.'::is_strict'});
      }
  
      if (exists($args{'is_lax'})) {
  	*{$callpkg.'::is_lax'} = \&{$CLASS.'::is_lax'}
  	  unless defined(&{$callpkg.'::is_lax'});
      }
  }
  
  
  1;
I686-LINUX_VERSION

$fatpacked{"i686-linux/version/regex.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'I686-LINUX_VERSION_REGEX';
  package version::regex;
  
  use strict;
  
  use vars qw($VERSION $CLASS $STRICT $LAX);
  
  $VERSION = 0.9912;
  
  #--------------------------------------------------------------------------#
  # Version regexp components
  #--------------------------------------------------------------------------#
  
  # Fraction part of a decimal version number.  This is a common part of
  # both strict and lax decimal versions
  
  my $FRACTION_PART = qr/\.[0-9]+/;
  
  # First part of either decimal or dotted-decimal strict version number.
  # Unsigned integer with no leading zeroes (except for zero itself) to
  # avoid confusion with octal.
  
  my $STRICT_INTEGER_PART = qr/0|[1-9][0-9]*/;
  
  # First part of either decimal or dotted-decimal lax version number.
  # Unsigned integer, but allowing leading zeros.  Always interpreted
  # as decimal.  However, some forms of the resulting syntax give odd
  # results if used as ordinary Perl expressions, due to how perl treats
  # octals.  E.g.
  #   version->new("010" ) == 10
  #   version->new( 010  ) == 8
  #   version->new( 010.2) == 82  # "8" . "2"
  
  my $LAX_INTEGER_PART = qr/[0-9]+/;
  
  # Second and subsequent part of a strict dotted-decimal version number.
  # Leading zeroes are permitted, and the number is always decimal.
  # Limited to three digits to avoid overflow when converting to decimal
  # form and also avoid problematic style with excessive leading zeroes.
  
  my $STRICT_DOTTED_DECIMAL_PART = qr/\.[0-9]{1,3}/;
  
  # Second and subsequent part of a lax dotted-decimal version number.
  # Leading zeroes are permitted, and the number is always decimal.  No
  # limit on the numerical value or number of digits, so there is the
  # possibility of overflow when converting to decimal form.
  
  my $LAX_DOTTED_DECIMAL_PART = qr/\.[0-9]+/;
  
  # Alpha suffix part of lax version number syntax.  Acts like a
  # dotted-decimal part.
  
  my $LAX_ALPHA_PART = qr/_[0-9]+/;
  
  #--------------------------------------------------------------------------#
  # Strict version regexp definitions
  #--------------------------------------------------------------------------#
  
  # Strict decimal version number.
  
  my $STRICT_DECIMAL_VERSION =
      qr/ $STRICT_INTEGER_PART $FRACTION_PART? /x;
  
  # Strict dotted-decimal version number.  Must have both leading "v" and
  # at least three parts, to avoid confusion with decimal syntax.
  
  my $STRICT_DOTTED_DECIMAL_VERSION =
      qr/ v $STRICT_INTEGER_PART $STRICT_DOTTED_DECIMAL_PART{2,} /x;
  
  # Complete strict version number syntax -- should generally be used
  # anchored: qr/ \A $STRICT \z /x
  
  $STRICT =
      qr/ $STRICT_DECIMAL_VERSION | $STRICT_DOTTED_DECIMAL_VERSION /x;
  
  #--------------------------------------------------------------------------#
  # Lax version regexp definitions
  #--------------------------------------------------------------------------#
  
  # Lax decimal version number.  Just like the strict one except for
  # allowing an alpha suffix or allowing a leading or trailing
  # decimal-point
  
  my $LAX_DECIMAL_VERSION =
      qr/ $LAX_INTEGER_PART (?: \. | $FRACTION_PART $LAX_ALPHA_PART? )?
  	|
  	$FRACTION_PART $LAX_ALPHA_PART?
      /x;
  
  # Lax dotted-decimal version number.  Distinguished by having either
  # leading "v" or at least three non-alpha parts.  Alpha part is only
  # permitted if there are at least two non-alpha parts. Strangely
  # enough, without the leading "v", Perl takes .1.2 to mean v0.1.2,
  # so when there is no "v", the leading part is optional
  
  my $LAX_DOTTED_DECIMAL_VERSION =
      qr/
  	v $LAX_INTEGER_PART (?: $LAX_DOTTED_DECIMAL_PART+ $LAX_ALPHA_PART? )?
  	|
  	$LAX_INTEGER_PART? $LAX_DOTTED_DECIMAL_PART{2,} $LAX_ALPHA_PART?
      /x;
  
  # Complete lax version number syntax -- should generally be used
  # anchored: qr/ \A $LAX \z /x
  #
  # The string 'undef' is a special case to make for easier handling
  # of return values from ExtUtils::MM->parse_version
  
  $LAX =
      qr/ undef | $LAX_DECIMAL_VERSION | $LAX_DOTTED_DECIMAL_VERSION /x;
  
  #--------------------------------------------------------------------------#
  
  # Preloaded methods go here.
  sub is_strict	{ defined $_[0] && $_[0] =~ qr/ \A $STRICT \z /x }
  sub is_lax	{ defined $_[0] && $_[0] =~ qr/ \A $LAX \z /x }
  
  1;
I686-LINUX_VERSION_REGEX

$fatpacked{"i686-linux/version/vpp.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'I686-LINUX_VERSION_VPP';
  package charstar;
  # a little helper class to emulate C char* semantics in Perl
  # so that prescan_version can use the same code as in C
  
  use overload (
      '""'	=> \&thischar,
      '0+'	=> \&thischar,
      '++'	=> \&increment,
      '--'	=> \&decrement,
      '+'		=> \&plus,
      '-'		=> \&minus,
      '*'		=> \&multiply,
      'cmp'	=> \&cmp,
      '<=>'	=> \&spaceship,
      'bool'	=> \&thischar,
      '='		=> \&clone,
  );
  
  sub new {
      my ($self, $string) = @_;
      my $class = ref($self) || $self;
  
      my $obj = {
  	string  => [split(//,$string)],
  	current => 0,
      };
      return bless $obj, $class;
  }
  
  sub thischar {
      my ($self) = @_;
      my $last = $#{$self->{string}};
      my $curr = $self->{current};
      if ($curr >= 0 && $curr <= $last) {
  	return $self->{string}->[$curr];
      }
      else {
  	return '';
      }
  }
  
  sub increment {
      my ($self) = @_;
      $self->{current}++;
  }
  
  sub decrement {
      my ($self) = @_;
      $self->{current}--;
  }
  
  sub plus {
      my ($self, $offset) = @_;
      my $rself = $self->clone;
      $rself->{current} += $offset;
      return $rself;
  }
  
  sub minus {
      my ($self, $offset) = @_;
      my $rself = $self->clone;
      $rself->{current} -= $offset;
      return $rself;
  }
  
  sub multiply {
      my ($left, $right, $swapped) = @_;
      my $char = $left->thischar();
      return $char * $right;
  }
  
  sub spaceship {
      my ($left, $right, $swapped) = @_;
      unless (ref($right)) { # not an object already
  	$right = $left->new($right);
      }
      return $left->{current} <=> $right->{current};
  }
  
  sub cmp {
      my ($left, $right, $swapped) = @_;
      unless (ref($right)) { # not an object already
  	if (length($right) == 1) { # comparing single character only
  	    return $left->thischar cmp $right;
  	}
  	$right = $left->new($right);
      }
      return $left->currstr cmp $right->currstr;
  }
  
  sub bool {
      my ($self) = @_;
      my $char = $self->thischar;
      return ($char ne '');
  }
  
  sub clone {
      my ($left, $right, $swapped) = @_;
      $right = {
  	string  => [@{$left->{string}}],
  	current => $left->{current},
      };
      return bless $right, ref($left);
  }
  
  sub currstr {
      my ($self, $s) = @_;
      my $curr = $self->{current};
      my $last = $#{$self->{string}};
      if (defined($s) && $s->{current} < $last) {
  	$last = $s->{current};
      }
  
      my $string = join('', @{$self->{string}}[$curr..$last]);
      return $string;
  }
  
  package version::vpp;
  
  use 5.006002;
  use strict;
  use warnings::register;
  
  use Config;
  use vars qw($VERSION $CLASS @ISA $LAX $STRICT $WARN_CATEGORY);
  $VERSION = 0.9912;
  $CLASS = 'version::vpp';
  if ($] > 5.015) {
      warnings::register_categories(qw/version/);
      $WARN_CATEGORY = 'version';
  } else {
      $WARN_CATEGORY = 'numeric';
  }
  
  require version::regex;
  *version::vpp::is_strict = \&version::regex::is_strict;
  *version::vpp::is_lax = \&version::regex::is_lax;
  *LAX = \$version::regex::LAX;
  *STRICT = \$version::regex::STRICT;
  
  use overload (
      '""'       => \&stringify,
      '0+'       => \&numify,
      'cmp'      => \&vcmp,
      '<=>'      => \&vcmp,
      'bool'     => \&vbool,
      '+'        => \&vnoop,
      '-'        => \&vnoop,
      '*'        => \&vnoop,
      '/'        => \&vnoop,
      '+='        => \&vnoop,
      '-='        => \&vnoop,
      '*='        => \&vnoop,
      '/='        => \&vnoop,
      'abs'      => \&vnoop,
  );
  
  sub import {
      no strict 'refs';
      my ($class) = shift;
  
      # Set up any derived class
      unless ($class eq $CLASS) {
  	local $^W;
  	*{$class.'::declare'} =  \&{$CLASS.'::declare'};
  	*{$class.'::qv'} = \&{$CLASS.'::qv'};
      }
  
      my %args;
      if (@_) { # any remaining terms are arguments
  	map { $args{$_} = 1 } @_
      }
      else { # no parameters at all on use line
  	%args =
  	(
  	    qv => 1,
  	    'UNIVERSAL::VERSION' => 1,
  	);
      }
  
      my $callpkg = caller();
  
      if (exists($args{declare})) {
  	*{$callpkg.'::declare'} =
  	    sub {return $class->declare(shift) }
  	  unless defined(&{$callpkg.'::declare'});
      }
  
      if (exists($args{qv})) {
  	*{$callpkg.'::qv'} =
  	    sub {return $class->qv(shift) }
  	  unless defined(&{$callpkg.'::qv'});
      }
  
      if (exists($args{'UNIVERSAL::VERSION'})) {
  	no warnings qw/redefine/;
  	*UNIVERSAL::VERSION
  		= \&{$CLASS.'::_VERSION'};
      }
  
      if (exists($args{'VERSION'})) {
  	*{$callpkg.'::VERSION'} = \&{$CLASS.'::_VERSION'};
      }
  
      if (exists($args{'is_strict'})) {
  	*{$callpkg.'::is_strict'} = \&{$CLASS.'::is_strict'}
  	  unless defined(&{$callpkg.'::is_strict'});
      }
  
      if (exists($args{'is_lax'})) {
  	*{$callpkg.'::is_lax'} = \&{$CLASS.'::is_lax'}
  	  unless defined(&{$callpkg.'::is_lax'});
      }
  }
  
  my $VERSION_MAX = 0x7FFFFFFF;
  
  # implement prescan_version as closely to the C version as possible
  use constant TRUE  => 1;
  use constant FALSE => 0;
  
  sub isDIGIT {
      my ($char) = shift->thischar();
      return ($char =~ /\d/);
  }
  
  sub isALPHA {
      my ($char) = shift->thischar();
      return ($char =~ /[a-zA-Z]/);
  }
  
  sub isSPACE {
      my ($char) = shift->thischar();
      return ($char =~ /\s/);
  }
  
  sub BADVERSION {
      my ($s, $errstr, $error) = @_;
      if ($errstr) {
  	$$errstr = $error;
      }
      return $s;
  }
  
  sub prescan_version {
      my ($s, $strict, $errstr, $sqv, $ssaw_decimal, $swidth, $salpha) = @_;
      my $qv          = defined $sqv          ? $$sqv          : FALSE;
      my $saw_decimal = defined $ssaw_decimal ? $$ssaw_decimal : 0;
      my $width       = defined $swidth       ? $$swidth       : 3;
      my $alpha       = defined $salpha       ? $$salpha       : FALSE;
  
      my $d = $s;
  
      if ($qv && isDIGIT($d)) {
  	goto dotted_decimal_version;
      }
  
      if ($d eq 'v') { # explicit v-string
  	$d++;
  	if (isDIGIT($d)) {
  	    $qv = TRUE;
  	}
  	else { # degenerate v-string
  	    # requires v1.2.3
  	    return BADVERSION($s,$errstr,"Invalid version format (dotted-decimal versions require at least three parts)");
  	}
  
  dotted_decimal_version:
  	if ($strict && $d eq '0' && isDIGIT($d+1)) {
  	    # no leading zeros allowed
  	    return BADVERSION($s,$errstr,"Invalid version format (no leading zeros)");
  	}
  
  	while (isDIGIT($d)) { 	# integer part
  	    $d++;
  	}
  
  	if ($d eq '.')
  	{
  	    $saw_decimal++;
  	    $d++; 		# decimal point
  	}
  	else
  	{
  	    if ($strict) {
  		# require v1.2.3
  		return BADVERSION($s,$errstr,"Invalid version format (dotted-decimal versions require at least three parts)");
  	    }
  	    else {
  		goto version_prescan_finish;
  	    }
  	}
  
  	{
  	    my $i = 0;
  	    my $j = 0;
  	    while (isDIGIT($d)) {	# just keep reading
  		$i++;
  		while (isDIGIT($d)) {
  		    $d++; $j++;
  		    # maximum 3 digits between decimal
  		    if ($strict && $j > 3) {
  			return BADVERSION($s,$errstr,"Invalid version format (maximum 3 digits between decimals)");
  		    }
  		}
  		if ($d eq '_') {
  		    if ($strict) {
  			return BADVERSION($s,$errstr,"Invalid version format (no underscores)");
  		    }
  		    if ( $alpha ) {
  			return BADVERSION($s,$errstr,"Invalid version format (multiple underscores)");
  		    }
  		    $d++;
  		    $alpha = TRUE;
  		}
  		elsif ($d eq '.') {
  		    if ($alpha) {
  			return BADVERSION($s,$errstr,"Invalid version format (underscores before decimal)");
  		    }
  		    $saw_decimal++;
  		    $d++;
  		}
  		elsif (!isDIGIT($d)) {
  		    last;
  		}
  		$j = 0;
  	    }
  
  	    if ($strict && $i < 2) {
  		# requires v1.2.3
  		return BADVERSION($s,$errstr,"Invalid version format (dotted-decimal versions require at least three parts)");
  	    }
  	}
      } 					# end if dotted-decimal
      else
      {					# decimal versions
  	my $j = 0;
  	# special $strict case for leading '.' or '0'
  	if ($strict) {
  	    if ($d eq '.') {
  		return BADVERSION($s,$errstr,"Invalid version format (0 before decimal required)");
  	    }
  	    if ($d eq '0' && isDIGIT($d+1)) {
  		return BADVERSION($s,$errstr,"Invalid version format (no leading zeros)");
  	    }
  	}
  
  	# and we never support negative version numbers
  	if ($d eq '-') {
  	    return BADVERSION($s,$errstr,"Invalid version format (negative version number)");
  	}
  
  	# consume all of the integer part
  	while (isDIGIT($d)) {
  	    $d++;
  	}
  
  	# look for a fractional part
  	if ($d eq '.') {
  	    # we found it, so consume it
  	    $saw_decimal++;
  	    $d++;
  	}
  	elsif (!$d || $d eq ';' || isSPACE($d) || $d eq '}') {
  	    if ( $d == $s ) {
  		# found nothing
  		return BADVERSION($s,$errstr,"Invalid version format (version required)");
  	    }
  	    # found just an integer
  	    goto version_prescan_finish;
  	}
  	elsif ( $d == $s ) {
  	    # didn't find either integer or period
  	    return BADVERSION($s,$errstr,"Invalid version format (non-numeric data)");
  	}
  	elsif ($d eq '_') {
  	    # underscore can't come after integer part
  	    if ($strict) {
  		return BADVERSION($s,$errstr,"Invalid version format (no underscores)");
  	    }
  	    elsif (isDIGIT($d+1)) {
  		return BADVERSION($s,$errstr,"Invalid version format (alpha without decimal)");
  	    }
  	    else {
  		return BADVERSION($s,$errstr,"Invalid version format (misplaced underscore)");
  	    }
  	}
  	elsif ($d) {
  	    # anything else after integer part is just invalid data
  	    return BADVERSION($s,$errstr,"Invalid version format (non-numeric data)");
  	}
  
  	# scan the fractional part after the decimal point
  	if ($d && !isDIGIT($d) && ($strict || ! ($d eq ';' || isSPACE($d) || $d eq '}') )) {
  		# $strict or lax-but-not-the-end
  		return BADVERSION($s,$errstr,"Invalid version format (fractional part required)");
  	}
  
  	while (isDIGIT($d)) {
  	    $d++; $j++;
  	    if ($d eq '.' && isDIGIT($d-1)) {
  		if ($alpha) {
  		    return BADVERSION($s,$errstr,"Invalid version format (underscores before decimal)");
  		}
  		if ($strict) {
  		    return BADVERSION($s,$errstr,"Invalid version format (dotted-decimal versions must begin with 'v')");
  		}
  		$d = $s; # start all over again
  		$qv = TRUE;
  		goto dotted_decimal_version;
  	    }
  	    if ($d eq '_') {
  		if ($strict) {
  		    return BADVERSION($s,$errstr,"Invalid version format (no underscores)");
  		}
  		if ( $alpha ) {
  		    return BADVERSION($s,$errstr,"Invalid version format (multiple underscores)");
  		}
  		if ( ! isDIGIT($d+1) ) {
  		    return BADVERSION($s,$errstr,"Invalid version format (misplaced underscore)");
  		}
  		$width = $j;
  		$d++;
  		$alpha = TRUE;
  	    }
  	}
      }
  
  version_prescan_finish:
      while (isSPACE($d)) {
  	$d++;
      }
  
      if ($d && !isDIGIT($d) && (! ($d eq ';' || $d eq '}') )) {
  	# trailing non-numeric data
  	return BADVERSION($s,$errstr,"Invalid version format (non-numeric data)");
      }
      if ($saw_decimal > 1 && ($d-1) eq '.') {
  	# no trailing period allowed
  	return BADVERSION($s,$errstr,"Invalid version format (trailing decimal)");
      }
  
      if (defined $sqv) {
  	$$sqv = $qv;
      }
      if (defined $swidth) {
  	$$swidth = $width;
      }
      if (defined $ssaw_decimal) {
  	$$ssaw_decimal = $saw_decimal;
      }
      if (defined $salpha) {
  	$$salpha = $alpha;
      }
      return $d;
  }
  
  sub scan_version {
      my ($s, $rv, $qv) = @_;
      my $start;
      my $pos;
      my $last;
      my $errstr;
      my $saw_decimal = 0;
      my $width = 3;
      my $alpha = FALSE;
      my $vinf = FALSE;
      my @av;
  
      $s = new charstar $s;
  
      while (isSPACE($s)) { # leading whitespace is OK
  	$s++;
      }
  
      $last = prescan_version($s, FALSE, \$errstr, \$qv, \$saw_decimal,
  	\$width, \$alpha);
  
      if ($errstr) {
  	# 'undef' is a special case and not an error
  	if ( $s ne 'undef') {
  	    require Carp;
  	    Carp::croak($errstr);
  	}
      }
  
      $start = $s;
      if ($s eq 'v') {
  	$s++;
      }
      $pos = $s;
  
      if ( $qv ) {
  	$$rv->{qv} = $qv;
      }
      if ( $alpha ) {
  	$$rv->{alpha} = $alpha;
      }
      if ( !$qv && $width < 3 ) {
  	$$rv->{width} = $width;
      }
  
      while (isDIGIT($pos)) {
  	$pos++;
      }
      if (!isALPHA($pos)) {
  	my $rev;
  
  	for (;;) {
  	    $rev = 0;
  	    {
    		# this is atoi() that delimits on underscores
    		my $end = $pos;
    		my $mult = 1;
  		my $orev;
  
  		#  the following if() will only be true after the decimal
  		#  point of a version originally created with a bare
  		#  floating point number, i.e. not quoted in any way
  		#
   		if ( !$qv && $s > $start && $saw_decimal == 1 ) {
  		    $mult *= 100;
   		    while ( $s < $end ) {
  			$orev = $rev;
   			$rev += $s * $mult;
   			$mult /= 10;
  			if (   (abs($orev) > abs($rev))
  			    || (abs($rev) > $VERSION_MAX )) {
  			    warn("Integer overflow in version %d",
  					   $VERSION_MAX);
  			    $s = $end - 1;
  			    $rev = $VERSION_MAX;
  			    $vinf = 1;
  			}
   			$s++;
  			if ( $s eq '_' ) {
  			    $s++;
  			}
   		    }
    		}
   		else {
   		    while (--$end >= $s) {
  			$orev = $rev;
   			$rev += $end * $mult;
   			$mult *= 10;
  			if (   (abs($orev) > abs($rev))
  			    || (abs($rev) > $VERSION_MAX )) {
  			    warn("Integer overflow in version");
  			    $end = $s - 1;
  			    $rev = $VERSION_MAX;
  			    $vinf = 1;
  			}
   		    }
   		}
    	    }
  
    	    # Append revision
  	    push @av, $rev;
  	    if ( $vinf ) {
  		$s = $last;
  		last;
  	    }
  	    elsif ( $pos eq '.' ) {
  		$pos++;
  		if ($qv) {
  		    # skip leading zeros
  		    while ($pos eq '0') {
  			$pos++;
  		    }
  		}
  		$s = $pos;
  	    }
  	    elsif ( $pos eq '_' && isDIGIT($pos+1) ) {
  		$s = ++$pos;
  	    }
  	    elsif ( $pos eq ',' && isDIGIT($pos+1) ) {
  		$s = ++$pos;
  	    }
  	    elsif ( isDIGIT($pos) ) {
  		$s = $pos;
  	    }
  	    else {
  		$s = $pos;
  		last;
  	    }
  	    if ( $qv ) {
  		while ( isDIGIT($pos) ) {
  		    $pos++;
  		}
  	    }
  	    else {
  		my $digits = 0;
  		while ( ( isDIGIT($pos) || $pos eq '_' ) && $digits < 3 ) {
  		    if ( $pos ne '_' ) {
  			$digits++;
  		    }
  		    $pos++;
  		}
  	    }
  	}
      }
      if ( $qv ) { # quoted versions always get at least three terms
  	my $len = $#av;
  	#  This for loop appears to trigger a compiler bug on OS X, as it
  	#  loops infinitely. Yes, len is negative. No, it makes no sense.
  	#  Compiler in question is:
  	#  gcc version 3.3 20030304 (Apple Computer, Inc. build 1640)
  	#  for ( len = 2 - len; len > 0; len-- )
  	#  av_push(MUTABLE_AV(sv), newSViv(0));
  	#
  	$len = 2 - $len;
  	while ($len-- > 0) {
  	    push @av, 0;
  	}
      }
  
      # need to save off the current version string for later
      if ( $vinf ) {
  	$$rv->{original} = "v.Inf";
  	$$rv->{vinf} = 1;
      }
      elsif ( $s > $start ) {
  	$$rv->{original} = $start->currstr($s);
  	if ( $qv && $saw_decimal == 1 && $start ne 'v' ) {
  	    # need to insert a v to be consistent
  	    $$rv->{original} = 'v' . $$rv->{original};
  	}
      }
      else {
  	$$rv->{original} = '0';
  	push(@av, 0);
      }
  
      # And finally, store the AV in the hash
      $$rv->{version} = \@av;
  
      # fix RT#19517 - special case 'undef' as string
      if ($s eq 'undef') {
  	$s += 5;
      }
  
      return $s;
  }
  
  sub new {
      my $class = shift;
      unless (defined $class or $#_ > 1) {
  	require Carp;
  	Carp::croak('Usage: version::new(class, version)');
      }
  
      my $self = bless ({}, ref ($class) || $class);
      my $qv = FALSE;
  
      if ( $#_ == 1 ) { # must be CVS-style
  	$qv = TRUE;
      }
      my $value = pop; # always going to be the last element
  
      if ( ref($value) && eval('$value->isa("version")') ) {
  	# Can copy the elements directly
  	$self->{version} = [ @{$value->{version} } ];
  	$self->{qv} = 1 if $value->{qv};
  	$self->{alpha} = 1 if $value->{alpha};
  	$self->{original} = ''.$value->{original};
  	return $self;
      }
  
      if ( not defined $value or $value =~ /^undef$/ ) {
  	# RT #19517 - special case for undef comparison
  	# or someone forgot to pass a value
  	push @{$self->{version}}, 0;
  	$self->{original} = "0";
  	return ($self);
      }
  
  
      if (ref($value) =~ m/ARRAY|HASH/) {
  	require Carp;
  	Carp::croak("Invalid version format (non-numeric data)");
      }
  
      $value = _un_vstring($value);
  
      if ($Config{d_setlocale}) {
  	use POSIX qw/locale_h/;
  	use if $Config{d_setlocale}, 'locale';
  	my $currlocale = setlocale(LC_ALL);
  
  	# if the current locale uses commas for decimal points, we
  	# just replace commas with decimal places, rather than changing
  	# locales
  	if ( localeconv()->{decimal_point} eq ',' ) {
  	    $value =~ tr/,/./;
  	}
      }
  
      # exponential notation
      if ( $value =~ /\d+.?\d*e[-+]?\d+/ ) {
  	$value = sprintf("%.9f",$value);
  	$value =~ s/(0+)$//; # trim trailing zeros
      }
  
      my $s = scan_version($value, \$self, $qv);
  
      if ($s) { # must be something left over
  	warn("Version string '%s' contains invalid data; "
  		   ."ignoring: '%s'", $value, $s);
      }
  
      return ($self);
  }
  
  *parse = \&new;
  
  sub numify {
      my ($self) = @_;
      unless (_verify($self)) {
  	require Carp;
  	Carp::croak("Invalid version object");
      }
      my $width = $self->{width} || 3;
      my $alpha = $self->{alpha} || "";
      my $len = $#{$self->{version}};
      my $digit = $self->{version}[0];
      my $string = sprintf("%d.", $digit );
  
      if ($alpha and warnings::enabled()) {
  	warnings::warn($WARN_CATEGORY, 'alpha->numify() is lossy');
      }
  
      for ( my $i = 1 ; $i < $len ; $i++ ) {
  	$digit = $self->{version}[$i];
  	if ( $width < 3 ) {
  	    my $denom = 10**(3-$width);
  	    my $quot = int($digit/$denom);
  	    my $rem = $digit - ($quot * $denom);
  	    $string .= sprintf("%0".$width."d_%d", $quot, $rem);
  	}
  	else {
  	    $string .= sprintf("%03d", $digit);
  	}
      }
  
      if ( $len > 0 ) {
  	$digit = $self->{version}[$len];
  	if ( $alpha && $width == 3 ) {
  	    $string .= "_";
  	}
  	$string .= sprintf("%0".$width."d", $digit);
      }
      else # $len = 0
      {
  	$string .= sprintf("000");
      }
  
      return $string;
  }
  
  sub normal {
      my ($self) = @_;
      unless (_verify($self)) {
  	require Carp;
  	Carp::croak("Invalid version object");
      }
      my $alpha = $self->{alpha} || "";
      my $qv = $self->{qv} || "";
  
      my $len = $#{$self->{version}};
      my $digit = $self->{version}[0];
      my $string = sprintf("v%d", $digit );
  
      for ( my $i = 1 ; $i < $len ; $i++ ) {
  	$digit = $self->{version}[$i];
  	$string .= sprintf(".%d", $digit);
      }
  
      if ( $len > 0 ) {
  	$digit = $self->{version}[$len];
  	if ( $alpha ) {
  	    $string .= sprintf("_%0d", $digit);
  	}
  	else {
  	    $string .= sprintf(".%0d", $digit);
  	}
      }
  
      if ( $len <= 2 ) {
  	for ( $len = 2 - $len; $len != 0; $len-- ) {
  	    $string .= sprintf(".%0d", 0);
  	}
      }
  
      return $string;
  }
  
  sub stringify {
      my ($self) = @_;
      unless (_verify($self)) {
  	require Carp;
  	Carp::croak("Invalid version object");
      }
      return exists $self->{original}
      	? $self->{original}
  	: exists $self->{qv}
  	    ? $self->normal
  	    : $self->numify;
  }
  
  sub vcmp {
      require UNIVERSAL;
      my ($left,$right,$swap) = @_;
      my $class = ref($left);
      unless ( UNIVERSAL::isa($right, $class) ) {
  	$right = $class->new($right);
      }
  
      if ( $swap ) {
  	($left, $right) = ($right, $left);
      }
      unless (_verify($left)) {
  	require Carp;
  	Carp::croak("Invalid version object");
      }
      unless (_verify($right)) {
  	require Carp;
  	Carp::croak("Invalid version format");
      }
      my $l = $#{$left->{version}};
      my $r = $#{$right->{version}};
      my $m = $l < $r ? $l : $r;
      my $lalpha = $left->is_alpha;
      my $ralpha = $right->is_alpha;
      my $retval = 0;
      my $i = 0;
      while ( $i <= $m && $retval == 0 ) {
  	$retval = $left->{version}[$i] <=> $right->{version}[$i];
  	$i++;
      }
  
      # tiebreaker for alpha with identical terms
      if ( $retval == 0
  	&& $l == $r
  	&& $left->{version}[$m] == $right->{version}[$m]
  	&& ( $lalpha || $ralpha ) ) {
  
  	if ( $lalpha && !$ralpha ) {
  	    $retval = -1;
  	}
  	elsif ( $ralpha && !$lalpha) {
  	    $retval = +1;
  	}
      }
  
      # possible match except for trailing 0's
      if ( $retval == 0 && $l != $r ) {
  	if ( $l < $r ) {
  	    while ( $i <= $r && $retval == 0 ) {
  		if ( $right->{version}[$i] != 0 ) {
  		    $retval = -1; # not a match after all
  		}
  		$i++;
  	    }
  	}
  	else {
  	    while ( $i <= $l && $retval == 0 ) {
  		if ( $left->{version}[$i] != 0 ) {
  		    $retval = +1; # not a match after all
  		}
  		$i++;
  	    }
  	}
      }
  
      return $retval;
  }
  
  sub vbool {
      my ($self) = @_;
      return vcmp($self,$self->new("0"),1);
  }
  
  sub vnoop {
      require Carp;
      Carp::croak("operation not supported with version object");
  }
  
  sub is_alpha {
      my ($self) = @_;
      return (exists $self->{alpha});
  }
  
  sub qv {
      my $value = shift;
      my $class = $CLASS;
      if (@_) {
  	$class = ref($value) || $value;
  	$value = shift;
      }
  
      $value = _un_vstring($value);
      $value = 'v'.$value unless $value =~ /(^v|\d+\.\d+\.\d)/;
      my $obj = $CLASS->new($value);
      return bless $obj, $class;
  }
  
  *declare = \&qv;
  
  sub is_qv {
      my ($self) = @_;
      return (exists $self->{qv});
  }
  
  
  sub _verify {
      my ($self) = @_;
      if ( ref($self)
  	&& eval { exists $self->{version} }
  	&& ref($self->{version}) eq 'ARRAY'
  	) {
  	return 1;
      }
      else {
  	return 0;
      }
  }
  
  sub _is_non_alphanumeric {
      my $s = shift;
      $s = new charstar $s;
      while ($s) {
  	return 0 if isSPACE($s); # early out
  	return 1 unless (isALPHA($s) || isDIGIT($s) || $s =~ /[.-]/);
  	$s++;
      }
      return 0;
  }
  
  sub _un_vstring {
      my $value = shift;
      # may be a v-string
      if ( length($value) >= 1 && $value !~ /[,._]/
  	&& _is_non_alphanumeric($value)) {
  	my $tvalue;
  	if ( $] >= 5.008_001 ) {
  	    $tvalue = _find_magic_vstring($value);
  	    $value = $tvalue if length $tvalue;
  	}
  	elsif ( $] >= 5.006_000 ) {
  	    $tvalue = sprintf("v%vd",$value);
  	    if ( $tvalue =~ /^v\d+(\.\d+)*$/ ) {
  		# must be a v-string
  		$value = $tvalue;
  	    }
  	}
      }
      return $value;
  }
  
  sub _find_magic_vstring {
      my $value = shift;
      my $tvalue = '';
      require B;
      my $sv = B::svref_2object(\$value);
      my $magic = ref($sv) eq 'B::PVMG' ? $sv->MAGIC : undef;
      while ( $magic ) {
  	if ( $magic->TYPE eq 'V' ) {
  	    $tvalue = $magic->PTR;
  	    $tvalue =~ s/^v?(.+)$/v$1/;
  	    last;
  	}
  	else {
  	    $magic = $magic->MOREMAGIC;
  	}
      }
      return $tvalue;
  }
  
  sub _VERSION {
      my ($obj, $req) = @_;
      my $class = ref($obj) || $obj;
  
      no strict 'refs';
      if ( exists $INC{"$class.pm"} and not %{"$class\::"} and $] >= 5.008) {
  	 # file but no package
  	require Carp;
  	Carp::croak( "$class defines neither package nor VERSION"
  	    ."--version check failed");
      }
  
      my $version = eval "\$$class\::VERSION";
      if ( defined $version ) {
  	local $^W if $] <= 5.008;
  	$version = version::vpp->new($version);
      }
  
      if ( defined $req ) {
  	unless ( defined $version ) {
  	    require Carp;
  	    my $msg =  $] < 5.006
  	    ? "$class version $req required--this is only version "
  	    : "$class does not define \$$class\::VERSION"
  	      ."--version check failed";
  
  	    if ( $ENV{VERSION_DEBUG} ) {
  		Carp::confess($msg);
  	    }
  	    else {
  		Carp::croak($msg);
  	    }
  	}
  
  	$req = version::vpp->new($req);
  
  	if ( $req > $version ) {
  	    require Carp;
  	    if ( $req->is_qv ) {
  		Carp::croak(
  		    sprintf ("%s version %s required--".
  			"this is only version %s", $class,
  			$req->normal, $version->normal)
  		);
  	    }
  	    else {
  		Carp::croak(
  		    sprintf ("%s version %s required--".
  			"this is only version %s", $class,
  			$req->stringify, $version->stringify)
  		);
  	    }
  	}
      }
  
      return defined $version ? $version->stringify : undef;
  }
  
  1; #this line is important and will help the module return a true value
I686-LINUX_VERSION_VPP

$fatpacked{"i686-linux/version/vxs.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'I686-LINUX_VERSION_VXS';
  #!perl -w
  package version::vxs;
  
  use v5.10;
  use strict;
  
  use vars qw(@ISA $VERSION $CLASS );
  $VERSION = 0.9912;
  $CLASS = 'version::vxs';
  
  eval {
      require XSLoader;
      local $^W; # shut up the 'redefined' warning for UNIVERSAL::VERSION
      XSLoader::load('version::vxs', $VERSION);
      1;
  } or do {
      require DynaLoader;
      push @ISA, 'DynaLoader'; 
      local $^W; # shut up the 'redefined' warning for UNIVERSAL::VERSION
      bootstrap version::vxs $VERSION;
  };
  
  # Preloaded methods go here.
  
  1;
I686-LINUX_VERSION_VXS

$fatpacked{"oo.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'OO';
  package oo;
  
  use strictures 1;
  use Moo::_Utils;
  
  sub moo {
    print <<'EOMOO';
   ______
  < Moo! >
   ------
          \   ^__^
           \  (oo)\_______
              (__)\       )\/\
                  ||----w |
                  ||     ||
  EOMOO
    exit 0;
  }
  
  BEGIN {
      my $package;
      sub import {
          moo() if $0 eq '-';
          $package = $_[1] || 'Class';
          if ($package =~ /^\+/) {
              $package =~ s/^\+//;
              _load_module($package);
          }
      }
      use Filter::Simple sub { s/^/package $package;\nuse Moo;\n/; }
  }
  
  1;
  __END__
  
  =head1 NAME
  
  oo - syntactic sugar for Moo oneliners
  
  =head1 SYNOPSIS
  
    perl -Moo=Foo -e 'has bar => ( is => q[ro], default => q[baz] ); print Foo->new->bar'
  
    # loads an existing class and re-"opens" the package definition
    perl -Moo=+My::Class -e 'print __PACKAGE__->new->bar'
  
  =head1 DESCRIPTION
  
  oo.pm is a simple source filter that adds C<package $name; use Moo;> to the
  beginning of your script, intended for use on the command line via the -M
  option.
  
  =head1 SUPPORT
  
  See L<Moo> for support and contact information.
  
  =head1 AUTHORS
  
  See L<Moo> for authors.
  
  =head1 COPYRIGHT AND LICENSE
  
  See L<Moo> for the copyright and license.
  
  =cut
OO

$fatpacked{"strictures.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'STRICTURES';
  package strictures;
  
  use strict;
  use warnings FATAL => 'all';
  
  use constant _PERL_LT_5_8_4 => ($] < 5.008004) ? 1 : 0;
  
  our $VERSION = '1.004004'; # 1.4.4
  
  sub VERSION {
    for ($_[1]) {
      last unless defined && !ref && int != 1;
      die "Major version specified as $_ - this is strictures version 1";
    }
    # disable this since Foo->VERSION(undef) correctly returns the version
    # and that can happen either if our caller passes undef explicitly or
    # because the for above autovivified $_[1] - I could make it stop but
    # it's pointless since we don't want to blow up if the caller does
    # something valid either.
    no warnings 'uninitialized';
    shift->SUPER::VERSION(@_);
  }
  
  my $extra_load_states;
  
  our $Smells_Like_VCS = (-e '.git' || -e '.svn'
    || (-e '../../dist.ini' && (-e '../../.git' || -e '../../.svn')));
  
  sub import {
    strict->import;
    warnings->import(FATAL => 'all');
  
    my $extra_tests = do {
      if (exists $ENV{PERL_STRICTURES_EXTRA}) {
        if (_PERL_LT_5_8_4 and $ENV{PERL_STRICTURES_EXTRA}) {
          die 'PERL_STRICTURES_EXTRA checks are not available on perls older than 5.8.4: '
            . "please unset \$ENV{PERL_STRICTURES_EXTRA}\n";
        }
        $ENV{PERL_STRICTURES_EXTRA};
      } elsif (! _PERL_LT_5_8_4) {
        !!((caller)[1] =~ /^(?:t|xt|lib|blib)/
           and $Smells_Like_VCS)
      }
    };
    if ($extra_tests) {
      $extra_load_states ||= do {
  
        my (%rv, @failed);
        foreach my $mod (qw(indirect multidimensional bareword::filehandles)) {
          eval "require $mod; \$rv{'$mod'} = 1;" or do {
            push @failed, $mod;
  
            # courtesy of the 5.8 require bug
            # (we do a copy because 5.16.2 at least uses the same read-only
            # scalars for the qw() list and it doesn't seem worth a $^V check)
  
            (my $file = $mod) =~ s|::|/|g;
            delete $INC{"${file}.pm"};
          };
        }
  
        if (@failed) {
          my $failed = join ' ', @failed;
          print STDERR <<EOE;
  strictures.pm extra testing active but couldn't load all modules. Missing were:
  
    $failed
  
  Extra testing is auto-enabled in checkouts only, so if you're the author
  of a strictures-using module you need to run:
  
    cpan indirect multidimensional bareword::filehandles
  
  but these modules are not required by your users.
  EOE
        }
  
        \%rv;
      };
  
      indirect->unimport(':fatal') if $extra_load_states->{indirect};
      multidimensional->unimport if $extra_load_states->{multidimensional};
      bareword::filehandles->unimport if $extra_load_states->{'bareword::filehandles'};
    }
  }
  
  1;
  
  __END__
  =head1 NAME
  
  strictures - turn on strict and make all warnings fatal
  
  =head1 SYNOPSIS
  
    use strictures 1;
  
  is equivalent to
  
    use strict;
    use warnings FATAL => 'all';
  
  except when called from a file which matches:
  
    (caller)[1] =~ /^(?:t|xt|lib|blib)/
  
  and when either C<.git> or C<.svn> is present in the current directory (with
  the intention of only forcing extra tests on the author side) -- or when C<.git>
  or C<.svn> is present two directories up along with C<dist.ini> (which would
  indicate we are in a C<dzil test> operation, via L<Dist::Zilla>) --
  or when the C<PERL_STRICTURES_EXTRA> environment variable is set, in which case
  
    use strictures 1;
  
  is equivalent to
  
    use strict;
    use warnings FATAL => 'all';
    no indirect 'fatal';
    no multidimensional;
    no bareword::filehandles;
  
  Note that C<PERL_STRICTURES_EXTRA> may at some point add even more tests, with only a minor
  version increase, but any changes to the effect of C<use strictures> in
  normal mode will involve a major version bump.
  
  If any of the extra testing modules are not present, L<strictures> will
  complain loudly, once, via C<warn()>, and then shut up. But you really
  should consider installing them, they're all great anti-footgun tools.
  
  =head1 DESCRIPTION
  
  I've been writing the equivalent of this module at the top of my code for
  about a year now. I figured it was time to make it shorter.
  
  Things like the importer in C<use Moose> don't help me because they turn
  warnings on but don't make them fatal -- which from my point of view is
  useless because I want an exception to tell me my code isn't warnings-clean.
  
  Any time I see a warning from my code, that indicates a mistake.
  
  Any time my code encounters a mistake, I want a crash -- not spew to STDERR
  and then unknown (and probably undesired) subsequent behaviour.
  
  I also want to ensure that obvious coding mistakes, like indirect object
  syntax (and not so obvious mistakes that cause things to accidentally compile
  as such) get caught, but not at the cost of an XS dependency and not at the
  cost of blowing things up on another machine.
  
  Therefore, L<strictures> turns on additional checking, but only when it thinks
  it's running in a test file in a VCS checkout -- although if this causes
  undesired behaviour this can be overridden by setting the
  C<PERL_STRICTURES_EXTRA> environment variable.
  
  If additional useful author side checks come to mind, I'll add them to the
  C<PERL_STRICTURES_EXTRA> code path only -- this will result in a minor version increase (e.g.
  1.000000 to 1.001000 (1.1.0) or similar). Any fixes only to the mechanism of
  this code will result in a sub-version increase (e.g. 1.000000 to 1.000001
  (1.0.1)).
  
  If the behaviour of C<use strictures> in normal mode changes in any way, that
  will constitute a major version increase -- and the code already checks
  when its version is tested to ensure that
  
    use strictures 1;
  
  will continue to only introduce the current set of strictures even if 2.0 is
  installed.
  
  =head1 METHODS
  
  =head2 import
  
  This method does the setup work described above in L</DESCRIPTION>
  
  =head2 VERSION
  
  This method traps the C<< strictures->VERSION(1) >> call produced by a use line
  with a version number on it and does the version check.
  
  =head1 EXTRA TESTING RATIONALE
  
  Every so often, somebody complains that they're deploying via C<git pull>
  and that they don't want L<strictures> to enable itself in this case -- and that
  setting C<PERL_STRICTURES_EXTRA> to 0 isn't acceptable (additional ways to
  disable extra testing would be welcome but the discussion never seems to get
  that far).
  
  In order to allow us to skip a couple of stages and get straight to a
  productive conversation, here's my current rationale for turning the
  extra testing on via a heuristic:
  
  The extra testing is all stuff that only ever blows up at compile time;
  this is intentional. So the oft-raised concern that it's different code being
  tested is only sort of the case -- none of the modules involved affect the
  final optree to my knowledge, so the author gets some additional compile
  time crashes which he/she then fixes, and the rest of the testing is
  completely valid for all environments.
  
  The point of the extra testing -- especially C<no indirect> -- is to catch
  mistakes that newbie users won't even realise are mistakes without
  help. For example,
  
    foo { ... };
  
  where foo is an & prototyped sub that you forgot to import -- this is
  pernicious to track down since all I<seems> fine until it gets called
  and you get a crash. Worse still, you can fail to have imported it due
  to a circular require, at which point you have a load order dependent
  bug which I've seen before now I<only> show up in production due to tiny
  differences between the production and the development environment. I wrote
  L<http://shadow.cat/blog/matt-s-trout/indirect-but-still-fatal/> to explain
  this particular problem before L<strictures> itself existed.
  
  As such, in my experience so far L<strictures>' extra testing has
  I<avoided> production versus development differences, not caused them.
  
  Additionally, L<strictures>' policy is very much "try and provide as much
  protection as possible for newbies -- who won't think about whether there's
  an option to turn on or not" -- so having only the environment variable
  is not sufficient to achieve that (I get to explain that you need to add
  C<use strict> at least once a week on freenode #perl -- newbies sometimes
  completely skip steps because they don't understand that that step
  is important).
  
  I make no claims that the heuristic is perfect -- it's already been evolved
  significantly over time, especially for 1.004 where we changed things to
  ensure it only fires on files in your checkout (rather than L<strictures>-using
  modules you happened to have installed, which was just silly). However, I
  hope the above clarifies why a heuristic approach is not only necessary but
  desirable from a point of view of providing new users with as much safety as possible,
  and will allow any future discussion on the subject to focus on "how do we
  minimise annoyance to people deploying from checkouts intentionally".
  
  =head1 COMMUNITY AND SUPPORT
  
  =head2 IRC channel
  
  irc.perl.org #toolchain
  
  (or bug 'mst' in query on there or freenode)
  
  =head2 Git repository
  
  Gitweb is on http://git.shadowcat.co.uk/ and the clone URL is:
  
    git clone git://git.shadowcat.co.uk/p5sagit/strictures.git
  
  The web interface to the repository is at:
  
    http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=p5sagit/strictures.git
  
  =head1 AUTHOR
  
  mst - Matt S. Trout (cpan:MSTROUT) <mst@shadowcat.co.uk>
  
  =head1 CONTRIBUTORS
  
  None required yet. Maybe this module is perfect (hahahahaha ...).
  
  =head1 COPYRIGHT
  
  Copyright (c) 2010 the strictures L</AUTHOR> and L</CONTRIBUTORS>
  as listed above.
  
  =head1 LICENSE
  
  This library is free software and may be distributed under the same terms
  as perl itself.
  
  =cut
STRICTURES

s/^  //mg for values %fatpacked;

my $class = 'FatPacked::'.(0+\%fatpacked);
no strict 'refs';
*{"${class}::files"} = sub { keys %{$_[0]} };

if ($] < 5.008) {
  *{"${class}::INC"} = sub {
     if (my $fat = $_[0]{$_[1]}) {
       return sub {
         return 0 unless length $fat;
         $fat =~ s/^([^\n]*\n?)//;
         $_ = $1;
         return 1;
       };
     }
     return;
  };
}

else {
  *{"${class}::INC"} = sub {
    if (my $fat = $_[0]{$_[1]}) {
      open my $fh, '<', \$fat
        or die "FatPacker error loading $_[1] (could be a perl installation issue?)";
      return $fh;
    }
    return;
  };
}

unshift @INC, bless \%fatpacked, $class;
  } # END OF FATPACK CODE

use strict;
use 5.008001;
use Carton::CLI;
$Carton::Fatpacked = 1;
exit Carton::CLI->new->run(@ARGV);
