text:
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 :


text:
using System;
using System.Collections.Generic;

namespace Nez
{
	/// <summary>
	/// A basic processing system that doesn't rely on entities.
	/// It's got no entities associated but it's still being called each frame.
	/// Use this as a base class for generic systems that need to coordinate other systems
	/// </summary>
	public abstract class ProcessingSystem : EntitySystem
	{
		public override void onChange( Entity entity )
		{
			// We do not manage any notification of entities changing state  and avoid polluting our list of entities as we want to keep it empty
		}

		protected override void process( List<Entity> entities )
		{
			// We replace the basic entity system with our own that doesn't take into account entities
			begin();
			process();
			end();
		}

		/// <summary>
		/// Process our system. This is being called each and every frame.
		/// </summary>
		public abstract void process();

	}
}

redpajama_set_name: RedPajamaGithub


text:
<?php
/**
 * Program to send all 50 queries to Google, Bing and Blekko, retrieve the results
 * and store the results in files for later processing
 *
 * PHP version 5
 *
 * @category PHP
 * @package  PHP_Metasearch_Engine
 * @author   Andrew Lamb <andrew.r.d.lamb@gmail.com>
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
 * @link     http://csserver.ucd.ie/~01421662/
 */
//Disabled as expensive and uses a lot of queries, particularly for Google
//********************************************************************************
exit("
    This option is disabled as all result sets have already been retrieved.

© Andrew Lamb 2013

    email

    Back To Goobling

"
);
//********************************************************************************

ini_set('max_execution_time', 600);

//INCLUDE FUNCTIONS:
require 'metrics/functions/getBlekkoResults.php'; //get results from Blekko
require 'metrics/functions/getGoogleResults.php'; //get results from Google
require 'metrics/functions/getBingResults.php'; //get results from Bing
require 'metrics/functions/removeDuplicates.php'; //remove duplicate URLs
require 'metrics/functions/aggregateResults.php'; //aggregate the results
require 'metrics/functions/calcWeight.php'; //calculate the weight for each engine
require 'metrics/functions/applyWeight.php'; //apply the weight to the results
require 'metrics/functions/compareValues.php'; //function used by usort to sort array

//****************************************************************************
//QUERY LIST FROM FILE
//Get contents of query list into a string
$queryStr = file_get_contents('metrics/trec2012queries.txt');

//Convert string to an array
$queryArr = explode("\n", $queryStr);

//Add query number to each string in array
$queryNum = 151;
for ($i=0; $i<50; $i++) {
    $queryArr[$i] = $queryNum++ . "|" . $queryArr[$i];
}

//Put Query Number and Query into separate elements
foreach ($queryArr as &$value) {
    $value = explode("|", $value);
}

//Get Results for each Query
for ($i=0; $i<50; $i++) {
    $query = $queryArr[$i][1];

    //Arrays to store results
    $blekkoResultsOrig = array(); //original results (may contain duplicates)
    $googleResultsOrig = array(); //original results (may contain duplicates)
    $bingResultsOrig = array ();  //original results (may contain duplicates)
    $blekkoResults = array(); //results with duplicates removed
    $googleResults = array(); //results with duplicates removed
    $bingResults = array();   //results with duplicates removed
    $aggregatedResults = array(); //array to store aggregated results in
    $weights = array(); //array to store weights applied

    //CALL FUNCTIONS TO GET RESULTS FROM SEARCH ENGINES
    getBlekkoResults($blekkoResultsOrig, $query); //get Blekko
    getGoogleResults($googleResultsOrig, $query); //get Google
    getBingResults($bingResultsOrig, $query); //get Bing

    //CALL FUNCTIONS TO REMOVE DUPLICATE URLS AND RE-SCORE DOCUMENTS
    removeDuplicates($blekkoResultsOrig, $blekkoResults);
    removeDuplicates($googleResultsOrig, $googleResults);
    removeDuplicates($bingResultsOrig, $bingResults);

    //*********************************************
    //Write results to files
    writeToFile($blekkoResults, "metrics/blekkoResults", $query);
    writeToFile($bingResults, "metrics/bingResults", $query);
    writeToFile($googleResults, "metrics/googleResults", $query);

    //AGGREGATE the Results using Borda-Fuse
    //NOTE THAT THE ORDER THE ARRAYS ARE SENT IN TO BE AGGREGATED MATTERS
    //FOR ANY RESULTS THAT HAVE THE SAME COMBINED SCORE/RANK
    aggregateResults(
        $googleResults, $bingResults,
        $blekkoResults, $aggregatedResults
    );

    //*********************************************
    //Write results to file
    writeToFile($aggregatedResults, "metrics/aggregatedResults", $query);

    //initialize variables to rank search engines
    $wsumGoogle = $wsumBing = $wsumBlekko = 0.00;
    //CALCULATE THE WEIGHT FOR EACH SEARCH ENGINE
    calcWeight(
        $googleResults, $bingResults,
        $blekkoResults, $wsumGoogle,
        $wsumBing, $wsumBlekko
    );
    //APPLY THE WEIGHT TO EACH OF THE SEARCH ENGINES RESULTS
    applyWeight($googleResults, $wsumGoogle);
    applyWeight($bingResults, $wsumBing);
    applyWeight($blekkoResults, $wsumBlekko);
    //AGGREGATE the Results using Borda-Fuse
    $aggregatedResults = array();
    aggregateResults(
        $googleResults, $bingResults,
        $blekkoResults, $aggregatedResults
    );

    $weights = array($query =>
        array(  "google" => $wsumGoogle,
                "bing" => $wsumBing,
                "blekko" => $wsumBlekko));

    writeToFile($weights, "metrics/weightedResults", $query." weights");

    //*********************************************
    //Write results to file
    writeToFile($aggregatedResults, "metrics/weightedResults", $query);

    sleep(5); //pause between queries
}
?>


