]> granicus.if.org Git - php/commitdiff
- Skip precommand 'phar.php' and keep a pre-built phar.phar in cvs
authorMarcus Boerger <helly@php.net>
Wed, 30 May 2007 16:45:23 +0000 (16:45 +0000)
committerMarcus Boerger <helly@php.net>
Wed, 30 May 2007 16:45:23 +0000 (16:45 +0000)
ext/phar/phar.phar [new file with mode: 0755]
ext/phar/phar.php [deleted file]

diff --git a/ext/phar/phar.phar b/ext/phar/phar.phar
new file mode 100755 (executable)
index 0000000..84ec090
--- /dev/null
@@ -0,0 +1,1218 @@
+#!/usr/bin/php
+<?php if (!class_exists('PHP_Archive')) {
+?><?php
+/**
+ * PHP_Archive Class (implements .phar)
+ *
+ * @package PHP_Archive
+ * @category PHP
+ */
+/**
+ * PHP_Archive Class (implements .phar)
+ *
+ * PHAR files a singular archive from which an entire application can run.
+ * To use it, simply package it using {@see PHP_Archive_Creator} and use phar://
+ * URIs to your includes. i.e. require_once 'phar://config.php' will include config.php
+ * from the root of the PHAR file.
+ *
+ * Gz code borrowed from the excellent File_Archive package by Vincent Lascaux.
+ *
+ * @copyright Copyright David Shafik and Synaptic Media 2004. All rights reserved.
+ * @author Davey Shafik <davey@synapticmedia.net>
+ * @author Greg Beaver <cellog@php.net>
+ * @link http://www.synapticmedia.net Synaptic Media
+ * @version $Id: Archive.php,v 1.43 2007/05/28 18:20:40 helly Exp $
+ * @package PHP_Archive
+ * @category PHP
+ */
+class PHP_Archive
+{
+    const GZ = 0x00001000;
+    const BZ2 = 0x00002000;
+    const SIG = 0x00010000;
+    const SHA1 = 0x0002;
+    const MD5 = 0x0001;
+    /**
+     * Whether this archive is compressed with zlib
+     *
+     * @var bool
+     */
+    private $_compressed;
+    /**
+     * @var string Real path to the .phar archive
+     */
+    private $_archiveName = null;
+    /**
+     * Current file name in the phar
+     * @var string
+     */
+    protected $currentFilename = null;
+    /**
+     * Length of current file in the phar
+     * @var string
+     */
+    protected $internalFileLength = null;
+    /**
+     * Current file statistics (size, creation date, etc.)
+     * @var string
+     */
+    protected $currentStat = null;
+    /**
+     * @var resource|null Pointer to open .phar
+     */
+    protected $fp = null;
+    /**
+     * @var int Current Position of the pointer
+     */
+    protected $position = 0;
+
+    /**
+     * Map actual realpath of phars to meta-data about the phar
+     *
+     * Data is indexed by the alias that is used by internal files.  In other
+     * words, if a file is included via:
+     * <code>
+     * require_once 'phar://PEAR.phar/PEAR/Installer.php';
+     * </code>
+     * then the alias is "PEAR.phar"
+     * 
+     * Information stored is a boolean indicating whether this .phar is compressed
+     * with zlib, another for bzip2, phar-specific meta-data, and
+     * the precise offset of internal files
+     * within the .phar, used with the {@link $_manifest} to load actual file contents
+     * @var array
+     */
+    private static $_pharMapping = array();
+    /**
+     * Map real file paths to alias used
+     *
+     * @var array
+     */
+    private static $_pharFiles = array();
+    /**
+     * File listing for the .phar
+     * 
+     * The manifest is indexed per phar.
+     * 
+     * Files within the .phar are indexed by their relative path within the
+     * .phar.  Each file has this information in its internal array
+     *
+     * - 0 = uncompressed file size
+     * - 1 = timestamp of when file was added to phar
+     * - 2 = offset of file within phar relative to internal file's start
+     * - 3 = compressed file size (actual size in the phar)
+     * @var array
+     */
+    private static $_manifest = array();
+    /**
+     * Absolute offset of internal files within the .phar, indexed by absolute
+     * path to the .phar
+     *
+     * @var array
+     */
+    private static $_fileStart = array();
+    /**
+     * file name of the phar
+     *
+     * @var string
+     */
+    private $_basename;
+
+
+    /**
+     * Default MIME types used for the web front controller
+     *
+     * @var array
+     */
+    public static $defaultmimes = array(
+            'aif' => 'audio/x-aiff',
+            'aiff' => 'audio/x-aiff',
+            'arc' => 'application/octet-stream',
+            'arj' => 'application/octet-stream',
+            'art' => 'image/x-jg',
+            'asf' => 'video/x-ms-asf',
+            'asx' => 'video/x-ms-asf',
+            'avi' => 'video/avi',
+            'bin' => 'application/octet-stream',
+            'bm' => 'image/bmp',
+            'bmp' => 'image/bmp',
+            'bz2' => 'application/x-bzip2',
+            'css' => 'text/css',
+            'doc' => 'application/msword',
+            'dot' => 'application/msword',
+            'dv' => 'video/x-dv',
+            'dvi' => 'application/x-dvi',
+            'eps' => 'application/postscript',
+            'exe' => 'application/octet-stream',
+            'gif' => 'image/gif',
+            'gz' => 'application/x-gzip',
+            'gzip' => 'application/x-gzip',
+            'htm' => 'text/html',
+            'html' => 'text/html',
+            'ico' => 'image/x-icon',
+            'jpe' => 'image/jpeg',
+            'jpg' => 'image/jpeg',
+            'jpeg' => 'image/jpeg',
+            'js' => 'application/x-javascript',
+            'log' => 'text/plain',
+            'mid' => 'audio/x-midi',
+            'mov' => 'video/quicktime',
+            'mp2' => 'audio/mpeg',
+            'mp3' => 'audio/mpeg3',
+            'mpg' => 'audio/mpeg',
+            'pdf' => 'aplication/pdf',
+            'png' => 'image/png',
+            'rtf' => 'application/rtf',
+            'tif' => 'image/tiff',
+            'tiff' => 'image/tiff',
+            'txt' => 'text/plain',
+            'xml' => 'text/xml',
+        );
+
+    public static $defaultphp = array(
+        'php' => true
+        );
+
+    public static $defaultphps = array(
+        'phps' => true
+        );
+
+    public static $deny = array('/.+\.inc$/');
+
+    public static function viewSource($archive, $file)
+    {
+        // security, idea borrowed from PHK
+        if (!file_exists($archive . '.introspect')) {
+            header("HTTP/1.0 404 Not Found");
+            exit;
+        }
+        if (self::_fileExists($archive, $_GET['viewsource'])) {
+            $source = highlight_file('phar://@ALIAS@/' .
+                $_GET['viewsource'], true);
+            header('Content-Type: text/html');
+            header('Content-Length: ' . strlen($source));
+            echo '<html><head><title>Source of ',
+                htmlspecialchars($_GET['viewsource']), '</title></head>';
+            echo '<body><h1>Source of ',
+                htmlspecialchars($_GET['viewsource']), '</h1>';
+            if (isset($_GET['introspect'])) {
+                echo '<a href="', htmlspecialchars($_SERVER['PHP_SELF']),
+                    '?introspect=', urlencode(htmlspecialchars($_GET['introspect'])),
+                    '">Return to ', htmlspecialchars($_GET['introspect']), '</a><br />';
+            }
+            echo $source;
+            exit;
+        } else {
+            header("HTTP/1.0 404 Not Found");
+            exit;
+        }
+        
+    }
+
+    public static function introspect($archive, $dir)
+    {
+        // security, idea borrowed from PHK
+        if (!file_exists($archive . '.introspect')) {
+            header("HTTP/1.0 404 Not Found");
+            exit;
+        }
+        if (!$dir) {
+            $dir = '/';
+        }
+        $dir = self::processFile($dir);
+        if ($dir[0] != '/') {
+            $dir = '/' . $dir;
+        }
+        try {
+            $self = htmlspecialchars($_SERVER['PHP_SELF']);
+            $iterate = new DirectoryIterator('phar://@ALIAS@' . $dir);
+            echo '<html><head><title>Introspect ', htmlspecialchars($dir),
+                '</title></head><body><h1>Introspect ', htmlspecialchars($dir),
+                '</h1><ul>';
+            if ($dir != '/') {
+                echo '<li><a href="', $self, '?introspect=',
+                    htmlspecialchars(dirname($dir)), '">..</a></li>';
+            }
+            foreach ($iterate as $entry) {
+                if ($entry->isDot()) continue;
+                $name = self::processFile($entry->getPathname());
+                $name = str_replace('phar://@ALIAS@/', '', $name);
+                if ($entry->isDir()) {
+                    echo '<li><a href="', $self, '?introspect=',
+                        urlencode(htmlspecialchars($name)),
+                        '">',
+                        htmlspecialchars($entry->getFilename()), '/</a> [directory]</li>';
+                } else {
+                    echo '<li><a href="', $self, '?introspect=',
+                        urlencode(htmlspecialchars($dir)), '&viewsource=',
+                        urlencode(htmlspecialchars($name)),
+                        '">',
+                        htmlspecialchars($entry->getFilename()), '</a></li>';
+                }
+            }
+            exit;
+        } catch (Exception $e) {
+            echo '<html><head><title>Directory not found: ',
+                htmlspecialchars($dir), '</title></head>',
+                '<body><h1>Directory not found: ', htmlspecialchars($dir), '</h1>',
+                '<p>Try <a href="', htmlspecialchars($_SERVER['PHP_SELF']), '?introspect=/">',
+                'This link</a></p></body></html>';
+            exit;
+        }
+    }
+
+    public static function webFrontController($initfile)
+    {
+        if (isset($_SERVER) && isset($_SERVER['REQUEST_URI'])) {
+            $uri = parse_url($_SERVER['REQUEST_URI']);
+            $archive = realpath($_SERVER['SCRIPT_FILENAME']);
+            $subpath = str_replace('/' . basename($archive), '', $uri['path']);
+            if (!$subpath || $subpath == '/') {
+                if (isset($_GET['viewsource'])) {
+                    self::viewSource($archive, $_GET['viewsource']);
+                }
+                if (isset($_GET['introspect'])) {
+                    self::introspect($archive, $_GET['introspect']);
+                }
+                $subpath = '/' . $initfile;
+            }
+            if (!self::_fileExists($archive, substr($subpath, 1))) {
+                header("HTTP/1.0 404 Not Found");
+                exit;
+            }
+            foreach (self::$deny as $pattern) {
+                if (preg_match($pattern, $subpath)) {
+                    header("HTTP/1.0 404 Not Found");
+                    exit;
+                }
+            }
+            $inf = pathinfo(basename($subpath));
+            if (!isset($inf['extension'])) {
+                header('Content-Type: text/plain');
+                header('Content-Length: ' .
+                    self::_filesize($archive, substr($subpath, 1)));
+                readfile('phar://@ALIAS@' . $subpath);
+                exit;
+            }
+            if (isset(self::$defaultphp[$inf['extension']])) {
+                include 'phar://@ALIAS@' . $subpath;
+                exit;
+            }
+            if (isset(self::$defaultmimes[$inf['extension']])) {
+                header('Content-Type: ' . self::$defaultmimes[$inf['extension']]);
+                header('Content-Length: ' .
+                    self::_filesize($archive, substr($subpath, 1)));
+                readfile('phar://@ALIAS@' . $subpath);
+                exit;
+            }
+            if (isset(self::$defaultphps[$inf['extension']])) {
+                header('Content-Type: text/html');
+                $c = highlight_file('phar://@ALIAS@' . $subpath, true);
+                header('Content-Length: ' . strlen($c));
+                echo $c;
+                exit;
+            }
+            header('Content-Type: text/plain');
+            header('Content-Length: ' .
+                    self::_filesize($archive, substr($subpath, 1)));
+            readfile('phar://@ALIAS@' . $subpath);
+            exit;
+        }
+    }
+
+    /**
+     * Detect end of stub
+     *
+     * @param string $buffer stub past '__HALT_'.'COMPILER();'
+     * @return end of stub, prior to length of manifest.
+     */
+    private static final function _endOfStubLength($buffer)
+    {
+        $pos = 0;
+        if (($buffer[0] == ' ' || $buffer[0] == "\n") && substr($buffer, 1, 2) == '?>')
+        {
+            $pos += 3;
+            if ($buffer[$pos] == "\r" && $buffer[$pos+1] == "\n") {
+                $pos += 2;
+            }
+            else if ($buffer[$pos] == "\n") {
+                $pos += 1;
+            }
+        }
+        return $pos;
+    }
+
+    /**
+     * Allows loading an external Phar archive without include()ing it
+     *
+     * @param string $file  phar package to load
+     * @param string $alias alias to use
+     * @throws Exception
+     */
+    public static final function loadPhar($file, $alias = NULL)
+    {
+        $file = realpath($file);
+        if ($file) {
+            $fp = fopen($file, 'rb');
+            $buffer = '';
+            while (!$found && !feof($fp)) {
+                $buffer .= fread($fp, 8192);
+                // don't break phars
+                if ($pos = strpos($buffer, '__HALT_COMPI' . 'LER();')) {
+                    $buffer .= fread($fp, 5);
+                    fclose($fp);
+                    $pos += 18;
+                    $pos += self::_endOfStubLength(substr($buffer, $pos));
+                    return self::_mapPhar($file, $pos, $alias);
+                }
+            }
+            fclose($fp);
+        }
+    }
+
+    /**
+     * Map a full real file path to an alias used to refer to the .phar
+     *
+     * This function can only be called from the initialization of the .phar itself.
+     * Any attempt to call from outside the .phar or to re-alias the .phar will fail
+     * as a security measure.
+     * @param string $alias
+     * @param int $dataoffset the value of __COMPILER_HALT_OFFSET__
+     */
+    public static final function mapPhar($alias = NULL, $dataoffset = NULL)
+    {
+        try {
+            $file = __FILE__;
+            // this ensures that this is safe
+            if (!in_array($file, get_included_files())) {
+                die('SECURITY ERROR: PHP_Archive::mapPhar can only be called from within ' .
+                    'the phar that initiates it');
+            }
+            if (!isset($dataoffset)) {
+                $dataoffset = constant('__COMPILER_HALT_OFFSET'.'__');
+            }
+            $file = realpath($file);
+
+            $fp = fopen($file, 'rb');
+            fseek($fp, $dataoffset, SEEK_SET);
+            $pos = $dataoffset + self::_endOfStubLength(fread($fp, 5));
+            fclose($fp);
+            self::_mapPhar($file, $pos);
+        } catch (Exception $e) {
+            die($e->getMessage());
+        }
+    }
+
+    /**
+     * Sub-function, allows recovery from errors
+     *
+     * @param unknown_type $file
+     * @param unknown_type $dataoffset
+     */
+    private static function _mapPhar($file, $dataoffset, $alias = NULL)
+    {
+        $file = realpath($file);
+        if (isset(self::$_manifest[$file])) {
+            return;
+        }
+        if (!is_array(self::$_pharMapping)) {
+            self::$_pharMapping = array();
+        }
+        $fp = fopen($file, 'rb');
+        // seek to __HALT_COMPILER_OFFSET__
+        fseek($fp, $dataoffset);
+        $manifest_length = unpack('Vlen', fread($fp, 4));
+        $manifest = '';
+        $last = '1';
+        while (strlen($last) && strlen($manifest) < $manifest_length['len']) {
+            $read = 8192;
+            if ($manifest_length['len'] - strlen($manifest) < 8192) {
+                $read = $manifest_length['len'] - strlen($manifest);
+            }
+            $last = fread($fp, $read);
+            $manifest .= $last;
+        }
+        if (strlen($manifest) < $manifest_length['len']) {
+            throw new Exception('ERROR: manifest length read was "' . 
+                strlen($manifest) .'" should be "' .
+                $manifest_length['len'] . '"');
+        }
+        $info = self::_unserializeManifest($manifest);
+        if ($info['alias']) {
+            $alias = $info['alias'];
+            $explicit = true;
+        } else {
+            if (!isset($alias)) {
+                $alias = $file;
+            }
+            $explicit = false;
+        }
+        self::$_manifest[$file] = $info['manifest'];
+        $compressed = $info['compressed'];
+        self::$_fileStart[$file] = ftell($fp);
+        fclose($fp);
+        if ($compressed & 0x00001000) {
+            if (!function_exists('gzinflate')) {
+                throw new Exception('Error: zlib extension is not enabled - gzinflate() function needed' .
+                    ' for compressed .phars');
+            }
+        }
+        if ($compressed & 0x00002000) {
+            if (!function_exists('bzdecompress')) {
+                throw new Exception('Error: bzip2 extension is not enabled - bzdecompress() function needed' .
+                    ' for compressed .phars');
+            }
+        }
+        if (isset(self::$_pharMapping[$alias])) {
+            throw new Exception('ERROR: PHP_Archive::mapPhar has already been called for alias "' .
+                $alias . '" cannot re-alias to "' . $file . '"');
+        }
+        self::$_pharMapping[$alias] = array($file, $compressed, $dataoffset, $explicit,
+            $info['metadata']);
+        self::$_pharFiles[$file] = $alias;
+    }
+
+    /**
+     * extract the manifest into an internal array
+     *
+     * @param string $manifest
+     * @return false|array
+     */
+    private static function _unserializeManifest($manifest)
+    {
+        // retrieve the number of files in the manifest
+        $info = unpack('V', substr($manifest, 0, 4));
+        $apiver = substr($manifest, 4, 2);
+        $apiver = bin2hex($apiver);
+        $apiver_dots = hexdec($apiver[0]) . '.' . hexdec($apiver[1]) . '.' . hexdec($apiver[2]);
+        $majorcompat = hexdec($apiver[0]);
+        $calcapi = explode('.', self::APIVersion());
+        if ($calcapi[0] != $majorcompat) {
+            throw new Exception('Phar is incompatible API version ' . $apiver_dots . ', but ' .
+                'PHP_Archive is API version '.self::APIVersion());
+        }
+        if ($calcapi[0] === '0') {
+            if (self::APIVersion() != $apiver_dots) {
+                throw new Exception('Phar is API version ' . $apiver_dots .
+                    ', but PHP_Archive is API version '.self::APIVersion(), E_USER_ERROR);
+            }
+        }
+        $flags = unpack('V', substr($manifest, 6, 4));
+        $ret = array('compressed' => $flags & 0x00003000);
+        // signature is not verified by default in PHP_Archive, phar is better
+        $ret['hassignature'] = $flags & 0x00010000;
+        $aliaslen = unpack('V', substr($manifest, 10, 4));
+        if ($aliaslen) {
+            $ret['alias'] = substr($manifest, 14, $aliaslen[1]);
+        } else {
+            $ret['alias'] = false;
+        }
+        $manifest = substr($manifest, 14 + $aliaslen[1]);
+        $metadatalen = unpack('V', substr($manifest, 0, 4));
+        if ($metadatalen[1]) {
+            $ret['metadata'] = unserialize(substr($manifest, 4, $metadatalen[1]));
+            $manifest = substr($manifest, 4 + $metadatalen[1]);
+        } else {
+            $ret['metadata'] = null;
+            $manifest = substr($manifest, 4);
+        }
+        $offset = 0;
+        $start = 0;
+        for ($i = 0; $i < $info[1]; $i++) {
+            // length of the file name
+            $len = unpack('V', substr($manifest, $start, 4));
+            $start += 4;
+            // file name
+            $savepath = substr($manifest, $start, $len[1]);
+            $start += $len[1];
+            // retrieve manifest data:
+            // 0 = uncompressed file size
+            // 1 = timestamp of when file was added to phar
+            // 2 = compressed filesize
+            // 3 = crc32
+            // 4 = flags
+            // 5 = metadata length
+            $ret['manifest'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', substr($manifest, $start, 24)));
+            $ret['manifest'][$savepath][3] = sprintf('%u', $ret['manifest'][$savepath][3]);
+            if ($ret['manifest'][$savepath][5]) {
+                $ret['manifest'][$savepath][6] = unserialize(substr($manifest, $start + 24,
+                    $ret['manifest'][$savepath][5]));
+            } else {
+                $ret['manifest'][$savepath][6] = null;
+            }
+            $ret['manifest'][$savepath][7] = $offset;
+            $offset += $ret['manifest'][$savepath][2];
+            $start += 24 + $ret['manifest'][$savepath][5];
+        }
+        return $ret;
+    }
+
+    /**
+     * @param string
+     */
+    private static function processFile($path)
+    {
+        if ($path == '.') {
+            return '';
+        }
+        $std = str_replace("\\", "/", $path);
+        while ($std != ($std = ereg_replace("[^\/:?]+/\.\./", "", $std))) ;
+        $std = str_replace("/./", "", $std);
+        if (strlen($std) > 1 && $std[0] == '/') {
+            $std = substr($std, 1);
+        }
+        if (strncmp($std, "./", 2) == 0) {
+            return substr($std, 2);
+        } else {
+            return $std;
+        }
+    }
+
+    /**
+     * Seek in the master archive to a matching file or directory
+     * @param string
+     */
+    protected function selectFile($path, $allowdirs = true)
+    {
+        $std = self::processFile($path);
+        if (isset(self::$_manifest[$this->_archiveName][$path])) {
+            $this->_setCurrentFile($path);
+            return true;
+        }
+        if (!$allowdirs) {
+            return 'Error: "' . $path . '" is not a file in phar "' . $this->_basename . '"';
+        }
+        foreach (self::$_manifest[$this->_archiveName] as $file => $info) {
+            if (empty($std) ||
+                  //$std is a directory
+                  strncmp($std.'/', $path, strlen($std)+1) == 0) {
+                $this->currentFilename = $this->internalFileLength = $this->currentStat = null;
+                return true;
+            }
+        }
+        return 'Error: "' . $path . '" not found in phar "' . $this->_basename . '"';
+    }
+
+    private function _setCurrentFile($path)
+    {
+        $this->currentStat = array(
+            2 => 0100444, // file mode, readable by all, writeable by none
+            4 => 0, // uid
+            5 => 0, // gid
+            7 => self::$_manifest[$this->_archiveName][$path][0], // size
+            9 => self::$_manifest[$this->_archiveName][$path][1], // creation time
+            );
+        $this->currentFilename = $path;
+        $this->internalFileLength = self::$_manifest[$this->_archiveName][$path][2];
+        // seek to offset of file header within the .phar
+        if (is_resource(@$this->fp)) {
+            fseek($this->fp, self::$_fileStart[$this->_archiveName] + self::$_manifest[$this->_archiveName][$path][7]);
+        }
+    }
+
+    private static function _fileExists($archive, $path)
+    {
+        return isset(self::$_manifest[$archive]) &&
+            isset(self::$_manifest[$archive][$path]);
+    }
+
+    private static function _filesize($archive, $path)
+    {
+        return self::$_manifest[$archive][$path][0];
+    }
+
+    /**
+     * Seek to a file within the master archive, and extract its contents
+     * @param string
+     * @return array|string an array containing an error message string is returned
+     *                      upon error, otherwise the file contents are returned
+     */
+    public function extractFile($path)
+    {
+        $this->fp = @fopen($this->_archiveName, "rb");
+        if (!$this->fp) {
+            return array('Error: cannot open phar "' . $this->_archiveName . '"');
+        }
+        if (($e = $this->selectFile($path, false)) === true) {
+            $data = '';
+            $count = $this->internalFileLength;
+            while ($count) {
+                if ($count < 8192) {
+                    $data .= @fread($this->fp, $count);
+                    $count = 0;
+                } else {
+                    $count -= 8192;
+                    $data .= @fread($this->fp, 8192);
+                }
+            }
+            @fclose($this->fp);
+            if (self::$_manifest[$this->_archiveName][$path][4] & self::GZ) {
+                $data = gzinflate($data);
+            } elseif (self::$_manifest[$this->_archiveName][$path][4] & self::BZ2) {
+                $data = bzdecompress($data);
+            }
+            if (!isset(self::$_manifest[$this->_archiveName][$path]['ok'])) {
+                if (strlen($data) != $this->currentStat[7]) {
+                    return array("Not valid internal .phar file (size error {$size} != " .
+                        $this->currentStat[7] . ")");
+                }
+                if (self::$_manifest[$this->_archiveName][$path][3] != sprintf("%u", crc32($data))) {
+                    return array("Not valid internal .phar file (checksum error)");
+                }
+                self::$_manifest[$this->_archiveName][$path]['ok'] = true;
+            }
+            return $data;
+        } else {
+            @fclose($this->fp);
+            return array($e);
+        }
+    }
+
+    /**
+     * Parse urls like phar:///fullpath/to/my.phar/file.txt
+     *
+     * @param string $file
+     * @return false|array
+     */
+    static protected function parseUrl($file)
+    {
+        if (substr($file, 0, 7) != 'phar://') {
+            return false;
+        }
+        $file = substr($file, 7);
+    
+        $ret = array('scheme' => 'phar');
+        $pos_p = strpos($file, '.phar.php');
+        $pos_z = strpos($file, '.phar.gz');
+        $pos_b = strpos($file, '.phar.bz2');
+        if ($pos_p) {
+            if ($pos_z) {
+                return false;
+            }
+            $ret['host'] = substr($file, 0, $pos_p + strlen('.phar.php'));
+            $ret['path'] = substr($file, strlen($ret['host']));
+        } elseif ($pos_z) {
+            $ret['host'] = substr($file, 0, $pos_z + strlen('.phar.gz'));
+            $ret['path'] = substr($file, strlen($ret['host']));
+        } elseif ($pos_b) {
+            $ret['host'] = substr($file, 0, $pos_z + strlen('.phar.bz2'));
+            $ret['path'] = substr($file, strlen($ret['host']));
+        } elseif (($pos_p = strpos($file, ".phar")) !== false) {
+            $ret['host'] = substr($file, 0, $pos_p + strlen('.phar'));
+            $ret['path'] = substr($file, strlen($ret['host']));
+        } else {
+            return false;
+        }
+        if (!$ret['path']) {
+            $ret['path'] = '/';
+        }
+        return $ret;
+    }
+    
+    /**
+     * Locate the .phar archive in the include_path and detect the file to open within
+     * the archive.
+     *
+     * Possible parameters are phar://pharname.phar/filename_within_phar.ext
+     * @param string a file within the archive
+     * @return string the filename within the .phar to retrieve
+     */
+    public function initializeStream($file)
+    {
+        $file = self::processFile($file);
+        $info = @parse_url($file);
+        if (!$info) {
+            $info = self::parseUrl($file);
+        }
+        if (!$info) {
+            return false;
+        }
+        if (!isset($info['host'])) {
+            // malformed internal file
+            return false;
+        }
+        if (!isset(self::$_pharFiles[$info['host']]) &&
+              !isset(self::$_pharMapping[$info['host']])) {
+            try {
+                self::loadPhar($info['host']);
+                // use alias from here out
+                $info['host'] = self::$_pharFiles[$info['host']];
+            } catch (Exception $e) {
+                return false;
+            }
+        }
+        if (!isset($info['path'])) {
+            return false;
+        } elseif (strlen($info['path']) > 1) {
+            $info['path'] = substr($info['path'], 1);
+        }
+        if (isset(self::$_pharMapping[$info['host']])) {
+            $this->_basename = $info['host'];
+            $this->_archiveName = self::$_pharMapping[$info['host']][0];
+            $this->_compressed = self::$_pharMapping[$info['host']][1];
+        } elseif (isset(self::$_pharFiles[$info['host']])) {
+            $this->_archiveName = $info['host'];
+            $this->_basename = self::$_pharFiles[$info['host']];
+            $this->_compressed = self::$_pharMapping[$this->_basename][1];
+        }
+        $file = $info['path'];
+        return $file;
+    }
+
+    /**
+     * Open the requested file - PHP streams API
+     *
+     * @param string $file String provided by the Stream wrapper
+     * @access private
+     */
+    public function stream_open($file)
+    {
+        return $this->_streamOpen($file);
+    }
+
+    /**
+     * @param string filename to opne, or directory name
+     * @param bool if true, a directory will be matched, otherwise only files
+     *             will be matched
+     * @uses trigger_error()
+     * @return bool success of opening
+     * @access private
+     */
+    private function _streamOpen($file, $searchForDir = false)
+    {
+        $path = $this->initializeStream($file);
+        if (!$path) {
+            trigger_error('Error: Unknown phar in "' . $file . '"', E_USER_ERROR);
+        }
+        if (is_array($this->file = $this->extractFile($path))) {
+            trigger_error($this->file[0], E_USER_ERROR);
+            return false;
+        }
+        if ($path != $this->currentFilename) {
+            if (!$searchForDir) {
+                trigger_error("Cannot open '$file', is a directory", E_USER_ERROR);
+                return false;
+            } else {
+                $this->file = '';
+                return true;
+            }
+        }
+
+        if (!is_null($this->file) && $this->file !== false) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+    
+    /**
+     * Read the data - PHP streams API
+     *
+     * @param int
+     * @access private
+     */
+    public function stream_read($count)
+    {
+        $ret = substr($this->file, $this->position, $count);
+        $this->position += strlen($ret);
+        return $ret;
+    }
+    
+    /**
+     * Whether we've hit the end of the file - PHP streams API
+     * @access private
+     */
+    function stream_eof()
+    {
+        return $this->position >= $this->currentStat[7];
+    }
+    
+    /**
+     * For seeking the stream - PHP streams API
+     * @param int
+     * @param SEEK_SET|SEEK_CUR|SEEK_END
+     * @access private
+     */
+    public function stream_seek($pos, $whence)
+    {
+        switch ($whence) {
+            case SEEK_SET:
+                if ($pos < 0) {
+                    return false;
+                }
+                $this->position = $pos;
+                break;
+            case SEEK_CUR:
+                if ($pos + $this->currentStat[7] < 0) {
+                    return false;
+                }
+                $this->position += $pos;
+                break;
+            case SEEK_END:
+                if ($pos + $this->currentStat[7] < 0) {
+                    return false;
+                }
+                $this->position = $pos + $this->currentStat[7];
+            default:
+                return false;
+        }
+        return true;
+    }
+    
+    /**
+     * The current position in the stream - PHP streams API
+     * @access private
+     */
+    public function stream_tell()
+    {
+        return $this->position;
+    }
+
+    /**
+     * The result of an fstat call, returns mod time from creation, and file size -
+     * PHP streams API
+     * @uses _stream_stat()
+     * @access private
+     */
+    public function stream_stat()
+    {
+        return $this->_stream_stat();
+    }
+
+    /**
+     * Retrieve statistics on a file or directory within the .phar
+     * @param string file/directory to stat
+     * @access private
+     */
+    public function _stream_stat($file = null)
+    {
+        $std = $file ? self::processFile($file) : $this->currentFilename;
+        if ($file) {
+            if (isset(self::$_manifest[$this->_archiveName][$file])) {
+                $this->_setCurrentFile($file);
+                $isdir = false;
+            } else {
+                do {
+                    $isdir = false;
+                    if ($file == '/') {
+                        break;
+                    }
+                    foreach (self::$_manifest[$this->_archiveName] as $path => $info) {
+                        if (strpos($path, $file) === 0) {
+                            if (strlen($path) > strlen($file) &&
+                                  $path[strlen($file)] == '/') {
+                                break 2;
+                            }
+                        }
+                    }
+                    // no files exist and no directories match this string
+                    return false;
+                } while (false);
+                $isdir = true;
+            }
+        } else {
+            $isdir = false; // open streams must be files
+        }
+        $mode = $isdir ? 0040444 : 0100444;
+        // 040000 = dir, 010000 = file
+        // everything is readable, nothing is writeable
+        return array(
+           0, 0, $mode, 0, 0, 0, 0, 0, 0, 0, 0, 0, // non-associative indices
+           'dev' => 0, 'ino' => 0,
+           'mode' => $mode,
+           'nlink' => 0, 'uid' => 0, 'gid' => 0, 'rdev' => 0, 'blksize' => 0, 'blocks' => 0,
+           'size' => $this->currentStat[7],
+           'atime' => $this->currentStat[9],
+           'mtime' => $this->currentStat[9],
+           'ctime' => $this->currentStat[9],
+           );
+    }
+
+    /**
+     * Stat a closed file or directory - PHP streams API
+     * @param string
+     * @param int
+     * @access private
+     */
+    public function url_stat($url, $flags)
+    {
+        $path = $this->initializeStream($url);
+        return $this->_stream_stat($path);
+    }
+
+    /**
+     * Open a directory in the .phar for reading - PHP streams API
+     * @param string directory name
+     * @access private
+     */
+    public function dir_opendir($path)
+    {
+        $info = @parse_url($path);
+        if (!$info) {
+            $info = self::parseUrl($path);
+            if (!$info) {
+                trigger_error('Error: "' . $path . '" is a file, and cannot be opened with opendir',
+                    E_USER_ERROR);
+                return false;
+            }
+        }
+        $path = !empty($info['path']) ?
+            $info['host'] . $info['path'] : $info['host'] . '/';
+        $path = $this->initializeStream('phar://' . $path);
+        if (isset(self::$_manifest[$this->_archiveName][$path])) {
+            trigger_error('Error: "' . $path . '" is a file, and cannot be opened with opendir',
+                E_USER_ERROR);
+            return false;
+        }
+        if ($path == false) {
+            trigger_error('Error: Unknown phar in "' . $file . '"', E_USER_ERROR);
+            return false;
+        }
+        $this->fp = @fopen($this->_archiveName, "rb");
+        if (!$this->fp) {
+            trigger_error('Error: cannot open phar "' . $this->_archiveName . '"');
+            return false;
+        }
+        $this->_dirFiles = array();
+        foreach (self::$_manifest[$this->_archiveName] as $file => $info) {
+            if ($path == '/') {
+                if (strpos($file, '/')) {
+                    $a = explode('/', $file);
+                    $this->_dirFiles[array_shift($a)] = true;
+                } else {
+                    $this->_dirFiles[$file] = true;
+                }
+            } elseif (strpos($file, $path) === 0) {
+                $fname = substr($file, strlen($path) + 1);
+                if (strpos($fname, '/')) {
+                    // this is a directory
+                    $a = explode('/', $fname);
+                    $this->_dirFiles[array_shift($a)] = true;
+                } elseif ($file[strlen($path)] == '/') {
+                    // this is a file
+                    $this->_dirFiles[$fname] = true;
+                }
+            }
+        }
+        @fclose($this->fp);
+        if (!count($this->_dirFiles)) {
+            return false;
+        }
+        @uksort($this->_dirFiles, 'strnatcmp');
+        return true;
+    }
+
+    /**
+     * Read the next directory entry - PHP streams API
+     * @access private
+     */
+    public function dir_readdir()
+    {
+        $ret = key($this->_dirFiles);
+        @next($this->_dirFiles);
+        if (!$ret) {
+            return false;
+        }
+        return $ret;
+    }
+
+    /**
+     * Close a directory handle opened with opendir() - PHP streams API
+     * @access private
+     */
+    public function dir_closedir()
+    {
+        $this->_dirFiles = array();
+        reset($this->_dirFiles);
+        return true;
+    }
+
+    /**
+     * Rewind to the first directory entry - PHP streams API
+     * @access private
+     */
+    public function dir_rewinddir()
+    {
+        reset($this->_dirFiles);
+        return true;
+    }
+
+    /**
+     * API version of this class
+     * @return string
+     */
+    public final function APIVersion()
+    {
+        return '1.1.0';
+    }
+
+    /**
+     * Retrieve Phar-specific metadata for a Phar archive
+     *
+     * @param string $phar full path to Phar archive, or alias
+     * @return null|mixed The value that was serialized for the Phar
+     *                    archive's metadata
+     * @throws Exception
+     */
+    public static function getPharMetadata($phar)
+    {
+        if (isset(self::$_pharFiles[$phar])) {
+            $phar = self::$_pharFiles[$phar];
+        }
+        if (!isset(self::$_pharMapping[$phar])) {
+            throw new Exception('Unknown Phar archive: "' . $phar . '"');
+        }
+        return self::$_pharMapping[$phar][4];
+    }
+
+    /**
+     * Retrieve File-specific metadata for a Phar archive file
+     *
+     * @param string $phar full path to Phar archive, or alias
+     * @param string $file relative path to file within Phar archive
+     * @return null|mixed The value that was serialized for the Phar
+     *                    archive's metadata
+     * @throws Exception
+     */
+    public static function getFileMetadata($phar, $file)
+    {
+        if (!isset(self::$_pharFiles[$phar])) {
+            if (!isset(self::$_pharMapping[$phar])) {
+                throw new Exception('Unknown Phar archive: "' . $phar . '"');
+            }
+            $phar = self::$_pharMapping[$phar][0];
+        }
+        if (!isset(self::$_manifest[$phar])) {
+            throw new Exception('Unknown Phar: "' . $phar . '"');
+        }
+        $file = self::processFile($file);
+        if (!isset(self::$_manifest[$phar][$file])) {
+            throw new Exception('Unknown file "' . $file . '" within Phar "'. $phar . '"');
+        }
+        return self::$_manifest[$phar][$file][6];
+    }
+
+    /**
+     * @return list of supported signature algorithmns.
+     */
+    public static function getsupportedsignatures()
+    {
+        $ret = array('MD5', 'SHA-1');
+        if (extension_loaded('hash')) {
+            $ret[] = 'SHA-256';
+            $ret[] = 'SHA-512';
+        }
+        return $ret;
+    }
+}
+?><?php
+}
+if (!in_array('phar', stream_get_wrappers())) {
+       stream_wrapper_register('phar', 'PHP_Archive');
+}
+if (!class_exists('Phar',0)) {
+       include 'phar://'.__FILE__.'/phar.inc';
+}
+?><?php
+
+/** @file phar.php
+ * @ingroup Phar
+ * @brief class CLICommand
+ * @author  Marcus Boerger
+ * @date    2007 - 2007
+ *
+ * Phar Command
+ */
+
+if (!extension_loaded('phar'))
+{
+       if (!class_exists('PHP_Archive', 0))
+       {
+           echo "Neither Extension Phar nor class PHP_Archive are available.\n";
+       exit(1);
+    }
+    if (!in_array('phar', stream_get_wrappers()))
+    {
+           stream_wrapper_register('phar', 'PHP_Archive');
+    }
+    if (!class_exists('Phar',0)) {
+           require 'phar://'.__FILE__.'/phar.inc';
+    }
+}
+
+foreach(array("SPL", "Reflection") as $ext)
+{
+    if (!extension_loaded($ext))
+    {
+        echo "$argv[0] requires PHP extension $ext.\n";
+        exit(1);
+    }
+}
+
+function command_include($file)
+{
+    $file = 'phar://' . __FILE__ . '/' . $file;
+    if (file_exists($file)) {
+        include($file);
+    }
+}
+
+function command_autoload($classname)
+{
+    command_include(strtolower($classname) . '.inc');
+}
+
+Phar::mapPhar();
+
+spl_autoload_register('command_autoload');
+
+new PharCommand($argc, $argv);
+
+__HALT_COMPILER(); ?>\r
+6\ 1\0\0\ 6\0\0\0\11\0\0\0\ 1\0\v\0\0\0pharcommand\0\0\0\0\ e\0\0\0clicommand.inc>,\0\0\89í[F¤
+\0\0+ó©P¶\11\0\0\0\0\0\0\1a\0\0\0directorygraphiterator.incô\ 2\0\0\89í[Fu\ 1\0\0ôÎr\86\11\0\0\0\0\0\0\19\0\0\0directorytreeiterator.inc%\ 5\0\0\89í[F]\ 2\0\0\17\86p\8b\11\0\0\0\0\0\0\19\0\0\0invertedregexiterator.incÖ\ 1\0\0\89í[FÕ\0\0\0ICÖC¶\11\0\0\0\0\0\0\ f\0\0\0pharcommand.incy£\0\0\89í[FÍ\1f\0\0\15\ fä\ 6\11\0\0\0\0\0\0\b\0\0\0phar.inc\16\ 3\0\0\89í[F)\ 1\0\0ìk\ 6\11\0\0\0\0\0\0Å\1akoÛFò»\7fÅZÐ\95T,É\96] wv¤^.w\ 5
+$m\90¤\9f\14A ©¥Ä\v\96¤íÀõ\7fïÌ>È]î\92\94\1d\81Ä\12wvÞ;¯Õë\1f\ f»ÃÉÉù«WäïQ\9cP\12&q\98í÷Aº\99ÆixBà}\9cnYV\1eÈ\87]Àø\8b[\16Ó\b \83<'oßýüVÀó¥ ,v\19#ä}ÀÂ2'ÿÈ(ÛR±k\13\14\94Àsyqñ\ 3\99ð?ð\1e\97\101©±\9cK~Zè\12òæ6/X\10\16ä6È\81ã,Í3ä\  ñþ\90Ð=M\8b \88³´\8f«;Êr\0#³é\ 5'\1d\96x\8f'Èý\81e\ 5\r\vº!Ã\80\eÇË;ëe¸ßädN\ 2Æ\82oþȵ§k¹øv0\96ùzT¦!ÊGÖkT@Áʰð9Kc\ 1)X\19q`Á:>Ãb\17ç\93\ 5Â\ 1JM\ 4sñN.ÞY\8bR\94\9c&Ñõõ\96\16R;¹Ï×G\16¼d¾\82\7fö\9fáU\ 5^ÁÇ\11\11ü\93×är¤±\8c\8fØN\19Ë\98?ø%«l½\8dïh:&á\8e\86_Éð\119^^¬\9eÈ\8e&\87/é@cç\89Ð$§Hä4ÎsZø\9a<K.êr¶Z-=V¦ÞjÔIÿ·ôk\9aݧ\15\13\9e$<[=yÏà¥Ab¨ÐIÍ\ 3:m\87©'\87\ 4r7H\0\9b\1d\12Ô¶Es\84A\92¬Ë\9c²5ú\91/\\8b\83\8cI7Ú\e\13k\fÈf\8dw{`\ fÎ.¬D\ 1Èi®Þï0Êøgg°õµpÀ&«º7Ü-\87ñ
+ÔHæsâM<\17¨\ 2\873\90дÞ5Â=\97ä»ï\88¡.ÔÀ²F\rF·teH\ 3\90\95\86\9bV`d\83\98·\8b¦?\86\97z\83\8d%Æ/Rdä\10°`O\vÊÀËÐ\ 2$\8b4¿\93\9f\8eóºæãôBKü\86ÒÀ\11î\82Ä[¡J¤\9f eqª¹îÁ\81â1\91\91HÄ \ e\1e\9c+O¤\8f5çyÔuõ¨ìõä¡\1a\95Ê\94Æ\9e­0\9bÑNõÝ2\1a|µ1\99XÌoÖ¹æ:÷\1cGYA\1fág­H!ÐÑÿ\94\80\1f\8fH×ò\91fPQP&à½,\88\13Ý\9fóÿ\87%,Á\94û\1aÙ¶ùð(åw\87¨n
\95\165ÎÎZ\82\86C\18ÓE\84hÒÚ\1dÌ4\ e\ 4}8\88âA\19ãel`2g|\892pùp§û\19    r\19>\17\10\13Ò¨Í\8fµÀÍ}Q%hØ"\959Ò¢8\7f+½s£¼×zÙâ\f*5Mç\84T\ e«Å\8d\89\b²ÏÒÑó\8f¹\12Xr3\1a\19\10ÝÆ­6µYF+\15þD\96\17åÏXwjIIâͱ¬\ eëò3Íà+$ôá>ß6\8bÍèÀâ´\88üO\9fÿù¯\8f\1f\ 1)Âtbã2
+d\0N\1fâ\ 2ªÛ\rÅ"cD\1aØ\ 5e_C\8a\ fîñë\9d\8aÎ\11IË*\9c¿\1dꤧçCXðV7\1d\ 5\1a\96ÀKܯ\80­\88ÎhQ²ô\18{Ù¸Æum2¶Ù\13«}µ§¤_!Ò\vÏ\ ekA9ÿ©¼ý     ¾æ~Ý(ñv\87wO@üÀh\14?T-I^Þæ\96f\ 3W4\1e2x\9bÒ{ò\91F    åôÞ"N¿Â®\ 3'ØbÈS%Hê­E\15\9bØd\ 1<¿§Ð\rBÇ2â\ 1j_\9f¾Gû¤\96Ø\ e\82\8fM\16\88\0\99\12^Y*:=g·¢\8d¨8Aø0²ÀZâÕý.(P´&\eÃäL\89\8bèÎf-yl\88¶"\15³dÊÉÃ\1foíá\17Äß²S\91\9aÑC\12ÀQ\83Mc¬ÂÇbµ\85&OV é]\90\v\9c\8b\91-t»à
+\8fJ\ 5Á\92S\µ éFÄÅQ\18ú2?>îªÔ@³D="²óWh\151,\0µ^_\83^_\9d\vÅÿÉ\9c\7fb\7fª\ ehgôÔÛq×yl\9e<\89µêͫì\9d`/Lâ5|EÓ\vÅñNpìAÊ\85ÿ1_\8cºcºÖô¿(SÀ\86Æ\14\ 6Ã\1eFÔ&\0]ßfY¢"\7f\18áÿ_é·\16V|\ 4\1e\81¾\97\ 6ä>\9bD3\8b¡\97û\0Éñ\93SQ3v\8e\1fÞhíá\ 4q\92}\99\17ä\96\92 %\80\89n)\9b6\ 6\ e'\96L\8a¤\12é(\89\18à~èU[³¦ë\f°zí· 3^ÍÁ\17Ùòó\8f:Ìd¶B\10xuÈrß;\1f{2Ã\81ê伡/"kÉ®«ºÅ4y\1c\9cÇR´ß\14¿´WfNÜÎTüËoïÞ\1d\99\85u\ 3\81£ÐÐáu\ e\v\9dÆéZV\18\1c\9a\7f^\ 30\9e´h»ô\ 4.¬V:ÝñCU=C©^R5§\80ê\8cd)Åy\857\0½ü;\8bS\7f\80ùcÐI\v@\a\9eå¾­¶;B'\9b\98õ*d\18A(\87D\9d\1c\82bçË\92ÉP×0\9aÏçÜ¿Èï¿\93S\9c\95¯¡ÊÌ\v\10\ 1:\e|\17ç\82VÔ­°\8fЦÐ\1c\9b3$¦ôµÉhÎ\95Æ\91ö* :Zü\88w²(\91Kf¬°>\1d\92\9f\0èç4ÊüFµÈa\86\11/\9b>\82z> z´õ~Í´\1d~\1aî2¢é\82_>´êÂ<R¼Æ\9f½ ~@\vý.\82\93Y°/\16`N5Õî³Ñ\96\1aª\82 ¦ÂT÷¡\ 2Ï\80Ò±G-Ý*\80£¤
+G.\9b\8a£\eÈ\93ÏRO\98¹2\99;Yró\83·à­D\81\ 3\a_\bætI\ 3_[«\ 6\e\11ß§\ f\97þ0\99\89p¿ÆqBKá 
+V\1a\14¾G0;$3rF.áß÷ðﯽT®$\95äò¿%%?\ 3&üÔ_\9b`\95\ 5ÄÖ8Wð[H\ e>C\83Ç'\ f\ 4¼\83ÿE7     \88\88 p\90ÔíÝÀ \a\9dø\1dÞ¿\19\ 4ï3¶¹g\ 1´ÀXÓ"ÿð/?X\9e\8f\8dï>xð\7fø\e\99p ï/F7|éü\9cìã4Þ\97{\ 2®µ\95N\8b\ 3\95-àÝÕ(nµ.F\10\13\9dÔ\r¢\80·1ÈS\16P¾ÄE\1c$°b6\82æV¾OPgt\1fÄé\ 6\fx­k\19ÀA\19\13ü\7f
+ÂÁn&¨Æi½\9bH`ò%õrë$aÃTë\8aa[[#\1cõë\19ÍĽ\vûrÑ\rUÊF~äÜÊÒ;8\ 3È2Т\9fê&\e\93\ 2\13åÈ\18¼Á9\8cº*05«@8{°f¿Å\12ÕäØ\8d\e\1f\8c\ 1qZ6®\80Ú\abfµèÆ)/d\ 6|TGÈ \v÷\115\9cB7\9dN»q\81b/µ[\ f#*\8dÅ|³q\ f\ 6ç^\eKÀvëò\fì;5PÖ^\96\1fê\9aRZ\ 1\95\8aL\88\ ek%+9jã'±­ª­Ð aV¦öJ¯Î\13¼4¼°ûÙjºa"ä\ e\98\1d
\80|T`íl\19xpB\18kàS\9d±\0UóæÑ6\90\95ËHWÂH\88Óa)AùÊ´Ö\95\ 3èÅÅíö\80K40¸8&r9J\1düe2|Lò§\1c^\8f\91\9aã |WÜ3®Ü\9ea«ÌÕ\9bèç\11\15;\8e\ e\ 4*\92r¯æU\1fîªo%®¿¤À.J\ 2$_¦+\93´~=`\18\86\94Ò ÕMÊh¸¬$\8dUAW\92\96#        \ fýA\e\17^\90~óÆüNc¾À\16O\8cQ`¡bSÝ;@s\ fØXLïh\95æ§Í \87Å\19+S7g|´K\8c\ 1¶þÛ\8eû]\1cî\1aãíú.ˬ÷epá[:½CÆ\1a\ 1\88ycÖ{sõ\1e\ e\18)vAÊ{GãW\1eÓg]GÕ\12ñ\ fË\8b\95\1d%O«6´êW8°q9â¼}íú9È\98\84A\8aUºa>'÷\8d\85\1f¡³Fº0~E¤\ 4\\9879üíªoÞ/\9a¯/éPÞe\91×\92ù\ 5YfÜ\13ó\15?%Í\8cfg\81¯yÆ\8c\9f¢4¸nÜ\vr\190\b\eŹG\1fÎ]JæÔD*¨3\ 1nk¦\82F\9e\96U\93\9a\84^[BäE£ª\92Û6\9a\ 1øuåYó§-G
\9fM\v\8cúÐ3`ÄÃÍ\9d!\ f\8dåÌ\10Àä\14\91ñ¤¶\19Ûý\b¼\1dÉ\`\e\93&\8b«\9bÄ0:wt:ZKch¦W'\8f.k    èº_ź¸ËäZ\1câèeqÔ_Èt$ÜÎÛ7\93\8aVj·%Z\9b\ 3ªg\96\ 6nì-²\98\8d\86S\ 2Á\85Ö~\14¬¤-w!ÿ3\1eÄ@äøj\ 5\1f\11Ã\90\81\86skcV\9c\13]<¯ñ^'\90   Z»ïw\98&Hp\17ÄIp[ÿæ4otÛ­yÙ\8d½+\86Êpåy\8e³ö¬\90ª¢\8e:jp\8e\9d:CµªcÈc\v\93\99éèO' è\8f\8b\93?\0\85RÑNÂ0\14}fÉþá>ø \ 6\ 15¾L#â\98°8\90°½ø´ÔîÂ\9a`·´\9d\7f·ÝØDc°\ f»Ý=ç\9e\9eÓôz\90§¹mÙVïä\ 4n\97l\8d\900\81Teb»\12$O\99BAô_\97qj[ I\8c¯DVäàmÈK¾FYu\9f\ 5Ã%Ð5\91\12FµÂØ(ø;\85\8aG
+\95f\ 2`J\ 4-$Üe(V¸Ã\12¢\10ô:ï÷/àÔ\94K\ 3\94`8\ ft+T\84'D$0\9fÌ!`Ï\82\88­\81{M\84\0\86 \ 4"Ô¡@¥DAÆ×[\90iö&\9bì\f\7f¿¯($Ë8\9cuÏv&\ eå\aÜ(äÉ\1e\1ci/ß·ón[­eÁ©2\92qL3.\95(¨:>Ê\89\1a5\8cÖ\ 2\8f}m&ëê8ûC\86Úâø\ 6\rß%4Õ·SÓ+FI\99\13\81\ 2~\ e7\9e\eVéªs\80á8\ fÞS<\fã{?ðfé·ÓmWµÝ\81jóË\97ã¸Ã \88£Ç0Zø³ñÇ\1fpäNâ±\17ÅîÄ\ fF¥H-\96\97I\1c\82{}î"\8cL»}¥¿\9f¶õi^Éàæ\v\8dSÛnÚ@\10}\ 6\89\7f\98\a\ 4\b\17'!¡@\12T'\8db^*U²\163Ø+\19Û\9a]' &ÿÞYÛ\r\11­%Öx.gÎ\1c\1f\9f_fQÖ¨7ê'GGpµ\901Â\\12\ 6:¥µ&D©\91\ 4?te\124êÀ52     )Í3\18¯Ä2\8bQ\95Ñ\19I\@\10\v¥`´\ 1\982À¤\ 2(ËD®£\94\0î\ 4\ 5¹\82ï)R\88Un.4\ 2__z½¯Ð1·o&Q$½\a\97C\9e\16É\Ð\1c\1en\1fÀ\953\12´6é\93í\ 2\87ÈÁ\8eØ\86\14è\14BLÌ\ 3ÂÀ\eN&\10\92È"\19ìT\0#\83ú7ý'$%Ó\ 4N»§\15§\ 3j\0®4&s\ 5\8f\18äÜ÷´ÍìôúÓ¨×ÌRÃ4Q\9aò@Ã\82Ò%\bÈ\84\8eº\9c4S3Ab M\13Ú§\9cBùâ°(c.µE\9e\ 4Úðóý`\ 3h\15}6gͬ\1aca¢\1dg¿ÂÄk >ï\88\ eE\10±Ì\e\9eeÅÛ\92\ f:\97\83Ú\a*\1cçÇø\97?ðüë\89\1fÜ\8dKX»\rå\9fwS\1dg8p]\7fúÓ\9b>Nîo^>IO\87·þÍxê\ fo'î¨\0Ù\80möôÆî5Ï{ô¦&l\9fñùj\9cT¨~E¨sJ@G\bLÚt\0Ƹ4÷\8cp!W8\87gɲ¿ñ\8d*\ 5¯í+^µ[[¡\9bÆRp\ 1­\96\99Y[°\1f¬f|Ñ;\83f\fçÐÔ\91T\9d~\88z\84\99\8e,ÛÄ\8f\8fm(\9a«îîÅ^\9d\97ÏvRÇv§\1f      uÏ\16³l¸\84Ö\v´Àá\1f\94ã^ÍQmWañøÿÅê\14X¿;-»\10\13Ê«{\88\8cïëÔÓÄïÇz'ò \f     C¶©*t\96  \7f\8a ·_À\a\99"\8e­¦  ´\8dëÙüj+kµ\93)ñs\85ä\9b2_\10\89µU\9e\9f\93d_\14\88ö\ e²¢Y0½ìÿ\ 5\85PÍj\ 21\10>o ï0ÞªPÝz\11VÑÒ\9b\a¡ô\rbvv7 É2\99\14A|w\93u[ZÅu.\ 3óý&«MÛ´RH1\9bLà½2\a\ 4c¿\91\18\1a\8f\86\91\14;\9a\1a«¥\80È1¶&\17Zøl\14]/{2X\81>(ïaÛ\8b¿\92\8b¯4\15¸q\ 4°S¤\83\87\ f\87Tc\8f\95\8a\11âÌó|\ 1¯ÝJ@\aþXÂ\9dçì·ø£R0 \1en\14UÞ8\voÓ¼\8f\1ax à\91Ñ\96þ6ä$EÖõ#ä@\16Fÿð¢PZcË/ãH\8b\11Y\U°\9a\1f(¹dO\1c\96\91s\96â\9c~d³¾\0í=ýwÛ6\92?'\7f\ 5\92sK¹\91e;{½{\97Ôn\9dÔMó^\92æÅéõm\9d¬\97\96 \89g\8aÔ\92Tb·\9bÿýf\ 6\1f\ 4@\80¤$§»{ïü^\eI\ 4\ 6\83Á|af\0~óír¾¼{wÿ«¯î²¯ØwÓ$ål9\8f\8bq¾XÄÙd\94dcz\90d³"_-ÙkxF?\\16   \9f²q\1a\97%{úâùSÑ\9e\1eÅ«j\9e\17\8c½\ 4\92=Éy1ã¢×$®8\83¿\87\a\aÿÉöè\1fø\1d\1f!`VCÙ¿»¿Ï~ÿýw9\ 2>\95\ f\19¿®x6±F\95è\9b­¨\1fþ\88ÿ½\9d\844\87\87)/Y5çâ3Ì\8cåSú¾\94\93\93\93/GìyÅ>&iÊ.9[\95|¦E¾P\8f\19tåûã<+ó\94c·$cy1á\ 5«rVð
+\bô\813\811\1f¯*\ 1\9fMWÙ¸J ×Ha\17".\13D\91#èa\93Å2å\v\9eU1\82颸\a^\94Ð\8c\1d\8e\ e\88¬½èùû]\$¹\ 2ËÕe\9a\8c5Þ@ÇäbÆ«\8b³×\ f©YËóÁNz8d;q1»H²é.5\17°ñ\ fh´*2VVÅEÁ\97\ 6\11\8b yzÈ\1e°\87ðß¿Ã\7fÿµû\98:|R(}úô©\1fv\7f\12Í\905ðï+ö4MØ3^1õ\88é'ß-ã"^ &È\r\88\0ý\9d¦°\82Y¨ÑCÑèíG\9e\81FræL?®ç\8cÏ\8119\13s\aæ\12?\8edÛ}ú×7/IÕôᶤ\95\9fq*ð©\83Ð%ò\9bAhdæ\v\18¾tÉLL\v\ fVÈ£¥úUýK¢XÏ*\a6N²\92Å dJ\ 4µüùWI\13÷ã<\19ÏñÑ/ôA\rÉPÖçyɳQ¨'\8eRÝ,9Ñ\9f>\80\ 6À\1f\87¬\òq2Å\89¢*\ 4\98\17W,ÏÜ\15\eWYþ1³\16+H¢\81ÀuX\8fì.Ø\8e\8e`&E|3ÐÏð/\8a#vtì{BO\ 1$=\8fâ4\89ËhØlñ!N©Å«\9f_¼ð<\ 6\1e\12\0¾!\bÇ {\8aüC2A\ 5Æè'\96Å\vΦ fô:!\89F\91\ 5\86\1d\8dû¡\r\8cÓÙ\96\88ÏrÀ\e\8dȲà%i=ü­Hªùbä\ 3\94\8f«6\f©ÙA\84ÿà\18¯räM\ 5Ý\ 3\92ÚgyÆ£5Ú\83öÎEû\13ø´@\1e\ 2q¸a\ 2=\13B=\9f¨\ 1j·u\1dx¿u\0ñ)n¶Z\ 5\82\0Ëð
\ 5¤\8a¾\e\ 6\8bU    2\9a\8dÓ\15p×ë\1fOÞÀ\97\8a\17Y\9c²IRÀ\8csè@Ì\96L\81ûnv;XlÚkjZò¶\99\1c2<²Ø\99P\12Ò\8dв`L³\ 3çy¿å\90\fº\rÊ\v\ e®Áä\98\9d\11(å÷\94ó\9a\95²~²\11-&_\v\98/¿ÿ:\1aFå<>\14ßÏ~<9\8cÚÙ/é7ß\82ÏøõVÓ%\bÇæ
+Å`\f\14\96\88_k9B5\96dËUEëVv¬ÖUOÝ\9bm':I6\11¸¯.Ëq\91\86Ð\8f\16c\r[qMûá
+"×\86ëA+¢è\16¥(ã«Å%¸»h;An9\9f q-W\97J\8cI@r²ºKá:\93\94 J\80G\1d\13Yü1D\aù\88Q¤_¿\f¶'±À8/8xþÕ\ê¯AÉ\8b\ 4Ìàoà¦Á\86\89\1avé¥e¿     ¤y\f{\86­æ @\1c³\17ù\98ö\ 4¸"¯\7f|}qR\8cç      ìA\84ÏO´\1f\803XÀÎ¥¬ö\88óÍvî\84¬¿Qôç|ÅÆà\rÀF\88½\8b\ eÞE°Û\81\ f\87ð\ 1H\96âØ ²+\16[FlU"S ÖAß\f\90\ 3
\ eC\bªí'¸v<\93\98\b\84&9L Ë+Æ\8b\ 2pÉA\9c?b{lÓ:\86A\10\98\11B\80\r\9e\98\ 1\8cI.j   «\8fNeZæ,\9eÀö¨Ì\1782zD°Y\83Ñ;G)«Õ%t\83\86q¥ö±Æª\807_¢n\82µà\ 5P\ 5\,´$\8fÀß\ 6\89áà¯~,âå\12\ 4¬u\140\92\19\b_YÆÅÍ\88\9d\0bÓ$#ÒWÆ<h\17\vó ¬õ.\1f·÷B0[\87 @Ëx|\15ÏÄ\86\16\19\ e\97\1aÖ\9dgåªàÆ6\1dÝoÔ³°ÚmüÔ.üe?ÙÁ\89l%9¸DdÐ\85«\85Ä¡UëáÙ^ÿÑ&íM§\19£õ¸&Ǫ\89¼þ\ eû<ý\19\98g@û\7f\ 4wAzd2\88~K\93Ëhwר\9eà_½E9\a·þý¹r\11àÓì·è=69bѳ_A×\9bNïãþ@\92%\82i\aò©\vùËß\1e®\85\7f/p\7f\ 2Ã>Ü\fùK@\1eát@1°ßA/ì"þ\10')ôBÉyô\bTÂÙj¹Ì\vÐCgÉ,\8ba«ÉËÁîckÎIv!]2ð¼ö\1e\1f¸³¯¡µN~n£\rN\1cö'¼\ 1\18~\ e\92Ú\1eöëÃ\870l;Úkb\82 \15&øÙO6k\8flò2\b\ 3\8fÇó\81±\95\ 6\95º\93\eÚ\0\8c§³\ 6>+|(8\17tn\95¯Pß\ e¨Ï®³ö\ 5ÿÛ*A=MM\97¹±©G(»ìÞÑ\11\9b\82½àNÇ\9c\1c¹8õtLÝ\8eVO$z=ìßÿ^\83rç¡ sN \91\888ÝÇ­\8dÎ#\ 5\9b¨®G²{}ºÛü$C \ 4l½ \11\10à4\9b\94¿\80\86\8dÎDl\ 6\1f3ýÜ\b\1cý\ 2\e\19°\85±
+âp°Cä¡Å`¿ñI\ 6\ e(hm\7fÐHE~æñ\rà4¾\12¡7õ-ÐX@ÄGØØ\86¯\ 3A\8bä\1a\ 3ø~¸bè\93dQe¢w\ 3ö3\9b\r¥u!Ð
+\88ý\a®3<\8f\0\25[Sx\96\80U\r\91'\83Î\ 3=ç¡\9aQ(ZHÃ\9bí÷à{ʳ\81ê·Ë\80\97õ\16\1eÃ\97\18«\ 4»(4uá®ÿ\89
+ßQ<Îh\13\K\80\a?\9f&´ú"\8a2d\91\92\11rOÁ]EËHÑ\ 4rÃü\84\97\7f:\1aÙpÖ\1c\f4
+ d\18pʦÉlU\bß\e\12{ÿ1¬ÕGB Ô\9fÔ\ f2\17~p9Ë\9a'6R\11Îöµo\92z\80 \86\84í\90Æt\19\05\r5ÂõÅx\17*\eõ\15ööìË/Ù=\9cÇ\ 5¿\ 6wµ¤¶Mí>%¿ø\88\\1a[\8b(Ý\.Ó¤\1aÜ\7f\97Ý\1f²¿¶lEþºKº\eæêUu°½\18Ïyé\1d\a¬ïì\82\1a\ eî\ fÿ\ 2\9b¶sö®zÿ`pþ\17üwô\15\8e\ eþößÃÀò\93\1c~\ 4Íww\86\80$¢0Ô\ 36¦Ü\98ºjy~ø¾\89\16þ]\ 2\9a\8f\r\7fÃÙÜKÊ\92W\ 31N\ 3\8d;;\8b\12\16\8bÝ\7f\8d$U\9eº¹Ù\0Y0æfî\bq÷CPG°*6bwÈ\ 2ÕlÑ\18ö\ eØïé£G\0"\19ó\ 1"áXÍ;\9f\18GÅèïGÛ6\7f·\16r\b\84$ÉM\1fA}RâCc\98Ò\80ó\15¬»¹òBç\ 2¤º]{¡Ø\8bd"=\rI¿\16\9e¼FØ"×"þ\ fÖ8\bMçUhSÔ[õHBuê\1e¹\9cþÕò\ 2°½á{Â\aMÊÿ\8eÓd\82_~\90\1a߯¥LÖ»ÿZ\85nKFaéyüAn\8fõÆ\82E#\9c
+\9a\16ú\80òS\7fÁÝ\ 3
+WDß`\1f\84R´ÛÂ\95\88ÓvܧW7È~¤¤q!õô\gê\8d@FÚFÆs\8c´Ûý\ 2\8e\94c}\99à\13"Y\92ÕápàÅ|Ù\92\81#6V½Ç\16;ÃÎ7/\162¹ÝÂĪ7~1ú4\1c43éGx\12cËô\ 4",v\8e5±j\b ØDsz¦*\ 1Dûµ\ 4Ak\9e6IÀ@£g¿D8\87\ 4Ä'\1dMã!D\ 4ñÆO\ 3\rÖkÏ,\ 1ù9\8b/Eb\ 3\97S¬m\84cF6\9f\v\86¶¾*\86W\83\19BÁÆd\97O¯Ç\D¹wx«\98Ö\r\ 4è .¸¦\ 6:\8f\0\1f6\ 2@{ǰ\1d}\89ñ°\19\1fìÂO÷}\12¹©ð­\8a´]ö\88S Õ^\9a\5Äîé\9cÃÖ£2\9tsÔ\18\18\14b\93ÔK*\99x\ 5wfJ;\r\ 5\8bö\ 32`è\8eszýH}ü\ 6C\96ÇÚí\95Ú\96Ô\95r\aâb\9fØ\1e\15ÛcÝÒ3s¡P5ä}\13t\9b\9a@   R$\11k&\a7+eBrûÖ̰í)¬×\92>\85z\9bðÉA#IÑ\b\18§)qaQÞN¥»,\85\95*±ÅVëx\13.\85We\93¸ùåÿ`À\13í;q¬ª\80\ 2?\ 2CÑko4\96¤WÖVp\12\e\85Æ`\1d\92ï~V\85òá\8fÐ(\94\j×'§\94\7fB\15ÐSÐ4ß\fpAi\84Ý\80hé>"É\ 5º\ 6\7fÍ©Wç¢\ 3\19²\1c\0\14´M\1f\93\ 6\8c«Å\90\e0¦â\a\fdC«\bä.ÆdÌ,Ép=n×y\92E&íôöV[¬%y"¦Ùâ½\90ïSû=LD,\82®\92å±÷qt4:\ 2\13\94gg"Ýk+iµ¹÷.ÆnsÞõ\a\91¢\12ÆÅ\11Úq\f\9bG\11ÚyäÝå÷M^8øbÆÂ³        §Íê\1ai\ 5\17*6
+\81íèzàëØøÅ\89\1eÜÒîb¼\98`\11áÅR\85B\réx^3\1c[Ö¡Ò\0ï\9d° ¯k\17âKLÉb/|&¶YIFÛÔ×\86\8dêÖ8&\82\83\80å¾ÿ\1aúö X\¤\ 6\11Ú\9c¹$½od\98÷J&2\82\14«Íìt æ5/96\ 38\r(2í&+\84iW\ 1{)4«F~n\7f\92\14åÈ×ýmÎÆ\ 5V\81\9d\947V1É×§0\19'0\89»U\1f8Â~\99\ 3\19ØÞÒð$rìºo\ 4\82ê\98Ϻü\82rîã\17Z\85¸\8eh Âj\14rÊ%£\1c\8eJéXÆ«$\8b\10×þÉZ¬¢pk°\8aJ\1e      uU\97gFñø\að\ 3\96å5îìeä"òé*\91@\89(câ+Ó¤¼/þéÚ\14»?5¢Ô¯jEù_æi¥³3Øêpè<¥ü°\1eIÿ~\92\81³ ËrÌÜ0\15\859#ö|Êö\12äêDÔt\10ÓüôêÅ\9f\8d\ e\14Í\94\ 5\1c\7fæ+¦\8a\v.%\ 3\89\8e\15\14\bú\1aA\8b>\ 4YFYj\80ÀÜ\ 1`¯~zk\ 3tòçú\8bo\85ú'§\1a|S¬².\9e~]ûá\81\92f\8a\12È\9aÇ¥ÝÑåâ:þVrðô®EEÅ"\86]\12\15U\10\8d>r¢É$Ï\1cî÷U¾\9b³hp¿HâR\19ù@Ä«@å\0Üô¦iÙ,où)ª&í\1eK\15[\ 27\95\18\1c\98°KôK\12èSQ+\av0"f!&c\14ã8û\ 5<\15ð³·ÁH%¦kh\92-T¦®\81\93!àTì\8crÅv°ðeïX\88|\8cYj\94\#°¿£TµÛxêkLe\97\1eÈs_cªúð4N|\8d© ÏÓ8õ6¦\9cP³ñÒ×\98Ì\9f\arék\9cd\1f\ 4ÚNãk\7fcÔMMÈFÛº1-3´Ô\eEEù!;\18Ê5Ûu;ì\1d\83\81(ª'«é\94£w2p+_dN\ 5çØ`7ã¹ \98×ùÛ\19\ 3R\94\18ó\19h«ÑxI\90\9eô;\1a\9f(rBtj8\95\7f\1dÓ¤\1eR²5ú·{\8d´\8b\ 1mtÄì^ªÂ\0¾Ñ.\95=`\87\1eD\80áïÀ\9f\80pÿ\e<\ 4\90\1c\f\95å\8b\8c\f\12©\88wÙ·Çà/Ô]=S\97ÔòN^\ fÖH5\19\r>µ=\14¹0]\89"#ó¢^\8e\10\915s²úä]ö®\92\ få\83\vUq§;Û³|ü.\13\b\18ôñQ\86ú\1e\881Â辫T¡»\ e,\8d..~xþâôâb\14í«\1a¼èñ¦\ 4\89¾=îf§\83á¡d¦\16^²XÉe£\a\ 1&j\80\91rÇ«3\90\0\90\ 37D\1cÚ
+9\1dC"Õ\888Ûs@e%\94ÄÙ2Å4\10î^\1aÒèÔ5ÝKJÉNB'5óÚB= wq2\11áó¡ÔºC©É\86Re\ fk58\14\18\r¥\8bçh\133zå!\8a®f\12z\12³á\89W\ 3u!·\ 5b6\89Ýr° r¼cp\9fbö!Û;üZ0¡s¼\94\8e9¤é\9dO&2Í!¦u Ýsê8ì\10*1?\98\8f\86®)½áxà?SbQ\8d¶+\87k\1dÓG@\15ò0\rßX[>\7f\14\9b\13\ 3Q?'KOpD
+\94
+g\9d¤$\ få³_\a\1e\14%\bà\18Ðð\r\1d{\8fúä×ç¯\1fö\1cx§ñ*­\82°ÁÝu ÷\0ìð.¹bÞâD¡\82T\rã\89\8a\9bÉ\1e~\8f\1aùÒr5Ôs0\19Õà`£Ó\95\93\89»\159\99LêZߨ
+õ»     [ß¶\ 4·\16±qÌ\8aÎ\13\831ÄÈC5/òÕL×Ýa%?<\ 5%¬kÆiÐ$+yQ\89\10K¥R£Á\8d\8d\88eR\e\93\â£\ e\99\8al\84\e\ 1U\87\97v\17©\97ø¦çÑÖQ;Òò°-~Ãí.ìzßà\97ç4ý¼è\18]z¶\ 4äyö\81c­«ÕßØÄº \fc$\8dÔ\99\8e*ÉD\fc.ÍD]¡\1c_±|àt#V  Þq@\æyÊãL\80Èråøÿ2\17¥\94¸A-ð\84s\85'\ 3Ô1\r«ò®í\+\18\eZ×þæ°I\87#i\82ê        ê_4¾²8Ö·\9b\95\ñå\97`äÞ\16&\9c
+Öà7à\90\90U·ª\84¼Ê¿1#õ¯BÖ»«Ý\811\99Ú«¼áãUQ\82d|¯XU±\8bBëqGGÕ¾î\aÍ\ 2\e\19"sÓ}A¸
+ªÁ°\ 4I­SØ=\92°Õ*¶\81÷Ê\85\1aF\ 3ð\8eÔL\rj\a\bá£ûC\ 5\v\1e\ f\88âõ\8beu#\1d=*^¤d1æíÞð8}\1d\ 1ÖY\v®s~\ f¹Ä}8\ 3p#hg«K\ 4\86\87^\a»C1¼Á(\ 6;{ýhÿ7#«¹ä}²\9a\ 6\ e\9cò\8a\12\9b²¬&\17!8\16\11rÑçInZÔòÙ®¸\8eØ´\9a+:r\15ëSµí\96α2a\v\13Pñuü\84:\88o2#n\17\ 49ýDÞTõ\13ß(ì\1eê@óÑ\1dôìð\V.ëB|õƺ\7fm\aDþ°¶\ 5åxÎ\8dóù>´\95\1c¦@\88\87×\1e\10YZe"¤â%}\8fÔ=\16i<æ\83\bÜý!f\8a\15h\83Y)\99?\10#ïí±cv\80\86\0¤Ö8{!Ñ\ 1\0»ÆÑ\8b\86VÓCË=±\9aÅÒÚ
+S\1c\85,\91\9e\v\f¨:\1f\19\9b\aÚåܹ#¬\ eF\17\fåÇÇó\9cÝ\17½h¯oû\96çâÉ{\7f¨\89Ôb\8d\91ÚYh\eu[{        \85\ 5yÈÊ\vá\93?bC\11\18úVv\15Þ\8cjßËf\88ûÁ\ 6
+ºêî\14WÕuQý\82½³\14N\9aë\ 3ÊKF.¨2agjIb+.Àò\19\8a\9c+Q\92Ó¦\9di¿ tmPÜéj\ f§¶9\8dË_H?L<\r\ 3\1a\ 5IgIxô¡6Ý»
+\87×p¶ì\a5e4£x-M.\12Áb\9bdÎJ\ 2\94YL\1f@J7j\80:¹Ù\9eÇi\92zÐN\87¡À|(1qNÈ5\94ªÚ\10õI,(§­% ÿ\7fÌ\11\9d \9axzpÚT¤iz\ 1\eÉâ\ 2\89?\90K åNÜÌÔÜ ô.ÅÀê\ 1W°*P]ÚE{¨\17ªQ°\1eã\17Ì â\ 5Tx,­Õ\90»\83\aË,pP¦Ì\ fzIN\9dÅ\16õ\ 4]\93Ö\95Z-\13¯+\bÒºQw¹@Û\94\eÕ\ 2?$ºN`U¤QGh§-OÛ5ã7«Ì;YÌ\17\9b\91ߦfî\93%öN:\bÖ®t@1Ó*ÿmÁµjj\1e\86\ fdFw\87\8db\1c©³¨\83$°6iî\r3\e°\99 *±x\ 5\18\17{«Ú\ 4Å\8b\f\90YñDâP\e8\1cEV²lVð\84\0\82\92\88\85F»%\89ì"\93\96ÈnZ\9dhÁL2öó\9b\17\95õ¯èi£Åg\14Ñ.\12 \88\1a³×¾Î\99\f\9c6\ 5I\9e\v®WnVÄËyâÆ!-a×¢ö\fÛ*Y[K\1fôV\v^Bo¢\16,\ÿ9ô\82)\üº*âq\97\99e§F³ w{\14\81yS\r\r%\ 2\19zÕûk\ 1\89hP\11H\f\95Ü«ó\9fÎp[¨\81\1e\94ªÅÛ¦\97Q%å\96÷Q}ºD]\rÛØ\bØ¥\82­@\8cîÝÚ$DÓ`\89 ¡Q6­\f\94·\ 2Â\92`Y ýX]\a\13\8ddÉ ùg7ÕWÃè\9fê½\17Ý\0#H
+\1f\arÛK\89\9bwÑè]´kÖÒmW>צB\ 2\f\83º2À\1eøÈ^KaL)zw\12\88ûÝ\8e\e\14d\ 5±¡\bU'5H'6)ª\96\0Ãô¾¢¢q¾Ê*ñ\18\87\9dGð~ÊRØ*g Ï\80\ 2¯Ìì]\9aæ\1fùdä9\8a\17¬³\90s\82\7fÎ\ f\9c#꾫>jbÐB\1c)6÷\16¸]b(çH%D\ 1W\8c\89SÂÜLs\ò̼D\ 5;©ã´Qw;\8aûá£ÝæÀ*V'\9a\1eÈ\86N        ÔÎeÊ3\ 1\97®¶ÀÆVéX\7f\92¤Áî®!\v\191Á~Q 9¢+2\rµ¡[Ó\9dq\87rÅò´Ö\18q3©Z+ðF>Y«\1aq\98\ 5·\84rGh\94ÉÚP)©,kÝÕYõFq²ê:áKX@º¡[\9e-æÅ"¡\80w)~\8añò\82tÂCÇ\95ë\0[àÁ\94~ÖÑxã \95\1dß\91EêÂÐ[\93y\82üd\9c˱÷Ù]k1p"\ 6®\ e"neZðL\99\95   CýìÐ*Ü\14u\9bµPÐ0\bÍ\94\ 5©R\84B`#:\805¢Î\ 1ýfÝ\ 2¢Êa$\98æ}Oª¼êc\91T\98\9aêî\81\7f¶öÓ^3(ÎtÂäe}*Á5ñ\1dC6¿Y_\16W\98\10n ÑZ\9c,C¦@\92û!\9a|7Î\97 ©¸\86
+¤3-\ 1\84\8dF#\9a\96UÐçÕÕu\87üÊn½\91\13\87\84#Á\Ùÿ\9e~¥Óÿ\94´ ó+q}vÃ9lÖâþ6Ïíw{¶\ 2§\90c\eIä,ÌÌ­m´¹Kë§\ 6eÕÀ«U~{}÷\ 5¸\9aÔŸ¡Ýï£\9a\9a@\9e\80ª,¯Õ>\91Ûí©¶Ó¨é§\9eºnê&\ e\\v³Ð\8dTôF\83ÆÞ\12,\89xÓAEÛ!ÙØÈ¤ÖÇ£|ùÜnW-@\v]\1fÞ]\84¯òzVKî\89g\aKÈåóUFáh3?U?l« ÛDv=\95`°ùBÆDN\95i[u\v\87+\86-2ëÙ²N9\95¾õ\16\ 3
+mL1ã/oûeõ\89<¹?ÝfC\1a¨\8c\93\ 5\ 3±óò\81n\19óM¢í°X\92z7\83ýö\80ø÷ÿÇÃ>Ïñ0c16ÝÉZ
\95Ñ\1cùR[Xcû*j)t\1d\8bjé/géV\7f^6U\99~G§\8d}ÚOUÆôÑ\94ëä      U\ 1M\9fóG=r\8aF[QõÙ÷\8c\91\9fÏXìïT2þc\vüÃÈÔ\82`\7fº\95\10ó¢¡ÀÒ»\v°\99®<©@9<_\1a1\1f³\82©Å\82\89K¶1,R\9b²~\ 2\14´`\ 6r\97\93\90Cÿ¼y\9e\1c\94[\96\eª\15õ\9c\8c¸ä\9b@\91Î++P\ fõ¹r|ÃT\97Q\fM\ 6\8dX\17\81µ3\8b\rÛ)ë\9eÃ&\9c{QÕDd\8dàjÙbNë³\86âæ¢å£ý}"]´½²·õk\88\82\eÚi¦s\89\88ñÈÆY¦Ý^t3\87\ fø·}\94¶¬ª\ e\9eÕl\88{¿\ 3W\eËû¬IÌg¼²r#\842]\13Ð!î±Ï]5\ 4ÓÕ\1a\7fÖ"þϺÄ?$ÿ°íë§\0p\7f\1a \85ä}4\80\19î²Ó-òr(Y©\8a úQÚÄì_S%xHê¦\80Ïj\8a2\93ì5ù\ 4¯çt®\9f\1d%&\19õR¨À£êJspµL-âë)\18\\ 5\7f¬ñöµ\f©\15\10\ 4\f\8d\1c\81Ð\91\19åã´­\10æq\9f\9aíÌKù\8cvº¾Ú\13Ï\r\93\96¼o\7f\ 6\ ej"\85=\1eõ©\8fÀÑ{óÄÖIØiuã\13\ 5$¶Q%ãn¢\9e\143\97¨~eÒÌÚ\8eínÝú£\8b>Mõñ\94ßF\1c¬\ fs¡ø\87è`d(×\92Ôà|?G¨ë\ f8\8ej\14p\8a¢ýàAôµkÍÛ¯×Zç\18lç}[õ4×­c¿\95ù\a\vÞ7!A\18X\1f*\ 4ëé·\98èÏZ­ñɦ³ìw:¸çÅj\ey½É¬Q\1aß(ÜÕ\a\8c70-¥êÛ·\9eÜÅ®u¯[C·_\12¸\95WÚA\12]Dx¦\1a\86\fÉ\89eD\*öðB[¦ß´ ?Þ\86\ 1é\9a\8e!v ëÑ<\96î¿Î±\v\8b-v\95Ä\v\16Ù û\9c¡ßD´ðU}]»stôèU~gÍÝy\9b\96 \85\14-ôË\ 4ë=£°Æuu®ªÒ\13W\ f\1aï\17¤ÐÑFÁ%\14\8azèp\88É\aY½Ý\8f^x'@Þ`(..ªdLQxñ&JySâÕ\bH-o(\8cEv\80\86¦\91a8ÿ\1d\89\9cÂÆçRÞt\88R\1dË\97é\ 13­ô¥ì"5 ÆÔè\ 3Ý){\10¸óÐÂ\0\v\ 5ä{è\90êtBXÞÅ&\86U×¹\8bb\14\91\96@ >à&`\ 5\94òÃl\9a\ 2    \ 4æúÎHÉ
+âWèq8b'HVE» þbaiº\b\82ÿ\8b¤LzÃ\8aX\1cÕÄQ\149\14Ól£\9eû\88\95\1d²\15,Ó$¶¬#fݪºKÎ\9aê\9a_½¼\r\85\r\ 3wQ\ 3u6\12"\10\ 1ôf"\ 2:ý¥d,?\0#\14ß[Õ\a       w\9b;\aÝR\b¨ÓòÊ×\928Àm¹Ø<\93£\8f\83M<gÁzy¡tn×öBÁB©\15 _\f°\93§\13UæXw\9dÕ\8b¹¾ó* êwÚ5:[¿\ 4Aé    m0\91?t\ 2w\e\8beäå\0TgYXôÒPÈ\96\12\16÷¹ÇÊt\18\87.b¼"²\a¾¸ýÅ\15\88Á¹`,z1\1er®ÝA0ó\11µìHó©¦X."µõ\80~ë¾\12³\95\81\9bÛ'½x\rð^¼\1a\ 5­MÊY:\9c¨®\98ªräfëùqÒ{X\88\9e\81J\90Nÿ®+%@kj\84\b{¸yIfúxX\ 65òº\ 1\1dé\ 3¿\8b×L"\88ë=þÕ¼<}I«\18_\15A6ÆÐ®P\9c¹þ³tãèØ+B­ß\11}M\17rÓ{\ 6j
+\ 6&¡|¼\16\97n[\8f«\83ÿ¡\9dââ\8d|-è×?;ÓÅô>gë\96|­NB(gËC\b\7fpÕð¡Îw®]£îs´,Ë·\9e£åMiýC\1c­þ¦\83ìíº\8e\ f\95\7f¸·\80Úf\9dÄÕ°r-þQ\97uªQ¼\1dÔ´ÁnuuB\17\ etx\98þ\ 6N#D@9\15A\87\8c(h5mºRzÆ\aë:i^:5i\15\84ᮯã.Ø\906\8f \92\Mxã=[>ï@5[ß;\80\9ezøõ\9c\ 3è\19t\ edÁúúþAÈ`c©ä\95S*éZá\90Åõ\ 2TfØ\e_\11åÕÒ{ðáRæ00\15h¢;-\9b{\rä\ 1£·2\7fLðªÅêvL¦\9f)\9e2#\1f)\99BÕ®÷ÏH.,nêi2[Xá³\9aÌ\ eéP&óû¦t8¦\11\0µ\9bF_\83\9e¦ÑG\9c\7f\ 5ÓØK«¯m?ñ¯§\ 2¦I\99\ 6+\18dht\ 3\ 6ú®Ê'âJ9Ú*\ 3cÓÝ~\f\84\917dÚÝ{\93\0ýÆOòt\84\9a\1dרÄÒ8AË\84\989À,Îeß\82BzÔ¸
+ß¼k1à\85¬Á\rÛsA;\e¬±ü'îòÿ3.ü­,øÚ\v½±_\82ö¼¡u_Ø>ÉsÕf­7dUòô\9c*\eZ#¡\8bÝZC\15¦\17"Fëçx<¹©Ó\15Â~/ó²Läý¢Ê\982l\92ÊMý6öÝK\§Öèy竤\9afÝ$kÿýp\eU\9b\86ýVìz\17\ 1Цû¸K\97
+ÚU\82Ý6Ú;Ç5ìs\7f«+_|cj1\9d\1d¶n\ 6 "`3\8cl\19îº÷     ¾î¥©`Eÿó\88\1eSeh£Kp¯wÏ\7f\84ø#<Û£Ã[Toúê§W§F¡©?¾êíJ£\9cGøÿ\vñãã`/·\83ÙÖ¼~~\Ân\8c!}\ f\fZ®¼¿Òå\13Í_åÏ\ e\ 4ï¯\vï¯òu\91zí¢g¿FGÇøö\84'¿>ÄOæbª\93/}®P s1 Í\8d\95!4\1e<°ÉGl\ 2­÷\8e\93ò©QKä\7fu\8f\17\84\aGL\0\9b\99EXg¸÷õ\984ÿØXh\16L¿Hª\9d#µÞû\10©_HÙ\84,ë·º\81ã
+ø¡÷³µ\92\11z\12ÊG\9e\96\13ù\92O» \ 4V¹Óß\92ìêâî}'\87\92½Sq`\15ÄÏø;\92\1cçj«óȬZÛ£R\!¸«@û§ÍÖ\ 2|wûÙo
+©#\87yZ»a­âûF7b\8b\8eéàÚ`×#¹N­Ã¨Æb\98öæ`\8cö(/' \97\8dªé úbô§Ù\17\15/\82\85\95\16\15;<8ØeûêÉ#úÞ\1cAñÃÞ,Í/é\80\03L\8fÅ0\b³\ 5@½:\ 4`\11X\1f¬_7æ®ÖG]/Ó¬s÷íFÃ1Æ{º\ 5\8eÖ\16@´®ÍxÃÿ¶â%\ 6gDDÆN\83øn\f²]y\11\89´\ 6µÛ7B\90¾;\83RÛL\18G\1eÑУjÿ8OÆsº`\15ðl(yì¿\88¯\a\8a\98Ô\1aï×OÛ\a^w 1[ÑdÄ¢Gôöwqç8\8f«AÄ\90#S¼H\88í1\e\19¼2\1f\9bó]´,WðÓ]ùáÛã»ÿ\v\8d\92AO\83@\10\85Ïì¯\98£6±T/\1e4ÖÚ\8b\1e\9a\a\98)\f°qYÈì.j\88ÿÝ\81jj    iË\85ÌûÞ¼}K¸\9f×E­T<\99(\98Àc¦\rA] OµMzEÛ\9c«PÃZÄ^ز¦\f\12\83ÎíE\f¾¨\18`\85\9c\ 4\aO\15qN;\94¢'\90çf6»\85«þ%z\87ºmXVe\896\959Vq\fmÛþË\ 6úôdS\19\9e×o\vN
+ÝÐ_×\9e÷Ön:Ö\15v^]Ö\86\1e½®ì©Ú\r±\13\e\Og}·ã¥öá\ e^)       ²ÛÐ\8b'F_±jU\94\ 5\9btÇBN~£s\8b>0]\ªHXÄ$\93\85\f\8d£;\15}«CÿÂhtçx\99>´M\7f\9d\a¤A£Ós"¤:Ë-Æ2ÞékL¶ò9Æô\ 2ݲÐ&\95¸3ï9°\ fÓVäQ~&\1cò}\ 2o|Ø\8e!7@\ 2ç\ f?¨ C\82
+¤Z·×\80ø@ï\8b\9dø\99\10ï³\ 2\0\0\0GBMB
\ No newline at end of file
diff --git a/ext/phar/phar.php b/ext/phar/phar.php
deleted file mode 100644 (file)
index befc696..0000000
+++ /dev/null
@@ -1,1908 +0,0 @@
-<?php
-/** @file phar.php
- * @ingroup Phar
- * @brief class Phar Pre Command
- * @author  Marcus Boerger
- * @date    2007 - 2007
- *
- * Phar Command
- */
-foreach(array("SPL", "Reflection", "Phar") as $ext)
-{
-       if (!extension_loaded($ext))
-       {
-               echo "$argv[0] requires PHP extension $ext.\n";
-               exit(1);
-       }
-}
-
-if (!class_exists('DirectoryTreeIterator', 0))
-{
-
-/** @file directorytreeiterator.inc
- * @ingroup Examples
- * @brief class DirectoryTreeIterator
- * @author  Marcus Boerger
- * @date    2003 - 2005
- *
- * SPL - Standard PHP Library
- */
-
-/** @ingroup Examples
- * @brief   DirectoryIterator to generate ASCII graphic directory trees
- * @author  Marcus Boerger
- * @version 1.1
- */
-class DirectoryTreeIterator extends RecursiveIteratorIterator
-{
-       /** Construct from a path.
-        * @param $path directory to iterate
-        */
-       function __construct($path)
-       {
-               parent::__construct(
-                       new RecursiveCachingIterator(
-                               new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::KEY_AS_FILENAME
-                               ), 
-                               CachingIterator::CALL_TOSTRING|CachingIterator::CATCH_GET_CHILD
-                       ), 
-                       parent::SELF_FIRST
-               );
-       }
-
-       /** @return the current element prefixed with ASCII graphics
-        */     
-       function current()
-       {
-               $tree = '';
-               for ($l=0; $l < $this->getDepth(); $l++) {
-                       $tree .= $this->getSubIterator($l)->hasNext() ? '| ' : '  ';
-               }
-               return $tree . ($this->getSubIterator($l)->hasNext() ? '|-' : '\-') 
-                      . $this->getSubIterator($l)->__toString();
-       }
-
-       /** Aggregates the inner iterator
-        */     
-       function __call($func, $params)
-       {
-               return call_user_func_array(array($this->getSubIterator(), $func), $params);
-       }
-}
-
-}
-
-if (!class_exists('DirectoryGraphIterator', 0))
-{
-
-/** @file directorygraphiterator.inc
- * @ingroup Examples
- * @brief class DirectoryGraphIterator
- * @author  Marcus Boerger
- * @date    2003 - 2005
- *
- * SPL - Standard PHP Library
- */
-
-/** @ingroup Examples
- * @brief   A tree iterator that only shows directories.
- * @author  Marcus Boerger
- * @version 1.1
- */
-class DirectoryGraphIterator extends DirectoryTreeIterator
-{
-       function __construct($path)
-       {
-               RecursiveIteratorIterator::__construct(
-                       new RecursiveCachingIterator(
-                               new ParentIterator(
-                                       new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::KEY_AS_FILENAME
-                                       )
-                               ), 
-                               CachingIterator::CALL_TOSTRING|CachingIterator::CATCH_GET_CHILD
-                       ), 
-                       parent::SELF_FIRST
-               );
-       }
-}
-
-}
-
-if (!class_exists('InvertedRegexIterator', 0))
-{
-
-/** @file invertedregexiterator.inc
- * @ingroup Phar
- * @brief class InvertedRegexIterator
- * @author  Marcus Boerger
- * @date    2007 - 2007
- *
- * Inverted RegexIterator
- */
-
-/** @ingroup Phar
- * @brief   Inverted RegexIterator
- * @author  Marcus Boerger
- * @version 1.0
- */
-class InvertedRegexIterator extends RegexIterator
-{
-       /** @return !RegexIterator::accept()
-        */     
-       function accept()
-       {
-               return !RegexIterator::accept();
-       }
-}
-
-}
-
-if (!class_exists('CLICommand', 0))
-{
-
-/** @file clicommand.inc
- * @ingroup Phar
- * @brief class CLICommand
- * @author  Marcus Boerger
- * @date    2007 - 2007
- *
- * Phar Command
- */
-
-/** @ingroup Phar
- * @brief   Abstract base console command implementation
- * @author  Marcus Boerger
- * @version 1.0
- */
-abstract class CLICommand
-{
-    protected $argc;
-    protected $argv;
-    protected $cmds = array();
-    protected $args = array();
-    protected $typs = array();
-
-    function __construct($argc, array $argv)
-    {
-        $this->argc = $argc;
-        $this->argv = $argv;
-        $this->cmds = self::getCommands($this);
-        $this->typs = self::getArgTyps($this);
-
-        if ($argc < 2) {
-            self::error("No command given, check ${argv[0]} help\n");
-        } elseif (!isset($this->cmds[$argv[1]]['run'])) {
-            self::error("Unknown command '${argv[1]}', check ${argv[0]} help\n");
-        } else {
-            $command = $argv[1];
-        }
-
-        if (isset($this->cmds[$command]['arg'])) {
-            $this->args = call_user_func(array($this, $this->cmds[$command]['arg']));
-            $i = 1;
-            $missing = false;
-            while (++$i < $argc) {
-                if ($argv[$i][0] == '-') {
-                    if (strlen($argv[$i]) == 2 && isset($this->args[$argv[$i][1]])) {
-                        $arg = $argv[$i][1];
-                        if (++$i >= $argc) {
-                            self::error("Missing argument to parameter '$arg' of command '$command', check ${argv[0]} help\n");
-                        } else {
-                            $this->args[$arg]['val'] = $this->checkArgTyp($arg, $i, $argc, $argv);
-                        }
-                    }  else {
-                        self::error("Unknown parameter '${argv[$i]}' to command $command, check ${argv[0]} help\n");
-                    }
-                } else {
-                    break;
-                }
-            }
-            if (isset($this->args[''])) {
-                if ($i >= $argc) {
-                    if (isset($this->args['']['require']) && $this->args['']['require']) {
-                        self::error("Missing default trailing arguments to command $command, check ${argv[0]} help\n");
-                    }
-                } else {
-                    $this->args['']['val'] = array();
-                    while($i < $argc) {
-                        $this->args['']['val'][] = $argv[$i++];
-                    }
-                }
-            } else if ($i < $argc) {
-                self::error("Unexpected default arguments to command $command, check ${argv[0]} help\n");
-            }
-            
-            foreach($this->args as $arg => $inf) {
-                if (strlen($arg) && !isset($inf['val']) && isset($inf['required']) && $inf['required']) {
-                    $missing .=  "Missing parameter '-$arg' to command $command, check ${argv[0]} help\n";
-                }
-            }
-            if (strlen($missing))
-            {
-                self::error($missing);
-            }
-        }
-
-        call_user_func(array($this, $this->cmds[$command]['run']), $this->args);
-    }
-
-    static function notice ($msg)
-    {
-        fprintf(STDERR, $msg);
-    }
-
-    static function error ($msg, $exit_code = 1) 
-    {
-        notice($msg);
-        exit($exit_code);
-    }
-
-    function checkArgTyp($arg, $i, $argc, $argv)
-    {
-        $typ = $this->args[$arg]['typ'];
-
-        if (isset($this->typs[$typ]['typ'])) {
-            return call_user_func(array($this, $this->typs[$typ]['typ']), $argv[$i], $this->args[$arg], $arg);
-        } else {
-            return $argv[$i];
-        }
-    }
-
-    static function getSubFuncs(CLICommand $cmdclass, $prefix, array $subs)
-    {
-        $a = array();
-        $r = new ReflectionClass($cmdclass);
-        $l = strlen($prefix);
-
-        foreach($r->getMethods() as $m)
-        {
-            if (substr($m->name, 0, $l) == $prefix)
-            {
-                foreach($subs as $sub)
-                {
-                    $what = substr($m->name, $l+strlen($sub)+1);
-                    $func = $prefix . $sub . '_' . $what;
-                    $what = str_replace('_', '-', $what);
-                    if ($r->hasMethod($func))
-                    {
-                        if (!isset($a[$what]))
-                        {
-                            $a[$what] = array();
-                        }
-                        $a[$what][$sub] = /*$m->class . '::' .*/ $func;
-                    }
-                }
-            }
-        }
-        return $a;
-    }
-
-    static function getCommands(CLICommand $cmdclass)
-    {
-        return self::getSubFuncs($cmdclass, 'cli_cmd_', array('arg','inf','run'));
-    }
-
-    static function getArgTyps(CLICommand $cmdclass)
-    {
-        return self::getSubFuncs($cmdclass, 'cli_arg_', array('typ'));
-    }
-
-    static function cli_arg_typ_bool($arg, $cfg, $key)
-    {
-        return (bool)$arg;
-    }
-
-    
-    static function cli_arg_typ_int($arg, $cfg, $key) 
-    {
-        if ((int)$arg != $arg) {
-            self::error("Argument to -$key must be an integer.\n");
-        }
-
-        return (int)$arg;
-    }
-    
-    static function cli_arg_typ_regex($arg, $cfg, $key)
-    {
-        if (strlen($arg))
-        {
-            if (strlen($arg) > 1 && $arg[0] == $arg[strlen($arg)-1] && strpos('/,', $arg) !== false)
-            {
-                return $arg;
-            }
-            else
-            {
-                return '/' . $arg . '/';
-            }
-        }
-        else
-        {
-            return NULL;
-        }
-    }
-
-    static function cli_arg_typ_select($arg, $cfg, $key)
-    {
-        if (!in_array($arg, array_keys($cfg['select']))) {
-            self::error("Parameter value '$arg' not one of '" . join("', '", array_keys($cfg['select'])) . "'.\n");
-        }
-        return $arg;
-    }
-
-    static function cli_arg_typ_dir($arg, $cfg, $key)
-    {
-        $f = realpath($arg);
-
-        if ($f===false || !file_exists($f) || !is_dir($f)) {
-            self::error("Requested path '$arg' does not exist.\n");
-        }
-        return $f;
-    }
-
-    static function cli_arg_typ_file($arg)
-    {
-        $f = new SplFileInfo($arg);
-        $f = $f->getRealPath();
-        if ($f===false || !file_exists($f))
-        {
-            echo "Requested file '$arg' does not exist.\n";
-            exit(1);
-        }
-        return $f;
-    }
-
-    static function cli_arg_typ_filenew($arg, $cfg, $key)
-    {
-        $d = dirname($arg);
-        $f = realpath($d);
-        
-        if ($f === false) {
-            self::error("Path for file '$arg' does not exist.\n");
-        }
-        return $f . substr($arg, strlen($d));;
-    }
-
-    static function cli_arg_typ_filecont($arg, $cfg, $key)
-    {
-        return file_get_contents(self::cli_arg_typ_file($arg, $cfg, $key));
-    }
-
-    function cli_get_SP2($l1, $arg_inf)
-    {
-        return str_repeat(' ', $l1 + 2 + 4 + 8);
-    }
-
-    function cli_get_SP3($l1, $l2, $arg_inf)
-    {
-        return str_repeat(' ', $l1 + 2 + 4 + 8 + 2 + $l2 + 2);
-    }
-
-    static function cli_cmd_inf_help()
-    {
-        return "This help or help for a selected command.";
-    }
-
-    private function cli_wordwrap($what, $l, $sp)
-    {
-        $p = max(79 - $l, 40);     // minimum length for paragraph
-        $b = substr($what, 0, $l); // strip out initial $l
-        $r = substr($what, $l);    // remainder
-        $r = str_replace("\n", "\n".$sp, $r); // in remainder replace \n's
-        return $b . wordwrap($r, $p, "\n".$sp);
-    }
-
-    private function cli_help_get_args($func, $l, $sp, $required)
-    {
-        $inf = "";
-        foreach(call_user_func($func, $l, $sp) as $arg => $conf)
-        {
-            if ((isset($conf['required']) && $conf['required']) != $required)
-            {
-                continue;
-            }
-            if (strlen($arg))
-            {
-                $arg = "-$arg  ";
-            }
-            else
-            {
-                $arg = "... ";
-            }
-            $sp2 = $this->cli_get_SP2($l, $inf);
-            $l2  = strlen($sp2);
-            $inf .= $this->cli_wordwrap($sp . $arg . $conf['inf'], $l2, $sp2) . "\n";
-            if (isset($conf['select']) && count($conf['select']))
-            {
-                $ls = 0;
-                foreach($conf['select'] as $opt => $what)
-                {
-                    $ls = max($ls, strlen($opt));
-                }
-                $sp3 = $this->cli_get_SP3($l, $ls, $inf);
-                $l3  = strlen($sp3);
-                foreach($conf['select'] as $opt => $what)
-                {
-                    $inf .= $this->cli_wordwrap($sp2 . "  " . sprintf("%-${ls}s  ", $opt) . $what, $l3, $sp3) . "\n";
-                }
-            }
-        }
-        if (strlen($inf))
-        {
-            if ($required)
-            {
-                return $sp . "Required arguments:\n\n" . $inf;
-            }
-            else
-            {
-                return $sp . "Optional arguments:\n\n". $inf;
-            }
-        }
-    }
-
-    function cli_cmd_arg_help()
-    {
-        return array('' => array('typ'=>'any','val'=>NULL,'inf'=>'Optional command to retrieve help for.'));
-    }
-
-    function cli_cmd_run_help()
-    {
-        $argv  = $this->argv;
-        $which = $this->args['']['val'];
-        if (isset($which))
-        {
-            if (count($which) != 1) {
-                self::error("More than one command given.\n");
-            }
-            
-            $which = $which[0];
-            if (!array_key_exists($which, $this->cmds)) {
-                self::error("Unknown command, cannot retrieve help.\n");
-            }
-
-            $l = strlen($which);
-            $cmds = array($which => $this->cmds[$which]);
-        } else {
-            echo "\n$argv[0] <command> [options]\n\n";
-            $l = 0;
-            ksort($this->cmds);
-            foreach($this->cmds as $name => $funcs) {
-                $l = max($l, strlen($name));
-            }
-            $inf = "Commands:";
-            $lst = "";
-            $ind = strlen($inf) + 1;
-            foreach($this->cmds as $name => $funcs)
-            {
-                $lst .= ' ' . $name;
-            }
-            echo $this->cli_wordwrap($inf.$lst, $ind, str_repeat(' ', $ind)) . "\n\n";
-            $cmds = $this->cmds;
-        }
-        $sp = str_repeat(' ', $l + 2);
-        foreach($cmds as $name => $funcs)
-        {
-            $inf = $name . substr($sp, strlen($name));
-            if (isset($funcs['inf']))
-            {
-                $inf .= $this->cli_wordwrap(call_user_func(array($this, $funcs['inf'])), $l, $sp) . "\n";
-                if (isset($funcs['arg']))
-                {
-                    $inf .= "\n";
-                    $inf .= $this->cli_help_get_args(array($this, $funcs['arg']), $l, $sp, true);
-                    $inf .= "\n";
-                    $inf .= $this->cli_help_get_args(array($this, $funcs['arg']), $l, $sp, false);
-                }
-            }
-            echo "$inf\n\n";
-        }
-        exit(0);
-    }
-
-    static function cli_cmd_inf_help_list()
-    {
-        return "Lists available commands.";
-    }
-
-    function cli_cmd_run_help_list()
-    {
-        ksort($this->cmds);
-        $lst = '';
-        foreach($this->cmds as $name => $funcs) {
-            $lst .= $name . ' ';
-        }
-        echo substr($lst, 0, -1) . "\n";
-    }
-}
-
-}
-
-if (!class_exists('PharCommand', 0))
-{
-
-/**
- * @file pharcommand.inc
- * @ingroup Phar
- * @brief class CLICommand
- * @author  Marcus Boerger
- * @date    2007 - 2007
- *
- * Phar Command
- */
-// {{{ class PharCommand extends CLICommand
-/**
- * PharCommand class
- * 
- * This class handles the handling of the phar
- * commands. It will be used from command line/console
- * in order to retrieve and execute phar functions.
- * 
- * @ingroup Phar
- * @brief   Phar console command implementation
- * @author  Marcus Boerger
- * @version 1.0
- */
-class PharCommand extends CLICommand
-{
-    // {{{ public function cli_get_SP2
-    public function cli_get_SP2($l1, $arg_inf)
-    {
-        return str_repeat(' ', $l1 + 2 + 4 + 9);
-    }
-    // }}}
-    // {{{ public function cli_get_SP3
-    /**
-     * Cli Get SP3
-     *
-     * @param string $l1      Eleven
-     * @param string $l2      Twelve
-     * @param string $arg_inf 
-     * @return string  The repeated string.
-     */
-    function cli_get_SP3($l1, $l2, $arg_inf)
-    {
-        return str_repeat(' ', $l1 + 2 + 4 + 9 + 2 + $l2 + 2);
-    }
-    // }}}
-    // {{{ static function phar_args
-    /**
-     * Phar arguments
-     * 
-     * This function contains all the phar commands
-     *
-     * @param  string $which    Which argument is chosen.
-     * @param  string $phartype The type of phar, specific file to work on
-     * @return unknown
-     */
-    static function phar_args($which, $phartype)
-    {
-        $phar_args = array(
-            'a' => array(
-                'typ' => 'alias',
-                'val' => NULL,
-                'inf' => '<alias>  Provide an alias name for the phar file.'
-            ),
-            'c' => array(
-                'typ' => 'compalg',
-                'val' => NULL,
-                'inf' => '<algo>   Compression algorithm.',
-                'select' => array(
-                    '0'    => 'No compression',
-                    'none' => 'No compression',
-                    'auto' => 'Automatically select compression algorithm'
-                )
-            ),
-            'e' => array(
-                'typ' => 'entry',
-                'val' => NULL,
-                'inf' => '<entry>  Name of entry to work on (must include PHAR internal directory name if any).'
-            ),
-            'f' => array(
-                'typ' => $phartype,
-                'val' => NULL,
-                'inf' => '<file>   Specifies the phar file to work on.'
-            ),
-            'h' => array(
-                'typ' => 'select',
-                'val' => NULL,
-                'inf' => '<method> Selects the hash algorithmn.',
-                'select' => array('md5' => 'MD5','sha1' => 'SHA1')
-            ),
-            'i' => array(
-                'typ' => 'regex',
-                'val' => NULL,
-                'inf' => '<regex>  Specifies a regular expression for input files.'
-            ),
-            'k' => array(
-                'typ' => 'any',
-                'val' => NULL,
-                'inf' => '<index>  Subscription index to work on.',
-            ),
-            'l' => array(
-                'typ' => 'int',
-                'val' => 0,
-                'inf' => '<level>  Number of preceeding subdirectories to strip from file entries',
-            ),
-            'm' => array(
-                'typ' => 'any',
-                'val' => NULL,
-                'inf' => '<meta>   Meta data to store with entry (serialized php data).'
-            ),
-            'p' => array(
-                'typ' => 'loader',
-                'val' => NULL,
-                'inf' => '<loader> Location of PHP_Archive class file (pear list-files PHP_Archive).'
-                         .'You can use \'0\' or \'1\' to locate it automatically using the mentioned '
-                         .'pear command. When using \'0\' the command does not error out when the '
-                         .'class file cannot be located. This switch also adds some code around the '
-                         .'stub so that class PHP_Archive gets registered as phar:// stream wrapper '
-                         .'if necessary. And finally this switch will add the file phar.inc from '
-                         .'this package and load it to ensure class Phar is present.'
-                         ,
-            ),
-            's' => array(
-                'typ' => 'file',
-                'val' => NULL,
-                'inf' => '<stub>   Select the stub file.'
-            ),
-            'x' => array(
-                'typ' => 'regex',
-                'val' => NULL,
-                'inf' => '<regex>  Regular expression for input files to exclude.'
-            ),
-
-        );
-
-        if (extension_loaded('zlib')) {
-            $phar_args['c']['select']['gz']    = 'GZip compression';
-            $phar_args['c']['select']['gzip']  = 'GZip compression';
-        }
-
-        if (extension_loaded('bz2')) {
-            $phar_args['c']['select']['bz2']   = 'BZip2 compression';
-            $phar_args['c']['select']['bzip2'] = 'BZip2 compression';
-        }
-
-        $hash_avail = Phar::getSupportedSignatures();
-        if (in_array('SHA-256', $hash_avail)) {
-            $phar_args['h']['select']['sha256'] = 'SHA256';
-        }
-
-        if (in_array('SHA-512', Phar::getSupportedSignatures())) {
-            $phar_args['h']['select']['sha512'] = 'SHA512';
-        }
-
-        $args = array();
-
-        foreach($phar_args as $lkey => $cfg) {
-            $ukey     = strtoupper($lkey);
-            $required = strpos($which, $ukey) !== false;
-            $optional = strpos($which, $lkey) !== false;
-
-            if ($required || $optional) {
-                $args[$lkey] = $cfg;
-                $args[$lkey]['required'] = $required;
-            }
-        }
-        return $args;
-    }
-    // }}}
-    // {{{ static function strEndsWith
-    /**
-     * String Ends With
-     * 
-     * Wether a string end with another needle.
-     *
-     * @param string $haystack  The haystack
-     * @param string $needle    The needle.
-     * @return mixed false if doesn't end with anything, the string 
-     *               substr'ed if the string ends with the needle.
-     */
-    static function strEndsWith($haystack, $needle)
-    {
-        return substr($haystack, -strlen($needle)) == $needle;
-    }
-    // }}}
-    // {{{ static function cli_arg_typ_loader
-    /**
-     * Argument type loader
-     *
-     * @param string $arg   Either 'auto', 'optional' or an filename that 
-     *                      contains class PHP_Archive
-     * @param  string $cfg  Configuration to pass to a new file
-     * @param  string $key  The key 
-     * @return string $arg  The argument.
-     */
-    static function cli_arg_typ_loader($arg, $cfg, $key)
-    {
-        if (($arg == '0' || $arg == '1') && !file_exists($arg)) {
-            $found = NULL;
-            foreach(split("\n", `pear list-files PHP_Archive`) as $ent) {
-                $matches = NULL;
-                if (preg_match(",^php[ \t]+([^ \t].*pear[\\\\/]PHP[\\\\/]Archive.php)$,", $ent, $matches)) {
-                    $found = $matches[1];
-                    break;
-                }
-            }
-            if (!isset($found)) {
-               $msg = "Pear package PHP_Archive or Archive.php class file not found.\n";
-               if ($arg == '0') {
-                       self::notice($msg);
-               } else {
-                       self::error($msg);
-               }
-            }
-            $arg = $found;
-        }
-        return self::cli_arg_typ_file($arg);
-    }
-    // }}}
-    // {{{ static function cli_arg_typ_pharnew
-    /**
-     * Argument type new phar
-     *
-     * @param  string $arg  The new phar component.
-     * @param  string $cfg  Configuration to pass to a new file
-     * @param  string $key  The key 
-     * @return string $arg  The new argument file.
-     */
-    static function cli_arg_typ_pharnew($arg, $cfg, $key)
-    {
-        $arg = self::cli_arg_typ_filenew($arg, $cfg, $key);
-        if (!Phar::isValidPharFilename($arg)) {
-            self::error("Phar files must have file extension '.phar', '.phar.php', '.phar.bz2' or 'phar.gz'.\n");
-        }
-        return $arg;
-    }
-    // }}}
-    // {{{ static function cli_arg_typ_pharfile
-    /**
-     * Argument type existing Phar file
-     * 
-     * Return filenam eof an existing Phar.
-     *
-     * @param  string $arg      The file in the phar to open.
-     * @param  string $cfg      The configuration information
-     * @param  string $key      The key information.
-     * @return string $pharfile The name of the loaded Phar file.
-     * @note The Phar will be loaded
-     */
-    static function cli_arg_typ_pharfile($arg, $cfg, $key)
-    {
-        try {
-            $pharfile = self::cli_arg_typ_file($arg, $cfg, $key);
-
-            if (!Phar::loadPhar($pharfile)) {
-                self::error("Unable to open phar '$arg'\n");
-            }
-
-            return $pharfile;
-        } catch(Exception $e) {
-            self::error("Exception while opening phar '$arg':\n" . $e->getMessage() . "\n");
-        }
-    }
-    // }}}
-    // {{{ static function cli_arg_typ_pharurl
-    /**
-     * Argument type Phar url-like
-     * 
-     * Check the argument as cli_arg_Typ_phar and return its name prefixed 
-     * with phar://
-     * 
-     * Ex:
-     * <code>
-     *  $arg = 'pharchive.phar/file.php';
-     *  cli_arg_typ_pharurl($arg)
-     * </code>
-     *
-     * @param  string $arg The url-like phar archive to retrieve.
-     * @return string The phar file-archive.
-     */
-    static function cli_arg_typ_pharurl($arg, $cfg, $key)
-    {
-        return 'phar://' . self::cli_arg_typ_pharfile($arg, $cfg, $key);
-    }
-    // }}}
-    // {{{ static function cli_arg_typ_phar
-    /**
-     * Cli argument type phar
-     *
-     * @param  string $arg  The phar archive to use.
-     * @return object new Phar of the passed argument.
-     */
-    static function cli_arg_typ_phar($arg, $cfg, $key)
-    {
-        try {
-            return new Phar(self::cli_arg_typ_pharfile($arg, $cfg, $key));
-        } catch(Exception $e) {
-            self::error("Exception while opening phar '$argv':\n" . $e->getMessage() . "\n");
-        }
-    }
-    // }}}
-    // {{{ static function cli_arg_typ_entry
-    /**
-     * Argument type Entry name
-     *
-     * @param  string $arg The argument (the entry)
-     * @return string $arg The entry itself.
-     */
-    static function cli_arg_typ_entry($arg, $cfg, $key)
-    {
-        // no further check atm, maybe check for no '/' at beginning
-        return $arg;
-    }
-    // }}}
-    // {{{ static function cli_arg_typ_compalg
-    /**
-     * Argument type compression algorithm
-     *
-     * @param  string $arg  The phar selection
-     * @param  string $cfg  The config option.
-     * @param  string $key  The key information.
-     * @return string $arg  The selected algorithm
-     */
-    static function cli_arg_typ_compalg($arg, $cfg, $key)
-    {
-        $arg = self::cli_arg_typ_select($arg, $cfg, $key);
-        
-        switch($arg) {
-            case 'auto':
-                if (extension_loaded('zlib')) {
-                    $arg = 'gz';
-                } elseif (extension_loaded('bz2')) {
-                    $arg = 'bz2';
-                } else {
-                    $arg = '0';
-                }
-                break;
-        }
-        return $arg;
-    }
-    // }}}
-    // {{{ static function cli_cmd_inf_pack
-    /**
-     * Information pack
-     *
-     * @return string A description about packing files into a Phar archive.
-     */
-    static function cli_cmd_inf_pack()
-    {
-        return "Pack files into a PHAR archive.\n" .  
-               "When using -s <stub>, then the stub file is being " .
-               "excluded from the list of input files/dirs." .
-               "To create an archive that contains PEAR class PHP_Archiave " .
-               "then point -p argument to PHP/Archive.php.\n";
-    }
-    // }}}
-    // {{{ static function cli_cmd_arg_pack
-    /**
-     * Pack a new phar infos
-     *
-     * @return array  $args  The arguments for a new Phar archive.
-     */
-    static function cli_cmd_arg_pack()
-    {
-        $args = self::phar_args('acFhilpsx', 'pharnew');
-        
-        $args[''] = array(
-            'typ'     => 'any',     
-            'val'      => NULL,      
-            'required' => 1, 
-            'inf'      => '         Any number of input files and directories. If -i is in use then ONLY files and matching thegiven regular expression are being packed. If -x is given then files matching that regular expression are NOT being packed.',
-            
-        );
-        
-        return $args;
-    }
-    // }}}
-    // {{{ function cli_cmd_run_pack
-    /**
-     * Pack a new Phar
-     * 
-     * This function will try to pack a new Phar archive.
-     * 
-     * @see Exit to make sure that we are done.
-     */
-    public function cli_cmd_run_pack()
-    {
-        if (ini_get('phar.readonly')) {
-            self::error("Creating phar files is disabled by ini setting 'phar.readonly'.\n");
-        }
-        
-        if (!Phar::canWrite()) {
-            self::error("Creating phar files is disabled, Phar::canWrite() returned false.\n");
-        }
-
-        $alias    = $this->args['a']['val'];
-        $archive  = $this->args['f']['val'];
-        $hash     = $this->args['h']['val'];
-        $regex    = $this->args['i']['val'];
-        $level    = $this->args['l']['val'];
-        $loader   = $this->args['p']['val'];
-        $stub     = $this->args['s']['val'];
-        $invregex = $this->args['x']['val'];
-        $input    = $this->args['']['val'];
-
-        $phar  = new Phar($archive, 0, $alias);
-
-        $phar->startBuffering();
-
-        if (isset($stub)) {
-            if (isset($loader)) {
-                $c = file_get_contents($stub);
-                $s = '';
-
-                if (substr($c, 0, 2) == '#!') {
-                    $s .= substr($c, 0, strpos($c, "\n") + 1);
-                }
-
-                               $s .= "<?php if (!class_exists('PHP_Archive')) {\n?>";
-                               $s .= file_get_contents($loader);
-                $s .= "<?php\n";
-                $s .= "}\n";
-                $s .= "if (!in_array('phar', stream_get_wrappers())) {\n\tstream_wrapper_register('phar', 'PHP_Archive');\n}\n";
-                               $s .= "if (!class_exists('Phar',0)) {\n";
-                $s .= "\tinclude 'phar://'.__FILE__.'/phar.inc';\n";
-                $s .= "}\n";
-                $s .= '?>';
-
-                if (substr($c,0,1) == '#') {
-                    $s.= substr($c,strpos($c, "\n")+1);
-                }
-
-                $phar->setStub($s);
-            } else {
-                $phar->setStub(file_get_contents($stub));
-            }
-            $stub = new SplFileInfo($stub);
-        }
-
-        if (!is_array($input)) {
-            $this->phar_add($phar, $level, $input, $regex, $invregex, $stub, NULL, isset($loader));
-        } else {
-            foreach($input as $i) {
-                $this->phar_add($phar, $level, $i, $regex, $invregex, $stub, NULL, isset($loader));
-            }
-        }
-
-        if (isset($loader)) {
-               if (substr(__FILE__, -15) == 'pharcommand.inc') {
-                   self::phar_add_file($phar, 0, 'phar.inc', 'phar://'.__FILE__.'/phar.inc', NULL);
-               } else {
-                   self::phar_add_file($phar, 0, 'phar.inc', dirname(__FILE__).'/phar/phar.inc', NULL);
-               }
-        }
-
-        switch($this->args['c']['val']) {
-            case 'gz':
-            case 'gzip':
-                $phar->compressAllFilesGZ();
-                break;
-            case 'bz2':
-            case 'bzip2':
-                $phar->compressAllFilesBZIP2();
-                break;
-            default:
-                $phar->uncompressAllFiles();
-                break;
-        }
-
-        if ($hash) {
-            $phar->setSignatureAlgorithm($hash);
-        }
-
-        $phar->stopBuffering();
-        exit(0);
-    }
-    // }}}
-    // {{{ static function phar_add
-    /**
-     * Add files to a phar archive.
-     *
-     * This function will take a directory and iterate through
-     * it and get the files to insert into the Phar archive.
-     * 
-     * @param Phar        $phar      The phar object.
-     * @param string      $input     The input directory
-     * @param string      $regex     The regex use in RegexIterator.
-     * @param string      $invregex  The InvertedRegexIterator expression.
-     * @param SplFileInfo $stub Stub file object    
-     * @param mixed       $compress  Compression algorithm or NULL
-     * @param boolean     $noloader  Whether to prevent adding the loader
-     */
-    static function phar_add(Phar $phar, $level, $input, $regex, $invregex, SplFileInfo $stub = NULL, $compress = NULL, $noloader = false)
-    {
-        if ($input && is_file($input) && !is_dir($input)) {
-            return self::phar_add_file($phar, $level, $input, $input, $compress);
-        }
-        $dir   = new RecursiveDirectoryIterator($input);
-        $dir   = new RecursiveIteratorIterator($dir);
-
-        if (isset($regex)) {
-            $dir = new RegexIterator($dir, $regex);
-        }
-
-        if (isset($invregex)) {
-            $dir = new InvertedRegexIterator($dir, $invregex);
-        }
-
-        try {
-            foreach($dir as $file) {
-                if (empty($stub) || $file->getRealPath() != $stub->getRealPath()) {
-                    self::phar_add_file($phar, $level, $dir->getSubPathName(), $file, $compress, $noloader);
-                }
-            }
-        } catch(Excpetion $e) {
-            self::error("Unable to complete operation on file '$file'\n" . $e->getMessage() . "\n");
-        }
-    }
-    // }}}
-    // {{{ static function phar_add_file
-    /**
-     * Add a phar file
-     *
-     * This function adds a file to a phar archive.
-     *
-     * @param Phar    $phar      The phar object
-     * @param string  $level     The level of the file.
-     * @param string  $entry     The entry point
-     * @param string  $file      The file to add to the archive
-     * @param string  $compress  The compression scheme for the file.
-     * @param boolean $noloader  Whether to prevent adding the loader
-     */
-    static function phar_add_file(Phar $phar, $level, $entry, $file, $compress, $noloader = false)
-    {
-        $entry = str_replace('//', '/', $entry);
-        while($level-- > 0 && ($p = strpos($entry, '/')) !== false) {
-            $entry = substr($entry, $p+1);
-        }
-
-               if ($noloader && $entry == 'phar.inc') {
-                       return;
-               }
-
-        echo "$entry\n";
-
-        $phar[$entry] = file_get_contents($file);
-        switch($compress) {
-            case 'gz':
-            case 'gzip':
-                $phar[$entry]->setCompressedGZ();
-                break;
-            case 'bz2':
-            case 'bzip2':
-                $phar[$entry]->setCompressedBZIP2();
-                break;
-            default:
-                break;
-        }
-    }
-    // }}}
-    // {{{ public function phar_dir_echo
-    /**
-     * Echo directory
-     *
-     * @param string $pn      
-     * @param unknown_type $f
-     */
-    public function phar_dir_echo($pn, $f)
-    {
-        echo "$f\n";
-    }
-    // }}}
-    // {{{ public function phar_dir_operation
-    /**
-     * Directory operations
-     * 
-     * Phar directory operations.
-     *
-     * @param RecursiveIteratorIterator $dir  The recursiveIteratorIterator object.
-     * @param string                    $func Function to call on the iterations
-     * @param array                     $args Function arguments.
-     */
-    public function phar_dir_operation(RecursiveIteratorIterator $dir, $func, array $args = array())
-    {
-        $regex   = $this->args['i']['val'];
-        $invregex= $this->args['x']['val'];
-
-        if (isset($regex)) {
-            $dir = new RegexIterator($dir, $regex);
-        }
-
-        if (isset($invregex)) {
-            $dir = new InvertedRegexIterator($dir, $invregex);
-        }
-
-        foreach($dir as $pn => $f) {
-            call_user_func($func, $pn, $f, $args);
-        }
-    }
-    // {{{ static function cli_cmd_inf_list
-    /**
-     * Cli Command Info List
-     *
-     * @return string What inf does
-     */
-    static function cli_cmd_inf_list()
-    {
-        return "List contents of a PHAR archive.";
-    }
-    // }}}
-    // {{{ static function cli_cmd_arg_list
-    /**
-     * Cli Command Argument List
-     *
-     * @return arguments list
-     */
-    static function cli_cmd_arg_list()
-    {
-        return self::phar_args('Fix', 'pharurl');
-    }
-    // }}}
-    // {{{ public function cli_cmd_run_list
-    /**
-     * Cli Command Run List
-     *
-     * @see $this->phar_dir_operation
-     */
-    public function cli_cmd_run_list()
-    {
-        $this->phar_dir_operation(
-            new DirectoryTreeIterator(
-                $this->args['f']['val']), 
-                array($this, 'phar_dir_echo')
-            );
-    }
-    // }}}
-    // {{{ static function cli_command_inf_tree
-    /**
-     * Cli Command Inf Tree
-     *
-     * @return string  The description of a directory tree for a Phar archive.
-     */
-    static function cli_cmd_inf_tree()
-    {
-        return "Get a directory tree for a PHAR archive.";
-    }
-    // }}}
-    // {{{ static function cli_cmd_arg_tree
-    /**
-     * Cli Command Argument Tree
-     *
-     * @return string Arguments in URL format.
-     */
-    static function cli_cmd_arg_tree()
-    {
-        return self::phar_args('Fix', 'pharurl');
-    }
-    // }}}
-    // {{{ public function cli_cmd_run_tree
-    /**
-     * Cli Command Run Tree
-     * 
-     * Set the phar_dir_operation with a directorygraphiterator.
-     * 
-     * @see DirectoryGraphIterator
-     * @see $this->phar_dir_operation
-     *
-     */
-    public function cli_cmd_run_tree()
-    {
-        $this->phar_dir_operation(
-            new DirectoryGraphIterator(
-                $this->args['f']['val']), 
-                array($this, 'phar_dir_echo')
-            );
-    }
-    // }}}
-    // {{{ cli_cmd_inf_extract
-    /**
-     * Cli Command Inf Extract
-     *
-     * @return string The description of the command extra to a directory.
-     */
-    static function cli_cmd_inf_extract()
-    {
-        return "Extract a PHAR package to a directory.";
-    }
-    // }}}
-    // {{{ static function cli_cmd_arg_extract
-    /**
-     * Cli Command Arguments Extract
-     * 
-     * The arguments for the extract function.
-     *
-     * @return array  The arguments for the extraction.
-     */
-    static function cli_cmd_arg_extract()
-    {
-        $args = self::phar_args('Fix', 'phar');
-        
-        $args[''] = array(
-            'type' => 'dir',  
-            'val' => '.',                 
-            'inf' => '         Directory to extract to (defaults to \'.\').',
-        );
-        
-        return $args;
-    }
-    // }}}
-    // {{{ public function cli_cmd_run_extract
-    /**
-     * Run Extract
-     * 
-     * Run the extraction of a phar Archive.
-     *
-     * @see $this->phar_dir_operation
-     */
-    public function cli_cmd_run_extract()
-    {
-        $dir = $this->args['']['val'];
-        
-        if (is_array($dir)) {
-            if (count($dir) != 1) {
-                self::error("Only one target directory allowed.\n");
-            } else {
-                $dir = $dir[0];
-            }
-        }
-        
-        $phar = $args['f']['val'];
-        $base = $phar->getPathname();
-        $bend = strpos($base, '.phar');
-        $bend = strpos($base, '/', $bend);
-        $base = substr($base, 0, $bend + 1);
-        $blen = strlen($base);
-
-        $this->phar_dir_operation(
-            new RecursiveIteratorIterator($phar), 
-            array($this, 'phar_dir_extract'), 
-            array($blen, $dir)
-        );
-    }
-    // }}}
-    // {{{ public function phar_dir_extract
-    /**
-     * Extract to a directory
-     * 
-     * This function will extract the content of a Phar
-     * to a directory and create new files and directories
-     * depending on the permissions on that folder.
-     *
-     * @param string $pn
-     * @param string $f     The file name
-     * @param array $args   The directory and Blen informations
-     */
-    public function phar_dir_extract($pn, $f, $args)
-    {
-        $blen   = $args[0];
-        $dir    = $args[1];
-        $sub    = substr($pn, $blen);
-        $target = $dir . '/' . $sub;
-        
-        if (!file_exists(dirname($target))) {
-            if (!is_writable(dirname($target))) {
-                self::error("Operation could not be completed\n");
-            }
-            
-            mkdir(dirname($target));
-        }
-        
-        echo "$sub";
-        
-        if (!@copy($f, $target)) {
-            echo " ...error\n";
-        } else {
-            echo " ...ok\n";
-        }
-    }
-    // }}}
-    // {{{ static function cli_cmd_inf_delete
-    /**
-     * Delete an entry from a phar information.
-     *
-     * @return string The information
-     */
-    static function cli_cmd_inf_delete()
-    {
-        return 'Delete entry from a PHAR archive';
-    }
-    // }}}
-    // {{{ static function cli_cmd_arg_delete
-    /**
-     * The cli command argument for deleting.
-     *
-     * @return array informations about the arguments to use.
-     */
-    static function cli_cmd_arg_delete()
-    {
-        return self::phar_args('FE', 'phar');
-    }
-    // }}}
-    // {{{ public function cli_cmd_run_delete
-    /**
-     * Deleting execution
-     *
-     * Execute the deleting of the file from the phar archive.
-     */
-    public function cli_cmd_run_delete()
-    {
-        $phar  = $this->args['f']['val'];
-        $entry = $this->args['e']['val'];
-
-       $phar->startBuffering();
-       unset($phar[$entry]);
-       $phar->stopBuffering();
-    }
-    // }}}
-    // {{{ static function cli_cmd_inf_add
-    /**
-     * Client comment add file information
-     *
-     * @return string The description of the feature
-     */
-    static function cli_cmd_inf_add()
-    {
-        return "Add entries to a PHAR package.";
-    }
-    // }}}
-    // {{{ static function cli_cmd_arg_add
-    /**
-     * Add a file arguments
-     */
-    static function cli_cmd_arg_add()
-    {
-        $args = self::phar_args('acFilx', 'phar');
-        $args[''] = array(
-            'type'     => 'any',     
-            'val'      => NULL,      
-            'required' => 1, 
-            'inf'      => '         Any number of input files and directories. If -i is in use then ONLY files and matching thegiven regular expression are being packed. If -x is given then files matching that regular expression are NOT being packed.',
-        );
-        return $args;
-    }
-    // }}}
-    // {{{ public functio cli_cmd_run_add
-    /**
-     * Add a file
-     *
-     * Run the action of adding a file to
-     * a phar archive.
-     */
-    public function cli_cmd_run_add()
-    {
-        $compress= $this->args['c']['val'];
-        $phar    = $this->args['f']['val'];
-        $regex   = $this->args['i']['val'];
-        $level   = $this->args['l']['val'];
-        $invregex= $this->args['x']['val'];
-        $input   = $this->args['']['val'];
-
-        $phar->startBuffering();
-
-        if (!is_array($input)) {
-            $this->phar_add($phar, $level, $input, $regex, $invregex, NULL, $compress);
-        } else {
-            foreach($input as $i) {
-                $this->phar_add($phar, $level, $i, $regex, $invregex, NULL, $compress);
-            }
-        }
-        $phar->stopBuffering();
-        exit(0);
-    }
-    // }}}
-    // {{{ public function cli_cmd_inf_stub_set
-    /**
-     * Set the stup of a phar file.
-     *
-     * @return string The stub set description.
-     */
-    public function cli_cmd_inf_stub_set()
-    {
-        return "Set the stub of a PHAR file. " . 
-               "If no input file is specified as stub then stdin is being used.";
-    }
-    // }}}
-    // {{{ public function cli_cmd_arg_stub_set
-    /**
-     * Set the argument stub
-     *
-     * @return string arguments for a stub 
-     */
-    public function cli_cmd_arg_stub_set()
-    {
-        $args = self::phar_args('Fs', 'phar');
-        $args['s']['val'] = 'php://stdin';
-        return $args;
-    }
-    // }}}
-    // {{{ public function cli_cmd_run_stub_set
-    /**
-     * Cli Command run stub set
-     *
-     * @see   $phar->setStub()
-     */
-    public function cli_cmd_run_stub_set()
-    {
-        $phar = $this->args['f']['val'];
-        $stub = $this->args['s']['val'];
-
-        $phar->setStub(file_get_contents($stub));
-    }
-    // }}}
-    // {{{ public function cli_cmd_inf_stub_get
-    /**
-     * Get the command stub infos.
-     *
-     * @return string a description of the stub of a Phar file.
-     */
-    public function cli_cmd_inf_stub_get()
-    {
-        return "Get the stub of a PHAR file. " .  
-               "If no output file is specified as stub then stdout is being used.";
-    }
-    // }}}
-    // {{{ public function cli_cmd_arg_stub_get
-    /**
-     * Get the argument stub
-     *
-     * @return array $args The arguments passed to the stub.
-     */
-    public function cli_cmd_arg_stub_get()
-    {
-        $args = self::phar_args('Fs', 'phar');
-        $args['s']['val'] = 'php://stdin';
-        return $args;
-    }
-    // }}}
-    // {{{ public function cli_cmd_run_stub_get
-    /**
-     * Cli Command Run Stub
-     * 
-     * Get arguments and store them into a stub.
-     *
-     * @param arguments $args
-     * @see   $this->args
-     */
-    public function cli_cmd_run_stub_get($args)
-    {
-        $phar = $this->args['f']['val'];
-        $stub = $this->args['s']['val'];
-
-        file_put_contents($stub, $phar->getStub());
-    }
-    // }}}
-    // {{{ public function cli_cmd_inf_compress
-    /**
-     * Cli Command Inf Compress
-     * 
-     * Cli Command compress informations
-     *
-     * @return string A description of the command.
-     */
-    public function cli_cmd_inf_compress()
-    {
-        return "Compress or uncompress all files or a selected entry.";
-    }
-    // }}}
-    // {{{ public function cli_cmd_arg_cmpress
-    /**
-     * Cli Command Arg Compress
-     *
-     * @return array The arguments for compress
-     */
-    public function cli_cmd_arg_compress()
-    {
-        return self::phar_args('FCe', 'phar');
-    }
-    // }}}
-    // {{{ public function cli_cmd_run_compress
-    /**
-     * Cli Command Run Compress
-     *
-     * @see $this->args
-     */
-    public function cli_cmd_run_compress()
-    {
-        $phar  = $this->args['f']['val'];
-        $entry = $this->args['e']['val'];
-
-        switch($this->args['c']['val']) {
-            case 'gz':
-            case 'gzip':
-                if (isset($entry)) {
-                    $phar[$entry]->setCompressedGZ();
-                } else {
-                    $phar->compressAllFilesGZ();
-                }
-                break;
-            case 'bz2':
-            case 'bzip2':
-                if (isset($entry)) {
-                    $phar[$entry]->setCompressedBZIP2();
-                } else {
-                    $phar->compressAllFilesBZIP2();
-                }
-                break;
-            default:
-                if (isset($entry)) {
-                    $phar[$entry]->setUncompressed();
-                } else {
-                    $phar->uncompressAllFiles();
-                }
-                break;
-        }
-    }
-    // }}}
-    // {{{ public function cli_cmd_inf_sign
-    /**
-     * Cli Command Info Signature
-     *
-     * @return string A description of the signature arguments.
-     */
-    public function cli_cmd_inf_sign()
-    {
-        return "Set signature hash algorithm.";
-    }
-    // }}}
-    // {{{ public function cli_cmd_arg_sign
-    /**
-     * Cli Command Argument Sign
-     *
-     * @return array Arguments for Signature
-     */
-    public function cli_cmd_arg_sign()
-    {
-        return self::phar_args('FH', 'phar');
-    }
-    // }}}
-    // {{{ public function cli_cmd_run_sign
-    /**
-     * Cli Command Run Signature
-     *
-     * @see $phar->setSignaturealgorithm
-     */
-    public function cli_cmd_run_sign()
-    {
-        $phar = $this->args['f']['val'];
-        $hash = $this->args['h']['val'];
-
-        $phar->setSignatureAlgorithm($hash);
-    }
-    // }}}
-    // {{{ public function cli_cmd_inf_meta_set
-    /**
-     * Cli Command Inf Meta Set
-     *
-     * @return string A description 
-     */
-    public function cli_cmd_inf_meta_set()
-    {
-        return "Set meta data of a PHAR entry or a PHAR package using serialized input. " . 
-               "If no input file is specified for meta data then stdin is being used." . 
-               "You can also specify a particular index using -k. In that case the metadata is " .
-               "expected to be an array and the value of the given index is being set. If " .
-               "the metadata is not present or empty a new array will be created. If the " .
-               "metadata is present and a flat value then the return value is 1. Also using -k " .
-               "the input is been taken directly rather then being serialized.";
-    }
-    // }}}
-    // {{{ public function cli_cmd_arg_meta_set
-    /**
-     * Cli Command Argument Meta Set
-     *
-     * @return array  The arguments for meta set
-     */
-    public function cli_cmd_arg_meta_set()
-    {
-        return self::phar_args('FekM', 'phar');
-    }
-    // }}}
-    // {{{ public function cli_cmd_run_met_set
-    /**
-     * Cli Command Run Metaset
-     *
-     * @see $phar->startBuffering
-     * @see $phar->setMetadata
-     * @see $phar->stopBuffering
-     */
-    public function cli_cmd_run_meta_set()
-    {
-        $phar  = $this->args['f']['val'];
-        $entry = $this->args['e']['val'];
-        $index = $this->args['k']['val'];
-        $meta  = $this->args['m']['val'];
-
-        $phar->startBuffering();
-
-        if (isset($index)) {
-            if (isset($entry)) {
-                if ($phar[$entry]->hasMetadata()) {
-                    $old = $phar[$entry]->getMetadata();
-                } else {
-                    $old = array();
-                }
-            } else {
-                if ($phar->hasMetadata()) {
-                    $old = $phar->getMetadata();
-                } else {
-                    $old = array();
-                }
-            }
-
-            if (!is_array($old)) {
-                self::error('Metadata is a flat value while an index operation was issued.');
-            }
-
-            $old[$index] = $meta;
-            $meta = $old;
-        } else {
-            $meta = unserialize($meta);
-        }
-        
-        if (isset($entry)) {
-            $phar[$entry]->setMetadata($meta);
-        } else {
-            $phar->setMetadata($meta);
-        }
-        $phar->stopBuffering();
-    }
-    // }}}
-    // {{{ public function cli_cmd_inf_met_get
-    /**
-     * Cli Command Inf Metaget
-     *
-     * @return string A description of the metaget arguments
-     */
-    public function cli_cmd_inf_meta_get()
-    {
-        return "Get meta information of a PHAR entry or a PHAR package in serialized from. " .
-               "If no output file is specified for meta data then stdout is being used.\n" . 
-               "You can also specify a particular index using -k. In that case the metadata is " .
-               "expected to be an array and the value of the given index is returned using echo " .
-               "rather than using serialize. If that index does not exist or no meta data is " .
-               "present then the return value is 1.";
-    }
-    // }}}
-    // {{{ public function cli_cmd_arg_meta_get
-    /**
-     * Cli Command arg metaget
-     *
-     * @return array  The arguments for meta get.
-     */
-    public function cli_cmd_arg_meta_get()
-    {
-        return self::phar_args('Fek', 'phar');
-    }
-    // }}}
-    // {{{ public function cli_cmd_run_meta_get
-    /**
-     * Cli Command Run Metaget
-     *
-     * @see $this->args
-     * @see $phar[$x]->hasMetadata()
-     * @see $phar->getMetadata()
-     */
-    public function cli_cmd_run_meta_get()
-    {
-        $phar  = $this->args['f']['val'];
-        $entry = $this->args['e']['val'];
-        $index = $this->args['k']['val'];
-
-        if (isset($entry)) {
-            if (!$phar[$entry]->hasMetadata()) {
-                exit(1);
-            }
-            echo serialize($phar[$entry]->getMetadata());
-        } else {
-            if (!$phar->hasMetadata()) {
-                exit(1);
-            }
-            $meta = $phar->getMetadata();
-        }
-
-        if (isset($index)) {
-            if (isset($index)) {
-                if (isset($meta[$index])) {
-                    echo $meta[$index];
-                    exit(0);
-                } else {
-                    exit(1);
-                }
-            } else {
-                echo serialize($meta);
-            }
-        }
-    }
-    // }}}
-    // {{{ public function cli_cmd_inf_meta_del
-    /**
-     * Cli Command Inf Metadel
-     *
-     * @return string A description of the metadel function
-     */
-    public function cli_cmd_inf_meta_del()
-    {
-        return "Delete meta information of a PHAR entry or a PHAR package.\n" . 
-               "If -k is given then the metadata is expected to be an array " . 
-               "and the given index is being deleted.\n" .
-               "If something was deleted the return value is 0 otherwise it is 1.";
-    }
-    // }}}
-    // {{{ public function cli_cmd_arg_meta_del
-    /**
-     * CliC ommand Arg Metadelete
-     *
-     * @return array The arguments for metadel
-     */
-    public function cli_cmd_arg_meta_del()
-    {
-        return self::phar_args('Fek', 'phar');
-    }
-    // }}}
-    // {{{ public function cli_cmd_run_meta_del
-    /**
-     * Cli Command Run MetaDel
-     *
-     * @see $phar[$x]->delMetadata()
-     * @see $phar->delMetadata()
-     */
-    public function cli_cmd_run_meta_del()
-    {
-        $phar  = $this->args['f']['val'];
-        $entry = $this->args['e']['val'];
-        $index = $this->args['k']['val'];
-
-        if (isset($entry)) {
-            if (isset($index)) {
-                if (!$phar[$entry]->hasMetadata()) {
-                    exit(1);
-                }
-                $meta = $phar[$entry]->getMetadata();
-
-                // @todo add error message here.
-                if (!is_array($meta)) {
-                    exit(1);
-                }
-
-                unset($meta[$index]);
-                $phar[$entry]->setMetadata($meta);
-            } else {
-                exit($phar[$entry]->delMetadata() ? 0 : 1);
-            }
-        } else {
-            if (isset($index)) {
-                if (!$phar->hasMetadata()) {
-                    exit(1);
-                }
-
-                $meta = $phar->getMetadata();
-
-                // @todo Add error message
-                if (!is_array($meta)) {
-                    exit(1);
-                }
-
-                unset($meta[$index]);
-                $phar->setMetadata($meta);
-            } else {
-                exit($phar->delMetadata() ? 0 : 1);
-            }
-        }
-    }
-    // }}}
-    // {{{ public function cli_cmd_inf_info
-    /**
-     * CLi Command Inf Info
-     *
-     * @return string A description about the info commands.
-     */
-    public function cli_cmd_inf_info()
-    {
-        return "Get information about a PHAR package.\n" . 
-               "By using -k it is possible to return a single value.";
-    }
-    // }}}
-    // {{{ public function cli_cmd_arg_info
-    /**
-     * Cli Command Arg Infos
-     *
-     * @return array The arguments for info command.
-     */
-    public function cli_cmd_arg_info()
-    {
-        return self::phar_args('Fk', 'phar');
-    }
-    // }}}
-    // {{{ public function cli_cmd_run_info
-    /**
-     * Cli Command Run Info
-     *
-     * @param args $args
-     */
-    public function cli_cmd_run_info()
-    {
-        $phar  = $this->args['f']['val'];
-        $index = $this->args['k']['val'];
-
-        $hash  = $phar->getSignature();
-        $infos = array();
-
-        if ($phar->getAlias()) {
-            $infos['Alias'] = $phar->getAlias();
-        }
-
-        if (!$hash) {
-            $infos['Hash-type'] = 'NONE';
-        } else {
-            $infos['Hash-type'] = $hash['hash_type'];
-            $infos['Hash'] = $hash['hash'];
-        }
-
-        $csize   = 0;
-        $usize   = 0;
-        $count   = 0;
-        $ccount  = 0;
-        $ucount  = 0;
-        $mcount  = 0;
-        $compalg = array('GZ'=>0, 'BZ2'=>0);
-
-        foreach(new RecursiveIteratorIterator($phar) as $ent) {
-            $count++;
-            if ($ent->isCompressed()) {
-                $ccount++;
-                $csize += $ent->getCompressedSize();
-                if ($ent->isCompressedGZ()) {
-                    $compalg['GZ']++;
-                } elseif ($ent->isCompressedBZIP2()) {
-                    $compalg['BZ2']++;
-                }
-            } else {
-                $ucount++;
-                $csize += $ent->getSize();
-            }
-            
-            $usize += $ent->getSize();
-            
-            if ($ent->hasMetadata()) {
-                $mcount++;
-            }
-        }
-
-        $infos['Entries']            = $count;
-        $infos['Uncompressed-files'] = $ucount;
-        $infos['Compressed-files']   = $ccount;
-        $infos['Compressed-gz']      = $compalg['GZ'];
-        $infos['Compressed-bz2']     = $compalg['BZ2'];
-        $infos['Uncompressed-size']  = $usize;
-        $infos['Compressed-size']    = $csize;
-        $infos['Compression-ratio']  = sprintf('%.3g%%', $usize ? ($csize * 100) / $usize : 100);
-        $infos['Metadata-global']    = $phar->hasMetadata() * 1;
-        $infos['Metadata-files']     = $mcount;
-        $infos['Stub-size']          = strlen($phar->getStub());
-
-        if (isset($index)) {
-            if (!isset($infos[$index])) {
-                self::error("Requested value does not exist.\n");
-            }
-
-            echo $infos[$index];
-            exit(0);
-        }
-        
-        $l = 0;
-        foreach($infos as $which => $val) {
-            $l = max(strlen($which), $l);
-        }
-        
-        foreach($infos as $which => $val) {
-            echo $which . ':' . str_repeat(' ', $l + 1 - strlen($which)) . $val . "\n";
-        }
-    }
-    // }}}
-}
-// }}}
-
-}
-
-
-new PharCommand($argc, $argv);