[Bps-public-commit] RT-Extension-PreviewInSearch branch, master, updated. 287015ae8b307f3cafb219d89c964f6c0d997b9d

Wallace Reis wreis at bestpractical.com
Thu Feb 26 15:22:38 EST 2015


The branch, master has been updated
       via  287015ae8b307f3cafb219d89c964f6c0d997b9d (commit)
       via  b39736bb224f0e2cbeb9dd66f9cae60ccc9de538 (commit)
       via  88c19cff53e36eec539f8ba74de301b914cb31a5 (commit)
       via  e29d54d4bdced63d3544eb00b55a04d217ddf62a (commit)
       via  00e7171b04cbe1b71af8446ce107ab0a129cc4f6 (commit)
       via  19fcf34da99322cd67f109e8f55e221af92326d1 (commit)
       via  40a418ba34d32556bfb04e69053df1df883c66ca (commit)
       via  00cdd5ad9017354cfe3b3aea4424e1029e736eb1 (commit)
       via  897ae7f32241cb353d5963e653bc6c7dc76efa4c (commit)
       via  3c5b20f917062c30883274c8150f68e5144c4ce3 (commit)
       via  1679e99e67d0e8729d169040583d6ac7cf314320 (commit)
      from  1d4b5123be451bebd6f608c4e350de7d7f4e6991 (commit)

Summary of changes:
 Changes                             |   4 +
 MANIFEST                            |   6 +
 META.yml                            |  12 +-
 Makefile.PL                         |  12 +-
 README                              |  14 +-
 inc/Module/Install.pm               |  22 +-
 inc/Module/Install/Base.pm          |   2 +-
 inc/Module/Install/Can.pm           |   2 +-
 inc/Module/Install/Fetch.pm         |   2 +-
 inc/Module/Install/GithubMeta.pm    |  53 +++
 inc/Module/Install/Include.pm       |  34 ++
 inc/Module/Install/Makefile.pm      |   4 +-
 inc/Module/Install/Metadata.pm      |   6 +-
 inc/Module/Install/RTx.pm           | 252 ++++++-----
 inc/Module/Install/RTx/Runtime.pm   |  79 ++++
 inc/Module/Install/Win32.pm         |   2 +-
 inc/Module/Install/WriteAll.pm      |   2 +-
 inc/YAML/Tiny.pm                    | 876 ++++++++++++++++++++++++++++++++++++
 inc/unicore/Name.pm                 | 416 +++++++++++++++++
 lib/RT/Extension/PreviewInSearch.pm |   2 +-
 20 files changed, 1666 insertions(+), 136 deletions(-)
 create mode 100644 Changes
 create mode 100644 inc/Module/Install/GithubMeta.pm
 create mode 100644 inc/Module/Install/Include.pm
 create mode 100644 inc/Module/Install/RTx/Runtime.pm
 create mode 100644 inc/YAML/Tiny.pm
 create mode 100644 inc/unicore/Name.pm

- Log -----------------------------------------------------------------
commit 1679e99e67d0e8729d169040583d6ac7cf314320
Author: Wallace Reis <wreis at bestpractical.com>
Date:   Thu Feb 26 17:03:10 2015 -0300

    RTx() implies both all_from and readme_from

diff --git a/Makefile.PL b/Makefile.PL
index 9261973..86b2051 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -1,5 +1,4 @@
 use inc::Module::Install;
+
 RTx('RT-Extension-PreviewInSearch');
-all_from('lib/RT/Extension/PreviewInSearch.pm');
-readme_from('lib/RT/Extension/PreviewInSearch.pm');
-WriteAll();
\ No newline at end of file
+WriteAll();

commit 3c5b20f917062c30883274c8150f68e5144c4ce3
Author: Wallace Reis <wreis at bestpractical.com>
Date:   Thu Feb 26 17:03:43 2015 -0300

    Add license info

diff --git a/Makefile.PL b/Makefile.PL
index 86b2051..ff0c5b8 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -1,4 +1,6 @@
 use inc::Module::Install;
 
 RTx('RT-Extension-PreviewInSearch');
+license 'gplv2';
+
 WriteAll();

commit 897ae7f32241cb353d5963e653bc6c7dc76efa4c
Author: Wallace Reis <wreis at bestpractical.com>
Date:   Thu Feb 26 17:04:09 2015 -0300

    Add RT min version

diff --git a/Makefile.PL b/Makefile.PL
index ff0c5b8..83bba88 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -3,4 +3,6 @@ use inc::Module::Install;
 RTx('RT-Extension-PreviewInSearch');
 license 'gplv2';
 
+requires_rt '4.0.0';
+
 WriteAll();

commit 00cdd5ad9017354cfe3b3aea4424e1029e736eb1
Author: Wallace Reis <wreis at bestpractical.com>
Date:   Thu Feb 26 17:04:28 2015 -0300

    Add repo meta-info

diff --git a/Makefile.PL b/Makefile.PL
index 83bba88..fdc2648 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -5,4 +5,6 @@ license 'gplv2';
 
 requires_rt '4.0.0';
 
+githubmeta('github');
+
 WriteAll();

commit 40a418ba34d32556bfb04e69053df1df883c66ca
Author: Wallace Reis <wreis at bestpractical.com>
Date:   Thu Feb 26 17:04:46 2015 -0300

    Do sign

diff --git a/Makefile.PL b/Makefile.PL
index fdc2648..37b4fa9 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -7,4 +7,5 @@ requires_rt '4.0.0';
 
 githubmeta('github');
 
+sign;
 WriteAll();

commit 19fcf34da99322cd67f109e8f55e221af92326d1
Author: Wallace Reis <wreis at bestpractical.com>
Date:   Thu Feb 26 17:16:04 2015 -0300

    Update perl version

diff --git a/lib/RT/Extension/PreviewInSearch.pm b/lib/RT/Extension/PreviewInSearch.pm
index 6b91116..1abb4a9 100644
--- a/lib/RT/Extension/PreviewInSearch.pm
+++ b/lib/RT/Extension/PreviewInSearch.pm
@@ -1,4 +1,4 @@
-use v5.10;
+use v5.10.1;
 use strict;
 use warnings;
 

commit 00e7171b04cbe1b71af8446ce107ab0a129cc4f6
Author: Wallace Reis <wreis at bestpractical.com>
Date:   Thu Feb 26 17:17:18 2015 -0300

    Update inc

diff --git a/inc/Module/Install.pm b/inc/Module/Install.pm
index 4ecf46b..ff767fa 100644
--- a/inc/Module/Install.pm
+++ b/inc/Module/Install.pm
@@ -17,7 +17,7 @@ package Module::Install;
 #     3. The ./inc/ version of Module::Install loads
 # }
 
-use 5.005;
+use 5.006;
 use strict 'vars';
 use Cwd        ();
 use File::Find ();