text:
namespace LibSystem1
{
    partial class Login
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.button1 = new System.Windows.Forms.Button();
            this.username = new System.Windows.Forms.MaskedTextBox();
            this.pass = new System.Windows.Forms.TextBox();
            this.groupBox1 = new System.Windows.Forms.GroupBox();
            this.label2 = new System.Windows.Forms.Label();
            this.label1 = new System.Windows.Forms.Label();
            this.groupBox1.SuspendLayout();
            this.SuspendLayout();
            //
            // button1
            //
            this.button1.Location = new System.Drawing.Point(76, 106);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(75, 23);
            this.button1.TabIndex = 0;
            this.button1.Text = "Login";
            this.button1.UseVisualStyleBackColor = true;
            this.button1.Click += new System.EventHandler(this.button1_Click);
            //
            // username
            //
            this.username.Location = new System.Drawing.Point(76, 19);
            this.username.Name = "username";
            this.username.Size = new System.Drawing.Size(100, 20);
            this.username.TabIndex = 1;
            //
            // pass
            //
            this.pass.Location = new System.Drawing.Point(76, 58);
            this.pass.Name = "pass";
            this.pass.Size = new System.Drawing.Size(100, 20);
            this.pass.TabIndex = 2;
            this.pass.UseSystemPasswordChar = true;
            //
            // groupBox1
            //
            this.groupBox1.Controls.Add(this.label2);
            this.groupBox1.Controls.Add(this.label1);
            this.groupBox1.Controls.Add(this.username);
            this.groupBox1.Controls.Add(this.pass);
            this.groupBox1.Controls.Add(this.button1);
            this.groupBox1.Location = new System.Drawing.Point(0, 0);
            this.groupBox1.Name = "groupBox1";
            this.groupBox1.Size = new System.Drawing.Size(281, 259);
            this.groupBox1.TabIndex = 3;
            this.groupBox1.TabStop = false;
            this.groupBox1.Text = "LMS Login";
            //
            // label2
            //
            this.label2.AutoSize = true;
            this.label2.Location = new System.Drawing.Point(12, 22);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(55, 13);
            this.label2.TabIndex = 3;
            this.label2.Text = "Username";
            //
            // label1
            //
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(12, 61);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(53, 13);
            this.label1.TabIndex = 3;
            this.label1.Text = "Password";
            //
            // Login
            //
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(284, 261);
            this.Controls.Add(this.groupBox1);
            this.Name = "Login";
            this.Text = "Login";
            this.groupBox1.ResumeLayout(false);
            this.groupBox1.PerformLayout();
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.MaskedTextBox username;
        private System.Windows.Forms.TextBox pass;
        private System.Windows.Forms.GroupBox groupBox1;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.Label label1;
    }
}


text:
import Text.Hastache
import Text.Hastache.Context
import qualified Data.Text.Lazy.IO as TL

-- begin example
main = mapM_ (\ctx ->
    hastacheStr defaultConfig (encodeStr template) (mkStrContext ctx)
    >>= TL.putStrLn) [context1,context2]

template = "{{#msg}}{{msg}}{{/msg}}{{^msg}}No{{/msg}} new messages."

context1 "msg" = MuVariable (100 :: Int)
context2 "msg" = MuVariable (0 :: Int)


