diff --git a/application/controllers/Labels.php b/application/controllers/Labels.php index 9b813de0..30633250 100644 --- a/application/controllers/Labels.php +++ b/application/controllers/Labels.php @@ -1,5 +1,6 @@ load->view('interface_assets/header', $data); $this->load->view('labels/index'); $this->load->view('interface_assets/footer', $footerData); - + } /* @@ -62,9 +63,9 @@ class Labels extends CI_Controller { | | Shows the form used to create a label type. | - */ + */ public function create() { - + $data['page_title'] = "Create Label Type"; $this->load->library('form_validation'); @@ -81,10 +82,10 @@ class Labels extends CI_Controller { { $this->load->model('labels_model'); $this->labels_model->addLabel(); - + redirect('labels'); } - + } public function printids() { @@ -103,11 +104,13 @@ class Labels extends CI_Controller { $this->prepareLabel($result); } - + function prepareLabel($qsos, $jscall = false) { $this->load->model('labels_model'); $label = $this->labels_model->getDefaultLabel(); - + $label->font='DejaVuSans'; // Fix font to DejaVuSans + + try { if ($label) { $pdf = new PDF_Label(array( @@ -144,20 +147,20 @@ class Labels extends CI_Controller { } } define('FPDF_FONTPATH', './src/Label/font/'); - + $pdf->AddPage(); - - if ($label->font == 'DejaVuSans') { + + if ($label->font == 'DejaVuSans') { // leave this here, for future Use $pdf->AddFont($label->font,'','DejaVuSansMono.ttf',true); $pdf->SetFont($label->font); } else { $pdf->AddFont($label->font); $pdf->SetFont($label->font); } - + if ($qsos->num_rows() > 0) { if ($label->qsos == 1) { - $this->makeOneQsoLabel($qsos->result(), $pdf); + $this->makeMultiQsoLabel($qsos->result(), $pdf,1); } else { $this->makeMultiQsoLabel($qsos->result(), $pdf, $label->qsos); } @@ -168,31 +171,19 @@ class Labels extends CI_Controller { $pdf->Output(); } - function makeOneQsoLabel($qsos, $pdf) { - foreach($qsos as $qso) { - $time = strtotime($qso->COL_TIME_ON); - $myFormatForView = date("d/m/Y H:i", $time); - if($qso->COL_SAT_NAME != "") { - $text = sprintf("%s\n\n%s %s\n%s %s \n\n%s", 'To: '.$qso->COL_CALL, $myFormatForView, 'on '.$qso->COL_BAND.' 2x'.$qso->COL_MODE.' RST '.$qso->COL_RST_SENT.'', 'Satellite: '.$qso->COL_SAT_NAME.' Mode: '.strtoupper($qso->COL_SAT_MODE).' ', '', 'Thanks for QSO.'); - } else { - $text = sprintf("%s\n\n%s %s\n%s %s \n\n%s", 'To: '.$qso->COL_CALL, $myFormatForView, 'on '.$qso->COL_BAND.' 2x'.$qso->COL_MODE.' RST '.$qso->COL_RST_SENT.'', '', '', 'Thanks for QSO.'); - } - - $pdf->Add_Label($text); - } - } - function makeMultiQsoLabel($qsos, $pdf, $numberofqsos) { $text = ''; $current_callsign = ''; + $current_sat = ''; $qso_data = []; foreach($qsos as $qso) { - if ($qso->COL_CALL !== $current_callsign) { + if (($qso->COL_SAT_NAME !== $current_sat) || ($qso->COL_CALL !== $current_callsign)) { if (!empty($qso_data)) { - $this->makeLabel($pdf, $current_callsign, $qso_data, $numberofqsos); + $this->finalizeData($pdf, $current_callsign, $qso_data, $numberofqsos); $qso_data = []; } $current_callsign = $qso->COL_CALL; + $current_sat = $qso->COL_SAT_NAME; } $qso_data[] = [ @@ -203,47 +194,63 @@ class Labels extends CI_Controller { 'mygrid' => $qso->station_gridsquare, 'sat' => $qso->COL_SAT_NAME, 'sat_mode' => $qso->COL_SAT_MODE, + 'qsl_recvd' => $qso->COL_QSL_RCVD ]; } if (!empty($qso_data)) { - $this->makeLabel($pdf, $current_callsign, $qso_data, $numberofqsos); + $this->finalizeData($pdf, $current_callsign, $qso_data, $numberofqsos); } } + // New begin - function makeLabel($pdf, $current_callsign, $qso_data, $numberofqsos) { - $text = 'To: ' . $current_callsign . "\n\n"; - $count = 0; - $qsotext = ''; - foreach ($qso_data as $key => $qso) { + function finalizeData($pdf, $current_callsign, &$preliminaryData, $qso_per_label) { + $tableData = []; + $count_qso = 0; + $qso=[]; + foreach ($preliminaryData as $key => $row) { + $qso=$row; $time = strtotime($qso['time']); - $myFormatForView = date("d/m/Y H:i", $time); + $myFormatForView = date("Y-m-d H:i", $time); + $rowData = [ + 'Date/Time (UTC)' => $myFormatForView, + 'Band' => $row['band'], + 'Mode' => $row['mode'], + 'RST' => $row['rst'], + ]; + $tableData[] = $rowData; + $count_qso++; - if($qso['sat'] != "") { - $qsotext .= sprintf("%s %s %s %s\n", $myFormatForView, 'on '.$qso['band'].' 2x'.$qso['mode'].' RST '.$qso['rst'].'', 'Satellite: '.$qso['sat'].' Mode: '.strtoupper($qso['sat_mode']).' ', ''); - } else { - $qsotext .= sprintf("%s %s\n", $myFormatForView, 'on '.$qso['band'].' 2x'.$qso['mode'].' RST '.$qso['rst']); + if($count_qso == $qso_per_label){ + $this->generateLabel($pdf, $current_callsign, $tableData,$count_qso,$qso); + $tableData = []; // reset the data + $count_qso = 0; // reset the counter } - $count++; - - if ($count == $numberofqsos) { - $text .= $qsotext; - $text .= "\n" . 'Thanks for QSOs.'; - $pdf->Add_Label($text); - $text = 'To: ' . $current_callsign . "\n\n"; - $count = 0; - $qsotext = ''; - } - unset($qso_data[$key]); + unset($preliminaryData[$key]); } - - if ($qsotext != '') { - $text .= $qsotext; - $text .= "\n" . 'Thanks for QSOs.'; - $pdf->Add_Label($text); + // generate label for remaining QSOs + if($count_qso > 0){ + $this->generateLabel($pdf, $current_callsign, $tableData,$count_qso,$qso); + $preliminaryData = []; // reset the data } - } + function generateLabel($pdf, $current_callsign, $tableData,$numofqsos,$qso){ + $builder = new \AsciiTable\Builder(); + $builder->addRows($tableData); + $text = "Confirming QSO".($numofqsos>1 ? 's' : '')." with "; + $text .= $current_callsign; + $text .= "\n"; + $text .= $builder->renderTable(); + if($qso['sat'] != "") { + $text .= "\n".'Satellite: '.$qso['sat'].' Mode: '.strtoupper($qso['sat_mode'][0]).'/'.strtoupper($qso['sat_mode'][1]); + } + $text .= "\nThanks for the QSO".($numofqsos>1 ? 's' : ''); + $text .= " | ".($qso['qsl_recvd'] == 'Y' ? 'TNX' : 'PSE')." QSL"; + $pdf->Add_Label($text); + } + + // New End + public function edit($id) { $this->load->model('labels_model'); @@ -278,4 +285,4 @@ class Labels extends CI_Controller { $this->labels_model->saveDefaultLabel($id); } -} \ No newline at end of file +} diff --git a/application/models/Labels_model.php b/application/models/Labels_model.php index c0c50494..bdce7eb8 100644 --- a/application/models/Labels_model.php +++ b/application/models/Labels_model.php @@ -123,6 +123,10 @@ class Labels_model extends CI_Model { $this->db->where('station_profile.user_id', $this->session->userdata('user_id')); $this->db->where_in('COL_QSL_SENT', array('R', 'Q')); $this->db->order_by("COL_DXCC", "ASC"); + $this->db->order_by("COL_CALL", "ASC"); + $this->db->order_by("COL_SAT_NAME", "ASC"); + $this->db->order_by("COL_TIME_ON", "ASC"); + $this->db->order_by("COL_MODE", "ASC"); $query = $this->db->get($this->config->item('table_name')); return $query; @@ -139,4 +143,4 @@ class Labels_model extends CI_Model { return $query; } -} \ No newline at end of file +} diff --git a/application/views/labels/create.php b/application/views/labels/create.php index 046d9674..daf88f55 100644 --- a/application/views/labels/create.php +++ b/application/views/labels/create.php @@ -111,29 +111,6 @@ -
- -
- -
-
- @@ -141,4 +118,4 @@ -
\ No newline at end of file +
diff --git a/application/views/labels/edit.php b/application/views/labels/edit.php index 076524d9..695fded7 100644 --- a/application/views/labels/edit.php +++ b/application/views/labels/edit.php @@ -110,30 +110,6 @@ - -
- -
- -
-
- @@ -141,4 +117,4 @@ -
\ No newline at end of file +
diff --git a/src/Label/vendor/autoload.php b/src/Label/vendor/autoload.php new file mode 100644 index 00000000..e09b8e09 --- /dev/null +++ b/src/Label/vendor/autoload.php @@ -0,0 +1,25 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier + * @author Jordi Boggiano + * @see https://www.php-fig.org/psr/psr-0/ + * @see https://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + /** @var \Closure(string):void */ + private static $includeFile; + + /** @var ?string */ + private $vendorDir; + + // PSR-4 + /** + * @var array[] + * @psalm-var array> + */ + private $prefixLengthsPsr4 = array(); + /** + * @var array[] + * @psalm-var array> + */ + private $prefixDirsPsr4 = array(); + /** + * @var array[] + * @psalm-var array + */ + private $fallbackDirsPsr4 = array(); + + // PSR-0 + /** + * @var array[] + * @psalm-var array> + */ + private $prefixesPsr0 = array(); + /** + * @var array[] + * @psalm-var array + */ + private $fallbackDirsPsr0 = array(); + + /** @var bool */ + private $useIncludePath = false; + + /** + * @var string[] + * @psalm-var array + */ + private $classMap = array(); + + /** @var bool */ + private $classMapAuthoritative = false; + + /** + * @var bool[] + * @psalm-var array + */ + private $missingClasses = array(); + + /** @var ?string */ + private $apcuPrefix; + + /** + * @var self[] + */ + private static $registeredLoaders = array(); + + /** + * @param ?string $vendorDir + */ + public function __construct($vendorDir = null) + { + $this->vendorDir = $vendorDir; + self::initializeIncludeClosure(); + } + + /** + * @return string[] + */ + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); + } + + return array(); + } + + /** + * @return array[] + * @psalm-return array> + */ + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + /** + * @return array[] + * @psalm-return array + */ + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + /** + * @return array[] + * @psalm-return array + */ + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + /** + * @return string[] Array of classname => path + * @psalm-return array + */ + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param string[] $classMap Class to filename map + * @psalm-param array $classMap + * + * @return void + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param string[]|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + * + * @return void + */ + public function add($prefix, $paths, $prepend = false) + { + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + (array) $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + (array) $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = (array) $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + (array) $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param string[]|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + * + * @return void + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + (array) $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + (array) $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + (array) $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param string[]|string $paths The PSR-0 base directories + * + * @return void + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param string[]|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + * + * @return void + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + * + * @return void + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + * + * @return void + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * APCu prefix to use to cache found/not-found classes, if the extension is enabled. + * + * @param string|null $apcuPrefix + * + * @return void + */ + public function setApcuPrefix($apcuPrefix) + { + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; + } + + /** + * The APCu prefix in use, or null if APCu caching is not enabled. + * + * @return string|null + */ + public function getApcuPrefix() + { + return $this->apcuPrefix; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + * + * @return void + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + + if (null === $this->vendorDir) { + return; + } + + if ($prepend) { + self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; + } else { + unset(self::$registeredLoaders[$this->vendorDir]); + self::$registeredLoaders[$this->vendorDir] = $this; + } + } + + /** + * Unregisters this instance as an autoloader. + * + * @return void + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + + if (null !== $this->vendorDir) { + unset(self::$registeredLoaders[$this->vendorDir]); + } + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return true|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + $includeFile = self::$includeFile; + $includeFile($file); + + return true; + } + + return null; + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { + return false; + } + if (null !== $this->apcuPrefix) { + $file = apcu_fetch($this->apcuPrefix.$class, $hit); + if ($hit) { + return $file; + } + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if (false === $file && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if (null !== $this->apcuPrefix) { + apcu_add($this->apcuPrefix.$class, $file); + } + + if (false === $file) { + // Remember that this class does not exist. + $this->missingClasses[$class] = true; + } + + return $file; + } + + /** + * Returns the currently registered loaders indexed by their corresponding vendor directories. + * + * @return self[] + */ + public static function getRegisteredLoaders() + { + return self::$registeredLoaders; + } + + /** + * @param string $class + * @param string $ext + * @return string|false + */ + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath . '\\'; + if (isset($this->prefixDirsPsr4[$search])) { + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); + foreach ($this->prefixDirsPsr4[$search] as $dir) { + if (file_exists($file = $dir . $pathEnd)) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + + return false; + } + + /** + * @return void + */ + private static function initializeIncludeClosure() + { + if (self::$includeFile !== null) { + return; + } + + /** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + * + * @param string $file + * @return void + */ + self::$includeFile = \Closure::bind(static function($file) { + include $file; + }, null, null); + } +} diff --git a/src/Label/vendor/composer/InstalledVersions.php b/src/Label/vendor/composer/InstalledVersions.php new file mode 100644 index 00000000..51e734a7 --- /dev/null +++ b/src/Label/vendor/composer/InstalledVersions.php @@ -0,0 +1,359 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer; + +use Composer\Autoload\ClassLoader; +use Composer\Semver\VersionParser; + +/** + * This class is copied in every Composer installed project and available to all + * + * See also https://getcomposer.org/doc/07-runtime.md#installed-versions + * + * To require its presence, you can require `composer-runtime-api ^2.0` + * + * @final + */ +class InstalledVersions +{ + /** + * @var mixed[]|null + * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array}|array{}|null + */ + private static $installed; + + /** + * @var bool|null + */ + private static $canGetVendors; + + /** + * @var array[] + * @psalm-var array}> + */ + private static $installedByVendor = array(); + + /** + * Returns a list of all package names which are present, either by being installed, replaced or provided + * + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackages() + { + $packages = array(); + foreach (self::getInstalled() as $installed) { + $packages[] = array_keys($installed['versions']); + } + + if (1 === \count($packages)) { + return $packages[0]; + } + + return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); + } + + /** + * Returns a list of all package names with a specific type e.g. 'library' + * + * @param string $type + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackagesByType($type) + { + $packagesByType = array(); + + foreach (self::getInstalled() as $installed) { + foreach ($installed['versions'] as $name => $package) { + if (isset($package['type']) && $package['type'] === $type) { + $packagesByType[] = $name; + } + } + } + + return $packagesByType; + } + + /** + * Checks whether the given package is installed + * + * This also returns true if the package name is provided or replaced by another package + * + * @param string $packageName + * @param bool $includeDevRequirements + * @return bool + */ + public static function isInstalled($packageName, $includeDevRequirements = true) + { + foreach (self::getInstalled() as $installed) { + if (isset($installed['versions'][$packageName])) { + return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false; + } + } + + return false; + } + + /** + * Checks whether the given package satisfies a version constraint + * + * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call: + * + * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3') + * + * @param VersionParser $parser Install composer/semver to have access to this class and functionality + * @param string $packageName + * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package + * @return bool + */ + public static function satisfies(VersionParser $parser, $packageName, $constraint) + { + $constraint = $parser->parseConstraints((string) $constraint); + $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); + + return $provided->matches($constraint); + } + + /** + * Returns a version constraint representing all the range(s) which are installed for a given package + * + * It is easier to use this via isInstalled() with the $constraint argument if you need to check + * whether a given version of a package is installed, and not just whether it exists + * + * @param string $packageName + * @return string Version constraint usable with composer/semver + */ + public static function getVersionRanges($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + $ranges = array(); + if (isset($installed['versions'][$packageName]['pretty_version'])) { + $ranges[] = $installed['versions'][$packageName]['pretty_version']; + } + if (array_key_exists('aliases', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); + } + if (array_key_exists('replaced', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); + } + if (array_key_exists('provided', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); + } + + return implode(' || ', $ranges); + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['version'])) { + return null; + } + + return $installed['versions'][$packageName]['version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getPrettyVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['pretty_version'])) { + return null; + } + + return $installed['versions'][$packageName]['pretty_version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference + */ + public static function getReference($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['reference'])) { + return null; + } + + return $installed['versions'][$packageName]['reference']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path. + */ + public static function getInstallPath($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @return array + * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool} + */ + public static function getRootPackage() + { + $installed = self::getInstalled(); + + return $installed[0]['root']; + } + + /** + * Returns the raw installed.php data for custom implementations + * + * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. + * @return array[] + * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} + */ + public static function getRawData() + { + @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED); + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + self::$installed = include __DIR__ . '/installed.php'; + } else { + self::$installed = array(); + } + } + + return self::$installed; + } + + /** + * Returns the raw data of all installed.php which are currently loaded for custom implementations + * + * @return array[] + * @psalm-return list}> + */ + public static function getAllRawData() + { + return self::getInstalled(); + } + + /** + * Lets you reload the static array from another file + * + * This is only useful for complex integrations in which a project needs to use + * this class but then also needs to execute another project's autoloader in process, + * and wants to ensure both projects have access to their version of installed.php. + * + * A typical case would be PHPUnit, where it would need to make sure it reads all + * the data it needs from this class, then call reload() with + * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure + * the project in which it runs can then also use this class safely, without + * interference between PHPUnit's dependencies and the project's dependencies. + * + * @param array[] $data A vendor/composer/installed.php data set + * @return void + * + * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $data + */ + public static function reload($data) + { + self::$installed = $data; + self::$installedByVendor = array(); + } + + /** + * @return array[] + * @psalm-return list}> + */ + private static function getInstalled() + { + if (null === self::$canGetVendors) { + self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); + } + + $installed = array(); + + if (self::$canGetVendors) { + foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { + if (isset(self::$installedByVendor[$vendorDir])) { + $installed[] = self::$installedByVendor[$vendorDir]; + } elseif (is_file($vendorDir.'/composer/installed.php')) { + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require $vendorDir.'/composer/installed.php'; + $installed[] = self::$installedByVendor[$vendorDir] = $required; + if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { + self::$installed = $installed[count($installed) - 1]; + } + } + } + } + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require __DIR__ . '/installed.php'; + self::$installed = $required; + } else { + self::$installed = array(); + } + } + + if (self::$installed !== array()) { + $installed[] = self::$installed; + } + + return $installed; + } +} diff --git a/src/Label/vendor/composer/LICENSE b/src/Label/vendor/composer/LICENSE new file mode 100644 index 00000000..f27399a0 --- /dev/null +++ b/src/Label/vendor/composer/LICENSE @@ -0,0 +1,21 @@ + +Copyright (c) Nils Adermann, Jordi Boggiano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/src/Label/vendor/composer/autoload_classmap.php b/src/Label/vendor/composer/autoload_classmap.php new file mode 100644 index 00000000..0fb0a2c1 --- /dev/null +++ b/src/Label/vendor/composer/autoload_classmap.php @@ -0,0 +1,10 @@ + $vendorDir . '/composer/InstalledVersions.php', +); diff --git a/src/Label/vendor/composer/autoload_namespaces.php b/src/Label/vendor/composer/autoload_namespaces.php new file mode 100644 index 00000000..15a2ff3a --- /dev/null +++ b/src/Label/vendor/composer/autoload_namespaces.php @@ -0,0 +1,9 @@ + array($vendorDir . '/dekor/php-array-table/src'), + 'Ds\\' => array($vendorDir . '/php-ds/php-ds/src'), + 'AsciiTable\\' => array($vendorDir . '/malios/php-to-ascii-table/src'), +); diff --git a/src/Label/vendor/composer/autoload_real.php b/src/Label/vendor/composer/autoload_real.php new file mode 100644 index 00000000..0cd90118 --- /dev/null +++ b/src/Label/vendor/composer/autoload_real.php @@ -0,0 +1,38 @@ +register(true); + + return $loader; + } +} diff --git a/src/Label/vendor/composer/autoload_static.php b/src/Label/vendor/composer/autoload_static.php new file mode 100644 index 00000000..b985aa95 --- /dev/null +++ b/src/Label/vendor/composer/autoload_static.php @@ -0,0 +1,44 @@ + + array ( + 'Ds\\' => 3, + ), + 'A' => + array ( + 'AsciiTable\\' => 11, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'Ds\\' => + array ( + 0 => __DIR__ . '/..' . '/php-ds/php-ds/src', + ), + 'AsciiTable\\' => + array ( + 0 => __DIR__ . '/..' . '/malios/php-to-ascii-table/src', + ), + ); + + public static $classMap = array ( + 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInit6ef2b7bf933fafec62d6bf7c15d6f12f::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit6ef2b7bf933fafec62d6bf7c15d6f12f::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInit6ef2b7bf933fafec62d6bf7c15d6f12f::$classMap; + + }, null, ClassLoader::class); + } +} diff --git a/src/Label/vendor/composer/installed.json b/src/Label/vendor/composer/installed.json new file mode 100644 index 00000000..dee3a022 --- /dev/null +++ b/src/Label/vendor/composer/installed.json @@ -0,0 +1,171 @@ +{ + "packages": [ + { + "name": "dekor/php-array-table", + "version": "2.0", + "version_normalized": "2.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/deniskoronets/php-array-table.git", + "reference": "ca40b21ba84eee6a9658a33fc5f897d76baaf8e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/deniskoronets/php-array-table/zipball/ca40b21ba84eee6a9658a33fc5f897d76baaf8e5", + "reference": "ca40b21ba84eee6a9658a33fc5f897d76baaf8e5", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=5.6.0" + }, + "require-dev": { + "phpunit/phpunit": "^10" + }, + "time": "2023-02-10T10:13:42+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "dekor\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Denis Koronets", + "email": "deniskoronets@woo.zp.ua", + "homepage": "https://woo.zp.ua/" + } + ], + "description": "PHP Library for printing associative arrays as text table (similar to mysql terminal console)", + "keywords": [ + "library", + "php" + ], + "support": { + "issues": "https://github.com/deniskoronets/php-array-table/issues", + "source": "https://github.com/deniskoronets/php-array-table/tree/2.0" + }, + "install-path": "../dekor/php-array-table" + }, + { + "name": "malios/php-to-ascii-table", + "version": "v3.0.0", + "version_normalized": "3.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/malios/php-to-ascii-table.git", + "reference": "1a4621f5286f72ff0823627088e94382546b9218" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/malios/php-to-ascii-table/zipball/1a4621f5286f72ff0823627088e94382546b9218", + "reference": "1a4621f5286f72ff0823627088e94382546b9218", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": "^7|^8", + "php-ds/php-ds": "^1.1" + }, + "require-dev": { + "phpunit/phpunit": "@stable", + "vimeo/psalm": "@stable" + }, + "time": "2022-02-13T20:15:16+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "AsciiTable\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mehmed Aliosman", + "email": "dev.mehmed.aliosman@gmail.com" + } + ], + "description": "A PHP library to generate plain text tables.", + "keywords": [ + "ascii", + "php", + "plain text table", + "table" + ], + "support": { + "issues": "https://github.com/malios/php-to-ascii-table/issues", + "source": "https://github.com/malios/php-to-ascii-table/tree/v3.0.0" + }, + "install-path": "../malios/php-to-ascii-table" + }, + { + "name": "php-ds/php-ds", + "version": "v1.4.1", + "version_normalized": "1.4.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-ds/polyfill.git", + "reference": "43d2df301a9e2017f67b8c11d94a5222f9c00fd1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-ds/polyfill/zipball/43d2df301a9e2017f67b8c11d94a5222f9c00fd1", + "reference": "43d2df301a9e2017f67b8c11d94a5222f9c00fd1", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": ">=7.0" + }, + "provide": { + "ext-ds": "1.3.0" + }, + "require-dev": { + "php-ds/tests": "^1.3" + }, + "suggest": { + "ext-ds": "to improve performance and reduce memory usage" + }, + "time": "2022-03-09T20:39:30+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Ds\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Rudi Theunissen", + "email": "rudolf.theunissen@gmail.com" + } + ], + "keywords": [ + "data structures", + "ds", + "php", + "polyfill" + ], + "support": { + "issues": "https://github.com/php-ds/polyfill/issues", + "source": "https://github.com/php-ds/polyfill/tree/v1.4.1" + }, + "install-path": "../php-ds/php-ds" + } + ], + "dev": true, + "dev-package-names": [] +} diff --git a/src/Label/vendor/composer/installed.php b/src/Label/vendor/composer/installed.php new file mode 100644 index 00000000..5b86cebf --- /dev/null +++ b/src/Label/vendor/composer/installed.php @@ -0,0 +1,50 @@ + array( + 'name' => '__root__', + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', + 'reference' => '377e3875ddde0f2437686215a845f75230f7dd17', + 'type' => 'library', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'dev' => true, + ), + 'versions' => array( + '__root__' => array( + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', + 'reference' => '377e3875ddde0f2437686215a845f75230f7dd17', + 'type' => 'library', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'dekor/php-array-table' => array( + 'pretty_version' => '2.0', + 'version' => '2.0.0.0', + 'reference' => 'ca40b21ba84eee6a9658a33fc5f897d76baaf8e5', + 'type' => 'library', + 'install_path' => __DIR__ . '/../dekor/php-array-table', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'malios/php-to-ascii-table' => array( + 'pretty_version' => 'v3.0.0', + 'version' => '3.0.0.0', + 'reference' => '1a4621f5286f72ff0823627088e94382546b9218', + 'type' => 'library', + 'install_path' => __DIR__ . '/../malios/php-to-ascii-table', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'php-ds/php-ds' => array( + 'pretty_version' => 'v1.4.1', + 'version' => '1.4.1.0', + 'reference' => '43d2df301a9e2017f67b8c11d94a5222f9c00fd1', + 'type' => 'library', + 'install_path' => __DIR__ . '/../php-ds/php-ds', + 'aliases' => array(), + 'dev_requirement' => false, + ), + ), +); diff --git a/src/Label/vendor/composer/platform_check.php b/src/Label/vendor/composer/platform_check.php new file mode 100644 index 00000000..f79e574b --- /dev/null +++ b/src/Label/vendor/composer/platform_check.php @@ -0,0 +1,26 @@ += 70000)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 7.0.0". You are running ' . PHP_VERSION . '.'; +} + +if ($issues) { + if (!headers_sent()) { + header('HTTP/1.1 500 Internal Server Error'); + } + if (!ini_get('display_errors')) { + if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { + fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); + } elseif (!headers_sent()) { + echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; + } + } + trigger_error( + 'Composer detected issues in your platform: ' . implode(' ', $issues), + E_USER_ERROR + ); +} diff --git a/src/Label/vendor/malios/php-to-ascii-table/.gitignore b/src/Label/vendor/malios/php-to-ascii-table/.gitignore new file mode 100644 index 00000000..4c36e385 --- /dev/null +++ b/src/Label/vendor/malios/php-to-ascii-table/.gitignore @@ -0,0 +1,2 @@ +.idea/ +vendor/ diff --git a/src/Label/vendor/malios/php-to-ascii-table/LICENSE.md b/src/Label/vendor/malios/php-to-ascii-table/LICENSE.md new file mode 100644 index 00000000..20a68f33 --- /dev/null +++ b/src/Label/vendor/malios/php-to-ascii-table/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 Mehmed Aliosman + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/src/Label/vendor/malios/php-to-ascii-table/README.md b/src/Label/vendor/malios/php-to-ascii-table/README.md new file mode 100644 index 00000000..46040aa6 --- /dev/null +++ b/src/Label/vendor/malios/php-to-ascii-table/README.md @@ -0,0 +1,116 @@ +# php-to-ascii-table +A small PHP library for generating plain text tables. + +![example table](assets/table.png) + +## Getting Started +### Prerequisites + +- PHP >= 7 +- ext-mbstring +- Optionally Install [php-ds](https://github.com/php-ds/extension) extension (Recommended). + +### Installation + +Install via composer: + +```bash +$ composer require malios/php-to-ascii-table + +``` + +## Usage + +```php +addRows([ + [ + 'Order No' => 'A0001', + 'Product Name' => 'Intel CPU', + 'Price' => 700.00, + 'Quantity' => 1 + ], + [ + 'Order No' => 'A0002', + 'Product Name' => 'Hard disk 10TB', + 'Price' => 500.00, + 'Quantity' => 2 + ], + [ + 'Order No' => 'A0003', + 'Product Name' => 'Dell Laptop', + 'Price' => 11600.00, + 'Quantity' => 8 + ], + [ + 'Order No' => 'A0004', + 'Product Name' => 'Intel CPU', + 'Price' => 5200.00, + 'Quantity' => 3 + ] + ]); + + $builder->addRow([ + 'Order No' => 'A0005', + 'Product Name' => 'A4Tech Mouse', + 'Price' => 100.00, + 'Quantity' => 10 + ]); + + $builder->setTitle('Product List'); + + echo $builder->renderTable(); + + + // Show only some fields + + $builder->showColumns(['Order No', 'Product Name', 'Quantity']); + + echo $builder->renderTable(); + +``` +### Build table from objects +You can build table form any object that implements JsonSerializable interface. + +```php +name = $name; + $this->age = $age; + } + + public function jsonSerialize() + { + return [ + 'name' => $this->name, + 'age' => $this->age + ]; + } + } + + $builder = new \AsciiTable\Builder(); + + $builder->addRow(new Person('John', 25)); + $builder->addRow(new Person('Bill', 30)); + + echo $builder->renderTable(); + +``` + +## Contributing + +All contributors are welcome. You can open a new issue or submit a pull request. +See [CONTRIBUTING.md](docs/CONTRIBUTING.md) for details. + +## License + +This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details. diff --git a/src/Label/vendor/malios/php-to-ascii-table/assets/table.png b/src/Label/vendor/malios/php-to-ascii-table/assets/table.png new file mode 100644 index 00000000..4df98037 Binary files /dev/null and b/src/Label/vendor/malios/php-to-ascii-table/assets/table.png differ diff --git a/src/Label/vendor/malios/php-to-ascii-table/composer.json b/src/Label/vendor/malios/php-to-ascii-table/composer.json new file mode 100644 index 00000000..a61cfeee --- /dev/null +++ b/src/Label/vendor/malios/php-to-ascii-table/composer.json @@ -0,0 +1,46 @@ +{ + "name": "malios/php-to-ascii-table", + "description": "A PHP library to generate plain text tables.", + "type": "library", + "keywords": [ + "php", + "table", + "ascii", + "plain text table" + ], + "authors": [ + { + "name": "Mehmed Aliosman", + "email": "dev.mehmed.aliosman@gmail.com" + } + ], + "license": "MIT", + "require": { + "php": "^7|^8", + "php-ds/php-ds": "^1.1", + "ext-mbstring": "*" + }, + "require-dev": { + "phpunit/phpunit": "@stable", + "vimeo/psalm": "@stable" + }, + "minimum-stability": "dev", + "autoload": { + "psr-4": { + "AsciiTable\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "AsciiTable\\Test\\": "tests/" + } + }, + "scripts": { + "test": [ + "@phpunit", + "@psalm" + ], + "phpunit": "phpunit tests/ colors=always", + "psalm": "psalm" + } +} diff --git a/src/Label/vendor/malios/php-to-ascii-table/composer.lock b/src/Label/vendor/malios/php-to-ascii-table/composer.lock new file mode 100644 index 00000000..a07970e2 --- /dev/null +++ b/src/Label/vendor/malios/php-to-ascii-table/composer.lock @@ -0,0 +1,2585 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "02916a8da4bcc0f9d2f42566f1b01d2a", + "packages": [ + { + "name": "php-ds/php-ds", + "version": "1.2.x-dev", + "source": { + "type": "git", + "url": "https://github.com/php-ds/polyfill.git", + "reference": "e1f03c9f3da643c0cd691b414d5ba89f03dde543" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-ds/polyfill/zipball/e1f03c9f3da643c0cd691b414d5ba89f03dde543", + "reference": "e1f03c9f3da643c0cd691b414d5ba89f03dde543", + "shasum": "" + }, + "require": { + "php": ">=7.0.0" + }, + "require-dev": { + "php-ds/tests": "^1.1" + }, + "suggest": { + "ext-ds": "to improve performance and reduce memory usage" + }, + "type": "library", + "autoload": { + "psr-4": { + "Ds\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Rudi Theunissen", + "email": "rudolf.theunissen@gmail.com" + } + ], + "keywords": [ + "data structures", + "ds", + "php", + "polyfill" + ], + "time": "2016-08-28T10:35:47+00:00" + } + ], + "packages-dev": [ + { + "name": "amphp/amp", + "version": "v2.4.0", + "source": { + "type": "git", + "url": "https://github.com/amphp/amp.git", + "reference": "13930a582947831bb66ff1aeac28672fd91c38ea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/amp/zipball/13930a582947831bb66ff1aeac28672fd91c38ea", + "reference": "13930a582947831bb66ff1aeac28672fd91c38ea", + "shasum": "" + }, + "require": { + "php": ">=7" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "dev-master", + "amphp/phpunit-util": "^1", + "ext-json": "*", + "phpstan/phpstan": "^0.8.5", + "phpunit/phpunit": "^6.0.9 | ^7", + "react/promise": "^2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Amp\\": "lib" + }, + "files": [ + "lib/functions.php", + "lib/Internal/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Lowrey", + "email": "rdlowrey@php.net" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Bob Weinand", + "email": "bobwei9@hotmail.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "A non-blocking concurrency framework for PHP applications.", + "homepage": "http://amphp.org/amp", + "keywords": [ + "async", + "asynchronous", + "awaitable", + "concurrency", + "event", + "event-loop", + "future", + "non-blocking", + "promise" + ], + "time": "2019-11-11T19:32:05+00:00" + }, + { + "name": "amphp/byte-stream", + "version": "v1.7.1", + "source": { + "type": "git", + "url": "https://github.com/amphp/byte-stream.git", + "reference": "9d8205686a004948475dc43f8a88d2fa5e75a113" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/byte-stream/zipball/9d8205686a004948475dc43f8a88d2fa5e75a113", + "reference": "9d8205686a004948475dc43f8a88d2fa5e75a113", + "shasum": "" + }, + "require": { + "amphp/amp": "^2" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "dev-master", + "amphp/phpunit-util": "^1", + "friendsofphp/php-cs-fixer": "^2.3", + "infection/infection": "^0.9.3", + "phpunit/phpunit": "^6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Amp\\ByteStream\\": "lib" + }, + "files": [ + "lib/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "A stream abstraction to make working with non-blocking I/O simple.", + "homepage": "http://amphp.org/byte-stream", + "keywords": [ + "amp", + "amphp", + "async", + "io", + "non-blocking", + "stream" + ], + "time": "2019-10-27T14:33:41+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "cbe23383749496fe0f373345208b79568e4bc248" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/cbe23383749496fe0f373345208b79568e4bc248", + "reference": "cbe23383749496fe0f373345208b79568e4bc248", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0", + "psr/log": "^1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "time": "2019-11-06T16:40:04+00:00" + }, + { + "name": "doctrine/instantiator", + "version": "1.3.x-dev", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "ae466f726242e637cebdd526a7d991b9433bacf1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/ae466f726242e637cebdd526a7d991b9433bacf1", + "reference": "ae466f726242e637cebdd526a7d991b9433bacf1", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "doctrine/coding-standard": "^6.0", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^0.13", + "phpstan/phpstan-phpunit": "^0.11", + "phpstan/phpstan-shim": "^0.11", + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2019-10-21T16:45:58+00:00" + }, + { + "name": "felixfbecker/advanced-json-rpc", + "version": "v3.0.4", + "source": { + "type": "git", + "url": "https://github.com/felixfbecker/php-advanced-json-rpc.git", + "reference": "23366dd0cab0a0f3fd3016bf3c0b36dec74348e7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/felixfbecker/php-advanced-json-rpc/zipball/23366dd0cab0a0f3fd3016bf3c0b36dec74348e7", + "reference": "23366dd0cab0a0f3fd3016bf3c0b36dec74348e7", + "shasum": "" + }, + "require": { + "netresearch/jsonmapper": "^1.0", + "php": ">=7.0", + "phpdocumentor/reflection-docblock": "^4.0.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "AdvancedJsonRpc\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Felix Becker", + "email": "felix.b@outlook.com" + } + ], + "description": "A more advanced JSONRPC implementation", + "time": "2019-09-12T22:41:08+00:00" + }, + { + "name": "felixfbecker/language-server-protocol", + "version": "v1.4.0", + "source": { + "type": "git", + "url": "https://github.com/felixfbecker/php-language-server-protocol.git", + "reference": "378801f6139bb74ac215d81cca1272af61df9a9f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/felixfbecker/php-language-server-protocol/zipball/378801f6139bb74ac215d81cca1272af61df9a9f", + "reference": "378801f6139bb74ac215d81cca1272af61df9a9f", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpstan/phpstan": "*", + "phpunit/phpunit": "^6.3", + "squizlabs/php_codesniffer": "^3.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "LanguageServerProtocol\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Felix Becker", + "email": "felix.b@outlook.com" + } + ], + "description": "PHP classes for the Language Server Protocol", + "keywords": [ + "language", + "microsoft", + "php", + "server" + ], + "time": "2019-06-23T21:03:50+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.x-dev", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "9012edbd1604a93cee7e7422d07a2c5776c56e0c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/9012edbd1604a93cee7e7422d07a2c5776c56e0c", + "reference": "9012edbd1604a93cee7e7422d07a2c5776c56e0c", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "replace": { + "myclabs/deep-copy": "self.version" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "time": "2019-08-26T15:40:39+00:00" + }, + { + "name": "netresearch/jsonmapper", + "version": "v1.6.0", + "source": { + "type": "git", + "url": "https://github.com/cweiske/jsonmapper.git", + "reference": "0d4d1b48d682a93b6bfedf60b88c7750e9cb0b06" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/0d4d1b48d682a93b6bfedf60b88c7750e9cb0b06", + "reference": "0d4d1b48d682a93b6bfedf60b88c7750e9cb0b06", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=5.6" + }, + "require-dev": { + "phpunit/phpunit": "~4.8.35 || ~5.7 || ~6.4", + "squizlabs/php_codesniffer": "~1.5" + }, + "type": "library", + "autoload": { + "psr-0": { + "JsonMapper": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "OSL-3.0" + ], + "authors": [ + { + "name": "Christian Weiske", + "email": "cweiske@cweiske.de", + "homepage": "http://github.com/cweiske/jsonmapper/", + "role": "Developer" + } + ], + "description": "Map nested JSON structures onto PHP classes", + "time": "2019-08-15T19:41:25+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.2.5", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "b76bbc3c51f22c570648de48e8c2d941ed5e2cf2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/b76bbc3c51f22c570648de48e8c2d941ed5e2cf2", + "reference": "b76bbc3c51f22c570648de48e8c2d941ed5e2cf2", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "0.0.4", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "time": "2019-10-25T18:33:07+00:00" + }, + { + "name": "ocramius/package-versions", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/Ocramius/PackageVersions.git", + "reference": "3a7ca6eafde0eec1b964cf967e6e71bf27ecc737" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Ocramius/PackageVersions/zipball/3a7ca6eafde0eec1b964cf967e6e71bf27ecc737", + "reference": "3a7ca6eafde0eec1b964cf967e6e71bf27ecc737", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0.0", + "php": "^7.3.0" + }, + "require-dev": { + "composer/composer": "^1.8.6", + "doctrine/coding-standard": "^6.0.0", + "ext-zip": "*", + "infection/infection": "^0.13.4", + "phpunit/phpunit": "^8.2.5", + "vimeo/psalm": "^3.4.9" + }, + "type": "composer-plugin", + "extra": { + "class": "PackageVersions\\Installer", + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-4": { + "PackageVersions\\": "src/PackageVersions" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", + "time": "2019-11-09T22:36:27+00:00" + }, + { + "name": "openlss/lib-array2xml", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/nullivex/lib-array2xml.git", + "reference": "a91f18a8dfc69ffabe5f9b068bc39bb202c81d90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nullivex/lib-array2xml/zipball/a91f18a8dfc69ffabe5f9b068bc39bb202c81d90", + "reference": "a91f18a8dfc69ffabe5f9b068bc39bb202c81d90", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "type": "library", + "autoload": { + "psr-0": { + "LSS": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Bryan Tong", + "email": "bryan@nullivex.com", + "homepage": "https://www.nullivex.com" + }, + { + "name": "Tony Butler", + "email": "spudz76@gmail.com", + "homepage": "https://www.nullivex.com" + } + ], + "description": "Array2XML conversion library credit to lalit.org", + "homepage": "https://www.nullivex.com", + "keywords": [ + "array", + "array conversion", + "xml", + "xml conversion" + ], + "time": "2019-03-29T20:06:56+00:00" + }, + { + "name": "phar-io/manifest", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "6008a32fa23816a6ac71889c80da7d58c056c2bb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/6008a32fa23816a6ac71889c80da7d58c056c2bb", + "reference": "6008a32fa23816a6ac71889c80da7d58c056c2bb", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^2.0", + "php": "^7.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "time": "2019-10-11T06:20:36+00:00" + }, + { + "name": "phar-io/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "time": "2018-07-08T19:19:57+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/63a995caa1ca9e5590304cd845c15ad6d482a62a", + "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "~6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "time": "2018-08-07T13:53:10+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "4.3.2", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/b83ff7cfcfee7827e1e78b637a5904fe6a96698e", + "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e", + "shasum": "" + }, + "require": { + "php": "^7.0", + "phpdocumentor/reflection-common": "^1.0.0 || ^2.0.0", + "phpdocumentor/type-resolver": "~0.4 || ^1.0.0", + "webmozart/assert": "^1.0" + }, + "require-dev": { + "doctrine/instantiator": "^1.0.5", + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^6.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "time": "2019-09-12T14:27:41+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "5ad886e77d4a28df9fd0c81c9a3cc191799e8f5f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/5ad886e77d4a28df9fd0c81c9a3cc191799e8f5f", + "reference": "5ad886e77d4a28df9fd0c81c9a3cc191799e8f5f", + "shasum": "" + }, + "require": { + "php": "^7.1", + "phpdocumentor/reflection-common": "^2.0" + }, + "require-dev": { + "ext-tokenizer": "^7.1", + "mockery/mockery": "~1", + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "time": "2019-10-07T19:23:43+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "1.9.0", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "f6811d96d97bdf400077a0cc100ae56aa32b9203" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/f6811d96d97bdf400077a0cc100ae56aa32b9203", + "reference": "f6811d96d97bdf400077a0cc100ae56aa32b9203", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0", + "sebastian/comparator": "^1.1|^2.0|^3.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.5|^3.2", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8.x-dev" + } + }, + "autoload": { + "psr-4": { + "Prophecy\\": "src/Prophecy" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2019-10-03T11:07:50+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "f1884187926fbb755a9aaf0b3836ad3165b478bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f1884187926fbb755a9aaf0b3836ad3165b478bf", + "reference": "f1884187926fbb755a9aaf0b3836ad3165b478bf", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-xmlwriter": "*", + "php": "^7.2", + "phpunit/php-file-iterator": "^2.0.2", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-token-stream": "^3.1.1", + "sebastian/code-unit-reverse-lookup": "^1.0.1", + "sebastian/environment": "^4.2.2", + "sebastian/version": "^2.0.1", + "theseer/tokenizer": "^1.1.3" + }, + "require-dev": { + "phpunit/phpunit": "^8.2.2" + }, + "suggest": { + "ext-xdebug": "^2.7.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2019-11-20T13:55:58+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "ee5d93c00b87b36e206f1e8407dfe3306f5fcb4d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/ee5d93c00b87b36e206f1e8407dfe3306f5fcb4d", + "reference": "ee5d93c00b87b36e206f1e8407dfe3306f5fcb4d", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2019-10-23T09:07:44+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2015-06-21T13:50:34+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "190db5a4b930a73afbba041cd3015aeb10d444d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/190db5a4b930a73afbba041cd3015aeb10d444d4", + "reference": "190db5a4b930a73afbba041cd3015aeb10d444d4", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2019-10-23T09:04:52+00:00" + }, + { + "name": "phpunit/php-token-stream", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "5bc2030589cad93e6c73ce3ccee3f5e960604a0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/5bc2030589cad93e6c73ce3ccee3f5e960604a0d", + "reference": "5bc2030589cad93e6c73ce3ccee3f5e960604a0d", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "time": "2019-10-23T09:04:36+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "8.4.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "67f9e35bffc0dd52d55d565ddbe4230454fd6a4e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/67f9e35bffc0dd52d55d565ddbe4230454fd6a4e", + "reference": "67f9e35bffc0dd52d55d565ddbe4230454fd6a4e", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.2.0", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.9.1", + "phar-io/manifest": "^1.0.3", + "phar-io/version": "^2.0.1", + "php": "^7.2", + "phpspec/prophecy": "^1.8.1", + "phpunit/php-code-coverage": "^7.0.7", + "phpunit/php-file-iterator": "^2.0.2", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-timer": "^2.1.2", + "sebastian/comparator": "^3.0.2", + "sebastian/diff": "^3.0.2", + "sebastian/environment": "^4.2.2", + "sebastian/exporter": "^3.1.1", + "sebastian/global-state": "^3.0.0", + "sebastian/object-enumerator": "^3.0.3", + "sebastian/resource-operations": "^2.0.1", + "sebastian/type": "^1.1.3", + "sebastian/version": "^2.0.1" + }, + "require-dev": { + "ext-pdo": "*" + }, + "suggest": { + "ext-soap": "*", + "ext-xdebug": "*", + "phpunit/php-invoker": "^2.0.0" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "8.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2019-11-06T09:42:23+00:00" + }, + { + "name": "psr/container", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "fc1bc363ecf887921e3897c7b1dad3587ae154eb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/fc1bc363ecf887921e3897c7b1dad3587ae154eb", + "reference": "fc1bc363ecf887921e3897c7b1dad3587ae154eb", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "time": "2019-10-04T14:07:35+00:00" + }, + { + "name": "psr/log", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "5628725d0e4d687e29575eb41f9d5ee7de33a84c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/5628725d0e4d687e29575eb41f9d5ee7de33a84c", + "reference": "5628725d0e4d687e29575eb41f9d5ee7de33a84c", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2019-11-12T16:45:05+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "5872e3737247e650995ac60e98611f69bfe8c556" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5872e3737247e650995ac60e98611f69bfe8c556", + "reference": "5872e3737247e650995ac60e98611f69bfe8c556", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "time": "2019-10-23T09:08:24+00:00" + }, + { + "name": "sebastian/comparator", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "c57ba51c28b64ef8a4b14b40bceb2c5ca19e9406" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/c57ba51c28b64ef8a4b14b40bceb2c5ca19e9406", + "reference": "c57ba51c28b64ef8a4b14b40bceb2c5ca19e9406", + "shasum": "" + }, + "require": { + "php": "^7.1", + "sebastian/diff": "^3.0", + "sebastian/exporter": "^3.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2019-10-28T09:22:49+00:00" + }, + { + "name": "sebastian/diff", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "16e54fbc971c14d98779b9c3b22572178ff9411f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/16e54fbc971c14d98779b9c3b22572178ff9411f", + "reference": "16e54fbc971c14d98779b9c3b22572178ff9411f", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.5 || ^8.0", + "symfony/process": "^2 || ^3.3 || ^4 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "time": "2019-11-18T19:26:59+00:00" + }, + { + "name": "sebastian/environment", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/464c90d7bdf5ad4e8a6aea15c091fec0603d4368", + "reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.5" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2019-11-20T08:46:58+00:00" + }, + { + "name": "sebastian/exporter", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "10b761abeab7ea48c2b89f16a7fca10d2f544d25" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/10b761abeab7ea48c2b89f16a7fca10d2f544d25", + "reference": "10b761abeab7ea48c2b89f16a7fca10d2f544d25", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2019-10-23T09:05:12+00:00" + }, + { + "name": "sebastian/global-state", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "95e10dd8f625c50dc0dcbeab936aadac79f017c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/95e10dd8f625c50dc0dcbeab936aadac79f017c7", + "reference": "95e10dd8f625c50dc0dcbeab936aadac79f017c7", + "shasum": "" + }, + "require": { + "php": "^7.2", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^8.0" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2019-10-23T09:05:27+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "6096279595e26594a68c03571fba1d7c0253f19a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/6096279595e26594a68c03571fba1d7c0253f19a", + "reference": "6096279595e26594a68c03571fba1d7c0253f19a", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "time": "2019-10-23T09:08:54+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "aff2a6b4fffc8e9f0f1de6388f3d7bd0f729dddc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/aff2a6b4fffc8e9f0f1de6388f3d7bd0f729dddc", + "reference": "aff2a6b4fffc8e9f0f1de6388f3d7bd0f729dddc", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "time": "2019-10-23T09:07:29+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "f95dcff26fa9fd4df1960c503d4180ec2f8172fd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/f95dcff26fa9fd4df1960c503d4180ec2f8172fd", + "reference": "f95dcff26fa9fd4df1960c503d4180ec2f8172fd", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2019-10-23T09:08:39+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "89893975fe3fcc2e60214471761af5e91cc7a933" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/89893975fe3fcc2e60214471761af5e91cc7a933", + "reference": "89893975fe3fcc2e60214471761af5e91cc7a933", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "time": "2019-10-23T09:09:44+00:00" + }, + { + "name": "sebastian/type", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "b4b5b44e8b89f789356aa9cd9a1f05d78a9d819a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b4b5b44e8b89f789356aa9cd9a1f05d78a9d819a", + "reference": "b4b5b44e8b89f789356aa9cd9a1f05d78a9d819a", + "shasum": "" + }, + "require": { + "php": "^7.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "time": "2019-10-23T09:06:38+00:00" + }, + { + "name": "sebastian/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2016-10-03T07:35:21+00:00" + }, + { + "name": "symfony/console", + "version": "4.4.x-dev", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "35d9077f495c6d184d9930f7a7ecbd1ad13c7ab8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/35d9077f495c6d184d9930f7a7ecbd1ad13c7ab8", + "reference": "35d9077f495c6d184d9930f7a7ecbd1ad13c7ab8", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php73": "^1.8", + "symfony/service-contracts": "^1.1|^2" + }, + "conflict": { + "symfony/dependency-injection": "<3.4", + "symfony/event-dispatcher": "<4.3|>=5", + "symfony/lock": "<4.4", + "symfony/process": "<3.3" + }, + "provide": { + "psr/log-implementation": "1.0" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "^3.4|^4.0|^5.0", + "symfony/dependency-injection": "^3.4|^4.0|^5.0", + "symfony/event-dispatcher": "^4.3", + "symfony/lock": "^4.4|^5.0", + "symfony/process": "^3.4|^4.0|^5.0", + "symfony/var-dumper": "^4.3|^5.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "https://symfony.com", + "time": "2019-11-13T07:39:40+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "550ebaac289296ce228a706d0867afc34687e3f4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/550ebaac289296ce228a706d0867afc34687e3f4", + "reference": "550ebaac289296ce228a706d0867afc34687e3f4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.12-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "time": "2019-08-06T08:03:45+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "a874bbf9135bd76175baa2c26d14312c9ef25543" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/a874bbf9135bd76175baa2c26d14312c9ef25543", + "reference": "a874bbf9135bd76175baa2c26d14312c9ef25543", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.12-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "time": "2019-09-17T10:46:08+00:00" + }, + { + "name": "symfony/polyfill-php73", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php73.git", + "reference": "2ceb49eaccb9352bff54d22570276bb75ba4a188" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/2ceb49eaccb9352bff54d22570276bb75ba4a188", + "reference": "2ceb49eaccb9352bff54d22570276bb75ba4a188", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.12-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php73\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2019-08-06T08:03:45+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "144c5e51266b281231e947b51223ba14acf1a749" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/144c5e51266b281231e947b51223ba14acf1a749", + "reference": "144c5e51266b281231e947b51223ba14acf1a749", + "shasum": "" + }, + "require": { + "php": "^7.2.5", + "psr/container": "^1.0" + }, + "suggest": { + "symfony/service-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "time": "2019-11-18T17:27:11+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.1.3", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/11336f6f84e16a720dae9d8e6ed5019efa85a0f9", + "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "time": "2019-06-13T22:48:21+00:00" + }, + { + "name": "vimeo/psalm", + "version": "3.6.6", + "source": { + "type": "git", + "url": "https://github.com/vimeo/psalm.git", + "reference": "5e17a9af104de39321c47f73b253cece9df1cf2c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vimeo/psalm/zipball/5e17a9af104de39321c47f73b253cece9df1cf2c", + "reference": "5e17a9af104de39321c47f73b253cece9df1cf2c", + "shasum": "" + }, + "require": { + "amphp/amp": "^2.1", + "amphp/byte-stream": "^1.5", + "composer/xdebug-handler": "^1.1", + "felixfbecker/advanced-json-rpc": "^3.0.3", + "felixfbecker/language-server-protocol": "^1.4", + "netresearch/jsonmapper": "^1.0", + "nikic/php-parser": "4.2.*", + "ocramius/package-versions": "^1.2", + "openlss/lib-array2xml": "^1.0", + "php": "^7.1.3", + "sebastian/diff": "^3.0", + "symfony/console": "^3.3||^4.0", + "webmozart/glob": "^4.1", + "webmozart/path-util": "^2.3" + }, + "provide": { + "psalm/psalm": "self.version" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.2", + "ext-curl": "*", + "friendsofphp/php-cs-fixer": "^2.15", + "phpmyadmin/sql-parser": "^5.0", + "phpunit/phpunit": "^7.5 || ^8.0", + "psalm/plugin-phpunit": "^0.6", + "slevomat/coding-standard": "^5.0", + "squizlabs/php_codesniffer": "3.4.0", + "symfony/process": "^4.3" + }, + "suggest": { + "ext-igbinary": "^2.0.5" + }, + "bin": [ + "psalm", + "psalter", + "psalm-language-server", + "psalm-plugin", + "psalm-refactor" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev", + "dev-2.x": "2.x-dev", + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psalm\\Plugin\\": "src/Psalm/Plugin", + "Psalm\\": "src/Psalm" + }, + "files": [ + "src/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matthew Brown" + } + ], + "description": "A static analysis tool for finding errors in PHP applications", + "keywords": [ + "code", + "inspection", + "php" + ], + "time": "2019-11-14T19:44:29+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.6.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "573381c0a64f155a0d9a23f4b0c797194805b925" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/573381c0a64f155a0d9a23f4b0c797194805b925", + "reference": "573381c0a64f155a0d9a23f4b0c797194805b925", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "vimeo/psalm": "<3.6.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36 || ^7.5.13" + }, + "type": "library", + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "time": "2019-11-24T13:36:37+00:00" + }, + { + "name": "webmozart/glob", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/webmozart/glob.git", + "reference": "8da14867b709e8776d9f6272faaf844aefc695e3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/glob/zipball/8da14867b709e8776d9f6272faaf844aefc695e3", + "reference": "8da14867b709e8776d9f6272faaf844aefc695e3", + "shasum": "" + }, + "require": { + "php": "^5.3.3|^7.0", + "webmozart/path-util": "^2.2" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1", + "symfony/filesystem": "^2.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Glob\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "A PHP implementation of Ant's glob.", + "time": "2016-08-15T15:31:26+00:00" + }, + { + "name": "webmozart/path-util", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/webmozart/path-util.git", + "reference": "95a8f7ad150c2a3773ff3c3d04f557a24c99cfd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/path-util/zipball/95a8f7ad150c2a3773ff3c3d04f557a24c99cfd2", + "reference": "95a8f7ad150c2a3773ff3c3d04f557a24c99cfd2", + "shasum": "" + }, + "require": { + "php": "^5.3.3|^7.0", + "webmozart/assert": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\PathUtil\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "A robust cross-platform utility for normalizing, comparing and modifying file paths.", + "time": "2016-08-15T15:31:42+00:00" + } + ], + "aliases": [], + "minimum-stability": "dev", + "stability-flags": { + "phpunit/phpunit": 0, + "vimeo/psalm": 0 + }, + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": "^7", + "ext-mbstring": "*" + }, + "platform-dev": [] +} diff --git a/src/Label/vendor/malios/php-to-ascii-table/docs/CONTRIBUTING.md b/src/Label/vendor/malios/php-to-ascii-table/docs/CONTRIBUTING.md new file mode 100644 index 00000000..b9f6ad7d --- /dev/null +++ b/src/Label/vendor/malios/php-to-ascii-table/docs/CONTRIBUTING.md @@ -0,0 +1,9 @@ +## Contributing + +1. Fork project +2. Create your feature branch: `git checkout -b my-new-feature` +3. Make changes +4. Run tests: `php vendor/bin/phpunit tests/` +5. Commit your changes: `git commit -am 'Add some feature'` +6. Push to the branch: `git push origin my-new-feature` +7. Submit a pull request diff --git a/src/Label/vendor/malios/php-to-ascii-table/psalm.xml b/src/Label/vendor/malios/php-to-ascii-table/psalm.xml new file mode 100644 index 00000000..42f355b2 --- /dev/null +++ b/src/Label/vendor/malios/php-to-ascii-table/psalm.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Label/vendor/malios/php-to-ascii-table/src/Builder.php b/src/Label/vendor/malios/php-to-ascii-table/src/Builder.php new file mode 100644 index 00000000..0e11e741 --- /dev/null +++ b/src/Label/vendor/malios/php-to-ascii-table/src/Builder.php @@ -0,0 +1,253 @@ +table = new Table(); + } + + /** + * Get the table + * + * @return Table + */ + public function getTable() : Table + { + return $this->table; + } + + /** + * Add single row. + * The value passed should be either an array or an JsonSerializable object + * + * @param array|\JsonSerializable $rowArrayOrObject + * @throws BuilderException + */ + public function addRow($rowArrayOrObject) + { + if (is_array($rowArrayOrObject)) { + $rowArray = $rowArrayOrObject; + } else if ($rowArrayOrObject instanceof \JsonSerializable) { + $rowArray = $rowArrayOrObject->jsonSerialize(); + } else { + throw new BuilderException(sprintf( + 'Row must be either an array or JsonSerializable, %s given instead', + gettype($rowArrayOrObject) + )); + } + + $row = new Row(); + foreach ($rowArray as $columnName => $value) { + $cell = new Cell($columnName, $value); + $row->addCell($cell); + } + + $this->table->addRow($row); + } + + public function setTitle(string $title) + { + $this->title = $title; + } + + /** + * Add multiple rows + * + * @param array[]|\JsonSerializable[] $rows + * @return void + */ + public function addRows(array $rows) + { + foreach ($rows as $row) { + $this->addRow($row); + } + } + + /** + * Show only specific columns of the table + * + * @param array $columnNames + * @return void + * @throws BuilderException + */ + public function showColumns(array $columnNames) + { + $this->table->setVisibleColumns($columnNames); + } + + /** + * Render table and return result string + * + * @return string + * @throws BuilderException + */ + public function renderTable() : string + { + if ($this->table->isEmpty()) throw new BuilderException('Cannot render empty table'); + + $visibleColumns = $this->table->getVisibleColumns(); + + // border for header and footer + $borderParts = array_map(function ($columnName) { + $width = $this->table->getColumnWidth($columnName); + return str_repeat(self::CHAR_LINE_SEPARATOR, ($width + 2)); + }, $visibleColumns->toArray()); + + $borderTop = self::CHAR_CORNER_TOP_LEFT + . join(self::CHAR_JOIN_TOP_INNER, $borderParts) + . self::CHAR_CORNER_TOP_RIGHT; + $borderMiddle = self::CHAR_JOIN_LEFT_INNER + . join(self::CHAR_JOIN_INNER, $borderParts) + . self::CHAR_JOIN_RIGHT_INNER; + $borderBottom = self::CHAR_CORNER_BOTTOM_LEFT + . join(self::CHAR_JOIN_BOTTOM_INNER, $borderParts) + . self::CHAR_CORNER_BOTTOM_RIGHT; + + $headerCells = array_map(function ($columnName) { + return new Cell($columnName, $columnName); + }, $visibleColumns->toArray()); + + $headerRow = new Row(); + $headerRow->addCells(...$headerCells); + $header = $this->renderRow($headerRow, $visibleColumns); + + $body = ''; + $rows = $this->table->getRows(); + $visibleColumns = $this->table->getVisibleColumns(); + foreach ($rows as $row) { + $currentLine = $this->renderRow($row, $visibleColumns); + $body .= $currentLine . PHP_EOL; + } + + if ($this->title === null) { + $titleString = ''; + } else { + $titlePadding = intdiv(max(0, mb_strwidth($borderTop) - mb_strwidth($this->title)), 2); + $titleString = str_repeat(' ', $titlePadding) . $this->title . PHP_EOL; + } + + $tableAsString = $titleString . $borderTop . PHP_EOL . $header . PHP_EOL . $borderMiddle . PHP_EOL . $body . $borderBottom; + return $tableAsString; + } + + /** + * Render single row and return string + * + * @param RowInterface $row + * @param Collection $columnNames + * @return string + */ + private function renderRow(RowInterface $row, Collection $columnNames) + { + $line = self::CHAR_CELL_SEPARATOR; + + // render cells of the row + foreach ($columnNames as $columnName) { + $colWidth = $this->table->getColumnWidth($columnName); + if ($row->hasCell($columnName)) { + $cell = $row->getCell($columnName); + $currentCell = $this->renderCell($cell, $colWidth); + } else { + $currentCell = $this->renderCell(new Cell($columnName, ''), $colWidth); + } + + $line .= $currentCell . self::CHAR_CELL_SEPARATOR; + } + + return $line; + } + + /** + * Render cell content with left and right padding depending on the column width + * + * @param CellInterface $cell + * @param int $colWidth + * @return string + */ + private function renderCell(CellInterface $cell, int $colWidth) : string + { + $filler = str_repeat(self::CHAR_CELL_PADDING, ($colWidth - $cell->getWidth())); + if ($cell->getAlign() == Cell::ALIGN_LEFT) { + $content = self::CHAR_CELL_PADDING . $cell->getValue() . $filler . self::CHAR_CELL_PADDING; + } else { + $content = self::CHAR_CELL_PADDING . $filler . $cell->getValue() . self::CHAR_CELL_PADDING; + } + return $content; + } +} diff --git a/src/Label/vendor/malios/php-to-ascii-table/src/Cell.php b/src/Label/vendor/malios/php-to-ascii-table/src/Cell.php new file mode 100644 index 00000000..9d779f06 --- /dev/null +++ b/src/Label/vendor/malios/php-to-ascii-table/src/Cell.php @@ -0,0 +1,105 @@ +setColumnName($columnName); + $this->setValue($value); + } + + /** + * {@inheritdoc} + */ + public function getValue() : string + { + return $this->value; + } + + /** + * {@inheritdoc} + */ + public function setValue($value) + { + if (is_float($value)) { + $round = round($value); + if (($value - $round) === (float)0) { + $this->value = number_format($value, 2, '.', ' '); + } else { + $this->value = (string) $value; + } + $this->align = self::ALIGN_RIGHT; + } elseif (is_int($value)) { + $this->value = (string) $value; + $this->align = self::ALIGN_RIGHT; + } else { + $this->value = (string) $value; + $this->align = self::ALIGN_LEFT; + } + + $this->width = mb_strwidth($this->value); + } + + public function getAlign(): int + { + return $this->align; + } + + /** + * {@inheritdoc} + */ + public function getColumnName() : string + { + return $this->columnName; + } + + /** + * {@inheritdoc} + */ + public function setColumnName(string $columnName) + { + $this->columnName = $columnName; + } + + /** + * {@inheritdoc} + */ + public function getWidth() : int + { + return $this->width; + } +} diff --git a/src/Label/vendor/malios/php-to-ascii-table/src/CellInterface.php b/src/Label/vendor/malios/php-to-ascii-table/src/CellInterface.php new file mode 100644 index 00000000..701fc401 --- /dev/null +++ b/src/Label/vendor/malios/php-to-ascii-table/src/CellInterface.php @@ -0,0 +1,48 @@ +cells = new Map(); + } + + /** + * {@inheritdoc} + */ + public function addCell(CellInterface $cell) + { + $this->cells->put($cell->getColumnName(), $cell); + } + + /** + * {@inheritdoc} + */ + public function addCells(CellInterface ...$cells) + { + foreach ($cells as $cell) { + $this->addCell($cell); + } + } + + /** + * {@inheritdoc} + */ + public function getCell($columnName) : CellInterface + { + return $this->cells->get($columnName); + } + + /** + * {@inheritdoc} + */ + public function hasCell($columnName) : bool + { + return $this->cells->hasKey($columnName); + } + + /** + * {@inheritdoc} + */ + public function getCells() : Collection + { + return $this->cells; + } +} diff --git a/src/Label/vendor/malios/php-to-ascii-table/src/RowInterface.php b/src/Label/vendor/malios/php-to-ascii-table/src/RowInterface.php new file mode 100644 index 00000000..4e5d6743 --- /dev/null +++ b/src/Label/vendor/malios/php-to-ascii-table/src/RowInterface.php @@ -0,0 +1,45 @@ +visibleColumns = new Set(); + $this->allColumns = new Set(); + $this->biggestValues = new Map(); + } + + /** + * {@inheritdoc} + */ + public function addRow(RowInterface $row) + { + foreach ($row->getCells() as $cell) { + $columnName = $cell->getColumnName(); + + $this->allColumns->add($columnName); + + $width = $cell->getWidth(); + if ($this->biggestValues->hasKey($columnName)) { + if ($width > $this->biggestValues->get($columnName)) { + $this->biggestValues->put($columnName, $width); + } + } else { + $this->biggestValues->put($columnName, $width); + } + } + + array_push($this->rows, $row); + } + + /** + * {@inheritdoc} + */ + public function getRows() : array + { + return $this->rows; + } + + /** + * {@inheritdoc} + */ + public function isEmpty() : bool + { + return empty($this->rows); + } + + /** + * {@inheritdoc} + */ + public function setVisibleColumns(array $columnNames) + { + $this->visibleColumns->clear(); + $this->visibleColumns->allocate(count($columnNames)); + $this->visibleColumns->add(...$columnNames); + } + + /** + * {@inheritdoc} + */ + public function getVisibleColumns() : Set + { + if ($this->visibleColumns->isEmpty()) { + return $this->getAllColumns(); + } + + return $this->visibleColumns; + } + + /** + * {@inheritdoc} + */ + public function getAllColumns() : Set + { + return $this->allColumns; + } + + /** + * {@inheritdoc} + */ + public function getColumnWidth(string $columnName) : int + { + $width = 0; + if ($this->biggestValues->hasKey($columnName)) { + $width = $this->biggestValues->get($columnName); + } + + $visibleColumns = $this->getVisibleColumns(); + if ($visibleColumns->contains($columnName) && mb_strwidth($columnName) > $width) { + $width = mb_strwidth($columnName); + } + + return $width; + } +} diff --git a/src/Label/vendor/malios/php-to-ascii-table/src/TableInterface.php b/src/Label/vendor/malios/php-to-ascii-table/src/TableInterface.php new file mode 100644 index 00000000..6b71ab3c --- /dev/null +++ b/src/Label/vendor/malios/php-to-ascii-table/src/TableInterface.php @@ -0,0 +1,58 @@ +=7.0", + "ext-json": "*" + }, + "require-dev": { + "php-ds/tests": "^1.3" + }, + "provide": { + "ext-ds": "1.3.0" + }, + "suggest": { + "ext-ds": "to improve performance and reduce memory usage" + }, + "scripts": { + "test": "phpunit" + }, + "autoload": { + "psr-4" : { + "Ds\\": "src" + } + } +} diff --git a/src/Label/vendor/php-ds/php-ds/src/Collection.php b/src/Label/vendor/php-ds/php-ds/src/Collection.php new file mode 100644 index 00000000..1172334c --- /dev/null +++ b/src/Label/vendor/php-ds/php-ds/src/Collection.php @@ -0,0 +1,56 @@ + + */ +interface Collection extends \IteratorAggregate, \Countable, \JsonSerializable +{ + /** + * Removes all values from the collection. + */ + public function clear(); + + /** + * Returns the size of the collection. + * + * @return int + */ + public function count(): int; + + /** + * Returns a shallow copy of the collection. + * + * @return static a copy of the collection. + * + * @psalm-return static + */ + public function copy(); + + /** + * Returns whether the collection is empty. + * + * This should be equivalent to a count of zero, but is not required. + * Implementations should define what empty means in their own context. + */ + public function isEmpty(): bool; + + /** + * Returns an array representation of the collection. + * + * The format of the returned array is implementation-dependent. + * Some implementations may throw an exception if an array representation + * could not be created. + * + * @return array + */ + public function toArray(): array; +} diff --git a/src/Label/vendor/php-ds/php-ds/src/Deque.php b/src/Label/vendor/php-ds/php-ds/src/Deque.php new file mode 100644 index 00000000..905200c5 --- /dev/null +++ b/src/Label/vendor/php-ds/php-ds/src/Deque.php @@ -0,0 +1,29 @@ + + */ +final class Deque implements Sequence +{ + use Traits\GenericCollection; + use Traits\GenericSequence; + use Traits\SquaredCapacity; + + public const MIN_CAPACITY = 8; + + protected function shouldIncreaseCapacity(): bool + { + return count($this) >= $this->capacity; + } +} diff --git a/src/Label/vendor/php-ds/php-ds/src/Hashable.php b/src/Label/vendor/php-ds/php-ds/src/Hashable.php new file mode 100644 index 00000000..a98b986a --- /dev/null +++ b/src/Label/vendor/php-ds/php-ds/src/Hashable.php @@ -0,0 +1,32 @@ + + */ +final class Map implements Collection, \ArrayAccess +{ + use Traits\GenericCollection; + use Traits\SquaredCapacity; + + public const MIN_CAPACITY = 8; + + /** + * @var array internal array to store pairs + * + * @psalm-var array + */ + private $pairs = []; + + /** + * Creates a new instance. + * + * @param iterable $values + * + * @psalm-param iterable $values + */ + public function __construct(iterable $values = []) + { + if (func_num_args()) { + $this->putAll($values); + } + + } + + /** + * Updates all values by applying a callback function to each value. + * + * @param callable $callback Accepts two arguments: key and value, should + * return what the updated value will be. + * + * @psalm-param callable(TKey, TValue): TValue $callback + */ + public function apply(callable $callback) + { + foreach ($this->pairs as &$pair) { + $pair->value = $callback($pair->key, $pair->value); + } + } + + /** + * @inheritDoc + */ + public function clear() + { + $this->pairs = []; + $this->capacity = self::MIN_CAPACITY; + } + + /** + * Return the first Pair from the Map + * + * @return Pair + * + * @throws UnderflowException + * + * @psalm-return Pair + */ + public function first(): Pair + { + if ($this->isEmpty()) { + throw new UnderflowException(); + } + + return $this->pairs[0]; + } + + /** + * Return the last Pair from the Map + * + * @return Pair + * + * @throws UnderflowException + * + * @psalm-return Pair + */ + public function last(): Pair + { + if ($this->isEmpty()) { + throw new UnderflowException(); + } + + return $this->pairs[count($this->pairs) - 1]; + } + + /** + * Return the pair at a specified position in the Map + * + * @return Pair + * + * @throws OutOfRangeException + * + * @psalm-return Pair + */ + public function skip(int $position): Pair + { + if ($position < 0 || $position >= count($this->pairs)) { + throw new OutOfRangeException(); + } + + return $this->pairs[$position]->copy(); + } + + /** + * Returns the result of associating all keys of a given traversable object + * or array with their corresponding values, as well as those of this map. + * + * @param array|\Traversable $values + * + * @return Map + * + * @template TKey2 + * @template TValue2 + * @psalm-param iterable $values + * @psalm-return Map + */ + public function merge($values): Map + { + $merged = new self($this); + $merged->putAll($values); + return $merged; + } + + /** + * Creates a new map containing the pairs of the current instance whose keys + * are also present in the given map. In other words, returns a copy of the + * current map with all keys removed that are not also in the other map. + * + * @param Map $map The other map. + * + * @return Map A new map containing the pairs of the current instance + * whose keys are also present in the given map. In other + * words, returns a copy of the current map with all keys + * removed that are not also in the other map. + * + * @template TKey2 + * @template TValue2 + * @psalm-param Map $map + * @psalm-return Map + */ + public function intersect(Map $map): Map + { + return $this->filter(function($key) use ($map) { + return $map->hasKey($key); + }); + } + + /** + * Returns the result of removing all keys from the current instance that + * are present in a given map. + * + * @param Map $map The map containing the keys to exclude. + * + * @return Map The result of removing all keys from the current instance + * that are present in a given map. + * + * @template TValue2 + * @psalm-param Map $map + * @psalm-return Map + */ + public function diff(Map $map): Map + { + return $this->filter(function($key) use ($map) { + return ! $map->hasKey($key); + }); + } + + /** + * Determines whether two keys are equal. + * + * @param mixed $a + * @param mixed $b + * + * @psalm-param TKey $a + * @psalm-param TKey $b + */ + private function keysAreEqual($a, $b): bool + { + if (is_object($a) && $a instanceof Hashable) { + return get_class($a) === get_class($b) && $a->equals($b); + } + + return $a === $b; + } + + /** + * Attempts to look up a key in the table. + * + * @param $key + * + * @return Pair|null + * + * @psalm-return Pair|null + */ + private function lookupKey($key) + { + foreach ($this->pairs as $pair) { + if ($this->keysAreEqual($pair->key, $key)) { + return $pair; + } + } + } + + /** + * Attempts to look up a value in the table. + * + * @param $value + * + * @return Pair|null + * + * @psalm-return Pair|null + */ + private function lookupValue($value) + { + foreach ($this->pairs as $pair) { + if ($pair->value === $value) { + return $pair; + } + } + } + + /** + * Returns whether an association a given key exists. + * + * @param mixed $key + * + * @psalm-param TKey $key + */ + public function hasKey($key): bool + { + return $this->lookupKey($key) !== null; + } + + /** + * Returns whether an association for a given value exists. + * + * @param mixed $value + * + * @psalm-param TValue $value + */ + public function hasValue($value): bool + { + return $this->lookupValue($value) !== null; + } + + /** + * @inheritDoc + */ + public function count(): int + { + return count($this->pairs); + } + + /** + * Returns a new map containing only the values for which a predicate + * returns true. A boolean test will be used if a predicate is not provided. + * + * @param callable|null $callback Accepts a key and a value, and returns: + * true : include the value, + * false: skip the value. + * + * @return Map + * + * @psalm-param (callable(TKey, TValue): bool)|null $callback + * @psalm-return Map + */ + public function filter(callable $callback = null): Map + { + $filtered = new self(); + + foreach ($this as $key => $value) { + if ($callback ? $callback($key, $value) : $value) { + $filtered->put($key, $value); + } + } + + return $filtered; + } + + /** + * Returns the value associated with a key, or an optional default if the + * key is not associated with a value. + * + * @param mixed $key + * @param mixed $default + * + * @return mixed The associated value or fallback default if provided. + * + * @throws OutOfBoundsException if no default was provided and the key is + * not associated with a value. + * + * @template TDefault + * @psalm-param TKey $key + * @psalm-param TDefault $default + * @psalm-return TValue|TDefault + */ + public function get($key, $default = null) + { + if (($pair = $this->lookupKey($key))) { + return $pair->value; + } + + // Check if a default was provided. + if (func_num_args() === 1) { + throw new OutOfBoundsException(); + } + + return $default; + } + + /** + * Returns a set of all the keys in the map. + * + * @return Set + * + * @psalm-return Set + */ + public function keys(): Set + { + $key = function($pair) { + return $pair->key; + }; + + return new Set(array_map($key, $this->pairs)); + } + + /** + * Returns a new map using the results of applying a callback to each value. + * + * The keys will be equal in both maps. + * + * @param callable $callback Accepts two arguments: key and value, should + * return what the updated value will be. + * + * @return Map + * + * @template TNewValue + * @psalm-param callable(TKey, TValue): TNewValue $callback + * @psalm-return Map + */ + public function map(callable $callback): Map + { + $mapped = new self(); + foreach ($this->pairs as $pair) { + $mapped->put($pair->key, $callback($pair->key, $pair->value)); + } + + return $mapped; + } + + /** + * Returns a sequence of pairs representing all associations. + * + * @return Sequence + * + * @psalm-return Sequence> + */ + public function pairs(): Sequence + { + $copy = function($pair) { + return $pair->copy(); + }; + + return new Vector(array_map($copy, $this->pairs)); + } + + /** + * Associates a key with a value, replacing a previous association if there + * was one. + * + * @param mixed $key + * @param mixed $value + * + * @psalm-param TKey $key + * @psalm-param TValue $value + */ + public function put($key, $value) + { + $pair = $this->lookupKey($key); + + if ($pair) { + $pair->value = $value; + + } else { + $this->checkCapacity(); + $this->pairs[] = new Pair($key, $value); + } + } + + /** + * Creates associations for all keys and corresponding values of either an + * array or iterable object. + * + * @param iterable $values + * + * @psalm-param iterable $values + */ + public function putAll(iterable $values) + { + foreach ($values as $key => $value) { + $this->put($key, $value); + } + } + + /** + * Iteratively reduces the map to a single value using a callback. + * + * @param callable $callback Accepts the carry, key, and value, and + * returns an updated carry value. + * + * @param mixed|null $initial Optional initial carry value. + * + * @return mixed The carry value of the final iteration, or the initial + * value if the map was empty. + * + * @template TCarry + * @psalm-param callable(TCarry, TKey, TValue): TCarry $callback + * @psalm-param TCarry $initial + * @psalm-return TCarry + */ + public function reduce(callable $callback, $initial = null) + { + $carry = $initial; + + foreach ($this->pairs as $pair) { + $carry = $callback($carry, $pair->key, $pair->value); + } + + return $carry; + } + + /** + * Completely removes a pair from the internal array by position. It is + * important to remove it from the array and not just use 'unset'. + * + * @return mixed + * + * @psalm-return TValue + */ + private function delete(int $position) + { + $pair = $this->pairs[$position]; + $value = $pair->value; + + array_splice($this->pairs, $position, 1, null); + $this->checkCapacity(); + + return $value; + } + + /** + * Removes a key's association from the map and returns the associated value + * or a provided default if provided. + * + * @param mixed $key + * @param mixed $default + * + * @return mixed The associated value or fallback default if provided. + * + * @throws \OutOfBoundsException if no default was provided and the key is + * not associated with a value. + * + * @template TDefault + * @psalm-param TKey $key + * @psalm-param TDefault $default + * @psalm-return TValue|TDefault + */ + public function remove($key, $default = null) + { + foreach ($this->pairs as $position => $pair) { + if ($this->keysAreEqual($pair->key, $key)) { + return $this->delete($position); + } + } + + // Check if a default was provided + if (func_num_args() === 1) { + throw new \OutOfBoundsException(); + } + + return $default; + } + + /** + * Reverses the map in-place + */ + public function reverse() + { + $this->pairs = array_reverse($this->pairs); + } + + /** + * Returns a reversed copy of the map. + * + * @return Map + * + * @psalm-return Map + */ + public function reversed(): Map + { + $reversed = new self(); + $reversed->pairs = array_reverse($this->pairs); + + return $reversed; + } + + /** + * Returns a sub-sequence of a given length starting at a specified offset. + * + * @param int $offset If the offset is non-negative, the map will + * start at that offset in the map. If offset is + * negative, the map will start that far from the + * end. + * + * @param int|null $length If a length is given and is positive, the + * resulting set will have up to that many pairs in + * it. If the requested length results in an + * overflow, only pairs up to the end of the map + * will be included. + * + * If a length is given and is negative, the map + * will stop that many pairs from the end. + * + * If a length is not provided, the resulting map + * will contains all pairs between the offset and + * the end of the map. + * + * @return Map + * + * @psalm-return Map + */ + public function slice(int $offset, int $length = null): Map + { + $map = new self(); + + if (func_num_args() === 1) { + $slice = array_slice($this->pairs, $offset); + } else { + $slice = array_slice($this->pairs, $offset, $length); + } + + foreach ($slice as $pair) { + $map->put($pair->key, $pair->value); + } + + return $map; + } + + /** + * Sorts the map in-place, based on an optional callable comparator. + * + * The map will be sorted by value. + * + * @param callable|null $comparator Accepts two values to be compared. + * + * @psalm-param (callable(TValue, TValue): int)|null $comparator + */ + public function sort(callable $comparator = null) + { + if ($comparator) { + usort($this->pairs, function($a, $b) use ($comparator) { + return $comparator($a->value, $b->value); + }); + + } else { + usort($this->pairs, function($a, $b) { + return $a->value <=> $b->value; + }); + } + } + + /** + * Returns a sorted copy of the map, based on an optional callable + * comparator. The map will be sorted by value. + * + * @param callable|null $comparator Accepts two values to be compared. + * + * @return Map + * + * @psalm-param (callable(TValue, TValue): int)|null $comparator + * @psalm-return Map + */ + public function sorted(callable $comparator = null): Map + { + $copy = $this->copy(); + $copy->sort($comparator); + return $copy; + } + + /** + * Sorts the map in-place, based on an optional callable comparator. + * + * The map will be sorted by key. + * + * @param callable|null $comparator Accepts two keys to be compared. + * + * @psalm-param (callable(TKey, TKey): int)|null $comparator + */ + public function ksort(callable $comparator = null) + { + if ($comparator) { + usort($this->pairs, function($a, $b) use ($comparator) { + return $comparator($a->key, $b->key); + }); + + } else { + usort($this->pairs, function($a, $b) { + return $a->key <=> $b->key; + }); + } + } + + /** + * Returns a sorted copy of the map, based on an optional callable + * comparator. The map will be sorted by key. + * + * @param callable|null $comparator Accepts two keys to be compared. + * + * @return Map + * + * @psalm-param (callable(TKey, TKey): int)|null $comparator + * @psalm-return Map + */ + public function ksorted(callable $comparator = null): Map + { + $copy = $this->copy(); + $copy->ksort($comparator); + return $copy; + } + + /** + * Returns the sum of all values in the map. + * + * @return int|float The sum of all the values in the map. + */ + public function sum() + { + return $this->values()->sum(); + } + + /** + * @inheritDoc + */ + public function toArray(): array + { + $array = []; + + foreach ($this->pairs as $pair) { + $array[$pair->key] = $pair->value; + } + + return $array; + } + + /** + * Returns a sequence of all the associated values in the Map. + * + * @return Sequence + * + * @psalm-return Sequence + */ + public function values(): Sequence + { + $value = function($pair) { + return $pair->value; + }; + + return new Vector(array_map($value, $this->pairs)); + } + + /** + * Creates a new map that contains the pairs of the current instance as well + * as the pairs of another map. + * + * @param Map $map The other map, to combine with the current instance. + * + * @return Map A new map containing all the pairs of the current + * instance as well as another map. + * + * @template TKey2 + * @template TValue2 + * @psalm-param Map $map + * @psalm-return Map + */ + public function union(Map $map): Map + { + return $this->merge($map); + } + + /** + * Creates a new map using keys of either the current instance or of another + * map, but not of both. + * + * @param Map $map + * + * @return Map A new map containing keys in the current instance as well + * as another map, but not in both. + * + * @template TKey2 + * @template TValue2 + * @psalm-param Map $map + * @psalm-return Map + */ + public function xor(Map $map): Map + { + return $this->merge($map)->filter(function($key) use ($map) { + return $this->hasKey($key) ^ $map->hasKey($key); + }); + } + + /** + * @inheritDoc + */ + #[\ReturnTypeWillChange] + public function getIterator() + { + foreach ($this->pairs as $pair) { + yield $pair->key => $pair->value; + } + } + + /** + * Returns a representation to be used for var_dump and print_r. + * + * @psalm-return array> + */ + public function __debugInfo() + { + return $this->pairs()->toArray(); + } + + /** + * @inheritdoc + */ + #[\ReturnTypeWillChange] + public function offsetSet($offset, $value) + { + $this->put($offset, $value); + } + + /** + * @inheritdoc + * + * @throws OutOfBoundsException + */ + #[\ReturnTypeWillChange] + public function &offsetGet($offset) + { + $pair = $this->lookupKey($offset); + + if ($pair) { + return $pair->value; + } + throw new OutOfBoundsException(); + } + + /** + * @inheritdoc + */ + #[\ReturnTypeWillChange] + public function offsetUnset($offset) + { + $this->remove($offset, null); + } + + /** + * @inheritdoc + */ + #[\ReturnTypeWillChange] + public function offsetExists($offset) + { + return $this->get($offset, null) !== null; + } + + /** + * Returns a representation that can be natively converted to JSON, which is + * called when invoking json_encode. + * + * @return mixed + * + * @see \JsonSerializable + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return (object) $this->toArray(); + } +} diff --git a/src/Label/vendor/php-ds/php-ds/src/Pair.php b/src/Label/vendor/php-ds/php-ds/src/Pair.php new file mode 100644 index 00000000..e3a97b88 --- /dev/null +++ b/src/Label/vendor/php-ds/php-ds/src/Pair.php @@ -0,0 +1,158 @@ +key = $key; + $this->value = $value; + } + + /** + * + * @param mixed $name + * + * @return mixed|null + */ + public function __isset($name) + { + if ($name === 'key' || $name === 'value') { + return $this->$name !== null; + } + return false; + } + + /** + * This allows unset($pair->key) to not completely remove the property, + * but be set to null instead. + * + * @return void + */ + public function __unset(string $name) + { + if ($name === 'key' || $name === 'value') { + $this->$name = null; + return; + } + throw new OutOfBoundsException(); + } + + /** + * @param mixed $name + * + * @return mixed|null + */ + public function &__get($name) + { + if ($name === 'key' || $name === 'value') { + return $this->$name; + } + throw new OutOfBoundsException(); + } + + /** + * @param mixed $name + * @param mixed $value + * + * @return mixed|null + */ + public function __set($name, $value) + { + if ($name === 'key' || $name === 'value') { + $this->$name = $value; + return; + } + throw new OutOfBoundsException(); + } + + /** + * Returns a copy of the Pair + * + * @psalm-return self + */ + public function copy(): self + { + return new self($this->key, $this->value); + } + + /** + * Returns a representation to be used for var_dump and print_r. + * + * @return array + * + * @psalm-return array{key: TKey, value: TValue} + */ + public function __debugInfo() + { + return $this->toArray(); + } + + /** + * @inheritDoc + * + * @psalm-return array{key: TKey, value: TValue} + */ + public function toArray(): array + { + return [ + 'key' => $this->key, + 'value' => $this->value, + ]; + } + + /** + * @inheritDoc + * + * @psalm-return array{key: TKey, value: TValue} + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return $this->toArray(); + } + + /** + * Returns a string representation of the pair. + */ + public function __toString() + { + return 'object(' . get_class($this) . ')'; + } +} diff --git a/src/Label/vendor/php-ds/php-ds/src/PriorityQueue.php b/src/Label/vendor/php-ds/php-ds/src/PriorityQueue.php new file mode 100644 index 00000000..5cd71d3e --- /dev/null +++ b/src/Label/vendor/php-ds/php-ds/src/PriorityQueue.php @@ -0,0 +1,340 @@ + + */ +final class PriorityQueue implements Collection +{ + use Traits\GenericCollection; + use Traits\SquaredCapacity; + + public const MIN_CAPACITY = 8; + + /** + * @var array> + */ + private $heap = []; + + /** + * @var int + */ + private $stamp = 0; + + /** + * Creates a new instance. + */ + public function __construct() + { + } + + /** + * @inheritDoc + */ + public function clear() + { + $this->heap = []; + $this->stamp = 0; + $this->capacity = self::MIN_CAPACITY; + } + + /** + * @inheritDoc + */ + public function copy(): self + { + $copy = new PriorityQueue(); + + $copy->heap = $this->heap; + $copy->stamp = $this->stamp; + $copy->capacity = $this->capacity; + + return $copy; + } + + /** + * @inheritDoc + */ + public function count(): int + { + return count($this->heap); + } + + /** + * Returns the value with the highest priority in the priority queue. + * + * @return mixed + * + * @throw UnderflowException + * + * @psalm-return TValue + */ + public function peek() + { + if ($this->isEmpty()) { + throw new UnderflowException(); + } + + return $this->heap[0]->value; + } + + /** + * Returns the index of a node's left leaf. + * + * @param int $index The index of the node. + * + * @return int The index of the left leaf. + */ + private function left(int $index): int + { + return ($index * 2) + 1; + } + + /** + * Returns the index of a node's right leaf. + * + * @param int $index The index of the node. + * + * @return int The index of the right leaf. + */ + private function right(int $index): int + { + return ($index * 2) + 2; + } + + /** + * Returns the index of a node's parent node. + * + * @param int $index The index of the node. + * + * @return int The index of the parent. + */ + private function parent(int $index): int + { + return (int) (($index - 1) / 2); + } + + /** + * Compares two indices of the heap. + * + * @return int + */ + private function compare(int $a, int $b) + { + $x = $this->heap[$a]; + $y = $this->heap[$b]; + + // Compare priority, using insertion stamp as fallback. + return ($x->priority <=> $y->priority) ?: ($y->stamp <=> $x->stamp); + } + + /** + * Swaps the nodes at two indices of the heap. + */ + private function swap(int $a, int $b) + { + $temp = $this->heap[$a]; + $this->heap[$a] = $this->heap[$b]; + $this->heap[$b] = $temp; + } + + /** + * Returns the index of a node's largest leaf node. + * + * @param int $parent the parent node. + * + * @return int the index of the node's largest leaf node. + */ + private function getLargestLeaf(int $parent) + { + $left = $this->left($parent); + $right = $this->right($parent); + + if ($right < count($this->heap) && $this->compare($left, $right) < 0) { + return $right; + } + + return $left; + } + + /** + * Starts the process of sifting down a given node index to ensure that + * the heap's properties are preserved. + */ + private function siftDown(int $node) + { + $last = floor(count($this->heap) / 2); + + for ($parent = $node; $parent < $last; $parent = $leaf) { + + // Determine the largest leaf to potentially swap with the parent. + $leaf = $this->getLargestLeaf($parent); + + // Done if the parent is not greater than its largest leaf + if ($this->compare($parent, $leaf) > 0) { + break; + } + + $this->swap($parent, $leaf); + } + } + + /** + * Sets the root node and sifts it down the heap. + * + * @param PriorityNode $node + */ + private function setRoot(PriorityNode $node) + { + $this->heap[0] = $node; + $this->siftDown(0); + } + + /** + * Returns the root node of the heap. + * + * @return PriorityNode + */ + private function getRoot(): PriorityNode + { + return $this->heap[0]; + } + + /** + * Returns and removes the value with the highest priority in the queue. + * + * @return mixed + * + * @psalm-return TValue + */ + public function pop() + { + if ($this->isEmpty()) { + throw new UnderflowException(); + } + + // Last leaf of the heap to become the new root. + $leaf = array_pop($this->heap); + + if (empty($this->heap)) { + return $leaf->value; + } + + // Cache the current root value to return before replacing with next. + $value = $this->getRoot()->value; + + // Replace the root, then sift down. + $this->setRoot($leaf); + $this->checkCapacity(); + + return $value; + } + + /** + * Sifts a node up the heap until it's in the right position. + */ + private function siftUp(int $leaf) + { + for (; $leaf > 0; $leaf = $parent) { + $parent = $this->parent($leaf); + + // Done when parent priority is greater. + if ($this->compare($leaf, $parent) < 0) { + break; + } + + $this->swap($parent, $leaf); + } + } + + /** + * Pushes a value into the queue, with a specified priority. + * + * @param mixed $value + * + * @psalm-param TValue $value + */ + public function push($value, int $priority) + { + $this->checkCapacity(); + + // Add new leaf, then sift up to maintain heap, + $this->heap[] = new PriorityNode($value, $priority, $this->stamp++); + $this->siftUp(count($this->heap) - 1); + } + + /** + * @inheritDoc + */ + public function toArray(): array + { + $heap = $this->heap; + $array = []; + + while ( ! $this->isEmpty()) { + $array[] = $this->pop(); + } + + $this->heap = $heap; + return $array; + } + + /** + * @inheritDoc + */ + #[\ReturnTypeWillChange] + public function getIterator() + { + while ( ! $this->isEmpty()) { + yield $this->pop(); + } + } +} + +/** + * @internal + * + * @template TValue + */ +final class PriorityNode +{ + /** + * @var mixed + * + * @psalm-var TValue + */ + public $value; + + /** + * @var int + */ + public $priority; + + /** + * @var int + */ + public $stamp; + + /** + * @param mixed $value + * @param int $priority + * @param int $stamp + * + * @psalm-param TValue $value + */ + public function __construct($value, int $priority, int $stamp) + { + $this->value = $value; + $this->priority = $priority; + $this->stamp = $stamp; + } +} diff --git a/src/Label/vendor/php-ds/php-ds/src/Queue.php b/src/Label/vendor/php-ds/php-ds/src/Queue.php new file mode 100644 index 00000000..b9aeff03 --- /dev/null +++ b/src/Label/vendor/php-ds/php-ds/src/Queue.php @@ -0,0 +1,195 @@ + + */ +final class Queue implements Collection, \ArrayAccess +{ + use Traits\GenericCollection; + + /** + * @var Deque internal deque to store values. + * + * @psalm-var Deque + */ + private $deque; + + /** + * Creates an instance using the values of an array or Traversable object. + * + * @param iterable $values + * + * @psalm-param iterable $values + */ + public function __construct(iterable $values = []) + { + $this->deque = new Deque($values); + } + + /** + * Ensures that enough memory is allocated for a specified capacity. This + * potentially reduces the number of reallocations as the size increases. + * + * @param int $capacity The number of values for which capacity should be + * allocated. Capacity will stay the same if this value + * is less than or equal to the current capacity. + */ + public function allocate(int $capacity) + { + $this->deque->allocate($capacity); + } + + /** + * Returns the current capacity of the queue. + */ + public function capacity(): int + { + return $this->deque->capacity(); + } + + /** + * @inheritDoc + */ + public function clear() + { + $this->deque->clear(); + } + + /** + * @inheritDoc + */ + public function copy(): self + { + return new self($this->deque); + } + + /** + * @inheritDoc + */ + public function count(): int + { + return count($this->deque); + } + + /** + * Returns the value at the front of the queue without removing it. + * + * @return mixed + * + * @psalm-return TValue + */ + public function peek() + { + return $this->deque->first(); + } + + /** + * Returns and removes the value at the front of the Queue. + * + * @return mixed + * + * @psalm-return TValue + */ + public function pop() + { + return $this->deque->shift(); + } + + /** + * Pushes zero or more values into the back of the queue. + * + * @param mixed ...$values + * + * @psalm-param TValue ...$values + */ + public function push(...$values) + { + $this->deque->push(...$values); + } + + /** + * @inheritDoc + */ + public function toArray(): array + { + return $this->deque->toArray(); + } + + /** + * Get iterator + */ + #[\ReturnTypeWillChange] + public function getIterator() + { + while ( ! $this->isEmpty()) { + yield $this->pop(); + } + } + + + /** + * @inheritdoc + * + * @throws OutOfBoundsException + */ + #[\ReturnTypeWillChange] + public function offsetSet($offset, $value) + { + if ($offset === null) { + $this->push($value); + } else { + throw new Error(); + } + } + + /** + * @inheritdoc + * + * @throws Error + */ + #[\ReturnTypeWillChange] + public function offsetGet($offset) + { + throw new Error(); + } + + /** + * @inheritdoc + * + * @throws Error + */ + #[\ReturnTypeWillChange] + public function offsetUnset($offset) + { + throw new Error(); + } + + /** + * @inheritdoc + * + * @throws Error + */ + #[\ReturnTypeWillChange] + public function offsetExists($offset) + { + throw new Error(); + } + + /** + * Ensures that the internal sequence will be cloned too. + */ + public function __clone() + { + $this->deque = clone $this->deque; + } +} diff --git a/src/Label/vendor/php-ds/php-ds/src/Sequence.php b/src/Label/vendor/php-ds/php-ds/src/Sequence.php new file mode 100644 index 00000000..c3a32995 --- /dev/null +++ b/src/Label/vendor/php-ds/php-ds/src/Sequence.php @@ -0,0 +1,330 @@ + + */ +interface Sequence extends Collection, \ArrayAccess +{ + /** + * Ensures that enough memory is allocated for a required capacity. + * + * @param int $capacity The number of values for which capacity should be + * allocated. Capacity will stay the same if this value + * is less than or equal to the current capacity. + */ + public function allocate(int $capacity); + + /** + * Updates every value in the sequence by applying a callback, using the + * return value as the new value. + * + * @param callable $callback Accepts the value, returns the new value. + * + * @psalm-param callable(TValue): TValue $callback + */ + public function apply(callable $callback); + + /** + * Returns the current capacity of the sequence. + * + * @return int + */ + public function capacity(): int; + + /** + * Determines whether the sequence contains all of zero or more values. + * + * @param mixed ...$values + * + * @return bool true if at least one value was provided and the sequence + * contains all given values, false otherwise. + * + * @psalm-param TValue ...$values + */ + public function contains(...$values): bool; + + /** + * Returns a new sequence containing only the values for which a callback + * returns true. A boolean test will be used if a callback is not provided. + * + * @param callable|null $callback Accepts a value, returns a boolean result: + * true : include the value, + * false: skip the value. + * + * @return Sequence + * + * @psalm-param (callable(TValue): bool)|null $callback + * @psalm-return Sequence + */ + public function filter(callable $callback = null): Sequence; + + /** + * Returns the index of a given value, or null if it could not be found. + * + * @param mixed $value + * + * @return int|null + * + * @psalm-param TValue $value + */ + public function find($value); + + /** + * Returns the first value in the sequence. + * + * @return mixed + * + * @throws \UnderflowException if the sequence is empty. + * + * @psalm-return TValue + */ + public function first(); + + /** + * Returns the value at a given index (position) in the sequence. + * + * @return mixed + * + * @throws \OutOfRangeException if the index is not in the range [0, size-1] + * + * @psalm-return TValue + */ + public function get(int $index); + + /** + * Inserts zero or more values at a given index. + * + * Each value after the index will be moved one position to the right. + * Values may be inserted at an index equal to the size of the sequence. + * + * @param mixed ...$values + * + * @throws \OutOfRangeException if the index is not in the range [0, n] + * + * @psalm-param TValue ...$values + */ + public function insert(int $index, ...$values); + + /** + * Joins all values of the sequence into a string, adding an optional 'glue' + * between them. Returns an empty string if the sequence is empty. + */ + public function join(string $glue = null): string; + + /** + * Returns the last value in the sequence. + * + * @return mixed + * + * @throws \UnderflowException if the sequence is empty. + * + * @psalm-return TValue + */ + public function last(); + + /** + * Returns a new sequence using the results of applying a callback to each + * value. + * + * @param callable $callback + * + * @return Sequence + * + * @template TNewValue + * @psalm-param callable(TValue): TNewValue $callback + * @psalm-return Sequence + */ + public function map(callable $callback): Sequence; + + /** + * Returns the result of adding all given values to the sequence. + * + * @param array|\Traversable $values + * + * @return Sequence + * + * @template TValue2 + * @psalm-param iterable $values + * @psalm-return Sequence + */ + public function merge($values): Sequence; + + /** + * Removes the last value in the sequence, and returns it. + * + * @return mixed what was the last value in the sequence. + * + * @throws \UnderflowException if the sequence is empty. + * + * @psalm-return TValue + */ + public function pop(); + + /** + * Adds zero or more values to the end of the sequence. + * + * @param mixed ...$values + * + * @psalm-param TValue ...$values + */ + public function push(...$values); + + /** + * Iteratively reduces the sequence to a single value using a callback. + * + * @param callable $callback Accepts the carry and current value, and + * returns an updated carry value. + * + * @param mixed|null $initial Optional initial carry value. + * + * @return mixed The carry value of the final iteration, or the initial + * value if the sequence was empty. + * + * @template TCarry + * @psalm-param callable(TCarry, TValue): TCarry $callback + * @psalm-param TCarry $initial + * @psalm-return TCarry + */ + public function reduce(callable $callback, $initial = null); + + /** + * Removes and returns the value at a given index in the sequence. + * + * @param int $index this index to remove. + * + * @return mixed the removed value. + * + * @throws \OutOfRangeException if the index is not in the range [0, size-1] + * + * @psalm-return TValue + */ + public function remove(int $index); + + /** + * Reverses the sequence in-place. + */ + public function reverse(); + + /** + * Returns a reversed copy of the sequence. + * + * @return Sequence + * + * @psalm-return Sequence + */ + public function reversed(); + + /** + * Rotates the sequence by a given number of rotations, which is equivalent + * to successive calls to 'shift' and 'push' if the number of rotations is + * positive, or 'pop' and 'unshift' if negative. + * + * @param int $rotations The number of rotations (can be negative). + */ + public function rotate(int $rotations); + + /** + * Replaces the value at a given index in the sequence with a new value. + * + * @param mixed $value + * + * @throws \OutOfRangeException if the index is not in the range [0, size-1] + * + * @psalm-param TValue $value + */ + public function set(int $index, $value); + + /** + * Removes and returns the first value in the sequence. + * + * @return mixed what was the first value in the sequence. + * + * @throws \UnderflowException if the sequence was empty. + * + * @psalm-return TValue + */ + public function shift(); + + /** + * Returns a sub-sequence of a given length starting at a specified index. + * + * @param int $index If the index is positive, the sequence will start + * at that index in the sequence. If index is negative, + * the sequence will start that far from the end. + * + * @param int $length If a length is given and is positive, the resulting + * sequence will have up to that many values in it. + * If the length results in an overflow, only values + * up to the end of the sequence will be included. + * + * If a length is given and is negative, the sequence + * will stop that many values from the end. + * + * If a length is not provided, the resulting sequence + * will contain all values between the index and the + * end of the sequence. + * + * @return Sequence + * + * @psalm-return Sequence + */ + public function slice(int $index, int $length = null): Sequence; + + /** + * Sorts the sequence in-place, based on an optional callable comparator. + * + * @param callable|null $comparator Accepts two values to be compared. + * Should return the result of a <=> b. + * + * @psalm-param (callable(TValue, TValue): int)|null $comparator + */ + public function sort(callable $comparator = null); + + /** + * Returns a sorted copy of the sequence, based on an optional callable + * comparator. Natural ordering will be used if a comparator is not given. + * + * @param callable|null $comparator Accepts two values to be compared. + * Should return the result of a <=> b. + * + * @return Sequence + * + * @psalm-param (callable(TValue, TValue): int)|null $comparator + * @psalm-return Sequence + */ + public function sorted(callable $comparator = null): Sequence; + + /** + * Returns the sum of all values in the sequence. + * + * @return int|float The sum of all the values in the sequence. + */ + public function sum(); + + /** + * @inheritDoc + * + * @return list + */ + function toArray(): array; + + /** + * Adds zero or more values to the front of the sequence. + * + * @param mixed ...$values + * + * @psalm-param TValue ...$values + */ + public function unshift(...$values); +} diff --git a/src/Label/vendor/php-ds/php-ds/src/Set.php b/src/Label/vendor/php-ds/php-ds/src/Set.php new file mode 100644 index 00000000..cd732311 --- /dev/null +++ b/src/Label/vendor/php-ds/php-ds/src/Set.php @@ -0,0 +1,538 @@ + + */ +final class Set implements Collection, \ArrayAccess +{ + use Traits\GenericCollection; + + public const MIN_CAPACITY = Map::MIN_CAPACITY; + + /** + * @var Map internal map to store the values. + * + * @psalm-var Map + */ + private $table; + + /** + * Creates a new set using the values of an array or Traversable object. + * The keys of either will not be preserved. + * + * @param iterable $values + * + * @psalm-param iterable $values + */ + public function __construct(iterable $values = []) + { + $this->table = new Map(); + + foreach ($values as $value) { + $this->add($value); + } + } + + /** + * Adds zero or more values to the set. + * + * @param mixed ...$values + * + * @psalm-param TValue ...$values + */ + public function add(...$values) + { + foreach ($values as $value) { + $this->table->put($value, null); + } + } + + /** + * Ensures that enough memory is allocated for a specified capacity. This + * potentially reduces the number of reallocations as the size increases. + * + * @param int $capacity The number of values for which capacity should be + * allocated. Capacity will stay the same if this value + * is less than or equal to the current capacity. + */ + public function allocate(int $capacity) + { + $this->table->allocate($capacity); + } + + /** + * Returns the current capacity of the set. + */ + public function capacity(): int + { + return $this->table->capacity(); + } + + /** + * Clear all elements in the Set + */ + public function clear() + { + $this->table->clear(); + } + + /** + * Determines whether the set contains all of zero or more values. + * + * @param mixed ...$values + * + * @return bool true if at least one value was provided and the set + * contains all given values, false otherwise. + * + * @psalm-param TValue ...$values + */ + public function contains(...$values): bool + { + foreach ($values as $value) { + if ( ! $this->table->hasKey($value)) { + return false; + } + } + + return true; + } + + /** + * @inheritDoc + */ + public function copy(): self + { + return new self($this); + } + + /** + * Returns the number of elements in the Stack + * + * @return int + */ + public function count(): int + { + return count($this->table); + } + + /** + * Creates a new set using values from this set that aren't in another set. + * + * Formally: A \ B = {x ∈ A | x ∉ B} + * + * @param Set $set + * + * @return Set + * + * @template TValue2 + * @psalm-param Set $set + * @psalm-return Set + */ + public function diff(Set $set): Set + { + return $this->table->diff($set->table)->keys(); + } + + /** + * Creates a new set using values in either this set or in another set, + * but not in both. + * + * Formally: A ⊖ B = {x : x ∈ (A \ B) ∪ (B \ A)} + * + * @param Set $set + * + * @return Set + * + * @template TValue2 + * @psalm-param Set $set + * @psalm-return Set + */ + public function xor(Set $set): Set + { + return $this->table->xor($set->table)->keys(); + } + + /** + * Returns a new set containing only the values for which a callback + * returns true. A boolean test will be used if a callback is not provided. + * + * @param callable|null $callback Accepts a value, returns a boolean: + * true : include the value, + * false: skip the value. + * + * @return Set + * + * @psalm-param (callable(TValue): bool)|null $callback + * @psalm-return Set + */ + public function filter(callable $callback = null): Set + { + return new self(array_filter($this->toArray(), $callback ?: 'boolval')); + } + + /** + * Returns the first value in the set. + * + * @return mixed the first value in the set. + * + * @psalm-return TValue + */ + public function first() + { + return $this->table->first()->key; + } + + /** + * Returns the value at a specified position in the set. + * + * @return mixed|null + * + * @throws OutOfRangeException + * + * @psalm-return TValue + */ + public function get(int $position) + { + return $this->table->skip($position)->key; + } + + /** + * Creates a new set using values common to both this set and another set. + * + * In other words, returns a copy of this set with all values removed that + * aren't in the other set. + * + * Formally: A ∩ B = {x : x ∈ A ∧ x ∈ B} + * + * @param Set $set + * + * @return Set + * + * @template TValue2 + * @psalm-param Set $set + * @psalm-return Set + */ + public function intersect(Set $set): Set + { + return $this->table->intersect($set->table)->keys(); + } + + /** + * @inheritDoc + */ + public function isEmpty(): bool + { + return $this->table->isEmpty(); + } + + /** + * Joins all values of the set into a string, adding an optional 'glue' + * between them. Returns an empty string if the set is empty. + * + * @param string|null $glue + */ + public function join(string $glue = null): string + { + return implode($glue ?? '', $this->toArray()); + } + + /** + * Returns the last value in the set. + * + * @return mixed the last value in the set. + * + * @psalm-return TValue + */ + public function last() + { + return $this->table->last()->key; + } + + /** + * Returns a new set using the results of applying a callback to each + * value. + * + * @param callable $callback + * + * @return Set + * + * @template TNewValue + * @psalm-param callable(TValue): TNewValue $callback + * @psalm-return Set + */ + public function map(callable $callback) { + return new self(array_map($callback, $this->toArray())); + } + + /** + * Iteratively reduces the set to a single value using a callback. + * + * @param callable $callback Accepts the carry and current value, and + * returns an updated carry value. + * + * @param mixed|null $initial Optional initial carry value. + * + * @return mixed The carry value of the final iteration, or the initial + * value if the set was empty. + * + * @template TCarry + * @psalm-param callable(TCarry, TValue): TCarry $callback + * @psalm-param TCarry $initial + * @psalm-return TCarry + */ + public function reduce(callable $callback, $initial = null) + { + $carry = $initial; + + foreach ($this as $value) { + $carry = $callback($carry, $value); + } + + return $carry; + } + + /** + * Removes zero or more values from the set. + * + * @param mixed ...$values + * + * @psalm-param TValue ...$values + */ + public function remove(...$values) + { + foreach ($values as $value) { + $this->table->remove($value, null); + } + } + + /** + * Reverses the set in-place. + */ + public function reverse() + { + $this->table->reverse(); + } + + /** + * Returns a reversed copy of the set. + * + * @return Set + * + * @psalm-return Set + */ + public function reversed(): Set + { + $reversed = $this->copy(); + $reversed->table->reverse(); + + return $reversed; + } + + /** + * Returns a subset of a given length starting at a specified offset. + * + * @param int $offset If the offset is non-negative, the set will start + * at that offset in the set. If offset is negative, + * the set will start that far from the end. + * + * @param int $length If a length is given and is positive, the resulting + * set will have up to that many values in it. + * If the requested length results in an overflow, only + * values up to the end of the set will be included. + * + * If a length is given and is negative, the set + * will stop that many values from the end. + * + * If a length is not provided, the resulting set + * will contains all values between the offset and the + * end of the set. + * + * @return Set + * + * @psalm-return Set + */ + public function slice(int $offset, int $length = null): Set + { + $sliced = new self(); + $sliced->table = $this->table->slice($offset, $length); + + return $sliced; + } + + /** + * Sorts the set in-place, based on an optional callable comparator. + * + * @param callable|null $comparator Accepts two values to be compared. + * Should return the result of a <=> b. + * + * @psalm-param (callable(TValue, TValue): int)|null $comparator + */ + public function sort(callable $comparator = null) + { + $this->table->ksort($comparator); + } + + /** + * Returns a sorted copy of the set, based on an optional callable + * comparator. Natural ordering will be used if a comparator is not given. + * + * @param callable|null $comparator Accepts two values to be compared. + * Should return the result of a <=> b. + * + * @return Set + * + * @psalm-param (callable(TValue, TValue): int)|null $comparator + * @psalm-return Set + */ + public function sorted(callable $comparator = null): Set + { + $sorted = $this->copy(); + $sorted->table->ksort($comparator); + + return $sorted; + } + + /** + * Returns the result of adding all given values to the set. + * + * @param array|\Traversable $values + * + * @return Set + * + * @template TValue2 + * @psalm-param iterable $values + * @psalm-return Set + */ + public function merge($values): Set + { + $merged = $this->copy(); + + foreach ($values as $value) { + $merged->add($value); + } + + return $merged; + } + + /** + * @inheritDoc + */ + public function toArray(): array + { + return iterator_to_array($this); + } + + /** + * Returns the sum of all values in the set. + * + * @return int|float The sum of all the values in the set. + */ + public function sum() + { + return array_sum($this->toArray()); + } + + /** + * Creates a new set that contains the values of this set as well as the + * values of another set. + * + * Formally: A ∪ B = {x: x ∈ A ∨ x ∈ B} + * + * @param Set $set + * + * @return Set + * + * @template TValue2 + * @psalm-param Set $set + * @psalm-return Set + */ + public function union(Set $set): Set + { + $union = new self(); + + foreach ($this as $value) { + $union->add($value); + } + + foreach ($set as $value) { + $union->add($value); + } + + return $union; + } + + /** + * Get iterator + */ + #[\ReturnTypeWillChange] + public function getIterator() + { + foreach ($this->table as $key => $value) { + yield $key; + } + } + + /** + * @inheritdoc + * + * @throws OutOfBoundsException + */ + #[\ReturnTypeWillChange] + public function offsetSet($offset, $value) + { + if ($offset === null) { + $this->add($value); + return; + } + throw new Error(); + } + + /** + * @inheritdoc + */ + #[\ReturnTypeWillChange] + public function offsetGet($offset) + { + return $this->table->skip($offset)->key; + } + + /** + * @inheritdoc + * + * @throws Error + */ + #[\ReturnTypeWillChange] + public function offsetExists($offset) + { + throw new Error(); + } + + /** + * @inheritdoc + * + * @throws Error + */ + #[\ReturnTypeWillChange] + public function offsetUnset($offset) + { + throw new Error(); + } + + /** + * Ensures that the internal table will be cloned too. + */ + public function __clone() + { + $this->table = clone $this->table; + } +} diff --git a/src/Label/vendor/php-ds/php-ds/src/Stack.php b/src/Label/vendor/php-ds/php-ds/src/Stack.php new file mode 100644 index 00000000..53b103fc --- /dev/null +++ b/src/Label/vendor/php-ds/php-ds/src/Stack.php @@ -0,0 +1,198 @@ + + */ +final class Stack implements Collection, \ArrayAccess +{ + use Traits\GenericCollection; + + /** + * @var Vector internal vector to store values of the stack. + * + * @psalm-var Vector + */ + private $vector; + + /** + * Creates an instance using the values of an array or Traversable object. + * + * @param iterable $values + * + * @psalm-param iterable $values + */ + public function __construct(iterable $values = []) + { + $this->vector = new Vector($values); + } + + /** + * Clear all elements in the Stack + */ + public function clear() + { + $this->vector->clear(); + } + + /** + * @inheritdoc + */ + public function copy(): self + { + return new self($this->vector); + } + + /** + * Returns the number of elements in the Stack + */ + public function count(): int + { + return count($this->vector); + } + + /** + * Ensures that enough memory is allocated for a specified capacity. This + * potentially reduces the number of reallocations as the size increases. + * + * @param int $capacity The number of values for which capacity should be + * allocated. Capacity will stay the same if this value + * is less than or equal to the current capacity. + */ + public function allocate(int $capacity) + { + $this->vector->allocate($capacity); + } + + /** + * Returns the current capacity of the stack. + */ + public function capacity(): int + { + return $this->vector->capacity(); + } + + /** + * Returns the value at the top of the stack without removing it. + * + * @return mixed + * + * @throws \UnderflowException if the stack is empty. + * + * @psalm-return TValue + */ + public function peek() + { + return $this->vector->last(); + } + + /** + * Returns and removes the value at the top of the stack. + * + * @return mixed + * + * @throws \UnderflowException if the stack is empty. + * + * @psalm-return TValue + */ + public function pop() + { + return $this->vector->pop(); + } + + /** + * Pushes zero or more values onto the top of the stack. + * + * @param mixed ...$values + * + * @psalm-param TValue ...$values + */ + public function push(...$values) + { + $this->vector->push(...$values); + } + + /** + * @inheritDoc + */ + public function toArray(): array + { + return array_reverse($this->vector->toArray()); + } + + /** + * + */ + #[\ReturnTypeWillChange] + public function getIterator() + { + while ( ! $this->isEmpty()) { + yield $this->pop(); + } + } + + /** + * @inheritdoc + * + * @throws OutOfBoundsException + */ + #[\ReturnTypeWillChange] + public function offsetSet($offset, $value) + { + if ($offset === null) { + $this->push($value); + } else { + throw new Error(); + } + } + + /** + * @inheritdoc + * + * @throws Error + */ + #[\ReturnTypeWillChange] + public function offsetGet($offset) + { + throw new Error(); + } + + /** + * @inheritdoc + * + * @throws Error + */ + #[\ReturnTypeWillChange] + public function offsetUnset($offset) + { + throw new Error(); + } + + /** + * @inheritdoc + * + * @throws Error + */ + #[\ReturnTypeWillChange] + public function offsetExists($offset) + { + throw new Error(); + } + + /** + * Ensures that the internal vector will be cloned too. + */ + public function __clone() + { + $this->vector = clone $this->vector; + } +} diff --git a/src/Label/vendor/php-ds/php-ds/src/Traits/Capacity.php b/src/Label/vendor/php-ds/php-ds/src/Traits/Capacity.php new file mode 100644 index 00000000..f59834ec --- /dev/null +++ b/src/Label/vendor/php-ds/php-ds/src/Traits/Capacity.php @@ -0,0 +1,130 @@ +capacity; + } + + /** + * Ensures that enough memory is allocated for a specified capacity. This + * potentially reduces the number of reallocations as the size increases. + * + * @param int $capacity The number of values for which capacity should be + * allocated. Capacity will stay the same if this value + * is less than or equal to the current capacity. + */ + public function allocate(int $capacity) + { + $this->capacity = max($capacity, $this->capacity); + } + + /** + * @return float the structures growth factor. + */ + protected function getGrowthFactor(): float + { + return 2; + } + + /** + * @return float to multiply by when decreasing capacity. + */ + protected function getDecayFactor(): float + { + return 0.5; + } + + /** + * @return float the ratio between size and capacity when capacity should be + * decreased. + */ + protected function getTruncateThreshold(): float + { + return 0.25; + } + + /** + * Checks and adjusts capacity if required. + */ + protected function checkCapacity() + { + if ($this->shouldIncreaseCapacity()) { + $this->increaseCapacity(); + } else { + if ($this->shouldDecreaseCapacity()) { + $this->decreaseCapacity(); + } + } + } + + /** + * @param int $total + */ + protected function ensureCapacity(int $total) + { + if ($total > $this->capacity()) { + $this->capacity = max($total, $this->nextCapacity()); + } + } + + /** + * @return bool whether capacity should be increased. + */ + protected function shouldIncreaseCapacity(): bool + { + return $this->count() >= $this->capacity(); + } + + protected function nextCapacity(): int + { + return (int) ($this->capacity() * $this->getGrowthFactor()); + } + + /** + * Called when capacity should be increased to accommodate new values. + */ + protected function increaseCapacity() + { + $this->capacity = max( + $this->count(), + $this->nextCapacity() + ); + } + + /** + * Called when capacity should be decrease if it drops below a threshold. + */ + protected function decreaseCapacity() + { + $this->capacity = max( + self::MIN_CAPACITY, + (int) ($this->capacity() * $this->getDecayFactor()) + ); + } + + /** + * @return bool whether capacity should be increased. + */ + protected function shouldDecreaseCapacity(): bool + { + return count($this) <= $this->capacity() * $this->getTruncateThreshold(); + } +} diff --git a/src/Label/vendor/php-ds/php-ds/src/Traits/GenericCollection.php b/src/Label/vendor/php-ds/php-ds/src/Traits/GenericCollection.php new file mode 100644 index 00000000..650230ce --- /dev/null +++ b/src/Label/vendor/php-ds/php-ds/src/Traits/GenericCollection.php @@ -0,0 +1,75 @@ +toArray(); + } + + /** + * Creates a shallow copy of the collection. + * + * @return static a shallow copy of the collection. + */ + public function copy(): self + { + return new static($this); + } + + /** + * Returns an array representation of the collection. + * + * The format of the returned array is implementation-dependent. Some + * implementations may throw an exception if an array representation + * could not be created (for example when object are used as keys). + * + * @return array + */ + abstract public function toArray(): array; + + /** + * Invoked when calling var_dump. + * + * @return array + */ + public function __debugInfo() + { + return $this->toArray(); + } + + /** + * Returns a string representation of the collection, which is invoked when + * the collection is converted to a string. + */ + public function __toString() + { + return 'object(' . get_class($this) . ')'; + } +} diff --git a/src/Label/vendor/php-ds/php-ds/src/Traits/GenericSequence.php b/src/Label/vendor/php-ds/php-ds/src/Traits/GenericSequence.php new file mode 100644 index 00000000..57678308 --- /dev/null +++ b/src/Label/vendor/php-ds/php-ds/src/Traits/GenericSequence.php @@ -0,0 +1,419 @@ + + */ + private $array = []; + + /** + * @param iterable $values + * + * @psalm-param iterable $values + */ + public function __construct(iterable $values = []) + { + foreach ($values as $value) { + $this->push($value); + } + + $this->capacity = max( + $values === null ? 0 : count($values), + $this::MIN_CAPACITY + ); + } + + /** + * @inheritdoc + */ + public function toArray(): array + { + return $this->array; + } + + /** + * @inheritdoc + */ + public function apply(callable $callback) + { + foreach ($this->array as &$value) { + $value = $callback($value); + } + } + + /** + * @inheritdoc + */ + public function merge($values): Sequence + { + $copy = $this->copy(); + $copy->push(...$values); + return $copy; + } + + /** + * @inheritdoc + */ + public function count(): int + { + return count($this->array); + } + + /** + * @inheritDoc + */ + public function contains(...$values): bool + { + foreach ($values as $value) { + if ($this->find($value) === null) { + return false; + } + } + + return true; + } + + /** + * @inheritDoc + */ + public function filter(callable $callback = null): Sequence + { + return new self(array_filter($this->array, $callback ?: 'boolval')); + } + + /** + * @inheritDoc + */ + public function find($value) + { + $offset = array_search($value, $this->array, true); + + return $offset === false ? null : $offset; + } + + /** + * @inheritDoc + */ + public function first() + { + if ($this->isEmpty()) { + throw new UnderflowException(); + } + + return $this->array[0]; + } + + /** + * @inheritDoc + */ + public function get(int $index) + { + if ( ! $this->validIndex($index)) { + throw new OutOfRangeException(); + } + + return $this->array[$index]; + } + + /** + * @inheritDoc + */ + public function insert(int $index, ...$values) + { + if ( ! $this->validIndex($index) && $index !== count($this)) { + throw new OutOfRangeException(); + } + + array_splice($this->array, $index, 0, $values); + $this->checkCapacity(); + } + + /** + * @inheritDoc + */ + public function join(string $glue = null): string + { + return implode($glue ?? '', $this->array); + } + + /** + * @inheritDoc + */ + public function last() + { + if ($this->isEmpty()) { + throw new UnderflowException(); + } + + return $this->array[count($this) - 1]; + } + + /** + * @inheritDoc + */ + public function map(callable $callback): Sequence + { + return new self(array_map($callback, $this->array)); + } + + /** + * @inheritDoc + */ + public function pop() + { + if ($this->isEmpty()) { + throw new UnderflowException(); + } + + $value = array_pop($this->array); + $this->checkCapacity(); + + return $value; + } + + /** + * @inheritDoc + */ + public function push(...$values) + { + $this->ensureCapacity($this->count() + count($values)); + + foreach ($values as $value) { + $this->array[] = $value; + } + } + + /** + * @inheritDoc + */ + public function reduce(callable $callback, $initial = null) + { + return array_reduce($this->array, $callback, $initial); + } + + /** + * @inheritDoc + */ + public function remove(int $index) + { + if ( ! $this->validIndex($index)) { + throw new OutOfRangeException(); + } + + $value = array_splice($this->array, $index, 1, null)[0]; + $this->checkCapacity(); + + return $value; + } + + /** + * @inheritDoc + */ + public function reverse() + { + $this->array = array_reverse($this->array); + } + + /** + * @inheritDoc + */ + public function reversed(): Sequence + { + return new self(array_reverse($this->array)); + } + + /** + * Converts negative or large rotations into the minimum positive number + * of rotations required to rotate the sequence by a given $r. + */ + private function normalizeRotations(int $r) + { + $n = count($this); + + if ($n < 2) return 0; + if ($r < 0) return $n - (abs($r) % $n); + + return $r % $n; + } + + /** + * @inheritDoc + */ + public function rotate(int $rotations) + { + for ($r = $this->normalizeRotations($rotations); $r > 0; $r--) { + array_push($this->array, array_shift($this->array)); + } + } + + /** + * @inheritDoc + */ + public function set(int $index, $value) + { + if ( ! $this->validIndex($index)) { + throw new OutOfRangeException(); + } + + $this->array[$index] = $value; + } + + /** + * @inheritDoc + */ + public function shift() + { + if ($this->isEmpty()) { + throw new UnderflowException(); + } + + $value = array_shift($this->array); + $this->checkCapacity(); + + return $value; + } + + /** + * @inheritDoc + */ + public function slice(int $offset, int $length = null): Sequence + { + if (func_num_args() === 1) { + $length = count($this); + } + + return new self(array_slice($this->array, $offset, $length)); + } + + /** + * @inheritDoc + */ + public function sort(callable $comparator = null) + { + if ($comparator) { + usort($this->array, $comparator); + } else { + sort($this->array); + } + } + + /** + * @inheritDoc + */ + public function sorted(callable $comparator = null): Sequence + { + $copy = $this->copy(); + $copy->sort($comparator); + return $copy; + } + + /** + * @inheritDoc + */ + public function sum() + { + return array_sum($this->array); + } + + /** + * @inheritDoc + */ + public function unshift(...$values) + { + if ($values) { + $this->array = array_merge($values, $this->array); + $this->checkCapacity(); + } + } + + /** + * + */ + private function validIndex(int $index) + { + return $index >= 0 && $index < count($this); + } + + /** + * + */ + #[\ReturnTypeWillChange] + public function getIterator() + { + foreach ($this->array as $value) { + yield $value; + } + } + + /** + * @inheritdoc + */ + public function clear() + { + $this->array = []; + $this->capacity = self::MIN_CAPACITY; + } + + /** + * @inheritdoc + */ + #[\ReturnTypeWillChange] + public function offsetSet($offset, $value) + { + if ($offset === null) { + $this->push($value); + } else { + $this->set($offset, $value); + } + } + + /** + * @inheritdoc + */ + #[\ReturnTypeWillChange] + public function &offsetGet($offset) + { + if ( ! $this->validIndex($offset)) { + throw new OutOfRangeException(); + } + + return $this->array[$offset]; + } + + /** + * @inheritdoc + */ + #[\ReturnTypeWillChange] + public function offsetUnset($offset) + { + if (is_integer($offset) && $this->validIndex($offset)) { + $this->remove($offset); + } + } + + /** + * @inheritdoc + */ + #[\ReturnTypeWillChange] + public function offsetExists($offset) + { + return is_integer($offset) + && $this->validIndex($offset) + && $this->get($offset) !== null; + } +} diff --git a/src/Label/vendor/php-ds/php-ds/src/Traits/SquaredCapacity.php b/src/Label/vendor/php-ds/php-ds/src/Traits/SquaredCapacity.php new file mode 100644 index 00000000..01bd25aa --- /dev/null +++ b/src/Label/vendor/php-ds/php-ds/src/Traits/SquaredCapacity.php @@ -0,0 +1,58 @@ +capacity = max($this->square($capacity), $this->capacity); + } + + /** + * Called when capacity should be increased to accommodate new values. + */ + protected function increaseCapacity() + { + $this->capacity = $this->square( + max( + count($this) + 1, + $this->capacity * $this->getGrowthFactor() + ) + ); + } + + /** + * @param int $total + */ + protected function ensureCapacity(int $total) + { + while ($total > $this->capacity()) { + $this->increaseCapacity(); + } + } +} diff --git a/src/Label/vendor/php-ds/php-ds/src/Vector.php b/src/Label/vendor/php-ds/php-ds/src/Vector.php new file mode 100644 index 00000000..adc38dc4 --- /dev/null +++ b/src/Label/vendor/php-ds/php-ds/src/Vector.php @@ -0,0 +1,35 @@ + + */ +final class Vector implements Sequence +{ + use Traits\GenericCollection; + use Traits\GenericSequence; + use Traits\Capacity; + + public const MIN_CAPACITY = 8; + + protected function getGrowthFactor(): float + { + return 1.5; + } + + /** + * @return bool whether capacity should be increased. + */ + protected function shouldIncreaseCapacity(): bool + { + return count($this) > $this->capacity; + } +}