@@ -31,7 +31,7 @@ BEGIN {
 	# This is not enforced yet, but will be some time in the next few
 	# releases once we can make sure it won't clash with custom
 	# Module::Install extensions.
-	$VERSION = '1.06';
+	$VERSION = '1.14';
 
 	# Storage for the pseudo-singleton
 	$MAIN    = undef;
@@ -156,10 +156,10 @@ END_DIE
 sub autoload {
 	my $self = shift;
 	my $who  = $self->_caller;
-	my $cwd  = Cwd::cwd();
+	my $cwd  = Cwd::getcwd();
 	my $sym  = "${who}::AUTOLOAD";
 	$sym->{$cwd} = sub {
-		my $pwd = Cwd::cwd();
+		my $pwd = Cwd::getcwd();
 		if ( my $code = $sym->{$pwd} ) {
 			# Delegate back to parent dirs
 			goto &$code unless $cwd eq $pwd;
@@ -239,7 +239,7 @@ sub new {
 
 	# ignore the prefix on extension modules built from top level.
 	my $base_path = Cwd::abs_path($FindBin::Bin);
-	unless ( Cwd::abs_path(Cwd::cwd()) eq $base_path ) {
+	unless ( Cwd::abs_path(Cwd::getcwd()) eq $base_path ) {
 		delete $args{prefix};
 	}
 	return $args{_self} if $args{_self};
@@ -338,7 +338,7 @@ sub find_extensions {
 		if ( $subpath eq lc($subpath) || $subpath eq uc($subpath) ) {
 			my $content = Module::Install::_read($subpath . '.pm');
 			my $in_pod  = 0;
-			foreach ( split //, $content ) {
+			foreach ( split /\n/, $content ) {
 				$in_pod = 1 if /^=\w/;
 				$in_pod = 0 if /^=cut/;
 				next if ($in_pod || /^=cut/);  # skip pod text
@@ -378,6 +378,7 @@ eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@;
 sub _read {
 	local *FH;
 	open( FH, '<', $_[0] ) or die "open($_[0]): $!";
+	binmode FH;
 	my $string = do { local $/; <FH> };
 	close FH or die "close($_[0]): $!";
 	return $string;
@@ -386,6 +387,7 @@ END_NEW
 sub _read {
 	local *FH;
 	open( FH, "< $_[0]"  ) or die "open($_[0]): $!";
+	binmode FH;
 	my $string = do { local $/; <FH> };
 	close FH or die "close($_[0]): $!";
 	return $string;
@@ -416,6 +418,7 @@ eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@;
 sub _write {
 	local *FH;
 	open( FH, '>', $_[0] ) or die "open($_[0]): $!";
+	binmode FH;
 	foreach ( 1 .. $#_ ) {
 		print FH $_[$_] or die "print($_[0]): $!";
 	}
@@ -425,6 +428,7 @@ END_NEW
 sub _write {
 	local *FH;
 	open( FH, "> $_[0]"  ) or die "open($_[0]): $!";
+	binmode FH;
 	foreach ( 1 .. $#_ ) {
 		print FH $_[$_] or die "print($_[0]): $!";
 	}
@@ -434,7 +438,7 @@ END_OLD
 
 # _version is for processing module versions (eg, 1.03_05) not
 # Perl versions (eg, 5.8.1).
-sub _version ($) {
+sub _version {
 	my $s = shift || 0;
 	my $d =()= $s =~ /(\.)/g;
 	if ( $d >= 2 ) {
@@ -450,12 +454,12 @@ sub _version ($) {
 	return $l + 0;
 }
 
-sub _cmp ($$) {
+sub _cmp {
 	_version($_[1]) <=> _version($_[2]);
 }
 
 # Cloned from Params::Util::_CLASS
-sub _CLASS ($) {
+sub _CLASS {
 	(
 		defined $_[0]
 		and
diff --git a/inc/Module/Install/Base.pm b/inc/Module/Install/Base.pm
index 802844a..4206347 100644
--- a/inc/Module/Install/Base.pm
+++ b/inc/Module/Install/Base.pm
@@ -4,7 +4,7 @@ package Module::Install::Base;
 use strict 'vars';
 use vars qw{$VERSION};
 BEGIN {
-	$VERSION = '1.06';
+	$VERSION = '1.14';
 }
 
 # Suspend handler for "redefined" warnings
diff --git a/inc/Module/Install/Can.pm b/inc/Module/Install/Can.pm
index 22167b8..9929b1b 100644
--- a/inc/Module/Install/Can.pm
+++ b/inc/Module/Install/Can.pm
@@ -8,7 +8,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '1.06';
+	$VERSION = '1.14';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
diff --git a/inc/Module/Install/Fetch.pm b/inc/Module/Install/Fetch.pm
index bee0c4f..3d8de76 100644
--- a/inc/Module/Install/Fetch.pm
+++ b/inc/Module/Install/Fetch.pm
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '1.06';
+	$VERSION = '1.14';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
diff --git a/inc/Module/Install/GithubMeta.pm b/inc/Module/Install/GithubMeta.pm
new file mode 100644
index 0000000..eabab2c
--- /dev/null
+++ b/inc/Module/Install/GithubMeta.pm
@@ -0,0 +1,53 @@
+#line 1
+package Module::Install::GithubMeta;
+
+use strict;
+use warnings;
+use Cwd;
+use base qw(Module::Install::Base);
+use vars qw($VERSION);
+
+$VERSION = '0.28';
+
+sub githubmeta {
+  my $self = shift;
+  return unless $Module::Install::AUTHOR;
+  return unless _under_git();
+  return unless $self->can_run('git');
+  my $remote = shift || 'origin';
+  local $ENV{LC_ALL}='C';
+  local $ENV{LANG}='C';
+  return unless my ($git_url) = `git remote show -n $remote` =~ /URL: (.*)$/m;
+  return unless $git_url =~ /github\.com/; # Not a Github repository
+  my $http_url = $git_url;
+  $git_url =~ s![\w\-]+\@([^:]+):!git://$1/!;
+  $http_url =~ s![\w\-]+\@([^:]+):!https://$1/!;
+  $http_url =~ s!\.git$!/tree!;
+  $self->repository( $git_url );
+  $self->homepage( $http_url ) unless $self->homepage();
+  return 1;
+}
+
+sub _under_git {
+  return 1 if -e '.git';
+  my $cwd = getcwd;
+  my $last = $cwd;
+  my $found = 0;
+  while (1) {
+    chdir '..' or last;
+    my $current = getcwd;
+    last if $last eq $current;
+    $last = $current;
+    if ( -e '.git' ) {
+       $found = 1;
+       last;
+    }
+  }
+  chdir $cwd;
+  return $found;
+}
+
+'Github';
+__END__
+
+#line 113
diff --git a/inc/Module/Install/Include.pm b/inc/Module/Install/Include.pm
new file mode 100644
index 0000000..f274f87
--- /dev/null
+++ b/inc/Module/Install/Include.pm
@@ -0,0 +1,34 @@
+#line 1
+package Module::Install::Include;
+
+use strict;
+use Module::Install::Base ();
+
+use vars qw{$VERSION @ISA $ISCORE};
+BEGIN {
+	$VERSION = '1.14';
+	@ISA     = 'Module::Install::Base';
+	$ISCORE  = 1;
+}
+
+sub include {
+	shift()->admin->include(@_);
+}
+
+sub include_deps {
+	shift()->admin->include_deps(@_);
+}
+
+sub auto_include {
+	shift()->admin->auto_include(@_);
+}
+
+sub auto_include_deps {
+	shift()->admin->auto_include_deps(@_);
+}
+
+sub auto_include_dependent_dists {
+	shift()->admin->auto_include_dependent_dists(@_);
+}
+
+1;
diff --git a/inc/Module/Install/Makefile.pm b/inc/Module/Install/Makefile.pm
index 7052f36..66993af 100644
--- a/inc/Module/Install/Makefile.pm
+++ b/inc/Module/Install/Makefile.pm
@@ -8,7 +8,7 @@ use Fcntl qw/:flock :seek/;
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '1.06';
+	$VERSION = '1.14';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
@@ -133,7 +133,7 @@ sub makemaker_args {
 	return $args;
 }
 
-# For mm args that take multiple space-seperated args,
+# For mm args that take multiple space-separated args,
 # append an argument to the current list.
 sub makemaker_append {
 	my $self = shift;
diff --git a/inc/Module/Install/Metadata.pm b/inc/Module/Install/Metadata.pm
index 58430f3..e547fa0 100644
--- a/inc/Module/Install/Metadata.pm
+++ b/inc/Module/Install/Metadata.pm
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '1.06';
+	$VERSION = '1.14';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
@@ -347,7 +347,7 @@ sub name_from {
 		^ \s*
 		package \s*
 		([\w:]+)
-		\s* ;
+		[\s|;]*
 		/ixms
 	) {
 		my ($name, $module_name) = ($1, $1);
@@ -705,7 +705,7 @@ sub _write_mymeta_data {
 	my @yaml = Parse::CPAN::Meta::LoadFile('META.yml');
 	my $meta = $yaml[0];
 
-	# Overwrite the non-configure dependency hashs
+	# Overwrite the non-configure dependency hashes
 	delete $meta->{requires};
 	delete $meta->{build_requires};
 	delete $meta->{recommends};
diff --git a/inc/Module/Install/RTx.pm b/inc/Module/Install/RTx.pm
index ac04c79..97acf77 100644
--- a/inc/Module/Install/RTx.pm
+++ b/inc/Module/Install/RTx.pm
@@ -8,7 +8,7 @@ no warnings 'once';
 
 use Module::Install::Base;
 use base 'Module::Install::Base';
-our $VERSION = '0.32';
+our $VERSION = '0.37';
 
 use FindBin;
 use File::Glob     ();
@@ -18,95 +18,79 @@ my @DIRS = qw(etc lib html static bin sbin po var);
 my @INDEX_DIRS = qw(lib bin sbin);
 
 sub RTx {
-    my ( $self, $name ) = @_;
+    my ( $self, $name, $extra_args ) = @_;
+    $extra_args ||= {};
 
-    my $original_name = $name;
-    my $RTx = 'RTx';
-    $RTx = $1 if $name =~ s/^(\w+)-//;
+    # Set up names
     my $fname = $name;
     $fname =~ s!-!/!g;
 
-    $self->name("$RTx-$name")
+    $self->name( $name )
         unless $self->name;
-    $self->all_from( -e "$name.pm" ? "$name.pm" : "lib/$RTx/$fname.pm" )
+    $self->all_from( "lib/$fname.pm" )
         unless $self->version;
-    $self->abstract("RT $name Extension")
+    $self->abstract("$name Extension")
         unless $self->abstract;
-
-    my @prefixes = (qw(/opt /usr/local /home /usr /sw ));
-    my $prefix   = $ENV{PREFIX};
-    @ARGV = grep { /PREFIX=(.*)/ ? ( ( $prefix = $1 ), 0 ) : 1 } @ARGV;
-
-    if ($prefix) {
-        $RT::LocalPath = $prefix;
-        $INC{'RT.pm'} = "$RT::LocalPath/lib/RT.pm";
-    } else {
-        local @INC = (
-            $ENV{RTHOME} ? ( $ENV{RTHOME}, "$ENV{RTHOME}/lib" ) : (),
-            @INC,
-            map { ( "$_/rt4/lib", "$_/lib/rt4", "$_/rt3/lib", "$_/lib/rt3", "$_/lib" )
-                } grep $_, @prefixes
-        );
-        until ( eval { require RT; $RT::LocalPath } ) {
-            warn
-                "Cannot find the location of RT.pm that defines \$RT::LocalPath in: @INC\n";
-            $_ = $self->prompt("Path to directory containing your RT.pm:") or exit;
-            $_ =~ s/\/RT\.pm$//;
-            push @INC, $_, "$_/rt3/lib", "$_/lib/rt3", "$_/lib";
-        }
+    unless ( $extra_args->{no_readme_generation} ) {
+        $self->readme_from( "lib/$fname.pm",
+                            { options => [ quotes => "none" ] } );
+    }
+    $self->add_metadata("x_module_install_rtx_version", $VERSION );
+
+    # Try to find RT.pm
+    my @prefixes = qw( /opt /usr/local /home /usr /sw /usr/share/request-tracker4);
+    $ENV{RTHOME} =~ s{/RT\.pm$}{} if defined $ENV{RTHOME};
+    $ENV{RTHOME} =~ s{/lib/?$}{}  if defined $ENV{RTHOME};
+    my @try = $ENV{RTHOME} ? ($ENV{RTHOME}, "$ENV{RTHOME}/lib") : ();
+    while (1) {
+        my @look = @INC;
+        unshift @look, grep {defined and -d $_} @try;
+        push @look, grep {defined and -d $_}
+            map { ( "$_/rt4/lib", "$_/lib/rt4", "$_/lib" ) } @prefixes;
+        last if eval {local @INC = @look; require RT; $RT::LocalLibPath};
+
+        warn
+            "Cannot find the location of RT.pm that defines \$RT::LocalPath in: @look\n";
+        my $given = $self->prompt("Path to directory containing your RT.pm:") or exit;
+        $given =~ s{/RT\.pm$}{};
+        $given =~ s{/lib/?$}{};
+        @try = ($given, "$given/lib");
     }
 
-    my $lib_path = File::Basename::dirname( $INC{'RT.pm'} );
-    my $local_lib_path = "$RT::LocalPath/lib";
     print "Using RT configuration from $INC{'RT.pm'}:\n";
-    unshift @INC, "$RT::LocalPath/lib" if $RT::LocalPath;
-    unshift @INC, $lib_path;
-
-    $RT::LocalVarPath    ||= $RT::VarPath;
-    $RT::LocalPoPath     ||= $RT::LocalLexiconPath;
-    $RT::LocalHtmlPath   ||= $RT::MasonComponentRoot;
-    $RT::LocalStaticPath ||= $RT::StaticPath;
-    $RT::LocalLibPath    ||= "$RT::LocalPath/lib";
 
-    my $with_subdirs = $ENV{WITH_SUBDIRS};
-    @ARGV = grep { /WITH_SUBDIRS=(.*)/ ? ( ( $with_subdirs = $1 ), 0 ) : 1 }
-        @ARGV;
+    my $local_lib_path = $RT::LocalLibPath;
+    unshift @INC, $local_lib_path;
+    my $lib_path = File::Basename::dirname( $INC{'RT.pm'} );
+    unshift @INC, $lib_path;
 
-    my %subdirs;
-    %subdirs = map { $_ => 1 } split( /\s*,\s*/, $with_subdirs )
-        if defined $with_subdirs;
-    unless ( keys %subdirs ) {
-        $subdirs{$_} = 1 foreach grep -d "$FindBin::Bin/$_", @DIRS;
+    # Set a baseline minimum version
+    unless ( $extra_args->{deprecated_rt} ) {
+        $self->requires_rt('4.0.0');
     }
 
-    # If we're running on RT 3.8 with plugin support, we really wany
-    # to install libs, mason templates and po files into plugin specific
-    # directories
+    # Installation locations
     my %path;
-    if ( $RT::LocalPluginPath ) {
-        die "Because of bugs in RT 3.8.0 this extension can not be installed.\n"
-            ."Upgrade to RT 3.8.1 or newer.\n" if $RT::VERSION =~ /^3\.8\.0/;
-        $path{$_} = $RT::LocalPluginPath . "/$original_name/$_"
-            foreach @DIRS;
-    } else {
-        foreach ( @DIRS ) {
-            no strict 'refs';
-            my $varname = "RT::Local" . ucfirst($_) . "Path";
-            $path{$_} = ${$varname} || "$RT::LocalPath/$_";
-        }
+    $path{$_} = $RT::LocalPluginPath . "/$name/$_"
+        foreach @DIRS;
 
-        $path{$_} .= "/$name" for grep $path{$_}, qw(etc po var);
-    }
+    # Copy RT 4.2.0 static files into NoAuth; insufficient for
+    # images, but good enough for css and js.
+    $path{static} = "$path{html}/NoAuth/"
+        unless $RT::StaticPath;
+
+    # Delete the ones we don't need
+    delete $path{$_} for grep {not -d "$FindBin::Bin/$_"} keys %path;
 
     my %index = map { $_ => 1 } @INDEX_DIRS;
     $self->no_index( directory => $_ ) foreach grep !$index{$_}, @DIRS;
 
     my $args = join ', ', map "q($_)", map { ($_, $path{$_}) }
-        grep $subdirs{$_}, keys %path;
+        sort keys %path;
 
-    print "./$_\t=> $path{$_}\n" for sort keys %subdirs;
+    printf "%-10s => %s\n", $_, $path{$_} for sort keys %path;
 
-    if ( my @dirs = map { ( -D => $_ ) } grep $subdirs{$_}, qw(bin html sbin) ) {
+    if ( my @dirs = map { ( -D => $_ ) } grep $path{$_}, qw(bin html sbin etc) ) {
         my @po = map { ( -o => $_ ) }
             grep -f,
             File::Glob::bsd_glob("po/*.po");
@@ -116,12 +100,15 @@ lexicons ::
 .
     }
 
+    $self->include('Module::Install::RTx::Runtime') if $self->admin;
+    $self->include_deps( 'YAML::Tiny', 0 ) if $self->admin;
     my $postamble = << ".";
 install ::
+\t\$(NOECHO) \$(PERL) -Ilib -I"$local_lib_path" -I"$lib_path" -Iinc -MModule::Install::RTx::Runtime -e"RTxPlugin()"
 \t\$(NOECHO) \$(PERL) -MExtUtils::Install -e \"install({$args})\"
 .
 
-    if ( $subdirs{var} and -d $RT::MasonDataDir ) {
+    if ( $path{var} and -d $RT::MasonDataDir ) {
         my ( $uid, $gid ) = ( stat($RT::MasonDataDir) )[ 4, 5 ];
         $postamble .= << ".";
 \t\$(NOECHO) chown -R $uid:$gid $path{var}
@@ -136,14 +123,16 @@ install ::
         $has_etc{acl}++;
     }
     if ( -e 'etc/initialdata' ) { $has_etc{initialdata}++; }
-    if ( -d 'etc/upgrade/' )    { $has_etc{upgrade}++; }
+    if ( grep { /\d+\.\d+\.\d+.*$/ } glob('etc/upgrade/*.*.*') ) {
+        $has_etc{upgrade}++;
+    }
 
     $self->postamble("$postamble\n");
-    unless ( $subdirs{'lib'} ) {
-        $self->makemaker_args( PM => { "" => "" }, );
-    } else {
+    if ( $path{lib} ) {
         $self->makemaker_args( INSTALLSITELIB => $path{'lib'} );
         $self->makemaker_args( INSTALLARCHLIB => $path{'lib'} );
+    } else {
+        $self->makemaker_args( PM => { "" => "" }, );
     }
 
     $self->makemaker_args( INSTALLSITEMAN1DIR => "$RT::LocalPath/man/man1" );
@@ -151,69 +140,122 @@ install ::
     $self->makemaker_args( INSTALLSITEARCH => "$RT::LocalPath/man" );
 
     if (%has_etc) {
-        $self->load('RTxInitDB');
         print "For first-time installation, type 'make initdb'.\n";
         my $initdb = '';
         $initdb .= <<"." if $has_etc{schema};
-\t\$(NOECHO) \$(PERL) -Ilib -I"$local_lib_path" -I"$lib_path" -Minc::Module::Install -e"RTxInitDB(qw(schema \$(NAME) \$(VERSION)))"
+\t\$(NOECHO) \$(PERL) -Ilib -I"$local_lib_path" -I"$lib_path" -Iinc -MModule::Install::RTx::Runtime -e"RTxDatabase(qw(schema \$(NAME) \$(VERSION)))"
 .
         $initdb .= <<"." if $has_etc{acl};
-\t\$(NOECHO) \$(PERL) -Ilib -I"$local_lib_path" -I"$lib_path" -Minc::Module::Install -e"RTxInitDB(qw(acl \$(NAME) \$(VERSION)))"
+\t\$(NOECHO) \$(PERL) -Ilib -I"$local_lib_path" -I"$lib_path" -Iinc -MModule::Install::RTx::Runtime -e"RTxDatabase(qw(acl \$(NAME) \$(VERSION)))"
 .
         $initdb .= <<"." if $has_etc{initialdata};
-\t\$(NOECHO) \$(PERL) -Ilib -I"$local_lib_path" -I"$lib_path" -Minc::Module::Install -e"RTxInitDB(qw(insert \$(NAME) \$(VERSION)))"
+\t\$(NOECHO) \$(PERL) -Ilib -I"$local_lib_path" -I"$lib_path" -Iinc -MModule::Install::RTx::Runtime -e"RTxDatabase(qw(insert \$(NAME) \$(VERSION)))"
 .
         $self->postamble("initdb ::\n$initdb\n");
         $self->postamble("initialize-database ::\n$initdb\n");
         if ($has_etc{upgrade}) {
             print "To upgrade from a previous version of this extension, use 'make upgrade-database'\n";
-            my $upgradedb = qq|\t\$(NOECHO) \$(PERL) -Ilib -I"$local_lib_path" -I"$lib_path" -Minc::Module::Install -e"RTxInitDB(qw(upgrade \$(NAME) \$(VERSION)))"\n|;
+            my $upgradedb = qq|\t\$(NOECHO) \$(PERL) -Ilib -I"$local_lib_path" -I"$lib_path" -Iinc -MModule::Install::RTx::Runtime -e"RTxDatabase(qw(upgrade \$(NAME) \$(VERSION)))"\n|;
             $self->postamble("upgrade-database ::\n$upgradedb\n");
             $self->postamble("upgradedb ::\n$upgradedb\n");
         }
     }
+
 }
 
-# stolen from RT::Handle so we work on 3.6 (cmp_versions came in with 3.8)
-{ my %word = (
-    a     => -4,
-    alpha => -4,
-    b     => -3,
-    beta  => -3,
-    pre   => -2,
-    rc    => -1,
-    head  => 9999,
-);
-sub cmp_version($$) {
-    my ($a, $b) = (@_);
-    my @a = grep defined, map { /^[0-9]+$/? $_ : /^[a-zA-Z]+$/? $word{$_}|| -10 : undef }
-        split /([^0-9]+)/, $a;
-    my @b = grep defined, map { /^[0-9]+$/? $_ : /^[a-zA-Z]+$/? $word{$_}|| -10 : undef }
-        split /([^0-9]+)/, $b;
-    @a > @b
-        ? push @b, (0) x (@a- at b)
-        : push @a, (0) x (@b- at a);
-    for ( my $i = 0; $i < @a; $i++ ) {
-        return $a[$i] <=> $b[$i] if $a[$i] <=> $b[$i];
-    }
-    return 0;
-}}
 sub requires_rt {
     my ($self,$version) = @_;
 
+    _load_rt_handle();
+
+    if ($self->is_admin) {
+        $self->add_metadata("x_requires_rt", $version);
+        my @sorted = sort RT::Handle::cmp_version $version,'4.0.0';
+        $self->perl_version('5.008003') if $sorted[0] eq '4.0.0'
+            and (not $self->perl_version or '5.008003' > $self->perl_version);
+        @sorted = sort RT::Handle::cmp_version $version,'4.2.0';
+        $self->perl_version('5.010001') if $sorted[0] eq '4.2.0'
+            and (not $self->perl_version or '5.010001' > $self->perl_version);
+    }
+
     # if we're exactly the same version as what we want, silently return
     return if ($version eq $RT::VERSION);
 
-    my @sorted = sort cmp_version $version,$RT::VERSION;
+    my @sorted = sort RT::Handle::cmp_version $version,$RT::VERSION;
 
     if ($sorted[-1] eq $version) {
-        # should we die?
-        warn "\nWarning: prerequisite RT $version not found. Your installed version of RT ($RT::VERSION) is too old.\n\n";
+        die <<"EOT";
+
+**** Error: This extension requires RT $version. Your installed version
+            of RT ($RT::VERSION) is too old.
+
+EOT
+    }
+}
+
+sub requires_rt_plugin {
+    my $self = shift;
+    my ( $plugin ) = @_;
+
+    if ($self->is_admin) {
+        my $plugins = $self->Meta->{values}{"x_requires_rt_plugins"} || [];
+        push @{$plugins}, $plugin;
+        $self->add_metadata("x_requires_rt_plugins", $plugins);
+    }
+
+    my $path = $plugin;
+    $path =~ s{\:\:}{-}g;
+    $path = "$RT::LocalPluginPath/$path/lib";
+    if ( -e $path ) {
+        unshift @INC, $path;
+    } else {
+        my $name = $self->name;
+        warn <<"EOT";
+
+**** Warning: $name requires that the $plugin plugin be installed and
+              enabled; it does not appear to be installed.
+
+EOT
+    }
+    $self->requires(@_);
+}
+
+sub rt_too_new {
+    my ($self,$version,$msg) = @_;
+    my $name = $self->name;
+    $msg ||= <<EOT;
+
+**** Error: Your installed version of RT (%s) is too new; this extension
+            only works with versions older than %s.
+
+EOT
+    $self->add_metadata("x_rt_too_new", $version) if $self->is_admin;
+
+    _load_rt_handle();
+    my @sorted = sort RT::Handle::cmp_version $version,$RT::VERSION;
+
+    if ($sorted[0] eq $version) {
+        die sprintf($msg,$RT::VERSION,$version);
+    }
+}
+
+# RT::Handle runs FinalizeDatabaseType which calls RT->Config->Get
+# On 3.8, this dies.  On 4.0/4.2 ->Config transparently runs LoadConfig.
+# LoadConfig requires being able to read RT_SiteConfig.pm (root) so we'd
+# like to avoid pushing that on users.
+# Fake up just enough Config to let FinalizeDatabaseType finish, and
+# anyone later calling LoadConfig will overwrite our shenanigans.
+sub _load_rt_handle {
+    unless ($RT::Config) {
+        require RT::Config;
+        $RT::Config = RT::Config->new;
+        RT->Config->Set('DatabaseType','mysql');
     }
+    require RT::Handle;
 }
 
 1;
 
 __END__
 
-#line 336
+#line 390
diff --git a/inc/Module/Install/RTx/Runtime.pm b/inc/Module/Install/RTx/Runtime.pm
new file mode 100644
index 0000000..937949f
--- /dev/null
+++ b/inc/Module/Install/RTx/Runtime.pm
@@ -0,0 +1,79 @@
+#line 1
+package Module::Install::RTx::Runtime;
+
+use base 'Exporter';
+our @EXPORT = qw/RTxDatabase RTxPlugin/;
+
+use strict;
+use File::Basename ();
+
+sub _rt_runtime_load {
+    require RT;
+
+    eval { RT::LoadConfig(); };
+    if (my $err = $@) {
+        die $err unless $err =~ /^RT couldn't load RT config file/m;
+        my $warn = <<EOT;
+This usually means that your current user cannot read the file.  You
+will likely need to run this installation step as root, or some user
+with more permissions.
+EOT
+        $err =~ s/This usually means.*/$warn/s;
+        die $err;
+    }
+}
+
+sub RTxDatabase {
+    my ($action, $name, $version) = @_;
+
+    _rt_runtime_load();
+
+    require RT::System;
+    my $has_upgrade = RT::System->can('AddUpgradeHistory');
+
+    my $lib_path = File::Basename::dirname($INC{'RT.pm'});
+    my @args = (
+        "-Ilib",
+        "-I$RT::LocalLibPath",
+        "-I$lib_path",
+        "$RT::SbinPath/rt-setup-database",
+        "--action"      => $action,
+        ($action eq 'upgrade' ? () : ("--datadir"     => "etc")),
+        (($action eq 'insert') ? ("--datafile"    => "etc/initialdata") : ()),
+        "--dba"         => $RT::DatabaseAdmin || $RT::DatabaseUser,
+        "--prompt-for-dba-password" => '',
+        ($has_upgrade ? ("--package" => $name, "--ext-version" => $version) : ()),
+    );
+    # If we're upgrading against an RT which isn't at least 4.2 (has
+    # AddUpgradeHistory) then pass --package.  Upgrades against later RT
+    # releases will pick up --package from AddUpgradeHistory.
+    if ($action eq 'upgrade' and not $has_upgrade) {
+        push @args, "--package" => $name;
+    }
+
+    print "$^X @args\n";
+    (system($^X, @args) == 0) or die "...returned with error: $?\n";
+}
+
+sub RTxPlugin {
+    my ($name) = @_;
+
+    _rt_runtime_load();
+    require YAML::Tiny;
+    my $data = YAML::Tiny::LoadFile('META.yml');
+    my $name = $data->{name};
+
+    my @enabled = RT->Config->Get('Plugins');
+    for my $required (@{$data->{x_requires_rt_plugins} || []}) {
+        next if grep {$required eq $_} @enabled;
+
+        warn <<"EOT";
+
+**** Warning: $name requires that the $required plugin be installed and
+              enabled; it is not currently in \@Plugins.
+
+EOT
+    }
+}
+
+1;
diff --git a/inc/Module/Install/Win32.pm b/inc/Module/Install/Win32.pm
index eeaa3fe..9706e5f 100644
--- a/inc/Module/Install/Win32.pm
+++ b/inc/Module/Install/Win32.pm
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '1.06';
+	$VERSION = '1.14';
 	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
 }
diff --git a/inc/Module/Install/WriteAll.pm b/inc/Module/Install/WriteAll.pm
index 85d8018..dbedc00 100644
--- a/inc/Module/Install/WriteAll.pm
+++ b/inc/Module/Install/WriteAll.pm
@@ -6,7 +6,7 @@ use Module::Install::Base ();
 
 use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '1.06';
+	$VERSION = '1.14';
 	@ISA     = qw{Module::Install::Base};
 	$ISCORE  = 1;
 }
diff --git a/inc/YAML/Tiny.pm b/inc/YAML/Tiny.pm
new file mode 100644
index 0000000..0df28c4
--- /dev/null
+++ b/inc/YAML/Tiny.pm
@@ -0,0 +1,876 @@
+#line 1
+use 5.008001; # sane UTF-8 support
+use strict;
+use warnings;
+package YAML::Tiny;
+BEGIN {
+  $YAML::Tiny::AUTHORITY = 'cpan:ADAMK';
+}
+# git description: v1.59-TRIAL-1-g33d9cd2
+$YAML::Tiny::VERSION = '1.60';
+# XXX-INGY is 5.8.1 too old/broken for utf8?
+# XXX-XDG Lancaster consensus was that it was sufficient until
+# proven otherwise
+
+
+#####################################################################
+# The YAML::Tiny API.
+#
+# These are the currently documented API functions/methods and
+# exports:
+
+use Exporter;
+our @ISA       = qw{ Exporter  };
+our @EXPORT    = qw{ Load Dump };
+our @EXPORT_OK = qw{ LoadFile DumpFile freeze thaw };
+
+###
+# Functional/Export API:
+
+sub Dump {
+    return YAML::Tiny->new(@_)->_dump_string;
+}
+
+# XXX-INGY Returning last document seems a bad behavior.
+# XXX-XDG I think first would seem more natural, but I don't know
+# that it's worth changing now
+sub Load {
+    my $self = YAML::Tiny->_load_string(@_);
+    if ( wantarray ) {
+        return @$self;
+    } else {
+        # To match YAML.pm, return the last document
+        return $self->[-1];
+    }
+}
+
+# XXX-INGY Do we really need freeze and thaw?
+# XXX-XDG I don't think so.  I'd support deprecating them.
+BEGIN {
+    *freeze = \&Dump;
+    *thaw   = \&Load;
+}
+
+sub DumpFile {
+    my $file = shift;
+    return YAML::Tiny->new(@_)->_dump_file($file);
+}
+
+sub LoadFile {
+    my $file = shift;
+    my $self = YAML::Tiny->_load_file($file);
+    if ( wantarray ) {
+        return @$self;
+    } else {
+        # Return only the last document to match YAML.pm,
+        return $self->[-1];
+    }
+}
+
+
+###
+# Object Oriented API:
+
+# Create an empty YAML::Tiny object
+# XXX-INGY Why do we use ARRAY object?
+# NOTE: I get it now, but I think it's confusing and not needed.
+# Will change it on a branch later, for review.
+#
+# XXX-XDG I don't support changing it yet.  It's a very well-documented
+# "API" of YAML::Tiny.  I'd support deprecating it, but Adam suggested
+# we not change it until YAML.pm's own OO API is established so that
+# users only have one API change to digest, not two
+sub new {
+    my $class = shift;
+    bless [ @_ ], $class;
+}
+
+# XXX-INGY It probably doesn't matter, and it's probably too late to
+# change, but 'read/write' are the wrong names. Read and Write
+# are actions that take data from storage to memory
+# characters/strings. These take the data to/from storage to native
+# Perl objects, which the terms dump and load are meant. As long as
+# this is a legacy quirk to YAML::Tiny it's ok, but I'd prefer not
+# to add new {read,write}_* methods to this API.
+
+sub read_string {
+    my $self = shift;
+    $self->_load_string(@_);
+}
+
+sub write_string {
+    my $self = shift;
+    $self->_dump_string(@_);
+}
+
+sub read {
+    my $self = shift;
+    $self->_load_file(@_);
+}
+
+sub write {
+    my $self = shift;
+    $self->_dump_file(@_);
+}
+
+
+
+
+#####################################################################
+# Constants
+
+# Printed form of the unprintable characters in the lowest range
+# of ASCII characters, listed by ASCII ordinal position.
+my @UNPRINTABLE = qw(
+    0    x01  x02  x03  x04  x05  x06  a
+    b    t    n    v    f    r    x0E  x0F
+    x10  x11  x12  x13  x14  x15  x16  x17
+    x18  x19  x1A  e    x1C  x1D  x1E  x1F
+);
+
+# Printable characters for escapes
+my %UNESCAPES = (
+    0 => "\x00", z => "\x00", N    => "\x85",
+    a => "\x07", b => "\x08", t    => "\x09",
+    n => "\x0a", v => "\x0b", f    => "\x0c",
+    r => "\x0d", e => "\x1b", '\\' => '\\',
+);
+
+# XXX-INGY
+# I(ngy) need to decide if these values should be quoted in
+# YAML::Tiny or not. Probably yes.
+
+# These 3 values have special meaning when unquoted and using the
+# default YAML schema. They need quotes if they are strings.
+my %QUOTE = map { $_ => 1 } qw{
+    null true false
+};
+
+# The commented out form is simpler, but overloaded the Perl regex
+# engine due to recursion and backtracking problems on strings
+# larger than 32,000ish characters. Keep it for reference purposes.
+# qr/\"((?:\\.|[^\"])*)\"/
+my $re_capture_double_quoted = qr/\"([^\\"]*(?:\\.[^\\"]*)*)\"/;
+my $re_capture_single_quoted = qr/\'([^\']*(?:\'\'[^\']*)*)\'/;
+# unquoted re gets trailing space that needs to be stripped
+my $re_capture_unquoted_key  = qr/([^:]+(?::+\S[^:]*)*)(?=\s*\:(?:\s+|$))/;
+my $re_trailing_comment      = qr/(?:\s+\#.*)?/;
+my $re_key_value_separator   = qr/\s*:(?:\s+(?:\#.*)?|$)/;
+
+
+
+
+
+#####################################################################
+# YAML::Tiny Implementation.
+#
+# These are the private methods that do all the work. They may change
+# at any time.
+
+
+###
+# Loader functions:
+
+# Create an object from a file
+sub _load_file {
+    my $class = ref $_[0] ? ref shift : shift;
+
+    # Check the file
+    my $file = shift or $class->_error( 'You did not specify a file name' );
+    $class->_error( "File '$file' does not exist" )
+        unless -e $file;
+    $class->_error( "'$file' is a directory, not a file" )
+        unless -f _;
+    $class->_error( "Insufficient permissions to read '$file'" )
+        unless -r _;
+
+    # Open unbuffered with strict UTF-8 decoding and no translation layers
+    open( my $fh, "<:unix:encoding(UTF-8)", $file );
+    unless ( $fh ) {
+        $class->_error("Failed to open file '$file': $!");
+    }
+
+    # flock if available (or warn if not possible for OS-specific reasons)
+    if ( _can_flock() ) {
+        flock( $fh, Fcntl::LOCK_SH() )
+            or warn "Couldn't lock '$file' for reading: $!";
+    }
+
+    # slurp the contents
+    my $contents = eval {
+        use warnings FATAL => 'utf8';
+        local $/;
+        <$fh>
+    };
+    if ( my $err = $@ ) {
+        $class->_error("Error reading from file '$file': $err");
+    }
+
+    # close the file (release the lock)
+    unless ( close $fh ) {
+        $class->_error("Failed to close file '$file': $!");
+    }
+
+    $class->_load_string( $contents );
+}
+
+# Create an object from a string
+sub _load_string {
+    my $class  = ref $_[0] ? ref shift : shift;
+    my $self   = bless [], $class;
+    my $string = $_[0];
+    eval {
+        unless ( defined $string ) {
+            die \"Did not provide a string to load";
+        }
+
+        # Check if Perl has it marked as characters, but it's internally
+        # inconsistent.  E.g. maybe latin1 got read on a :utf8 layer
+        if ( utf8::is_utf8($string) && ! utf8::valid($string) ) {
+            die \<<'...';
+Read an invalid UTF-8 string (maybe mixed UTF-8 and 8-bit character set).
+Did you decode with lax ":utf8" instead of strict ":encoding(UTF-8)"?
+...
+        }
+
+        # Ensure Unicode character semantics, even for 0x80-0xff
+        utf8::upgrade($string);
+
+        # Check for and strip any leading UTF-8 BOM
+        $string =~ s/^\x{FEFF}//;
+
+        # Check for some special cases
+        return $self unless length $string;
+
+        # Split the file into lines
+        my @lines = grep { ! /^\s*(?:\#.*)?\z/ }
+                split /(?:\015{1,2}\012|\015|\012)/, $string;
+
+        # Strip the initial YAML header
+        @lines and $lines[0] =~ /^\%YAML[: ][\d\.]+.*\z/ and shift @lines;
+
+        # A nibbling parser
+        my $in_document = 0;
+        while ( @lines ) {
+            # Do we have a document header?
+            if ( $lines[0] =~ /^---\s*(?:(.+)\s*)?\z/ ) {
+                # Handle scalar documents
+                shift @lines;
+                if ( defined $1 and $1 !~ /^(?:\#.+|\%YAML[: ][\d\.]+)\z/ ) {
+                    push @$self,
+                        $self->_load_scalar( "$1", [ undef ], \@lines );
+                    next;
+                }
+                $in_document = 1;
+            }
+
+            if ( ! @lines or $lines[0] =~ /^(?:---|\.\.\.)/ ) {
+                # A naked document
+                push @$self, undef;
+                while ( @lines and $lines[0] !~ /^---/ ) {
+                    shift @lines;
+                }
+                $in_document = 0;
+
+            # XXX The final '-+$' is to look for -- which ends up being an
+            # error later.
+            } elsif ( ! $in_document && @$self ) {
+                # only the first document can be explicit
+                die \"YAML::Tiny failed to classify the line '$lines[0]'";
+            } elsif ( $lines[0] =~ /^\s*\-(?:\s|$|-+$)/ ) {
+                # An array at the root
+                my $document = [ ];
+                push @$self, $document;
+                $self->_load_array( $document, [ 0 ], \@lines );
+
+            } elsif ( $lines[0] =~ /^(\s*)\S/ ) {
+                # A hash at the root
+                my $document = { };
+                push @$self, $document;
+                $self->_load_hash( $document, [ length($1) ], \@lines );
+
+            } else {
+                # Shouldn't get here.  @lines have whitespace-only lines
+                # stripped, and previous match is a line with any
+                # non-whitespace.  So this clause should only be reachable via
+                # a perlbug where \s is not symmetric with \S
+
+                # uncoverable statement
+                die \"YAML::Tiny failed to classify the line '$lines[0]'";
+            }
+        }
+    };
+    if ( ref $@ eq 'SCALAR' ) {
+        $self->_error(${$@});
+    } elsif ( $@ ) {
+        $self->_error($@);
+    }
+
+    return $self;
+}
+
+sub _unquote_single {
+    my ($self, $string) = @_;
+    return '' unless length $string;
+    $string =~ s/\'\'/\'/g;
+    return $string;
+}
+
+sub _unquote_double {
+    my ($self, $string) = @_;
+    return '' unless length $string;
+    $string =~ s/\\"/"/g;
+    $string =~
+        s{\\([Nnever\\fartz0b]|x([0-9a-fA-F]{2}))}
+         {(length($1)>1)?pack("H2",$2):$UNESCAPES{$1}}gex;
+    return $string;
+}
+
+# Load a YAML scalar string to the actual Perl scalar
+sub _load_scalar {
+    my ($self, $string, $indent, $lines) = @_;
+
+    # Trim trailing whitespace
+    $string =~ s/\s*\z//;
+
+    # Explitic null/undef
+    return undef if $string eq '~';
+
+    # Single quote
+    if ( $string =~ /^$re_capture_single_quoted$re_trailing_comment\z/ ) {
+        return $self->_unquote_single($1);
+    }
+
+    # Double quote.
+    if ( $string =~ /^$re_capture_double_quoted$re_trailing_comment\z/ ) {
+        return $self->_unquote_double($1);
+    }
+
+    # Special cases
+    if ( $string =~ /^[\'\"!&]/ ) {
+        die \"YAML::Tiny does not support a feature in line '$string'";
+    }
+    return {} if $string =~ /^{}(?:\s+\#.*)?\z/;
+    return [] if $string =~ /^\[\](?:\s+\#.*)?\z/;
+
+    # Regular unquoted string
+    if ( $string !~ /^[>|]/ ) {
+        die \"YAML::Tiny found illegal characters in plain scalar: '$string'"
+            if $string =~ /^(?:-(?:\s|$)|[\@\%\`])/ or
+                $string =~ /:(?:\s|$)/;
+        $string =~ s/\s+#.*\z//;
+        return $string;
+    }
+
+    # Error
+    die \"YAML::Tiny failed to find multi-line scalar content" unless @$lines;
+
+    # Check the indent depth
+    $lines->[0]   =~ /^(\s*)/;
+    $indent->[-1] = length("$1");
+    if ( defined $indent->[-2] and $indent->[-1] <= $indent->[-2] ) {
+        die \"YAML::Tiny found bad indenting in line '$lines->[0]'";
+    }
+
+    # Pull the lines
+    my @multiline = ();
+    while ( @$lines ) {
+        $lines->[0] =~ /^(\s*)/;
+        last unless length($1) >= $indent->[-1];
+        push @multiline, substr(shift(@$lines), length($1));
+    }
+
+    my $j = (substr($string, 0, 1) eq '>') ? ' ' : "\n";
+    my $t = (substr($string, 1, 1) eq '-') ? ''  : "\n";
+    return join( $j, @multiline ) . $t;
+}
+
+# Load an array
+sub _load_array {
+    my ($self, $array, $indent, $lines) = @_;
+
+    while ( @$lines ) {
+        # Check for a new document
+        if ( $lines->[0] =~ /^(?:---|\.\.\.)/ ) {
+            while ( @$lines and $lines->[0] !~ /^---/ ) {
+                shift @$lines;
+            }
+            return 1;
+        }
+
+        # Check the indent level
+        $lines->[0] =~ /^(\s*)/;
+        if ( length($1) < $indent->[-1] ) {
+            return 1;
+        } elsif ( length($1) > $indent->[-1] ) {
+            die \"YAML::Tiny found bad indenting in line '$lines->[0]'";
+        }
+
+        if ( $lines->[0] =~ /^(\s*\-\s+)[^\'\"]\S*\s*:(?:\s+|$)/ ) {
+            # Inline nested hash
+            my $indent2 = length("$1");
+            $lines->[0] =~ s/-/ /;
+            push @$array, { };
+            $self->_load_hash( $array->[-1], [ @$indent, $indent2 ], $lines );
+
+        } elsif ( $lines->[0] =~ /^\s*\-\s*\z/ ) {
+            shift @$lines;
+            unless ( @$lines ) {
+                push @$array, undef;
+                return 1;
+            }
+            if ( $lines->[0] =~ /^(\s*)\-/ ) {
+                my $indent2 = length("$1");
+                if ( $indent->[-1] == $indent2 ) {
+                    # Null array entry
+                    push @$array, undef;
+                } else {
+                    # Naked indenter
+                    push @$array, [ ];
+                    $self->_load_array(
+                        $array->[-1], [ @$indent, $indent2 ], $lines
+                    );
+                }
+
+            } elsif ( $lines->[0] =~ /^(\s*)\S/ ) {
+                push @$array, { };
+                $self->_load_hash(
+                    $array->[-1], [ @$indent, length("$1") ], $lines
+                );
+
+            } else {
+                die \"YAML::Tiny failed to classify line '$lines->[0]'";
+            }
+
+        } elsif ( $lines->[0] =~ /^\s*\-(\s*)(.+?)\s*\z/ ) {
+            # Array entry with a value
+            shift @$lines;
+            push @$array, $self->_load_scalar(
+                "$2", [ @$indent, undef ], $lines
+            );
+
+        } elsif ( defined $indent->[-2] and $indent->[-1] == $indent->[-2] ) {
+            # This is probably a structure like the following...
+            # ---
+            # foo:
+            # - list
+            # bar: value
+            #
+            # ... so lets return and let the hash parser handle it
+            return 1;
+
+        } else {
+            die \"YAML::Tiny failed to classify line '$lines->[0]'";
+        }
+    }
+
+    return 1;
+}
+
+# Load a hash
+sub _load_hash {
+    my ($self, $hash, $indent, $lines) = @_;
+
+    while ( @$lines ) {
+        # Check for a new document
+        if ( $lines->[0] =~ /^(?:---|\.\.\.)/ ) {
+            while ( @$lines and $lines->[0] !~ /^---/ ) {
+                shift @$lines;
+            }
+            return 1;
+        }
+
+        # Check the indent level
+        $lines->[0] =~ /^(\s*)/;
+        if ( length($1) < $indent->[-1] ) {
+            return 1;
+        } elsif ( length($1) > $indent->[-1] ) {
+            die \"YAML::Tiny found bad indenting in line '$lines->[0]'";
+        }
+
+        # Find the key
+        my $key;
+
+        # Quoted keys
+        if ( $lines->[0] =~
+            s/^\s*$re_capture_single_quoted$re_key_value_separator//
+        ) {
+            $key = $self->_unquote_single($1);
+        }
+        elsif ( $lines->[0] =~
+            s/^\s*$re_capture_double_quoted$re_key_value_separator//
+        ) {
+            $key = $self->_unquote_double($1);
+        }
+        elsif ( $lines->[0] =~
+            s/^\s*$re_capture_unquoted_key$re_key_value_separator//
+        ) {
+            $key = $1;
+            $key =~ s/\s+$//;
+        }
+        elsif ( $lines->[0] =~ /^\s*\?/ ) {
+            die \"YAML::Tiny does not support a feature in line '$lines->[0]'";
+        }
+        else {
+            die \"YAML::Tiny failed to classify line '$lines->[0]'";
+        }
+
+        # Do we have a value?
+        if ( length $lines->[0] ) {
+            # Yes
+            $hash->{$key} = $self->_load_scalar(
+                shift(@$lines), [ @$indent, undef ], $lines
+            );
+        } else {
+            # An indent
+            shift @$lines;
+            unless ( @$lines ) {
+                $hash->{$key} = undef;
+                return 1;
+            }
+            if ( $lines->[0] =~ /^(\s*)-/ ) {
+                $hash->{$key} = [];
+                $self->_load_array(
+                    $hash->{$key}, [ @$indent, length($1) ], $lines
+                );
+            } elsif ( $lines->[0] =~ /^(\s*)./ ) {
+                my $indent2 = length("$1");
+                if ( $indent->[-1] >= $indent2 ) {
+                    # Null hash entry
+                    $hash->{$key} = undef;
+                } else {
+                    $hash->{$key} = {};
+                    $self->_load_hash(
+                        $hash->{$key}, [ @$indent, length($1) ], $lines
+                    );
+                }
+            }
+        }
+    }
+
+    return 1;
+}
+
+
+###
+# Dumper functions:
+
+# Save an object to a file
+sub _dump_file {
+    my $self = shift;
+
+    require Fcntl;
+
+    # Check the file
+    my $file = shift or $self->_error( 'You did not specify a file name' );
+
+    my $fh;
+    # flock if available (or warn if not possible for OS-specific reasons)
+    if ( _can_flock() ) {
+        # Open without truncation (truncate comes after lock)
+        my $flags = Fcntl::O_WRONLY()|Fcntl::O_CREAT();
+        sysopen( $fh, $file, $flags );
+        unless ( $fh ) {
+            $self->_error("Failed to open file '$file' for writing: $!");
+        }
+
+        # Use no translation and strict UTF-8
+        binmode( $fh, ":raw:encoding(UTF-8)");
+
+        flock( $fh, Fcntl::LOCK_EX() )
+            or warn "Couldn't lock '$file' for reading: $!";
+
+        # truncate and spew contents
+        truncate $fh, 0;
+        seek $fh, 0, 0;
+    }
+    else {
+        open $fh, ">:unix:encoding(UTF-8)", $file;
+    }
+
+    # serialize and spew to the handle
+    print {$fh} $self->_dump_string;
+
+    # close the file (release the lock)
+    unless ( close $fh ) {
+        $self->_error("Failed to close file '$file': $!");
+    }
+
+    return 1;
+}
+
+# Save an object to a string
+sub _dump_string {
+    my $self = shift;
+    return '' unless ref $self && @$self;
+
+    # Iterate over the documents
+    my $indent = 0;
+    my @lines  = ();
+
+    eval {
+        foreach my $cursor ( @$self ) {
+            push @lines, '---';
+
+            # An empty document
+            if ( ! defined $cursor ) {
+                # Do nothing
+
+            # A scalar document
+            } elsif ( ! ref $cursor ) {
+                $lines[-1] .= ' ' . $self->_dump_scalar( $cursor );
+
+            # A list at the root
+            } elsif ( ref $cursor eq 'ARRAY' ) {
+                unless ( @$cursor ) {
+                    $lines[-1] .= ' []';
+                    next;
+                }
+                push @lines, $self->_dump_array( $cursor, $indent, {} );
+
+            # A hash at the root
+            } elsif ( ref $cursor eq 'HASH' ) {
+                unless ( %$cursor ) {
+                    $lines[-1] .= ' {}';
+                    next;
+                }
+                push @lines, $self->_dump_hash( $cursor, $indent, {} );
+
+            } else {
+                die \("Cannot serialize " . ref($cursor));
+            }
+        }
+    };
+    if ( ref $@ eq 'SCALAR' ) {
+        $self->_error(${$@});
+    } elsif ( $@ ) {
+        $self->_error($@);
+    }
+
+    join '', map { "$_\n" } @lines;
+}
+
+sub _has_internal_string_value {
+    my $value = shift;
+    my $b_obj = B::svref_2object(\$value);  # for round trip problem
+    return $b_obj->FLAGS & B::SVf_POK();
+}
+
+sub _dump_scalar {
+    my $string = $_[1];
+    my $is_key = $_[2];
+    # Check this before checking length or it winds up looking like a string!
+    my $has_string_flag = _has_internal_string_value($string);
+    return '~'  unless defined $string;
+    return "''" unless length  $string;
+    if (Scalar::Util::looks_like_number($string)) {
+        # keys and values that have been used as strings get quoted
+        if ( $is_key || $has_string_flag ) {
+            return qq['$string'];
+        }
+        else {
+            return $string;
+        }
+    }
+    if ( $string =~ /[\x00-\x09\x0b-\x0d\x0e-\x1f\x7f-\x9f\'\n]/ ) {
+        $string =~ s/\\/\\\\/g;
+        $string =~ s/"/\\"/g;
+        $string =~ s/\n/\\n/g;
+        $string =~ s/[\x85]/\\N/g;
+        $string =~ s/([\x00-\x1f])/\\$UNPRINTABLE[ord($1)]/g;
+        $string =~ s/([\x7f-\x9f])/'\x' . sprintf("%X",ord($1))/ge;
+        return qq|"$string"|;
+    }
+    if ( $string =~ /(?:^[~!@#%&*|>?:,'"`{}\[\]]|^-+$|\s|:\z)/ or
+        $QUOTE{$string}
+    ) {
+        return "'$string'";
+    }
+    return $string;
+}
+
+sub _dump_array {
+    my ($self, $array, $indent, $seen) = @_;
+    if ( $seen->{refaddr($array)}++ ) {
+        die \"YAML::Tiny does not support circular references";
+    }
+    my @lines  = ();
+    foreach my $el ( @$array ) {
+        my $line = ('  ' x $indent) . '-';
+        my $type = ref $el;
+        if ( ! $type ) {
+            $line .= ' ' . $self->_dump_scalar( $el );
+            push @lines, $line;
+
+        } elsif ( $type eq 'ARRAY' ) {
+            if ( @$el ) {
+                push @lines, $line;
+                push @lines, $self->_dump_array( $el, $indent + 1, $seen );
+            } else {
+                $line .= ' []';
+                push @lines, $line;
+            }
+
+        } elsif ( $type eq 'HASH' ) {
+            if ( keys %$el ) {
+                push @lines, $line;
+                push @lines, $self->_dump_hash( $el, $indent + 1, $seen );
+            } else {
+                $line .= ' {}';
+                push @lines, $line;
+            }
+
+        } else {
+            die \"YAML::Tiny does not support $type references";
+        }
+    }
+
+    @lines;
+}
+
+sub _dump_hash {
+    my ($self, $hash, $indent, $seen) = @_;
+    if ( $seen->{refaddr($hash)}++ ) {
+        die \"YAML::Tiny does not support circular references";
+    }
+    my @lines  = ();
+    foreach my $name ( sort keys %$hash ) {
+        my $el   = $hash->{$name};
+        my $line = ('  ' x $indent) . $self->_dump_scalar($name, 1) . ":";
+        my $type = ref $el;
+        if ( ! $type ) {
+            $line .= ' ' . $self->_dump_scalar( $el );
+            push @lines, $line;
+
+        } elsif ( $type eq 'ARRAY' ) {
+            if ( @$el ) {
+                push @lines, $line;
+                push @lines, $self->_dump_array( $el, $indent + 1, $seen );
+            } else {
+                $line .= ' []';
+                push @lines, $line;
+            }
+
+        } elsif ( $type eq 'HASH' ) {
+            if ( keys %$el ) {
+                push @lines, $line;
+                push @lines, $self->_dump_hash( $el, $indent + 1, $seen );
+            } else {
+                $line .= ' {}';
+                push @lines, $line;
+            }
+
+        } else {
+            die \"YAML::Tiny does not support $type references";
+        }
+    }
+
+    @lines;
+}
+
+
+
+#####################################################################
+# DEPRECATED API methods:
+
+# Error storage (DEPRECATED as of 1.57)
+our $errstr    = '';
+
+# Set error
+sub _error {
+    require Carp;
+    $errstr = $_[1];
+    $errstr =~ s/ at \S+ line \d+.*//;
+    Carp::croak( $errstr );
+}
+
+# Retrieve error
+my $errstr_warned;
+sub errstr {
+    require Carp;
+    Carp::carp( "YAML::Tiny->errstr and \$YAML::Tiny::errstr is deprecated" )
+        unless $errstr_warned++;
+    $errstr;
+}
+
+
+
+
+#####################################################################
+# Helper functions. Possibly not needed.
+
+
+# Use to detect nv or iv
+use B;
+
+# XXX-INGY Is flock YAML::Tiny's responsibility?
+# Some platforms can't flock :-(
+# XXX-XDG I think it is.  When reading and writing files, we ought
+# to be locking whenever possible.  People (foolishly) use YAML
+# files for things like session storage, which has race issues.
+my $HAS_FLOCK;
+sub _can_flock {
+    if ( defined $HAS_FLOCK ) {
+        return $HAS_FLOCK;
+    }
+    else {
+        require Config;
+        my $c = \%Config::Config;
+        $HAS_FLOCK = grep { $c->{$_} } qw/d_flock d_fcntl_can_lock d_lockf/;
+        require Fcntl if $HAS_FLOCK;
+        return $HAS_FLOCK;
+    }
+}
+
+
+# XXX-INGY Is this core in 5.8.1? Can we remove this?
+# XXX-XDG Scalar::Util 1.18 didn't land until 5.8.8, so we need this
+#####################################################################
+# Use Scalar::Util if possible, otherwise emulate it
+
+BEGIN {
+    local $@;
+    if ( eval { require Scalar::Util }
+      && $Scalar::Util::VERSION
+      && eval($Scalar::Util::VERSION) >= 1.18
+    ) {
+        *refaddr = *Scalar::Util::refaddr;
+    }
+    else {
+        eval <<'END_PERL';
+# Scalar::Util failed to load or too old
+sub refaddr {
+    my $pkg = ref($_[0]) or return undef;
+    if ( !! UNIVERSAL::can($_[0], 'can') ) {
+        bless $_[0], 'Scalar::Util::Fake';
+    } else {
+        $pkg = undef;
+    }
+    "$_[0]" =~ /0x(\w+)/;
+    my $i = do { no warnings 'portable'; hex $1 };
+    bless $_[0], $pkg if defined $pkg;
+    $i;
+}
+END_PERL
+    }
+}
+
+
+
+
+1;
+
+# XXX-INGY Doc notes I'm putting up here. Changing the doc when it's wrong
+# but leaving grey area stuff up here.
+#
+# I would like to change Read/Write to Load/Dump below without
+# changing the actual API names.
+#
+# It might be better to put Load/Dump API in the SYNOPSIS instead of the
+# dubious OO API.
+#
+# null and bool explanations may be outdated.
+
+__END__
+
+#line 1491
diff --git a/inc/unicore/Name.pm b/inc/unicore/Name.pm
new file mode 100644
index 0000000..48044d2
--- /dev/null
+++ b/inc/unicore/Name.pm
@@ -0,0 +1,416 @@
+#line 1
+# !!!!!!!   DO NOT EDIT THIS FILE   !!!!!!!
+# This file is machine-generated by lib/unicore/mktables from the Unicode
+# database, Version 6.1.0.  Any changes made here will be lost!
+
+
+# !!!!!!!   INTERNAL PERL USE ONLY   !!!!!!!
+# This file is for internal use by core Perl only.  The format and even the
+# name or existence of this file are subject to change without notice.  Don't
+# use it directly.
+
+
+package charnames;
+
+# This module contains machine-generated tables and code for the
+# algorithmically-determinable Unicode character names.  The following
+# routines can be used to translate between name and code point and vice versa
+
+{ # Closure
+
+    # Matches legal code point.  4-6 hex numbers, If there are 6, the first
+    # two must be 10; if there are 5, the first must not be a 0.  Written this
+    # way to decrease backtracking.  The first regex allows the code point to
+    # be at the end of a word, but to work properly, the word shouldn't end
+    # with a valid hex character.  The second one won't match a code point at
+    # the end of a word, and doesn't have the run-on issue
+    my $run_on_code_point_re = qr/(?^aax: (?: 10[0-9A-F]{4} | [1-9A-F][0-9A-F]{4} | [0-9A-F]{4} ) \b)/;
+    my $code_point_re = qr/(?^aa:\b(?^aax: (?: 10[0-9A-F]{4} | [1-9A-F][0-9A-F]{4} | [0-9A-F]{4} ) \b))/;
+
+    # In the following hash, the keys are the bases of names which includes
+    # the code point in the name, like CJK UNIFIED IDEOGRAPH-4E01.  The values
+    # of each key is another hash which is used to get the low and high ends
+    # for each range of code points that apply to the name.
+    my %names_ending_in_code_point = (
+'CJK COMPATIBILITY IDEOGRAPH' => 
+{
+'high' => 
+[
+64109,
+64217,
+195101,
+],
+'low' => 
+[
+63744,
+64112,
+194560,
+],
+},
+'CJK UNIFIED IDEOGRAPH' => 
+{
+'high' => 
+[
+19893,
+40908,
+173782,
+177972,
+178205,
+],
+'low' => 
+[
+13312,
+19968,
+131072,
+173824,
+177984,
+],
+},
+
+    );
+
+    # The following hash is a copy of the previous one, except is for loose
+    # matching, so each name has blanks and dashes squeezed out
+    my %loose_names_ending_in_code_point = (
+'CJKCOMPATIBILITYIDEOGRAPH' => 
+{
+'high' => 
+[
+64109,
+64217,
+195101,
+],
+'low' => 
+[
+63744,
+64112,
+194560,
+],
+},
+'CJKUNIFIEDIDEOGRAPH' => 
+{
+'high' => 
+[
+19893,
+40908,
+173782,
+177972,
+178205,
+],
+'low' => 
+[
+13312,
+19968,
+131072,
+173824,
+177984,
+],
+},
+
+    );
+
+    # And the following array gives the inverse mapping from code points to
+    # names.  Lowest code points are first
+    my @code_points_ending_in_code_point = (
+
+{
+'high' => 19893,
+'low' => 13312,
+'name' => 'CJK UNIFIED IDEOGRAPH',
+},
+{
+'high' => 40908,
+'low' => 19968,
+'name' => 'CJK UNIFIED IDEOGRAPH',
+},
+{
+'high' => 64109,
+'low' => 63744,
+'name' => 'CJK COMPATIBILITY IDEOGRAPH',
+},
+{
+'high' => 64217,
+'low' => 64112,
+'name' => 'CJK COMPATIBILITY IDEOGRAPH',
+},
+{
+'high' => 173782,
+'low' => 131072,
+'name' => 'CJK UNIFIED IDEOGRAPH',
+},
+{
+'high' => 177972,
+'low' => 173824,
+'name' => 'CJK UNIFIED IDEOGRAPH',
+},
+{
+'high' => 178205,
+'low' => 177984,
+'name' => 'CJK UNIFIED IDEOGRAPH',
+},
+{
+'high' => 195101,
+'low' => 194560,
+'name' => 'CJK COMPATIBILITY IDEOGRAPH',
+},
+,
+
+    );
+
+    # Convert from code point to Jamo short name for use in composing Hangul
+    # syllable names
+    my %Jamo = (
+4352 => 'G',
+4353 => 'GG',
+4354 => 'N',
+4355 => 'D',
+4356 => 'DD',
+4357 => 'R',
+4358 => 'M',
+4359 => 'B',
+4360 => 'BB',
+4361 => 'S',
+4362 => 'SS',
+4363 => '',
+4364 => 'J',
+4365 => 'JJ',
+4366 => 'C',
+4367 => 'K',
+4368 => 'T',
+4369 => 'P',
+4370 => 'H',
+4449 => 'A',
+4450 => 'AE',
+4451 => 'YA',
+4452 => 'YAE',
+4453 => 'EO',
+4454 => 'E',
+4455 => 'YEO',
+4456 => 'YE',
+4457 => 'O',
+4458 => 'WA',
+4459 => 'WAE',
+4460 => 'OE',
+4461 => 'YO',
+4462 => 'U',
+4463 => 'WEO',
+4464 => 'WE',
+4465 => 'WI',
+4466 => 'YU',
+4467 => 'EU',
+4468 => 'YI',
+4469 => 'I',
+4520 => 'G',
+4521 => 'GG',
+4522 => 'GS',
+4523 => 'N',
+4524 => 'NJ',
+4525 => 'NH',
+4526 => 'D',
+4527 => 'L',
+4528 => 'LG',
+4529 => 'LM',
+4530 => 'LB',
+4531 => 'LS',
+4532 => 'LT',
+4533 => 'LP',
+4534 => 'LH',
+4535 => 'M',
+4536 => 'B',
+4537 => 'BS',
+4538 => 'S',
+4539 => 'SS',
+4540 => 'NG',
+4541 => 'J',
+4542 => 'C',
+4543 => 'K',
+4544 => 'T',
+4545 => 'P',
+4546 => 'H',
+
+    );
+
+    # Leading consonant (can be null)
+    my %Jamo_L = (
+'' => 11,
+'B' => 7,
+'BB' => 8,
+'C' => 14,
+'D' => 3,
+'DD' => 4,
+'G' => 0,
+'GG' => 1,
+'H' => 18,
+'J' => 12,
+'JJ' => 13,
+'K' => 15,
+'M' => 6,
+'N' => 2,
+'P' => 17,
+'R' => 5,
+'S' => 9,
+'SS' => 10,
+'T' => 16,
+
+    );
+
+    # Vowel
+    my %Jamo_V = (
+'A' => 0,
+'AE' => 1,
+'E' => 5,
+'EO' => 4,
+'EU' => 18,
+'I' => 20,
+'O' => 8,
+'OE' => 11,
+'U' => 13,
+'WA' => 9,
+'WAE' => 10,
+'WE' => 15,
+'WEO' => 14,
+'WI' => 16,
+'YA' => 2,
+'YAE' => 3,
+'YE' => 7,
+'YEO' => 6,
+'YI' => 19,
+'YO' => 12,
+'YU' => 17,
+
+    );
+
+    # Optional trailing consonant
+    my %Jamo_T = (
+'B' => 17,
+'BS' => 18,
+'C' => 23,
+'D' => 7,
+'G' => 1,
+'GG' => 2,
+'GS' => 3,
+'H' => 27,
+'J' => 22,
+'K' => 24,
+'L' => 8,
+'LB' => 11,
+'LG' => 9,
+'LH' => 15,
+'LM' => 10,
+'LP' => 14,
+'LS' => 12,
+'LT' => 13,
+'M' => 16,
+'N' => 4,
+'NG' => 21,
+'NH' => 6,
+'NJ' => 5,
+'P' => 26,
+'S' => 19,
+'SS' => 20,
+'T' => 25,
+
+    );
+
+    # Computed re that splits up a Hangul name into LVT or LV syllables
+    my $syllable_re = qr/(|B|BB|C|D|DD|G|GG|H|J|JJ|K|M|N|P|R|S|SS|T)(A|AE|E|EO|EU|I|O|OE|U|WA|WAE|WE|WEO|WI|YA|YAE|YE|YEO|YI|YO|YU)(B|BS|C|D|G|GG|GS|H|J|K|L|LB|LG|LH|LM|LP|LS|LT|M|N|NG|NH|NJ|P|S|SS|T)?/;
+
+    my $HANGUL_SYLLABLE = "HANGUL SYLLABLE ";
+    my $loose_HANGUL_SYLLABLE = "HANGULSYLLABLE";
+
+    # These constants names and values were taken from the Unicode standard,
+    # version 5.1, section 3.12.  They are used in conjunction with Hangul
+    # syllables
+    my $SBase = 0xAC00;
+    my $LBase = 0x1100;
+    my $VBase = 0x1161;
+    my $TBase = 0x11A7;
+    my $SCount = 11172;
+    my $LCount = 19;
+    my $VCount = 21;
+    my $TCount = 28;
+    my $NCount = $VCount * $TCount;
+
+    sub name_to_code_point_special {
+        my ($name, $loose) = @_;
+
+        # Returns undef if not one of the specially handled names; otherwise
+        # returns the code point equivalent to the input name
+        # $loose is non-zero if to use loose matching, 'name' in that case
+        # must be input as upper case with all blanks and dashes squeezed out.
+
+        if ((! $loose && $name =~ s/$HANGUL_SYLLABLE//)
+            || ($loose && $name =~ s/$loose_HANGUL_SYLLABLE//))
+        {
+            return if $name !~ qr/^$syllable_re$/;
+            my $L = $Jamo_L{$1};
+            my $V = $Jamo_V{$2};
+            my $T = (defined $3) ? $Jamo_T{$3} : 0;
+            return ($L * $VCount + $V) * $TCount + $T + $SBase;
+        }
+
+        # Name must end in 'code_point' for this to handle.
+        return if (($loose && $name !~ /^ (.*?) ($run_on_code_point_re) $/x)
+                   || (! $loose && $name !~ /^ (.*) ($code_point_re) $/x));
+
+        my $base = $1;
+        my $code_point = CORE::hex $2;
+        my $names_ref;
+
+        if ($loose) {
+            $names_ref = \%loose_names_ending_in_code_point;
+        }
+        else {
+            return if $base !~ s/-$//;
+            $names_ref = \%names_ending_in_code_point;
+        }
+
+        # Name must be one of the ones which has the code point in it.
+        return if ! $names_ref->{$base};
+
+        # Look through the list of ranges that apply to this name to see if
+        # the code point is in one of them.
+        for (my $i = 0; $i < scalar @{$names_ref->{$base}{'low'}}; $i++) {
+            return if $names_ref->{$base}{'low'}->[$i] > $code_point;
+            next if $names_ref->{$base}{'high'}->[$i] < $code_point;
+
+            # Here, the code point is in the range.
+            return $code_point;
+        }
+
+        # Here, looked like the name had a code point number in it, but
+        # did not match one of the valid ones.
+        return;
+    }
+
+    sub code_point_to_name_special {
+        my $code_point = shift;
+
+        # Returns the name of a code point if algorithmically determinable;
+        # undef if not
+
+        # If in the Hangul range, calculate the name based on Unicode's
+        # algorithm
+        if ($code_point >= $SBase && $code_point <= $SBase + $SCount -1) {
+            use integer;
+            my $SIndex = $code_point - $SBase;
+            my $L = $LBase + $SIndex / $NCount;
+            my $V = $VBase + ($SIndex % $NCount) / $TCount;
+            my $T = $TBase + $SIndex % $TCount;
+            $name = "$HANGUL_SYLLABLE$Jamo{$L}$Jamo{$V}";
+            $name .= $Jamo{$T} if $T != $TBase;
+            return $name;
+        }
+
+        # Look through list of these code points for one in range.
+        foreach my $hash (@code_points_ending_in_code_point) {
+            return if $code_point < $hash->{'low'};
+            if ($code_point <= $hash->{'high'}) {
+                return sprintf("%s-%04X", $hash->{'name'}, $code_point);
+            }
+        }
+        return;            # None found
+    }
+} # End closure
+
+1;

commit e29d54d4bdced63d3544eb00b55a04d217ddf62a
Author: Wallace Reis <wreis at bestpractical.com>
Date:   Thu Feb 26 17:17:31 2015 -0300

    Update README

diff --git a/README b/README
index 5c8555a..7e0606f 100644
--- a/README
+++ b/README
@@ -20,9 +20,9 @@ RT VERSIONS
     Works with RT 4.2.
 
 INSTALLATION
-    "perl Makefile.PL"
-    "make"
-    "make install"
+    perl Makefile.PL
+    make
+    make install
         May need root permissions
 
     Edit your /opt/rt4/etc/RT_SiteConfig.pm
@@ -30,7 +30,7 @@ INSTALLATION
 
             Set(@Plugins, qw(RT::Extension::PreviewInSearch));
 
-        or add "RT::Extension::PreviewInSearch" to your existing @Plugins
+        or add RT::Extension::PreviewInSearch to your existing @Plugins
         line. Starting with RT 4.2 you can also use:
 
             Plugin( "RT::Extension::PreviewInSearch" );
@@ -40,6 +40,12 @@ INSTALLATION
 
     Restart your webserver
 
+CONFIGURATION
+  $SideBySidePreview
+    This allow the preview box to be displayed aside of search results box.
+
+        Set($SideBySidePreview, 1);
+
 AUTHOR
     Ruslan Zakirov <ruz at bestpractical.com>
 

commit 88c19cff53e36eec539f8ba74de301b914cb31a5
Author: Wallace Reis <wreis at bestpractical.com>
Date:   Thu Feb 26 17:17:41 2015 -0300

    Update META

diff --git a/META.yml b/META.yml
index 0b36813..94476f4 100644
--- a/META.yml
+++ b/META.yml
@@ -8,8 +8,8 @@ configure_requires:
   ExtUtils::MakeMaker: 6.59
 distribution_type: module
 dynamic_config: 1
-generated_by: 'Module::Install version 1.06'
-license: gpl
+generated_by: 'Module::Install version 1.14'
+license: gplv2
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
   version: 1.4
@@ -19,7 +19,11 @@ no_index:
     - html
     - inc
 requires:
-  perl: 5.10.0
+  perl: 5.10.1
 resources:
+  homepage: https://github.com/bestpractical/rt-extension-previewinsearch/tree
   license: http://opensource.org/licenses/gpl-license.php
-version: 0.01
+  repository: https://github.com/bestpractical/rt-extension-previewinsearch.git
+version: '0.03'
+x_module_install_rtx_version: '0.37'
+x_requires_rt: 4.0.0

commit b39736bb224f0e2cbeb9dd66f9cae60ccc9de538
Author: Wallace Reis <wreis at bestpractical.com>
Date:   Thu Feb 26 17:17:50 2015 -0300

    Update MANIFEST

diff --git a/MANIFEST b/MANIFEST
index ae4fb90..899fa09 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -6,12 +6,17 @@ inc/Module/Install.pm
 inc/Module/Install/Base.pm
 inc/Module/Install/Can.pm
 inc/Module/Install/Fetch.pm
+inc/Module/Install/GithubMeta.pm
+inc/Module/Install/Include.pm
 inc/Module/Install/Makefile.pm
 inc/Module/Install/Metadata.pm
 inc/Module/Install/ReadmeFromPod.pm
 inc/Module/Install/RTx.pm
+inc/Module/Install/RTx/Runtime.pm
 inc/Module/Install/Win32.pm
 inc/Module/Install/WriteAll.pm
+inc/unicore/Name.pm
+inc/YAML/Tiny.pm
 lib/RT/Extension/PreviewInSearch.pm
 Makefile.PL
 MANIFEST			This list of files

commit 287015ae8b307f3cafb219d89c964f6c0d997b9d
Author: Wallace Reis <wreis at bestpractical.com>
Date:   Thu Feb 26 17:21:22 2015 -0300

    Add changelog

diff --git a/Changes b/Changes
new file mode 100644
index 0000000..b408894
--- /dev/null
+++ b/Changes
@@ -0,0 +1,4 @@
+Revision history for RT-Extension-PreviewInSearch
+
+0.03     2015-02-26
+ A bunch of changes were done previously, but there wasn't any changelog file.
\ No newline at end of file
diff --git a/MANIFEST b/MANIFEST
index 899fa09..ec2ddc5 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1,3 +1,4 @@
+Changes
 doc/images/preview-screenshot.png
 html/Callbacks/RT-Extension-PreviewInSearch/Search/Results.html/AfterResults
 html/Callbacks/RT-Extension-PreviewInSearch/Search/Results.html/BeforeResults

-----------------------------------------------------------------------


More information about the Bps-public-commit mailing list