text:
A Dockerfile to build [PhantomJS](https://github.com/ariya/phantomjs) 2.1.1 for Linux from source.

## Installation
There is an [Automated Build on hub.docker.com](https://registry.hub.docker.com/u/nathanmarks/phantomjs2/):

```
docker pull nathanmarks/phantomjs2:latest
```

## Usage

```bash
docker run nathanmarks/phantomjs2 phantomjs -v
```


text:
import java.util.Collections;
import java.util.List;
import java.util.ArrayList;

class C {
    List<List<String>> test() {
        List<String> result = new ArrayList<>();
        return List.of(Collections.unmodifiableList(result));
    }
}


text:
define(["require", "exports", "../util/Methods"], function (require, exports, Methods) {
    "use strict";
    var RoundRect = (function () {
        function RoundRect(x, y, w, h, radiusTL, radiusTR, radiusBR, radiusBL) {
            this.x = x;
            this.y = y;
            this.w = w;
            this.h = h;
            this.radiusTL = radiusTL;
            this.radiusTR = radiusTR;
            this.radiusBR = radiusBR;
            this.radiusBL = radiusBL;
        }
        RoundRect.prototype.exec = function (ctx) {
            var max = (w < h ? w : h) / 2;
            var mTL = 0, mTR = 0, mBR = 0, mBL = 0;
            var x = this.x, y = this.y, w = this.w, h = this.h;
            var rTL = this.radiusTL, rTR = this.radiusTR, rBR = this.radiusBR, rBL = this.radiusBL;
            if (rTL < 0) {
                rTL *= (mTL = -1);
            }
            if (rTL > max) {
                rTL = max;
            }
            if (rTR < 0) {
                rTR *= (mTR = -1);
            }
            if (rTR > max) {
                rTR = max;
            }
            if (rBR < 0) {
                rBR *= (mBR = -1);
            }
            if (rBR > max) {
                rBR = max;
            }
            if (rBL < 0) {
                rBL *= (mBL = -1);
            }
            if (rBL > max) {
                rBL = max;
            }
            ctx.moveTo(x + w - rTR, y);
            ctx.arcTo(x + w + rTR * mTR, y - rTR * mTR, x + w, y + rTR, rTR);
            ctx.lineTo(x + w, y + h - rBR);
            ctx.arcTo(x + w + rBR * mBR, y + h + rBR * mBR, x + w - rBR, y + h, rBR);
            ctx.lineTo(x + rBL, y + h);
            ctx.arcTo(x - rBL * mBL, y + h + rBL * mBL, x, y + h - rBL, rBL);
            ctx.lineTo(x, y + rTL);
            ctx.arcTo(x - rTL * mTL, y - rTL * mTL, x + rTL, y, rTL);
            ctx.closePath();
        };
        return RoundRect;
    }());
    var Oval = (function () {
        function Oval(x, y, xRadius, yRadius, rotationAngle, startAngle, endAngle) {
            this.x = x;
            this.y = y;
            this.xRadius = xRadius;
            this.yRadius = yRadius;
            this.rotationAngle = rotationAngle;
            this.startAngle = startAngle;
            this.endAngle = endAngle;
        }
        Oval.prototype.exec = function (ctx) {
            var x = this.x;
            var y = this.y;
            for (var i = this.startAngle * Math.PI; i < this.endAngle * Math.PI; i += 0.01) {
                var xPos = x - (this.xRadius * Math.sin(i)) * Math.sin(this.rotationAngle * Math.PI) + (this.yRadius * Math.cos(i)) * Math.cos(this.rotationAngle * Math.PI);
                var yPos = y + (this.yRadius * Math.cos(i)) * Math.sin(this.rotationAngle * Math.PI) + (this.xRadius * Math.sin(i)) * Math.cos(this.rotationAngle * Math.PI);
                if (i == 0) {
                    ctx.moveTo(xPos, yPos);
                }
                else {
                    ctx.lineTo(xPos, yPos);
                }
            }
        };
        return Oval;
    }());
    var LineTo = (function () {
        function LineTo(x, y) {
            this.x = x;
            this.y = y;
        }
        LineTo.prototype.exec = function (ctx) {
            ctx.lineTo(this.x, this.y);
        };
        return LineTo;
    }());
    var MoveTo = (function () {
        function MoveTo(x, y) {
            this.x = x;
            this.y = y;
        }
        MoveTo.prototype.exec = function (ctx) {
            ctx.moveTo(this.x, this.y);
        };
        return MoveTo;
    }());
    var ArcTo = (function () {
        function ArcTo(x1, y1, x2, y2, radius) {
            this.x1 = x1;
            this.y1 = y1;
            this.x2 = x2;
            this.y2 = y2;
            this.radius = radius;
        }
        ArcTo.prototype.exec = function (ctx) {
            ctx.arcTo(this.x1, this.y1, this.x2, this.y2, this.radius);
        };
        return ArcTo;
    }());
    var Arc = (function () {
        function Arc(x, y, radius, startAngle, endAngle, anticlockwise) {
            this.exec = function (ctx) {
                ctx.arc(this.x, this.y, this.radius, this.startAngle, this.endAngle, this.anticlockwise);
            };
            this.x = x;
            this.y = y;
            this.radius = radius;
            this.startAngle = startAngle;
            this.endAngle = endAngle;
            this.anticlockwise = !!anticlockwise;
        }
        return Arc;
    }());
    var QuadraticCurveTo = (function () {
        function QuadraticCurveTo(cpx, cpy, x, y) {
            this.exec = function (ctx) {
                ctx.quadraticCurveTo(this.cpx, this.cpy, this.x, this.y);
            };
            this.cpx = cpx;
            this.cpy = cpy;
            this.x = x;
            this.y = y;
        }
        return QuadraticCurveTo;
    }());
    var BezierCurveTo = (function () {
        function BezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) {
            this.exec = function (ctx) {
                ctx.bezierCurveTo(this.cp1x, this.cp1y, this.cp2x, this.cp2y, this.x, this.y);
            };
            this.cp1x = cp1x;
            this.cp1y = cp1y;
            this.cp2x = cp2x;
            this.cp2y = cp2y;
            this.x = x;
            this.y = y;
        }
        return BezierCurveTo;
    }());
    var Rect = (function () {
        function Rect(x, y, w, h) {
            this.exec = function (ctx) {
                ctx.rect(this.x, this.y, this.w, this.h);
            };
            this.x = x;
            this.y = y;
            this.w = w;
            this.h = h;
        }
        return Rect;
    }());
    var ClosePath = (function () {
        function ClosePath() {
            this.exec = function (ctx) {
                ctx.closePath();
            };
        }
        return ClosePath;
    }());
    var BeginPath = (function () {
        function BeginPath() {
        }
        BeginPath.prototype.exec = function (ctx) {
            ctx.beginPath();
        };
        return BeginPath;
    }());
    var Fill = (function () {
        function Fill(style, matrix) {
            this.path = false;
            this.style = style;
            this.matrix = matrix;
        }
        Fill.prototype.exec = function (ctx) {
            if (!this.style) {
                return;
            }
            ctx.fillStyle = this.style;
            var mtx = this.matrix;
            if (mtx) {
                ctx.save();
                ctx.transform(mtx.a, mtx.b, mtx.c, mtx.d, mtx.tx, mtx.ty);
            }
            ctx.fill();
            if (mtx) {
                ctx.restore();
            }
        };
        Fill.prototype.linearGradient = function (colors, ratios, x0, y0, x1, y1) {
            var o = this.style = Graphics._ctx.createLinearGradient(x0, y0, x1, y1);
            for (var i = 0, l = colors.length; i < l; i++) {
                o.addColorStop(ratios[i], colors[i]);
            }
            o['props'] = { colors: colors, ratios: ratios, x0: x0, y0: y0, x1: x1, y1: y1, type: "linear" };
            return this;
        };
        Fill.prototype.radialGradient = function (colors, ratios, x0, y0, r0, x1, y1, r1) {
            var o = this.style = Graphics._ctx.createRadialGradient(x0, y0, r0, x1, y1, r1);
            for (var i = 0, l = colors.length; i < l; i++) {
                o.addColorStop(ratios[i], colors[i]);
            }
            o['props'] = { colors: colors, ratios: ratios, x0: x0, y0: y0, r0: r0, x1: x1, y1: y1, r1: r1, type: "radial" };
            return this;
        };
        Fill.prototype.bitmap = function (image, repetition) {
            var o = this.style = Graphics._ctx.createPattern(image, "");
            o['props'] = { image: image, repetition: repetition, type: "bitmap" };
            return this;
        };
        return Fill;
    }());
    var Stroke = (function () {
        function Stroke(style, ignoreScale) {
            this.linearGradient = Fill.prototype.linearGradient;
            this.radialGradient = Fill.prototype.radialGradient;
            this.bitmap = Fill.prototype.bitmap;
            this.path = false;
            this.style = style;
            this.ignoreScale = ignoreScale;
        }
        Stroke.prototype.exec = function (ctx) {
            if (!this.style) {
                return;
            }
            ctx.strokeStyle = this.style;
            if (this.ignoreScale) {
                ctx.save();
                ctx.setTransform(1, 0, 0, 1, 0, 0);
            }
            ctx.stroke();
            if (this.ignoreScale) {
                ctx.restore();
            }
        };
        return Stroke;
    }());
    var StrokeStyle = (function () {
        function StrokeStyle(width, caps, joints, miterLimit) {
            this.path = false;
            this.width = width;
            this.caps = caps;
            this.joints = joints;
            this.miterLimit = miterLimit;
        }
        StrokeStyle.prototype.exec = function (ctx) {
            ctx.lineWidth = (this.width == null ? "1" : this.width);
            ctx.lineCap = (this.caps == null ? "butt" : this.caps);
            ctx.lineJoin = (this.joints == null ? "miter" : this.joints);
            ctx.miterLimit = (this.miterLimit == null ? "10" : this.miterLimit);
        };
        return StrokeStyle;
    }());
    var StrokeDash = (function () {
        function StrokeDash(segments, offset) {
            this.segments = segments;
            this.offset = offset;
        }
        StrokeDash.prototype.exec = function (ctx) {
            ctx.setLineDash(this.segments);
            ctx.lineDashOffset = this.offset;
        };
        return StrokeDash;
    }());
    var Circle = (function () {
        function Circle(x, y, radius) {
            this.x = x;
            this.y = y;
            this.radius = radius;
        }
        Circle.prototype.exec = function (ctx) {
            ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
        };
        return Circle;
    }());
    var Ellipse = (function () {
        function Ellipse(x, y, w, h) {
            this.x = x;
            this.y = y;
            this.w = w;
            this.h = h;
        }
        Ellipse.prototype.exec = function (ctx) {
            var x = this.x, y = this.y;
            var w = this.w, h = this.h;
            var k = 0.5522848;
            var ox = (w / 2) * k;
            var oy = (h / 2) * k;
            var xe = x + w;
            var ye = y + h;
            var xm = x + w / 2;
            var ym = y + h / 2;
            ctx.moveTo(x, ym);
            ctx.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
            ctx.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
            ctx.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
            ctx.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
        };
        return Ellipse;
    }());
    var PolyStar = (function () {
        function PolyStar(x, y, radius, sides, pointSize, angle) {
            this.x = x;
            this.y = y;
            this.radius = radius;
            this.sides = sides;
            this.pointSize = pointSize;
            this.angle = angle;
        }
        PolyStar.prototype.exec = function (ctx) {
            var x = this.x, y = this.y;
            var radius = this.radius;
            var angle = (this.angle || 0) / 180 * Math.PI;
            var sides = this.sides;
            var ps = 1 - (this.pointSize || 0);
            var a = Math.PI / sides;
            ctx.moveTo(x + Math.cos(angle) * radius, y + Math.sin(angle) * radius);
            for (var i = 0; i < sides; i++) {
                angle += a;
                if (ps != 1) {
                    ctx.lineTo(x + Math.cos(angle) * radius * ps, y + Math.sin(angle) * radius * ps);
                }
                angle += a;
                ctx.lineTo(x + Math.cos(angle) * radius, y + Math.sin(angle) * radius);
            }
            ctx.closePath();
        };
        return PolyStar;
    }());
    var Graphics = (function () {
        function Graphics() {
            this.command = null;
            this._stroke = null;
            this._strokeStyle = null;
            this._strokeIgnoreScale = false;
            this._fill = null;
            this._instructions = null;
            this._commitIndex = 0;
            this._activeInstructions = null;
            this._dirty = false;
            this._ctx = Graphics._ctx;
            this.curveTo = this.quadraticCurveTo;
            this.drawRect = this.rect;
            this.mt = this.moveTo;
            this.lt = this.lineTo;
            this.at = this.arcTo;
            this.bt = this.bezierCurveTo;
            this.qt = this.quadraticCurveTo;
            this.a = this.arc;
            this.r = this.rect;
            this.cp = this.closePath;
            this.c = this.clear;
            this.f = this.beginFill;
            this.lf = this.beginLinearGradientFill;
            this.rf = this.beginRadialGradientFill;
            this.bf = this.beginBitmapFill;
            this.ef = this.endFill;
            this.ss = this.setStrokeStyle;
            this.s = this.beginStroke;
            this.ls = this.beginLinearGradientStroke;
            this.rs = this.beginRadialGradientStroke;
            this.bs = this.beginBitmapStroke;
            this.es = this.endStroke;
            this.dr = this.rect;
            this.rr = this.drawRoundRect;
            this.rc = this.drawRoundRectComplex;
            this.dc = this.drawCircle;
            this.de = this.drawEllipse;
            this.dp = this.drawPolyStar;
            this.p = this.decodePath;
            this.clear();
        }
        Graphics.getRGB = function (r, g, b, alpha) {
            if (alpha === void 0) { alpha = null; }
            if (r != null && b == null) {
                alpha = g;
                b = r & 0xFF;
                g = r >> 8 & 0xFF;
                r = r >> 16 & 0xFF;
            }
            if (alpha == null) {
                return "rgb(" + r + "," + g + "," + b + ")";
            }
            else {
                return "rgba(" + r + "," + g + "," + b + "," + alpha + ")";
            }
        };
        Graphics.getHSL = function (hue, saturation, lightness, alpha) {
            if (alpha == null) {
                return "hsl(" + (hue % 360) + "," + saturation + "%," + lightness + "%)";
            }
            else {
                return "hsla(" + (hue % 360) + "," + saturation + "%," + lightness + "%," + alpha + ")";
            }
        };
        Graphics.prototype.isEmpty = function () {
            return !(this._instructions.length || this._activeInstructions.length);
        };
        Graphics.prototype.draw = function (ctx, data) {
            this._updateInstructions();
            var instr = this._instructions;
            for (var i = 0, l = instr.length; i < l; i++) {
                instr[i].exec(ctx, data);
            }
        };
        Graphics.prototype.drawAsPath = function (ctx) {
            this._updateInstructions();
            var instr, instrs = this._instructions;
            for (var i = 0, l = instrs.length; i < l; i++) {
                if ((instr = instrs[i]).path !== false) {
                    instr.exec(ctx);
                }
            }
        };
        Graphics.prototype.moveTo = function (x, y) {
            return this.append(new Graphics.MoveTo(x, y), true);
        };
        Graphics.prototype.lineTo = function (x, y) {
            return this.append(new Graphics.LineTo(x, y));
        };
        Graphics.prototype.oval = function (x, y, xRadius, yRadius, rotationAngle, startAngle, endAngle) {
            return this.append(new Graphics.Oval(x, y, xRadius, yRadius, rotationAngle, startAngle, endAngle));
        };
        Graphics.prototype.arcTo = function (x1, y1, x2, y2, radius) {
            return this.append(new Graphics.ArcTo(x1, y1, x2, y2, radius));
        };
        Graphics.prototype.arc = function (x, y, radius, startAngle, endAngle, anticlockwise) {
            return this.append(new Graphics.Arc(x, y, radius, startAngle, endAngle, anticlockwise));
        };
        Graphics.prototype.quadraticCurveTo = function (cpx, cpy, x, y) {
            return this.append(new Graphics.QuadraticCurveTo(cpx, cpy, x, y));
        };
        Graphics.prototype.bezierCurveTo = function (cp1x, cp1y, cp2x, cp2y, x, y) {
            return this.append(new Graphics.BezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y));
        };
        Graphics.prototype.rect = function (x, y, width, height) {
            return this.append(new Graphics.Rect(x, y, width, height));
        };
        Graphics.prototype.closePath = function () {
            return this._activeInstructions.length ? this.append(new Graphics.ClosePath()) : this;
        };
        Graphics.prototype.clear = function () {
            this._instructions = [];
            this._activeInstructions = [];
            this._commitIndex = 0;
            this._strokeStyle = this._stroke = this._fill = null;
            this._dirty = this._strokeIgnoreScale = false;
            return this;
        };
        Graphics.prototype.beginFill = function (color) {
            return this._setFill(color ? new Graphics.Fill(color) : null);
        };
        Graphics.prototype.beginLinearGradientFill = function (colors, ratios, x0, y0, x1, y1) {
            return this._setFill(new Graphics.Fill().linearGradient(colors, ratios, x0, y0, x1, y1));
        };
        Graphics.prototype.beginRadialGradientFill = function (colors, ratios, x0, y0, r0, x1, y1, r1) {
            return this._setFill(new Graphics.Fill().radialGradient(colors, ratios, x0, y0, r0, x1, y1, r1));
        };
        Graphics.prototype.beginBitmapFill = function (image, repetition, matrix) {
            if (repetition === void 0) { repetition = 'repeat'; }
            return this._setFill(new Graphics.Fill(null, matrix).bitmap(image, repetition));
        };
        Graphics.prototype.endFill = function () {
            return this.beginFill();
        };
        Graphics.prototype.setStrokeStyle = function (thickness, caps, joints, miterLimit, ignoreScale) {
            if (caps === void 0) { caps = null; }
            if (joints === void 0) { joints = null; }
            if (miterLimit === void 0) { miterLimit = null; }
            if (ignoreScale === void 0) { ignoreScale = false; }
            this._updateInstructions(true);
            this._strokeStyle = this.command = new Graphics.StrokeStyle(thickness, caps, joints, miterLimit);
            if (this._stroke) {
                this._stroke.ignoreScale = ignoreScale;
            }
            this._strokeIgnoreScale = ignoreScale;
            return this;
        };
        Graphics.prototype.beginStroke = function (color) {
            return this._setStroke(color ? new Graphics.Stroke(color, null) : null);
        };
        Graphics.prototype.beginLinearGradientStroke = function (colors, ratios, x0, y0, x1, y1) {
            return this._setStroke(new Graphics.Stroke(null, null).linearGradient(colors, ratios, x0, y0, x1, y1));
        };
        Graphics.prototype.beginRadialGradientStroke = function (colors, ratios, x0, y0, r0, x1, y1, r1) {
            return this._setStroke(new Graphics.Stroke(null, null).radialGradient(colors, ratios, x0, y0, r0, x1, y1, r1));
        };
        Graphics.prototype.beginBitmapStroke = function (image, repetition) {
            return this._setStroke(new Graphics.Stroke(null, null).bitmap(image, repetition));
        };
        Graphics.prototype.endStroke = function () {
            return this.beginStroke(null);
        };
        Graphics.prototype.drawRoundRect = function (x, y, w, h, radius) {
            return this.drawRoundRectComplex(x, y, w, h, radius, radius, radius, radius);
        };
        Graphics.prototype.drawRoundRectComplex = function (x, y, w, h, radiusTL, radiusTR, radiusBR, radiusBL) {
            return this.append(new Graphics.RoundRect(x, y, w, h, radiusTL, radiusTR, radiusBR, radiusBL));
        };
        Graphics.prototype.drawCircle = function (x, y, radius) {
            return this.append(new Graphics.Circle(x, y, radius));
        };
        Graphics.prototype.drawEllipse = function (x, y, w, h) {
            return this.append(new Graphics.Ellipse(x, y, w, h));
        };
        Graphics.prototype.drawPolyStar = function (x, y, radius, sides, pointSize, angle) {
            return this.append(new Graphics.PolyStar(x, y, radius, sides, pointSize, angle));
        };
        Graphics.prototype.setStrokeDash = function (segments, offset) {
            if (offset === void 0) { offset = 0; }
            return this.append(new StrokeDash(segments, offset));
        };
        Graphics.prototype.append = function (command, clean) {
            this._activeInstructions.push(command);
            this.command = command;
            if (!clean) {
                this._dirty = true;
            }
            return this;
        };
        Graphics.prototype.decodePath = function (str) {
            var instructions = [this.moveTo, this.lineTo, this.quadraticCurveTo, this.bezierCurveTo, this.closePath];
            var paramCount = [2, 2, 4, 6, 0];
            var i = 0, l = str.length;
            var params = [];
            var x = 0, y = 0;
            var base64 = Graphics.BASE_64;
            while (i < l) {
                var c = str.charAt(i);
                var n = base64[c];
                var fi = n >> 3;
                var f = instructions[fi];
                if (!f || (n & 3)) {
                    throw ("bad path data (@" + i + "): " + c);
                }
                var pl = paramCount[fi];
                if (!fi) {
                    x = y = 0;
                }
                params.length = 0;
                i++;
                var charCount = (n >> 2 & 1) + 2;
                for (var p = 0; p < pl; p++) {
                    var num = base64[str.charAt(i)];
                    var sign = (num >> 5) ? -1 : 1;
                    num = ((num & 31) << 6) | (base64[str.charAt(i + 1)]);
                    if (charCount == 3) {
                        num = (num << 6) | (base64[str.charAt(i + 2)]);
                    }
                    num = sign * num / 10;
                    if (p % 2) {
                        x = (num += x);
                    }
                    else {
                        y = (num += y);
                    }
                    params[p] = num;
                    i += charCount;
                }
                f.apply(this, params);
            }
            return this;
        };
        Graphics.prototype.getInstructions = function () {
            this._updateInstructions();
            return this._instructions;
        };
        Graphics.prototype.clone = function () {
            var o = new Graphics();
            o._instructions = this._instructions.slice();
            o._activeInstructions = this._activeInstructions.slice();
            o._commitIndex = this._commitIndex;
            o._fill = this._fill;
            o._stroke = this._stroke;
            o._strokeStyle = this._strokeStyle;
            o._dirty = this._dirty;
            o._strokeIgnoreScale = this._strokeIgnoreScale;
            return o;
        };
        Graphics.prototype.toString = function () {
            return "[Graphics]";
        };
        Graphics.prototype._updateInstructions = function (commit) {
            var instr = this._instructions, active = this._activeInstructions, commitIndex = this._commitIndex;
            if (this._dirty && active.length) {
                instr.length = commitIndex;
                instr.push(Graphics.beginCmd);
                instr.push.apply(instr, active);
                if (this._fill) {
                    instr.push(this._fill);
                }
                if (this._stroke && this._strokeStyle) {
                    instr.push(this._strokeStyle);
                }
                if (this._stroke) {
                    instr.push(this._stroke);
                }
                this._dirty = false;
            }
            if (commit) {
                active.length = 0;
                this._commitIndex = instr.length;
            }
        };
        Graphics.prototype._setFill = function (fill) {
            this._updateInstructions(true);
            if (this._fill = fill) {
                this.command = fill;
            }
            return this;
        };
        Graphics.prototype._setStroke = function (stroke) {
            this._updateInstructions(true);
            if (this._stroke = stroke) {
                this.command = stroke;
                stroke.ignoreScale = this._strokeIgnoreScale;
            }
            return this;
        };
        Graphics.RoundRect = RoundRect;
        Graphics.MoveTo = MoveTo;
        Graphics.LineTo = LineTo;
        Graphics.ArcTo = ArcTo;
        Graphics.Arc = Arc;
        Graphics.QuadraticCurveTo = QuadraticCurveTo;
        Graphics.BezierCurveTo = BezierCurveTo;
        Graphics.Rect = Rect;
        Graphics.ClosePath = ClosePath;
        Graphics.BeginPath = BeginPath;
        Graphics.Fill = Fill;
        Graphics.Stroke = Stroke;
        Graphics.StrokeStyle = StrokeStyle;
        Graphics.Oval = Oval;
        Graphics.Circle = Circle;
        Graphics.Ellipse = Ellipse;
        Graphics.PolyStar = PolyStar;
        Graphics.beginCmd = new BeginPath();
        Graphics.BASE_64 = {
            "A": 0,
            "B": 1,
            "C": 2,
            "D": 3,
            "E": 4,
            "F": 5,
            "G": 6,
            "H": 7,
            "I": 8,
            "J": 9,
            "K": 10,
            "L": 11,
            "M": 12,
            "N": 13,
            "O": 14,
            "P": 15,
            "Q": 16,
            "R": 17,
            "S": 18,
            "T": 19,
            "U": 20,
            "V": 21,
            "W": 22,
            "X": 23,
            "Y": 24,
            "Z": 25,
            "a": 26,
            "b": 27,
            "c": 28,
            "d": 29,
            "e": 30,
            "f": 31,
            "g": 32,
            "h": 33,
            "i": 34,
            "j": 35,
            "k": 36,
            "l": 37,
            "m": 38,
            "n": 39,
            "o": 40,
            "p": 41,
            "q": 42,
            "r": 43,
            "s": 44,
            "t": 45,
            "u": 46,
            "v": 47,
            "w": 48,
            "x": 49,
            "y": 50,
            "z": 51,
            "0": 52,
            "1": 53,
            "2": 54,
            "3": 55,
            "4": 56,
            "5": 57,
            "6": 58,
            "7": 59,
            "8": 60,
            "9": 61,
            "+": 62,
            "/": 63
        };
        Graphics.STROKE_CAPS_MAP = ["butt", "round", "square"];
        Graphics.STROKE_JOINTS_MAP = ["miter", "round", "bevel"];
        Graphics._canvas = Methods.createCanvas();
        Graphics._ctx = Graphics._canvas.getContext('2d');
        return Graphics;
    }());
    Graphics._canvas.width = Graphics._canvas.height = 1;
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.default = Graphics;
});


text:
<?php
namespace Seedling\KeyGenerators;

/**
 * CRC32 Key Generator
 */
class Crc32 implements KeyGeneratorInterface
{
    /**
     * @var int $max The maximum supported CRC32 value
     */
    private $max;

    /**
     * Initialize max key size
     *
     * @param int $max
     */
    public function __construct($max = PHP_INT_MAX)
    {
        $this->max = $max;
    }

    /**
     * {@inheritdoc}
     */
    public function generateKey($value, $tableName = null)
    {
        $crc = (float)sprintf('%u', crc32($tableName . $value));
        // 32-bit system can't handle unsigned mod using %
        if ($crc > PHP_INT_MAX) {
            $cycles = floor($crc / $this->max);
            return (int)($crc - ($cycles * $this->max));
        }
        return (int)$crc % $this->max;
    }
}


text:
/**
 * This setup is based on Julie Ralph's `ng2-test-seed` project.
 * See https://github.com/juliemr/ng2-test-seed
 * Hopefully Angular2 and Karma integration will be more seamless in the future.
 * Unit tests are currently only implemented to run against the development target.
 */

/** Tun on full stack traces in errors to help debugging */
Error.stackTraceLimit = Infinity;

jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;

/**
 * Cancel Karma's synchronous start,
 * we will call `__karma__.start()` later, once all the specs are loaded.
 */
__karma__.loaded = function() {};

System.config({
	packages: {
		'base/.karma': {
			defaultExtension: false,
			format: 'register',
			map: Object.keys(window.__karma__.files).
				filter(onlyAppFiles).
				reduce(function createPathRecords(pathsMapping, appPath) {
					/**
					 * Creates local module name mapping to global path with karma's fingerprint in path, e.g.:
					 * './hero.service': '/base/build/js/hero.service.js?f4523daf879cfb7310ef6242682ccf10b2041b3e'
					 */
					var moduleName = appPath
						.replace(/^\/base\/.karma\//, './')
						.replace(/\.js$/, '');

					pathsMapping[moduleName] = appPath + '?' + window.__karma__.files[appPath]

					return pathsMapping;
				}, {})
		}
	}
});

System.import('angular2/platform/browser').then(function(browser_adapter) {
	browser_adapter.BrowserDomAdapter.makeCurrent();
})
.then(function() {
	return Promise.all(
		Object.keys(window.__karma__.files) // All files served by Karma.
		.filter(onlySpecFiles)
		.map(function(moduleName) {
			/** Loads all spec files via their global module names (e.g. 'base/src/app/hero.service.spec') */
			return System.import(moduleName);
		}));
})
.then(function() {
	__karma__.start();
}, function(error) {
	__karma__.error(error.stack || String(error));
});

function filePath2moduleName(filePath) {
	return filePath
		.replace(/^\//, '') // remove / prefix
		.replace(/\.\w+$/, ''); // remove suffix
}

function onlyAppFiles(filePath) {
	return /^\/base\/.karma\/.*\.js$/.test(filePath);
}

function onlySpecFiles(path) {
	return /.spec\.js$/.test(path);
}


text:
package org.tp23.antinstaller.renderer.swing;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.io.File;
import java.util.ArrayList;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

import org.tp23.antinstaller.InstallerContext;
import org.tp23.antinstaller.ValidationException;
import org.tp23.antinstaller.input.OutputField;
import org.tp23.antinstaller.page.SimpleInputPage;
import org.tp23.antinstaller.renderer.RendererFactory;
import org.tp23.gui.GBCF;

import gov.nih.nci.cagrid.antinstaller.utils.ClassPathModifier;
import gov.nih.nci.cagrid.installer.certificate.CertificateValidator;

public class CaExistPageRenderer  extends SwingPageRenderer{

	private JPanel contentPanel = new JPanel(){
		/**
		 * added by kumarvi
		 */
		public void paintComponent(Graphics g)
		 {  super.paintComponent(g);
		   this.setForeground(Color.BLUE);
		    super.paintComponent(g);
		    ImageScaler is = new ImageScaler();
				ImageIcon icon = new ImageIcon(is.getScaledInstance("resources/mainbackground.jpg",600,400));
				Image image = icon.getImage();
		    if(image != null) g.drawImage(image, 0,0,600,400,this);

		 }
		/**
		 * end of addition
		 */

	};

	private GridBagLayout gridLayout = new GridBagLayout();
	private GBCF cf = new GBCF(); // GridBagConstraintsFactory
	private boolean overflow = false;
	// used in overflow
	JScrollPane scroller = null;

	private ArrayList renderers = new ArrayList();;

	public CaExistPageRenderer(){
		try{
		File installRoot = InstallerContext.getLatestInstallDir();
		File resources = new File(installRoot,"resources");

		File lib = new File(resources,"lib");
		File cert_task_jar = new File(lib,"certificate_tasks.jar");
		File ext = new File(lib,"ext");
		File core_jar = new File(ext,"caGrid-1.0-core.jar");
		File grid_ca_jar = new File(ext,"caGrid-1.0-gridca-1.0.jar");
		File jglobus_jar = new File(ext,"cog-jglobus.jar");
		File jce_jar = new File(ext,"jce-jdk13-125.jar");

		ClassPathModifier.addFile(cert_task_jar);
		ClassPathModifier.addFile(core_jar);
		ClassPathModifier.addFile(grid_ca_jar);
		ClassPathModifier.addFile(jglobus_jar);
		ClassPathModifier.addFile(jce_jar);
		}catch(Exception ex){
			ex.printStackTrace();
		}
	}

	public boolean validateFields() throws ValidationException {
		StringBuffer stbr= new StringBuffer();
		OutputField[] fields = page.getOutputField();
		for (int i = 0; i < fields.length; i++) {

			if(!fields[i].validate(ctx)){
				SwingOutputFieldRenderer renderer = (SwingOutputFieldRenderer)renderers.get(i);
				renderer.renderError();
				return false;
			}
		}
		String result = validatePage();
		if(result.length()>1){
		ctx.getMessageRenderer().printMessage(result);
		return false;
		}
		return true;
	}

	public String validatePage(){
		CertificateValidator cv = new CertificateValidator();
		StringBuffer stbr = new StringBuffer();
		String caCertFile = ctx.getInstaller().getResultContainer().getDefaultValue("${ca.cert.file}");
		String cakeyFile =  ctx.getInstaller().getResultContainer().getDefaultValue("${ca.key.file}");
		String cakeyPwd =  ctx.getInstaller().getResultContainer().getDefaultValue("${ca.keypwd}");

		stbr.append(cv.validateCert(caCertFile));
		if(stbr.toString().length()>1){
			return stbr.toString();
		}

		stbr.append(cv.validateKey(cakeyFile,cakeyPwd));
		if(stbr.toString().length()>1){
			return stbr.toString();
		}
		String host_dv = ctx.getInstaller().getResultContainer().getDefaultValue("${host.dv}");
		Integer host_days= null;
		try{
			host_days = new Integer(host_dv);
		}catch(NumberFormatException nfe){
			stbr.append("The days valid for host can only be a number !");

		}
		if(stbr.toString().length()>1){
			return stbr.toString();
		}

		stbr.append(cv.validateHostCertificateExpiry(caCertFile, host_days.intValue()));

		return stbr.toString();
	}
	public void updateInputFields(){
		for (int i = 0; i < renderers.size(); i++) {
			((SwingOutputFieldRenderer)renderers.get(i)).updateInputField();
		}
	}

	public void updateDefaultValues(){
		for (int i = 0; i < renderers.size(); i++) {
			((SwingOutputFieldRenderer)renderers.get(i)).updateDefaultValue();
		}
	}

	public void instanceInit() throws Exception {
		overflow = ((SimpleInputPage)page).isOverflow();
		if(overflow){
			//WARNING this causes flickering in the UI
			contentPanel.setMaximumSize(new Dimension(SwingPageRenderer.PAGE_WIDTH - 50,SwingPageRenderer.PAGE_HEIGHT));
			scroller = new JScrollPane();
			scroller.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
			scroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
			scroller.setBorder(BorderFactory.createCompoundBorder(
							BorderFactory.createEmptyBorder(4,4,4,4),
							BorderFactory.createEtchedBorder()
							));
			add(scroller,BorderLayout.CENTER);
			scroller.getViewport().add(contentPanel);
			//contentPanel.setBackground(Color.red);
		}
		else {
			this.add(contentPanel,BorderLayout.CENTER);
			contentPanel.setBorder(BorderFactory.createEmptyBorder(SwingOutputFieldRenderer.TOP_INDENT,4,4,4));
		}

		OutputField[] fields = page.getOutputField();
		contentPanel.setDoubleBuffered(true);
		contentPanel.setLayout(gridLayout);
		int row = 0;
		for (int i = 0; i < fields.length; i++) {
			SwingOutputFieldRenderer renderer = RendererFactory.getSwingRenderer(fields[i]);
			/**
			 * Commented out following section by Kumarvi
			 */
			//String text = fields[i].getExplanatoryText();
			//if(fields[i].getExplanatoryText()!=null){
				//JTextArea area = new DisplayTextArea(contentPanel.getBackground(),contentPanel.getForeground());
				//area.setIgnoreRepaint(true);
				//area.setText(text);
				//contentPanel.add(area,cf.getSpan(row++));
			//}

			/**
			 * End of comments
			 */
			renderer.setOutputField(fields[i]);
			renderer.setInstallerContext(ctx);
			renderer.initComponent(contentPanel);
			row = renderer.addSelf(contentPanel,cf,row,overflow);
			renderers.add(renderer);
		}
		JPanel filler = new JPanel();
		filler.setOpaque(false);
		//contentPanel.add(new JPanel(),cf.getVertGlue(row++));
		contentPanel.add(filler,cf.getVertGlue(row++));
	}

}